diff --git a/pom.xml b/pom.xml index be37b503e..f5d54218d 100644 --- a/pom.xml +++ b/pom.xml @@ -193,7 +193,7 @@ org.verapdf validation-model-jakarta - 1.28.2 + 1.30.2 net.sf.saxon diff --git a/src/main/java/gov/nasa/pds/tools/util/PDFUtil.java b/src/main/java/gov/nasa/pds/tools/util/PDFUtil.java index 3f883a263..52fb5a9cc 100644 --- a/src/main/java/gov/nasa/pds/tools/util/PDFUtil.java +++ b/src/main/java/gov/nasa/pds/tools/util/PDFUtil.java @@ -89,6 +89,20 @@ private synchronized void writeErrorToFile(String baseDir, String pdfFullName, V } } + /** + * Returns the detected PDF/A flavour for the given parser, or null if the PDF has no + * conformance declaration. veraPDF 1.30+ throws IndexOutOfBoundsException (rather than + * returning NO_FLAVOUR) when no pdfaid metadata is present. + */ + private PDFAFlavour detectFlavour(PDFAParser parser) { + try { + PDFAFlavour flavour = parser.getFlavour(); + return PDFAFlavour.NO_FLAVOUR.equals(flavour) ? null : flavour; + } catch (IndexOutOfBoundsException e) { + return null; + } + } + private boolean validatePDF(String baseDir, URI uri, String pdfRef) throws IOException { boolean pdfValidateFlag = false; @@ -98,35 +112,31 @@ private boolean validatePDF(String baseDir, URI uri, String pdfRef) throws IOExc this.errorMessage = "Zero length file is an invalid PDF file."; return pdfValidateFlag; } - // Create a parser and auto-detect flavour PDFAParser parser = Foundries.defaultInstance().createParser(new FileInputStream(pdfRef)); - PDFAFlavour detectedFlavour = parser.getFlavour(); + PDFAFlavour detectedFlavour = detectFlavour(parser); LOG.debug("validatePDF: parser.getFlavour() [{}]", detectedFlavour); - // First, check the flavour is valid 1a or 1b - if (!detectedFlavour.equals(PDFAFlavour.PDFA_1_A) + if (detectedFlavour == null) { + this.errorMessage = "File does not contain a PDF/A conformance declaration for " + uri + + ". Expected: PDF/A-1a or PDF/A-1b."; + } else if (!detectedFlavour.equals(PDFAFlavour.PDFA_1_A) && !detectedFlavour.equals(PDFAFlavour.PDFA_1_B)) { this.errorMessage = "Invalid PDF/A version detected for " + uri + ". Expected: 1a or 1b. Actual: " + detectedFlavour.getId(); } else { - // Next, check the PDF is actually a valid 1a/1b flavour + // Check the PDF is actually a valid 1a/1b flavour PDFAValidator validator = Foundries.defaultInstance().createValidator(detectedFlavour, false); this.parserFlavor = parser.getFlavour().getId(); ValidationResult result = validator.validate(parser); if (result.isCompliant()) { - // File is a valid PDF LOG.debug("validatePDF file " + pdfRef + " is a valid PDF file with flavor " + parser.getFlavour().getId()); pdfValidateFlag = true; } else { LOG.error("validatePDF file" + pdfRef + " is not valid PDF file with flavor " + parser.getFlavour().getId()); - - // Write the result to external file so the user can look over in the validate - // report. this.writeErrorToFile(baseDir, pdfRef, result, parser.getFlavour().getId()); - this.errorMessage = "Validation failed for flavour PDF/A-" + detectedFlavour.getId() + " in file " + Paths.get(pdfRef).getFileName() + "."; if (this.getExternalErrorFilename() != null) this.errorMessage += " Detailed error output can be found at " + this.getExternalErrorFilename();