From 5e0759650d0176109954a9152ffb70494848c985 Mon Sep 17 00:00:00 2001 From: Simon Steiner Date: Wed, 27 Dec 2023 14:24:17 +0000 Subject: FOP-3144: Add new schema to handle pdf/a and pdfa/ua by João André Gonçalves MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/apache/fop/pdf/PDFMetadata.java | 9 +++ .../fop/render/pdf/PDFAMetadataTestCase.java | 79 ++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/fop-core/src/main/java/org/apache/fop/pdf/PDFMetadata.java b/fop-core/src/main/java/org/apache/fop/pdf/PDFMetadata.java index 107dba9fa..ce8cfdf2d 100644 --- a/fop-core/src/main/java/org/apache/fop/pdf/PDFMetadata.java +++ b/fop-core/src/main/java/org/apache/fop/pdf/PDFMetadata.java @@ -37,6 +37,7 @@ import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFAdapter; import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAAdapter; +import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAExtensionXMPSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAXMPSchema; import org.apache.xmlgraphics.xmp.schemas.pdf.PDFUAAdapter; import org.apache.xmlgraphics.xmp.schemas.pdf.PDFUAXMPSchema; @@ -168,6 +169,14 @@ public class PDFMetadata extends PDFStream { PDFUAMode pdfuaMode = pdfDoc.getProfile().getPDFUAMode(); if (pdfuaMode.isEnabled()) { + /* + If the if below is true, we need to add this schema extension element + otherwise pdf/a validators will fail + */ + if (pdfaMode.isEnabled()) { + PDFAExtensionXMPSchema.getAdapter(meta); + } + PDFUAAdapter pdfua = PDFUAXMPSchema.getAdapter(meta); pdfua.setPart(pdfuaMode.getPart()); } diff --git a/fop-core/src/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java b/fop-core/src/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java index 8f8afc8f4..806fb5403 100644 --- a/fop-core/src/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java +++ b/fop-core/src/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java @@ -19,7 +19,9 @@ package org.apache.fop.render.pdf; +import java.util.ArrayList; import java.util.Calendar; +import java.util.List; import java.util.Locale; import java.util.TimeZone; @@ -27,10 +29,16 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import org.apache.xmlgraphics.util.QName; import org.apache.xmlgraphics.xmp.Metadata; +import org.apache.xmlgraphics.xmp.XMPArray; +import org.apache.xmlgraphics.xmp.XMPArrayType; +import org.apache.xmlgraphics.xmp.XMPConstants; +import org.apache.xmlgraphics.xmp.XMPProperty; import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter; import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema; import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter; @@ -42,6 +50,7 @@ import org.apache.fop.pdf.PDFAMode; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.pdf.PDFInfo; import org.apache.fop.pdf.PDFMetadata; +import org.apache.fop.pdf.PDFUAMode; /** * Test case for PDF/A metadata handling. @@ -143,4 +152,74 @@ public class PDFAMetadataTestCase { assertFalse(meta.getProperty("http://purl.org/dc/elements/1.1/", "date").getValue().toString() .contains("rdf:Seq")); } + + @Test + public void testPDFAExtensionSchema() { + PDFDocument doc = new PDFDocument("SuperFOP"); + doc.getProfile().setPDFAMode(PDFAMode.PDFA_1A); + doc.getProfile().setPDFUAMode(PDFUAMode.PDFUA_1); + Metadata meta = PDFMetadata.createXMPFromPDFDocument(doc); + + XMPProperty schemas = meta.getProperty(XMPConstants.PDF_A_EXTENSION, "schemas"); + assertProperties(schemas, XMPConstants.PDF_A_EXTENSION, "schemas", null, null); + assertNotNull("When PDF/A and PDF/UA are both active, we need to add an " + + "extension element to avoid validation errors from PDF/A validators", schemas); + + List schemasArrayList = assertArrayValue(schemas, XMPArrayType.BAG); + assertProperties(schemasArrayList.get(0), XMPConstants.PDF_A_SCHEMA, "schema", + "pdfaSchema", "PDF/UA identification schema"); + assertProperties(schemasArrayList.get(1), XMPConstants.PDF_A_SCHEMA, "namespaceURI", + "pdfaSchema", "http://www.aiim.org/pdfua/ns/id/"); + assertProperties(schemasArrayList.get(2), XMPConstants.PDF_A_SCHEMA, "prefix", + "pdfaSchema", "pdfuaid"); + assertProperties(schemasArrayList.get(3), XMPConstants.PDF_A_SCHEMA, "property", + "pdfaSchema", null); + + List propertyArrayList = assertArrayValue(schemasArrayList.get(3), XMPArrayType.SEQ); + assertProperties(propertyArrayList.get(0), XMPConstants.PDF_A_PROPERTY, "name", + "pdfaProperty", "part"); + assertProperties(propertyArrayList.get(1), XMPConstants.PDF_A_PROPERTY, "valueType", + "pdfaProperty", "Integer"); + assertProperties(propertyArrayList.get(2), XMPConstants.PDF_A_PROPERTY, "category", + "pdfaProperty", "internal"); + assertProperties(propertyArrayList.get(3), XMPConstants.PDF_A_PROPERTY, "description", + "pdfaProperty", "Indicates, which part of ISO 14289 standard is followed"); + } + + private void assertProperties(XMPProperty prop, String ns, String localName, String prefix, + String value) { + QName name = prop.getName(); + assertEquals("Property must have expected value or the validator might fail", + ns, name.getNamespaceURI()); + assertEquals("Property must have expected value or the validator might fail", + localName, name.getLocalName()); + assertEquals("Property must have expected value or the validator might fail", + prefix, name.getPrefix()); + + if (value != null) { + assertEquals("Property must have expected value or the validator might fail", + value, prop.getValue()); + } + } + + private List assertArrayValue(XMPProperty prop, XMPArrayType type) { + Object value = prop.getValue(); + assertEquals("Property value must be an array", XMPArray.class, value.getClass()); + + XMPArray array = (XMPArray) value; + assertEquals("The property expects an array of the given type", + type, array.getType()); + assertEquals("Array must only have 1 element with 4 properties inside", + 1, array.getSize()); + + Object arrayValue = array.getValue(0); + assertEquals("Array must only have 1 element with 4 properties inside", + ArrayList.class, arrayValue.getClass()); + + List arrayList = (List) arrayValue; + assertEquals("Array must only have 1 element with 4 properties inside", + 4, arrayList.size()); + + return arrayList; + } } -- cgit v1.2.3