mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-11-16 01:21:16 +01:00
refactor(service): make validation methods non-static in VeraPDFService
- Changed `validatePDF` and `validateAllDeclaredStandards` methods from static to instance methods - Updated comments to include explicit null checks for better NPE prevention in warning logic Signed-off-by: Balázs Szücs <bszucs1209@gmail.com>
This commit is contained in:
parent
b733dae1af
commit
525864ff2c
@ -61,90 +61,37 @@ public class VeraPDFService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PDFVerificationResult validatePDF(InputStream pdfStream, String standardString)
|
private static boolean isWarningByMessage(String message) {
|
||||||
throws IOException, ValidationException, ModelParsingException, EncryptedPdfException {
|
// Check for null or blank message - explicit null check is necessary to avoid NPE
|
||||||
|
if (message == null || message.isBlank()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
byte[] pdfBytes = pdfStream.readAllBytes();
|
String normalized = message.toLowerCase(Locale.ROOT);
|
||||||
PDFAFlavour validationFlavour = PDFAFlavour.fromString(standardString);
|
|
||||||
Optional<PDFAFlavour> declaredPdfaFlavour = extractDeclaredPdfaFlavour(pdfBytes);
|
|
||||||
|
|
||||||
try (PDFAParser parser =
|
return normalized.contains("recommended")
|
||||||
Foundries.defaultInstance()
|
|| normalized.contains("should")
|
||||||
.createParser(new ByteArrayInputStream(pdfBytes), validationFlavour)) {
|
|| normalized.contains("optional")
|
||||||
PDFAValidator validator =
|
|| normalized.contains("missing recommended");
|
||||||
Foundries.defaultInstance().createValidator(validationFlavour, false);
|
}
|
||||||
ValidationResult result = validator.validate(parser);
|
|
||||||
|
|
||||||
return convertToVerificationResult(
|
private static boolean isWarningByClause(String clause) {
|
||||||
result, declaredPdfaFlavour.orElse(null), validationFlavour);
|
// Check for null or blank clause - explicit null check is necessary to avoid NPE
|
||||||
|
if (clause == null || clause.isBlank()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clause.startsWith("6.7")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String criticalPrefix : CRITICAL_CLAUSE_PREFIXES) {
|
||||||
|
if (clause.startsWith(criticalPrefix)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<PDFVerificationResult> validateAllDeclaredStandards(InputStream pdfStream)
|
return true;
|
||||||
throws IOException, ValidationException, ModelParsingException, EncryptedPdfException {
|
|
||||||
|
|
||||||
byte[] pdfBytes = pdfStream.readAllBytes();
|
|
||||||
Optional<PDFAFlavour> declaredPdfaFlavour = extractDeclaredPdfaFlavour(pdfBytes);
|
|
||||||
List<PDFVerificationResult> results = new ArrayList<>();
|
|
||||||
|
|
||||||
List<PDFAFlavour> detectedFlavours;
|
|
||||||
try (PDFAParser detectionParser =
|
|
||||||
Foundries.defaultInstance().createParser(new ByteArrayInputStream(pdfBytes))) {
|
|
||||||
detectedFlavours = detectionParser.getFlavours();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<PDFAFlavour> flavoursToValidate = new ArrayList<>();
|
|
||||||
|
|
||||||
declaredPdfaFlavour.ifPresent(flavoursToValidate::add);
|
|
||||||
|
|
||||||
for (PDFAFlavour flavour : detectedFlavours) {
|
|
||||||
if (PDFFlavours.isFlavourFamily(flavour, PDFAFlavour.SpecificationFamily.PDF_A)) {
|
|
||||||
if (declaredPdfaFlavour.isPresent() && !declaredPdfaFlavour.get().equals(flavour)) {
|
|
||||||
flavoursToValidate.add(flavour);
|
|
||||||
} else if (declaredPdfaFlavour.isEmpty()) {
|
|
||||||
log.debug(
|
|
||||||
"Ignoring detected PDF/A flavour {} because no PDF/A declaration exists in XMP",
|
|
||||||
flavour.getId());
|
|
||||||
}
|
|
||||||
} else if (PDFFlavours.isFlavourFamily(flavour, PDFAFlavour.SpecificationFamily.PDF_UA)
|
|
||||||
|| PDFFlavours.isFlavourFamily(
|
|
||||||
flavour, PDFAFlavour.SpecificationFamily.WTPDF)) {
|
|
||||||
flavoursToValidate.add(flavour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (declaredPdfaFlavour.isEmpty()) {
|
|
||||||
results.add(createNoPdfaDeclarationResult());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flavoursToValidate.isEmpty()) {
|
|
||||||
log.info("No verifiable PDF/A, PDF/UA, or WTPDF standards declared via XMP metadata");
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PDFAFlavour flavour : flavoursToValidate) {
|
|
||||||
try (PDFAParser parser =
|
|
||||||
Foundries.defaultInstance()
|
|
||||||
.createParser(new ByteArrayInputStream(pdfBytes), flavour)) {
|
|
||||||
PDFAValidator validator =
|
|
||||||
Foundries.defaultInstance().createValidator(flavour, false);
|
|
||||||
ValidationResult result = validator.validate(parser);
|
|
||||||
PDFAFlavour declaredForResult =
|
|
||||||
PDFFlavours.isFlavourFamily(flavour, PDFAFlavour.SpecificationFamily.PDF_A)
|
|
||||||
? declaredPdfaFlavour.orElse(null)
|
|
||||||
: flavour;
|
|
||||||
results.add(convertToVerificationResult(result, declaredForResult, flavour));
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error validating standard {}: {}", flavour.getId(), e.getMessage());
|
|
||||||
results.add(
|
|
||||||
buildErrorResult(
|
|
||||||
declaredPdfaFlavour,
|
|
||||||
flavour,
|
|
||||||
"Validation error: " + e.getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PDFVerificationResult convertToVerificationResult(
|
private static PDFVerificationResult convertToVerificationResult(
|
||||||
@ -264,37 +211,90 @@ public class VeraPDFService {
|
|||||||
return ruleId != null && WARNING_RULES.contains(ruleId);
|
return ruleId != null && WARNING_RULES.contains(ruleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isWarningByMessage(String message) {
|
public PDFVerificationResult validatePDF(InputStream pdfStream, String standardString)
|
||||||
// isBlank() already handles null and empty strings
|
throws IOException, ValidationException, ModelParsingException, EncryptedPdfException {
|
||||||
if (message == null || message.isBlank()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String normalized = message.toLowerCase(Locale.ROOT);
|
byte[] pdfBytes = pdfStream.readAllBytes();
|
||||||
|
PDFAFlavour validationFlavour = PDFAFlavour.fromString(standardString);
|
||||||
|
Optional<PDFAFlavour> declaredPdfaFlavour = extractDeclaredPdfaFlavour(pdfBytes);
|
||||||
|
|
||||||
return normalized.contains("recommended")
|
try (PDFAParser parser =
|
||||||
|| normalized.contains("should")
|
Foundries.defaultInstance()
|
||||||
|| normalized.contains("optional")
|
.createParser(new ByteArrayInputStream(pdfBytes), validationFlavour)) {
|
||||||
|| normalized.contains("missing recommended");
|
PDFAValidator validator =
|
||||||
}
|
Foundries.defaultInstance().createValidator(validationFlavour, false);
|
||||||
|
ValidationResult result = validator.validate(parser);
|
||||||
|
|
||||||
private static boolean isWarningByClause(String clause) {
|
return convertToVerificationResult(
|
||||||
// isBlank() already handles null and empty strings
|
result, declaredPdfaFlavour.orElse(null), validationFlavour);
|
||||||
if (clause == null || clause.isBlank()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clause.startsWith("6.7")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String criticalPrefix : CRITICAL_CLAUSE_PREFIXES) {
|
|
||||||
if (clause.startsWith(criticalPrefix)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
public List<PDFVerificationResult> validateAllDeclaredStandards(InputStream pdfStream)
|
||||||
|
throws IOException, ValidationException, ModelParsingException, EncryptedPdfException {
|
||||||
|
|
||||||
|
byte[] pdfBytes = pdfStream.readAllBytes();
|
||||||
|
Optional<PDFAFlavour> declaredPdfaFlavour = extractDeclaredPdfaFlavour(pdfBytes);
|
||||||
|
List<PDFVerificationResult> results = new ArrayList<>();
|
||||||
|
|
||||||
|
List<PDFAFlavour> detectedFlavours;
|
||||||
|
try (PDFAParser detectionParser =
|
||||||
|
Foundries.defaultInstance().createParser(new ByteArrayInputStream(pdfBytes))) {
|
||||||
|
detectedFlavours = detectionParser.getFlavours();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PDFAFlavour> flavoursToValidate = new ArrayList<>();
|
||||||
|
|
||||||
|
declaredPdfaFlavour.ifPresent(flavoursToValidate::add);
|
||||||
|
|
||||||
|
for (PDFAFlavour flavour : detectedFlavours) {
|
||||||
|
if (PDFFlavours.isFlavourFamily(flavour, PDFAFlavour.SpecificationFamily.PDF_A)) {
|
||||||
|
if (declaredPdfaFlavour.isPresent() && !declaredPdfaFlavour.get().equals(flavour)) {
|
||||||
|
flavoursToValidate.add(flavour);
|
||||||
|
} else if (declaredPdfaFlavour.isEmpty()) {
|
||||||
|
log.debug(
|
||||||
|
"Ignoring detected PDF/A flavour {} because no PDF/A declaration exists in XMP",
|
||||||
|
flavour.getId());
|
||||||
|
}
|
||||||
|
} else if (PDFFlavours.isFlavourFamily(flavour, PDFAFlavour.SpecificationFamily.PDF_UA)
|
||||||
|
|| PDFFlavours.isFlavourFamily(
|
||||||
|
flavour, PDFAFlavour.SpecificationFamily.WTPDF)) {
|
||||||
|
flavoursToValidate.add(flavour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaredPdfaFlavour.isEmpty()) {
|
||||||
|
results.add(createNoPdfaDeclarationResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flavoursToValidate.isEmpty()) {
|
||||||
|
log.info("No verifiable PDF/A, PDF/UA, or WTPDF standards declared via XMP metadata");
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PDFAFlavour flavour : flavoursToValidate) {
|
||||||
|
try (PDFAParser parser =
|
||||||
|
Foundries.defaultInstance()
|
||||||
|
.createParser(new ByteArrayInputStream(pdfBytes), flavour)) {
|
||||||
|
PDFAValidator validator =
|
||||||
|
Foundries.defaultInstance().createValidator(flavour, false);
|
||||||
|
ValidationResult result = validator.validate(parser);
|
||||||
|
PDFAFlavour declaredForResult =
|
||||||
|
PDFFlavours.isFlavourFamily(flavour, PDFAFlavour.SpecificationFamily.PDF_A)
|
||||||
|
? declaredPdfaFlavour.orElse(null)
|
||||||
|
: flavour;
|
||||||
|
results.add(convertToVerificationResult(result, declaredForResult, flavour));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error validating standard {}: {}", flavour.getId(), e.getMessage());
|
||||||
|
results.add(
|
||||||
|
buildErrorResult(
|
||||||
|
declaredPdfaFlavour,
|
||||||
|
flavour,
|
||||||
|
"Validation error: " + e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PDFVerificationResult createNoPdfaDeclarationResult() {
|
private static PDFVerificationResult createNoPdfaDeclarationResult() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user