@@ -25,6 +25,9 @@ This file is part of the iText (R) project.
2525import com .itextpdf .kernel .xmp .XMPConst ;
2626import com .itextpdf .kernel .xmp .XMPException ;
2727import com .itextpdf .kernel .xmp .XMPMeta ;
28+ import com .itextpdf .kernel .xmp .XMPMetaFactory ;
29+ import com .itextpdf .kernel .xmp .XMPUtils ;
30+ import com .itextpdf .kernel .xmp .options .PropertyOptions ;
2831import com .itextpdf .kernel .xmp .properties .XMPProperty ;
2932
3033/**
@@ -192,6 +195,46 @@ public static PdfConformance getConformance(XMPMeta meta) {
192195 return new PdfConformance (aLevel , uaLevel );
193196 }
194197
198+ /**
199+ * Sets required fields into XMP metadata according to passed PDF conformance.
200+ *
201+ * @param xmpMeta the xmp metadata to which required PDF conformance fields will be set
202+ * @param conformance the PDF conformance according to which XMP will be updated
203+ *
204+ * @throws XMPException if the file is not well-formed XML or if the parsing fails
205+ */
206+ public static void setConformanceToXmp (XMPMeta xmpMeta , PdfConformance conformance ) throws XMPException {
207+ if (conformance == null ) {
208+ return ;
209+ }
210+ // Don't set any property if property value was set, so if
211+ // smth was invalid in source document, it will be left as is.
212+ // But if e.g. for PDF/A-4 revision wasn't specified, we will fix it.
213+ if (conformance .isPdfUA ()) {
214+ if (xmpMeta .getProperty (XMPConst .NS_PDFUA_ID , XMPConst .PART ) == null ) {
215+ xmpMeta .setPropertyInteger (XMPConst .NS_PDFUA_ID , XMPConst .PART , 1 ,
216+ new PropertyOptions (PropertyOptions .SEPARATE_NODE ));
217+ }
218+ }
219+ if (conformance .isPdfA ()) {
220+ final PdfAConformance aLevel = conformance .getAConformance ();
221+ if (xmpMeta .getProperty (XMPConst .NS_PDFA_ID , XMPConst .PART ) == null ) {
222+ xmpMeta .setProperty (XMPConst .NS_PDFA_ID , XMPConst .PART , aLevel .getPart ());
223+ }
224+ if (aLevel .getLevel () != null && xmpMeta .getProperty (XMPConst .NS_PDFA_ID , XMPConst .CONFORMANCE ) == null ) {
225+ xmpMeta .setProperty (XMPConst .NS_PDFA_ID , XMPConst .CONFORMANCE , aLevel .getLevel ());
226+ }
227+ if ("4" .equals (aLevel .getPart ()) && xmpMeta .getProperty (XMPConst .NS_PDFA_ID , XMPConst .REV ) == null ) {
228+ xmpMeta .setProperty (XMPConst .NS_PDFA_ID , XMPConst .REV , PdfConformance .PDF_A_4_REVISION );
229+ }
230+
231+ if (xmpMeta .getPropertyInteger (XMPConst .NS_PDFUA_ID , XMPConst .PART ) != null ) {
232+ XMPMeta taggedExtensionMeta = XMPMetaFactory .parseFromString (PDF_UA_EXTENSION );
233+ XMPUtils .appendProperties (taggedExtensionMeta , xmpMeta , true , false );
234+ }
235+ }
236+ }
237+
195238 /**
196239 * Gets an instance of {@link PdfAConformance} based on passed part and level.
197240 *
@@ -257,4 +300,44 @@ private static PdfUAConformance getUAConformance(String part) {
257300 }
258301 return null ;
259302 }
303+
304+ private static final String PDF_UA_EXTENSION =
305+ " <x:xmpmeta xmlns:x=\" adobe:ns:meta/\" >\n " +
306+ " <rdf:RDF xmlns:rdf=\" http://www.w3.org/1999/02/22-rdf-syntax-ns#\" >\n " +
307+ " <rdf:Description rdf:about=\" \" xmlns:pdfaExtension=\" http://www.aiim.org/pdfa/ns/extension/\" xmlns:pdfaSchema=\" http://www.aiim.org/pdfa/ns/schema#\" xmlns:pdfaProperty=\" http://www.aiim.org/pdfa/ns/property#\" >\n " +
308+ " <pdfaExtension:schemas>\n " +
309+ " <rdf:Bag>\n " +
310+ " <rdf:li rdf:parseType=\" Resource\" >\n " +
311+ " <pdfaSchema:namespaceURI rdf:resource=\" http://www.aiim.org/pdfua/ns/id/\" />\n " +
312+ " <pdfaSchema:prefix>pdfuaid</pdfaSchema:prefix>\n " +
313+ " <pdfaSchema:schema>PDF/UA identification schema</pdfaSchema:schema>\n " +
314+ " <pdfaSchema:property>\n " +
315+ " <rdf:Seq>\n " +
316+ " <rdf:li rdf:parseType=\" Resource\" >\n " +
317+ " <pdfaProperty:category>internal</pdfaProperty:category>\n " +
318+ " <pdfaProperty:description>PDF/UA version identifier</pdfaProperty:description>\n " +
319+ " <pdfaProperty:name>part</pdfaProperty:name>\n " +
320+ " <pdfaProperty:valueType>Integer</pdfaProperty:valueType>\n " +
321+ " </rdf:li>\n " +
322+ " <rdf:li rdf:parseType=\" Resource\" >\n " +
323+ " <pdfaProperty:category>internal</pdfaProperty:category>\n " +
324+ " <pdfaProperty:description>PDF/UA amendment identifier</pdfaProperty:description>\n " +
325+ " <pdfaProperty:name>amd</pdfaProperty:name>\n " +
326+ " <pdfaProperty:valueType>Text</pdfaProperty:valueType>\n " +
327+ " </rdf:li>\n " +
328+ " <rdf:li rdf:parseType=\" Resource\" >\n " +
329+ " <pdfaProperty:category>internal</pdfaProperty:category>\n " +
330+ " <pdfaProperty:description>PDF/UA corrigenda identifier</pdfaProperty:description>\n " +
331+ " <pdfaProperty:name>corr</pdfaProperty:name>\n " +
332+ " <pdfaProperty:valueType>Text</pdfaProperty:valueType>\n " +
333+ " </rdf:li>\n " +
334+ " </rdf:Seq>\n " +
335+ " </pdfaSchema:property>\n " +
336+ " </rdf:li>\n " +
337+ " </rdf:Bag>\n " +
338+ " </pdfaExtension:schemas>\n " +
339+ " </rdf:Description>\n " +
340+ " </rdf:RDF>\n " +
341+ " </x:xmpmeta>" ;
342+
260343}
0 commit comments