XMPMetadataTest.java
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2025 Apryse Group NV
Authors: Apryse Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itextpdf.kernel.pdf;
import com.itextpdf.io.logs.IoLogMessageConstant;
import com.itextpdf.kernel.utils.CompareTool;
import com.itextpdf.kernel.xmp.PdfConst;
import com.itextpdf.kernel.xmp.XMPConst;
import com.itextpdf.kernel.xmp.XMPException;
import com.itextpdf.kernel.xmp.XMPMeta;
import com.itextpdf.kernel.xmp.XMPMetaFactory;
import com.itextpdf.kernel.xmp.XMPUtils;
import com.itextpdf.kernel.xmp.options.SerializeOptions;
import com.itextpdf.test.AssertUtil;
import com.itextpdf.test.ExtendedITextTest;
import com.itextpdf.test.TestUtil;
import com.itextpdf.test.annotations.LogMessage;
import com.itextpdf.test.annotations.LogMessages;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Tag("IntegrationTest")
public class XMPMetadataTest extends ExtendedITextTest{
public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/kernel/pdf/XMPMetadataTest/";
public static final String DESTINATION_FOLDER = TestUtil.getOutputPath() + "/kernel/pdf/XMPMetadataTest/";
@BeforeAll
public static void beforeClass() {
createOrClearDestinationFolder(DESTINATION_FOLDER);
}
@AfterAll
public static void afterClass() {
CompareTool.cleanup(DESTINATION_FOLDER);
}
@Test
public void createEmptyDocumentWithXmp() throws Exception {
String filename = "emptyDocumentWithXmp.pdf";
PdfWriter writer = CompareTool.createTestPdfWriter(DESTINATION_FOLDER + filename, new WriterProperties().addXmpMetadata());
PdfDocument pdfDoc = new PdfDocument(writer);
pdfDoc.getDocumentInfo().setAuthor("Alexander Chingarev").
setCreator("iText").
setTitle("Empty iText Document");
pdfDoc.getDocumentInfo().getPdfObject().remove(PdfName.CreationDate);
pdfDoc.getDocumentInfo().getPdfObject().remove(PdfName.ModDate);
PdfPage page = pdfDoc.addNewPage();
page.flush();
pdfDoc.close();
PdfReader reader = CompareTool.createOutputReader(DESTINATION_FOLDER + filename);
PdfDocument pdfDocument = new PdfDocument(reader);
Assertions.assertEquals(false, reader.hasRebuiltXref(), "Rebuilt");
byte[] outBytes = pdfDocument.getXmpMetadataBytes();
pdfDocument.close();
byte[] cmpBytes = readFile(SOURCE_FOLDER + "emptyDocumentWithXmp.xml");
cmpBytes = removeAlwaysDifferentEntries(cmpBytes);
outBytes = removeAlwaysDifferentEntries(outBytes);
Assertions.assertTrue(new CompareTool().compareXmls(outBytes, cmpBytes));
}
@Test
public void emptyDocumentWithXmpAppendMode01() throws Exception {
String created = DESTINATION_FOLDER + "emptyDocumentWithXmpAppendMode01.pdf";
String updated = DESTINATION_FOLDER + "emptyDocumentWithXmpAppendMode01_updated.pdf";
String updatedAgain = DESTINATION_FOLDER + "emptyDocumentWithXmpAppendMode01_updatedAgain.pdf";
PdfDocument pdfDocument = new PdfDocument(CompareTool.createTestPdfWriter(created));
pdfDocument.addNewPage();
// create XMP metadata
pdfDocument.getXmpMetadata(true);
pdfDocument.close();
pdfDocument = new PdfDocument(CompareTool.createOutputReader(created), CompareTool.createTestPdfWriter(updated), new StampingProperties().useAppendMode());
pdfDocument.close();
pdfDocument = new PdfDocument(CompareTool.createOutputReader(updated), CompareTool.createTestPdfWriter(updatedAgain), new StampingProperties().useAppendMode());
pdfDocument.close();
PdfReader reader = CompareTool.createOutputReader(updatedAgain);
pdfDocument = new PdfDocument(reader);
Assertions.assertEquals(false, reader.hasRebuiltXref(), "Rebuilt");
Assertions.assertNotNull(pdfDocument.getCatalog().getPdfObject().getAsStream(PdfName.Metadata));
PdfIndirectReference metadataRef = pdfDocument.getCatalog().getPdfObject().getAsStream(PdfName.Metadata).getIndirectReference();
Assertions.assertEquals(6, metadataRef.getObjNumber());
Assertions.assertEquals(0, metadataRef.getGenNumber());
byte[] outBytes = pdfDocument.getXmpMetadataBytes();
pdfDocument.close();
byte[] cmpBytes = readFile(SOURCE_FOLDER + "emptyDocumentWithXmpAppendMode01.xml");
cmpBytes = removeAlwaysDifferentEntries(cmpBytes);
outBytes = removeAlwaysDifferentEntries(outBytes);
Assertions.assertTrue(new CompareTool().compareXmls(outBytes, cmpBytes));
}
@Test
public void emptyDocumentWithXmpAppendMode02() throws Exception {
String created = DESTINATION_FOLDER + "emptyDocumentWithXmpAppendMode02.pdf";
String updated = DESTINATION_FOLDER + "emptyDocumentWithXmpAppendMode02_updated.pdf";
String updatedAgain = DESTINATION_FOLDER + "emptyDocumentWithXmpAppendMode02_updatedAgain.pdf";
PdfDocument pdfDocument = new PdfDocument(CompareTool.createTestPdfWriter(created));
pdfDocument.addNewPage();
pdfDocument.close();
pdfDocument = new PdfDocument(CompareTool.createOutputReader(created), CompareTool.createTestPdfWriter(updated), new StampingProperties().useAppendMode());
// create XMP metadata
pdfDocument.getXmpMetadata(true);
pdfDocument.close();
pdfDocument = new PdfDocument(CompareTool.createOutputReader(updated), CompareTool.createTestPdfWriter(updatedAgain), new StampingProperties().useAppendMode());
pdfDocument.close();
PdfReader reader = CompareTool.createOutputReader(updatedAgain);
pdfDocument = new PdfDocument(reader);
Assertions.assertEquals(false, reader.hasRebuiltXref(), "Rebuilt");
Assertions.assertNotNull(pdfDocument.getCatalog().getPdfObject().getAsStream(PdfName.Metadata));
PdfIndirectReference metadataRef = pdfDocument.getCatalog().getPdfObject().getAsStream(PdfName.Metadata).getIndirectReference();
Assertions.assertEquals(6, metadataRef.getObjNumber());
Assertions.assertEquals(0, metadataRef.getGenNumber());
byte[] outBytes = pdfDocument.getXmpMetadataBytes();
pdfDocument.close();
byte[] cmpBytes = readFile(SOURCE_FOLDER + "emptyDocumentWithXmpAppendMode02.xml");
cmpBytes = removeAlwaysDifferentEntries(cmpBytes);
outBytes = removeAlwaysDifferentEntries(outBytes);
Assertions.assertTrue(new CompareTool().compareXmls(outBytes, cmpBytes));
}
@Test
@LogMessages(messages = {
@LogMessage(messageTemplate = IoLogMessageConstant.EXCEPTION_WHILE_UPDATING_XMPMETADATA, count = 2)
})
public void createEmptyDocumentWithAbcXmp() throws IOException {
ByteArrayOutputStream fos = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(fos);
PdfDocument pdfDoc = new PdfDocument(writer);
pdfDoc.getDocumentInfo().setAuthor("Alexander Chingarev").
setCreator("iText").
setTitle("Empty iText Document");
pdfDoc.getDocumentInfo().getPdfObject().remove(PdfName.CreationDate);
pdfDoc.getDocumentInfo().getPdfObject().remove(PdfName.ModDate);
PdfPage page = pdfDoc.addNewPage();
page.flush();
pdfDoc.setXmpMetadata("abc".getBytes(StandardCharsets.ISO_8859_1));
pdfDoc.close();
PdfReader reader = new PdfReader(new ByteArrayInputStream(fos.toByteArray()));
PdfDocument pdfDocument = new PdfDocument(reader);
Assertions.assertFalse(reader.hasRebuiltXref(), "Rebuilt");
Assertions.assertArrayEquals("abc".getBytes(StandardCharsets.ISO_8859_1), pdfDocument.getXmpMetadataBytes());
Assertions.assertNotNull(pdfDocument.getPage(1));
reader.close();
}
@Test
@Disabled("DEVSIX-1899: fails in .NET passes in Java")
public void customXmpTest() throws IOException, InterruptedException, XMPException {
runCustomXmpTest("customXmp",
"<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d' bytes='770'?>\n" +
"\n" +
"<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'\n" +
" xmlns:iX='http://ns.adobe.com/iX/1.0/'>\n" +
"\n" +
" <rdf:Description about=''\n" +
" xmlns='http://ns.adobe.com/pdf/1.3/'\n" +
" xmlns:pdf='http://ns.adobe.com/pdf/1.3/'>\n" +
" <pdf:ModDate>2001-03-28T15:17:00-08:00</pdf:ModDate>\n" +
" <pdf:CreationDate>2001-03-28T15:19:45-08:00</pdf:CreationDate>\n" +
" </rdf:Description>\n" +
"\n" +
" <rdf:Description about=''\n" +
" xmlns='http://ns.adobe.com/xap/1.0/'\n" +
" xmlns:xap='http://ns.adobe.com/xap/1.0/'>\n" +
" <xap:ModifyDate>2001-03-28T15:17:00-08:00</xap:ModifyDate>\n" +
" <xap:CreateDate>2001-03-28T15:19:45-08:00</xap:CreateDate>\n" +
" <xap:MetadataDate>2001-03-28T15:17:00-08:00</xap:MetadataDate>\n" +
" </rdf:Description>\n" +
"\n" +
"</rdf:RDF>\n" +
"<?xpacket end='r'?>");
}
@Test
@Disabled("DEVSIX-1899: fails in .NET passes in Java")
public void customXmpTest02() throws IOException, InterruptedException, XMPException {
runCustomXmpTest("customXmp02",
"<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d' bytes='1026'?><rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'><rdf:Description about='' xmlns='http://ns.adobe.com/pdf/1.3/' xmlns:pdf='http://ns.adobe.com/pdf/1.3/' pdf:CreationDate='2016-01-27T13:07:23Z' pdf:ModDate='2016-01-27T13:07:23Z' pdf:Producer='Acrobat Distiller 5.0.5 (Windows)' pdf:Author='Koeck' pdf:Creator='PScript5.dll Version 5.2.2' pdf:Title='Rasant_ACE.indd'/>\n" +
"<rdf:Description about='' xmlns='http://ns.adobe.com/xap/1.0/' xmlns:xap='http://ns.adobe.com/xap/1.0/' xap:CreateDate='2016-01-27T13:07:23Z' xap:ModifyDate='2016-01-27T13:07:23Z' xap:Author='Koeck' xap:MetadataDate='2016-01-27T13:07:23Z'><xap:Title><rdf:Alt><rdf:li xml:lang='x-default'>Rasant_ACE.indd</rdf:li></rdf:Alt></xap:Title></rdf:Description>\n" +
"<rdf:Description about='' xmlns='http://purl.org/dc/elements/1.1/' xmlns:dc='http://purl.org/dc/elements/1.1/' dc:creator='Koeck' dc:title='Rasant_ACE.indd'/>\n" +
"</rdf:RDF><?xpacket end='r'?>");
}
private void runCustomXmpTest(String name, String xmp) throws IOException, InterruptedException {
String outPath = DESTINATION_FOLDER + name + ".pdf";
String cmpPath = SOURCE_FOLDER + "cmp_" + name + ".pdf";
PdfDocument pdfDoc = new PdfDocument(CompareTool.createTestPdfWriter(outPath));
PdfPage page = pdfDoc.addNewPage();
page.flush();
pdfDoc.setXmpMetadata(xmp.getBytes(StandardCharsets.ISO_8859_1));
pdfDoc.close();
CompareTool compareTool = new CompareTool();
Assertions.assertNull(compareTool.compareByContent(outPath, cmpPath, DESTINATION_FOLDER, "diff_" + name + "_"));
Assertions.assertNull(compareTool.compareDocumentInfo(outPath, cmpPath));
}
private byte[] removeAlwaysDifferentEntries(byte[] cmpBytes) throws XMPException {
XMPMeta xmpMeta = XMPMetaFactory.parseFromBuffer(cmpBytes);
XMPUtils.removeProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.CreateDate, true, true);
XMPUtils.removeProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.ModifyDate, true, true);
XMPUtils.removeProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.MetadataDate, true, true);
XMPUtils.removeProperties(xmpMeta, XMPConst.NS_PDF, PdfConst.Producer, true, true);
cmpBytes = XMPMetaFactory.serializeToBuffer(xmpMeta, new SerializeOptions(SerializeOptions.SORT));
return cmpBytes;
}
@Test
public void bagParsingTest() {
String xmp = "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 6.0-c006 79.dabacbb, "
+ "2021/04/14-00:39:44 \">\n"
+ " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n"
+ " <rdf:Description rdf:about=\"\"\n"
+ " xmlns:photoshop=\"http://ns.adobe.com/photoshop/1.0/\"\n"
+ " xmlns:xmpMM=\"http://ns.adobe.com/xap/1.0/mm/\"\n"
+ " xmlns:stEvt=\"http://ns.adobe.com/xap/1.0/sType/ResourceEvent#\"\n"
+ " xmlns:stRef=\"http://ns.adobe.com/xap/1.0/sType/ResourceRef#\"\n"
+ " xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"\n"
+ " xmlns:xmpGImg=\"http://ns.adobe.com/xap/1.0/g/img/\"\n"
+ " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n"
+ " xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n"
+ " <photoshop:LegacyIPTCDigest>CDCFFA7DA8C7BE09057076AEAF05C34E</photoshop:LegacyIPTCDigest>\n"
+ " <photoshop:ColorMode>3</photoshop:ColorMode>\n"
+ " <photoshop:ICCProfile>sRGB IEC61966-2.1</photoshop:ICCProfile>\n"
+ " <photoshop:DocumentAncestors>\n"
+ " <rdf:Bag>\n"
+ " <rdf:li>78274CCED3154607AD19599D29855E30</rdf:li>\n"
+ " <rdf:li>A61D41481CEE4032AE7A116AD6C942DC</rdf:li>\n"
+ " <rdf:li>A2A26CD02B014819824FC4314B4152FF</rdf:li>\n"
+ " <rdf:li>425FC234DCE84124A5EEAF17C69CCC62</rdf:li>\n"
+ " <rdf:li>D2B4867567A547EA9F87B476EB21147E</rdf:li>\n"
+ " <rdf:li>CE995EEDAD734D029F9B27AD04BA7052</rdf:li>\n"
+ " <rdf:li>E754B36AD97E49EAABC7E8F7CEA30696</rdf:li>\n"
+ " <rdf:li>713B782250904422BDDCAD1723C25C3C</rdf:li>\n"
+ " <rdf:li>DC818BB5F9F1421C87DA05C97DEEB2CF</rdf:li>\n"
+ " \n"
+ " <rdf:li>D2B4867567A547EA9F87B476EB21147E</rdf:li>\n"
+ " <rdf:li>CE995EEDAD734D029F9B27AD04BA7052</rdf:li>\n"
+ " <rdf:li>E754B36AD97E49EAABC7E8F7CEA30696</rdf:li>\n"
+ " <rdf:li>713B782250904422BDDCAD1723C25C3C</rdf:li>\n"
+ " <rdf:li>DC818BB5F9F1421C87DA05C97DEEB2CF</rdf:li>\n"
+ " </rdf:Bag>\n"
+ " </photoshop:DocumentAncestors> \n"
+ " </rdf:Description>\n"
+ " </rdf:RDF>\n"
+ "</x:xmpmeta>";
AssertUtil.doesNotThrow(
() -> XMPMetaFactory.parseFromBuffer(xmp.getBytes(StandardCharsets.UTF_8)));
}
@Test
public void altParsingTest() {
String xmp = "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 6.0-c006 79.dabacbb, "
+ "2021/04/14-00:39:44 \">\n"
+ " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n"
+ " <rdf:Description rdf:about=\"\"\n"
+ " xmlns:photoshop=\"http://ns.adobe.com/photoshop/1.0/\"\n"
+ " xmlns:xmpMM=\"http://ns.adobe.com/xap/1.0/mm/\"\n"
+ " xmlns:stEvt=\"http://ns.adobe.com/xap/1.0/sType/ResourceEvent#\"\n"
+ " xmlns:stRef=\"http://ns.adobe.com/xap/1.0/sType/ResourceRef#\"\n"
+ " xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"\n"
+ " xmlns:xmpGImg=\"http://ns.adobe.com/xap/1.0/g/img/\"\n"
+ " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n"
+ " xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n"
+ " <photoshop:LegacyIPTCDigest>CDCFFA7DA8C7BE09057076AEAF05C34E</photoshop:LegacyIPTCDigest>\n"
+ " <photoshop:ColorMode>3</photoshop:ColorMode>\n"
+ " <photoshop:ICCProfile>sRGB IEC61966-2.1</photoshop:ICCProfile>\n"
+ " <photoshop:DocumentAncestors>\n"
+ " <rdf:Alt>\n"
+ " <rdf:li>0006528E7FAD8C1170BB8605BDABA5EC</rdf:li>\n"
+ " <rdf:li>00072919E3FCD9243A279B11FA36E751</rdf:li>\n"
+ " <rdf:li>D2B4867567A547EA9F87B476EB21147E</rdf:li>\n"
+ " <rdf:li>CE995EEDAD734D029F9B27AD04BA7052</rdf:li>\n"
+ " <rdf:li>E754B36AD97E49EAABC7E8F7CEA30696</rdf:li>\n"
+ " <rdf:li>713B782250904422BDDCAD1723C25C3C</rdf:li>\n"
+ " <rdf:li>DC818BB5F9F1421C87DA05C97DEEB2CF</rdf:li>\n"
+ " \n"
+ " <rdf:li>D2B4867567A547EA9F87B476EB21147E</rdf:li>\n"
+ " <rdf:li>CE995EEDAD734D029F9B27AD04BA7052</rdf:li>\n"
+ " <rdf:li>E754B36AD97E49EAABC7E8F7CEA30696</rdf:li>\n"
+ " <rdf:li>713B782250904422BDDCAD1723C25C3C</rdf:li>\n"
+ " <rdf:li>DC818BB5F9F1421C87DA05C97DEEB2CF</rdf:li>\n"
+ " </rdf:Alt>\n"
+ " </photoshop:DocumentAncestors> \n"
+ " </rdf:Description>\n"
+ " </rdf:RDF>\n"
+ "</x:xmpmeta>";
AssertUtil.doesNotThrow(
() -> XMPMetaFactory.parseFromBuffer(xmp.getBytes(StandardCharsets.UTF_8)));
}
@Test
public void seqParsingTest() {
String xmp = "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 6.0-c006 79.dabacbb, "
+ "2021/04/14-00:39:44 \">\n"
+ " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n"
+ " <rdf:Description rdf:about=\"\"\n"
+ " xmlns:photoshop=\"http://ns.adobe.com/photoshop/1.0/\"\n"
+ " xmlns:xmpMM=\"http://ns.adobe.com/xap/1.0/mm/\"\n"
+ " xmlns:stEvt=\"http://ns.adobe.com/xap/1.0/sType/ResourceEvent#\"\n"
+ " xmlns:stRef=\"http://ns.adobe.com/xap/1.0/sType/ResourceRef#\"\n"
+ " xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"\n"
+ " xmlns:xmpGImg=\"http://ns.adobe.com/xap/1.0/g/img/\"\n"
+ " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n"
+ " xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n"
+ " <photoshop:LegacyIPTCDigest>CDCFFA7DA8C7BE09057076AEAF05C34E</photoshop:LegacyIPTCDigest>\n"
+ " <photoshop:ColorMode>3</photoshop:ColorMode>\n"
+ " <photoshop:ICCProfile>sRGB IEC61966-2.1</photoshop:ICCProfile>\n"
+ " <photoshop:DocumentAncestors>\n"
+ " <rdf:Seq>\n"
+ " <rdf:li>78274CCED3154607AD19599D29855E30</rdf:li>\n"
+ " <rdf:li>A61D41481CEE4032AE7A116AD6C942DC</rdf:li>\n"
+ " <rdf:li>A2A26CD02B014819824FC4314B4152FF</rdf:li>\n"
+ " <rdf:li>425FC234DCE84124A5EEAF17C69CCC62</rdf:li>\n"
+ " <rdf:li>D2B4867567A547EA9F87B476EB21147E</rdf:li>\n"
+ " <rdf:li>CE995EEDAD734D029F9B27AD04BA7052</rdf:li>\n"
+ " <rdf:li>E754B36AD97E49EAABC7E8F7CEA30696</rdf:li>\n"
+ " <rdf:li>713B782250904422BDDCAD1723C25C3C</rdf:li>\n"
+ " <rdf:li>DC818BB5F9F1421C87DA05C97DEEB2CF</rdf:li>\n"
+ " \n"
+ " <rdf:li>D2B4867567A547EA9F87B476EB21147E</rdf:li>\n"
+ " <rdf:li>CE995EEDAD734D029F9B27AD04BA7052</rdf:li>\n"
+ " <rdf:li>E754B36AD97E49EAABC7E8F7CEA30696</rdf:li>\n"
+ " <rdf:li>713B782250904422BDDCAD1723C25C3C</rdf:li>\n"
+ " <rdf:li>DC818BB5F9F1421C87DA05C97DEEB2CF</rdf:li>\n"
+ " </rdf:Seq>\n"
+ " </photoshop:DocumentAncestors> \n"
+ " </rdf:Description>\n"
+ " </rdf:RDF>\n"
+ "</x:xmpmeta>";
AssertUtil.doesNotThrow(
() -> XMPMetaFactory.parseFromBuffer(xmp.getBytes(StandardCharsets.UTF_8)));
}
@Test
public void listParsingTest() {
String xmp = "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 6.0-c006 79.dabacbb, "
+ "2021/04/14-00:39:44 \">\n"
+ " <rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n"
+ " <rdf:Description rdf:about=\"\"\n"
+ " xmlns:photoshop=\"http://ns.adobe.com/photoshop/1.0/\"\n"
+ " xmlns:xmpMM=\"http://ns.adobe.com/xap/1.0/mm/\"\n"
+ " xmlns:stEvt=\"http://ns.adobe.com/xap/1.0/sType/ResourceEvent#\"\n"
+ " xmlns:stRef=\"http://ns.adobe.com/xap/1.0/sType/ResourceRef#\"\n"
+ " xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"\n"
+ " xmlns:xmpGImg=\"http://ns.adobe.com/xap/1.0/g/img/\"\n"
+ " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n"
+ " xmlns:pdf=\"http://ns.adobe.com/pdf/1.3/\">\n"
+ " <photoshop:LegacyIPTCDigest>CDCFFA7DA8C7BE09057076AEAF05C34E</photoshop:LegacyIPTCDigest>\n"
+ " <photoshop:ColorMode>3</photoshop:ColorMode>\n"
+ " <photoshop:ICCProfile>sRGB IEC61966-2.1</photoshop:ICCProfile>\n"
+ " <photoshop:ICCProfile>sRGB IEC61966-2.2</photoshop:ICCProfile>\n"
+ " </rdf:Description>\n"
+ " </rdf:RDF>\n"
+ "</x:xmpmeta>";
Assertions.assertThrows(XMPException.class,
() -> XMPMetaFactory.parseFromBuffer(xmp.getBytes(StandardCharsets.UTF_8)));
}
@Test
public void readDocumentWithControlCharactersInXMPMetadata() throws IOException {
String src = SOURCE_FOLDER + "docWithControlCharactersInXmp.pdf";
try (PdfDocument document = new PdfDocument(new PdfReader(src),
new PdfWriter(new ByteArrayOutputStream()), new StampingProperties())) {
Assertions.assertEquals(PdfConformance.PDF_A_3A, document.getConformance());
}
}
@Test
public void readDocumentWithBrokenControlCharactersInXMPMetadata() throws IOException {
String src = SOURCE_FOLDER + "docWithBrokenControlCharactersInXmp.pdf";
try (PdfDocument document = new PdfDocument(new PdfReader(src),
new PdfWriter(new ByteArrayOutputStream()), new StampingProperties())) {
Assertions.assertEquals(PdfConformance.PDF_A_3A, document.getConformance());
}
}
@Test
public void readDocumentWithInvalidConformance() throws IOException {
String src = SOURCE_FOLDER + "docWithInvalidConformance.pdf";
try (PdfDocument document = new PdfDocument(new PdfReader(src),
new PdfWriter(new ByteArrayOutputStream()), new StampingProperties())) {
Assertions.assertEquals(PdfConformance.PDF_NONE_CONFORMANCE, document.getConformance());
}
}
@LogMessages(messages = {@LogMessage(messageTemplate = IoLogMessageConstant.EXCEPTION_WHILE_UPDATING_XMPMETADATA)})
@Test
public void readDocumentWithInvalidXMPMetadata() throws IOException {
String src = SOURCE_FOLDER + "docWithInvalidMetadata.pdf";
try (PdfDocument document = new PdfDocument(new PdfReader(src),
new PdfWriter(new ByteArrayOutputStream()), new StampingProperties())) {
Assertions.assertEquals(PdfConformance.PDF_NONE_CONFORMANCE, document.getConformance());
}
}
}