Skip to content

Commit f15fb9a

Browse files
author
Vitali Prudnikovich
committed
Cache PdfReader.getPdfAConformanceLevel result for non pdfA docs
DEVSIX-7188
1 parent 0fdc3a0 commit f15fb9a

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

kernel/src/main/java/com/itextpdf/kernel/pdf/PdfReader.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ This file is part of the iText (R) project.
6161
import com.itextpdf.kernel.exceptions.XrefCycledReferencesException;
6262
import com.itextpdf.kernel.pdf.filters.FilterHandlers;
6363
import com.itextpdf.kernel.pdf.filters.IFilterHandler;
64+
import com.itextpdf.kernel.xmp.XMPException;
65+
import com.itextpdf.kernel.xmp.XMPMeta;
66+
import com.itextpdf.kernel.xmp.XMPMetaFactory;
6467

6568
import java.io.ByteArrayInputStream;
6669
import java.io.Closeable;
@@ -70,10 +73,6 @@ This file is part of the iText (R) project.
7073
import java.util.HashSet;
7174
import java.nio.charset.StandardCharsets;
7275
import java.util.Map;
73-
74-
import com.itextpdf.kernel.xmp.XMPException;
75-
import com.itextpdf.kernel.xmp.XMPMetaFactory;
76-
7776
import java.util.Set;
7877
import org.slf4j.Logger;
7978
import org.slf4j.LoggerFactory;
@@ -106,6 +105,8 @@ public class PdfReader implements Closeable {
106105
//indicate nearest first Indirect reference object which includes current reading the object, using for PdfString decrypt
107106
private PdfIndirectReference currentIndirectReference;
108107

108+
private XMPMeta xmpMeta;
109+
109110
protected PdfTokenizer tokens;
110111
protected PdfEncryption decrypt;
111112

@@ -641,14 +642,18 @@ public PdfAConformanceLevel getPdfAConformanceLevel() {
641642
if (pdfDocument == null || !pdfDocument.getXref().isReadingCompleted()) {
642643
throw new PdfException(KernelExceptionMessageConstant.DOCUMENT_HAS_NOT_BEEN_READ_YET);
643644
}
644-
if (pdfDocument.getXmpMetadata() != null) {
645-
try {
646-
pdfAConformanceLevel = PdfAConformanceLevel.getConformanceLevel(
647-
XMPMetaFactory.parseFromBuffer(pdfDocument.getXmpMetadata()));
648-
} catch (XMPException ignored) {
645+
646+
try {
647+
if (xmpMeta == null && pdfDocument.getXmpMetadata() != null) {
648+
xmpMeta = XMPMetaFactory.parseFromBuffer(pdfDocument.getXmpMetadata());
649+
}
650+
if (xmpMeta != null) {
651+
pdfAConformanceLevel = PdfAConformanceLevel.getConformanceLevel(xmpMeta);
649652
}
653+
} catch (XMPException ignored) {
650654
}
651655
}
656+
652657
return pdfAConformanceLevel;
653658
}
654659

kernel/src/test/java/com/itextpdf/kernel/pdf/PdfReaderTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ This file is part of the iText (R) project.
6060
import com.itextpdf.kernel.exceptions.XrefCycledReferencesException;
6161
import com.itextpdf.kernel.pdf.PdfReader.StrictnessLevel;
6262
import com.itextpdf.kernel.utils.CompareTool;
63+
import com.itextpdf.kernel.xmp.XMPConst;
6364
import com.itextpdf.kernel.xmp.XMPException;
65+
import com.itextpdf.kernel.xmp.XMPMeta;
66+
import com.itextpdf.kernel.xmp.XMPMetaFactory;
67+
import com.itextpdf.kernel.xmp.options.PropertyOptions;
6468
import com.itextpdf.test.AssertUtil;
6569
import com.itextpdf.test.ExtendedITextTest;
6670
import com.itextpdf.test.annotations.LogMessage;
@@ -2298,6 +2302,12 @@ public void getPdfAConformanceLevelPdfDocumentNotReadTest() throws IOException {
22982302
Assert.assertEquals(KernelExceptionMessageConstant.DOCUMENT_HAS_NOT_BEEN_READ_YET, e.getMessage());
22992303
}
23002304

2305+
@Test
2306+
public void getPdfAConformanceLevelNoMetadataTest() throws IOException {
2307+
PdfDocument pdfDoc = new PdfDocument(new PdfReader(new ByteArrayInputStream(createPdfDocumentForTest())));
2308+
Assert.assertNull(pdfDoc.getReader().getPdfAConformanceLevel());
2309+
}
2310+
23012311
@Test
23022312
public void xrefStreamPointsItselfTest() throws IOException {
23032313
String fileName = SOURCE_FOLDER + "xrefStreamPointsItself.pdf";
@@ -2636,6 +2646,26 @@ public void tokensPositionIsNotUpdatedWhileReadingLengthTest() throws IOExceptio
26362646
}
26372647
}
26382648

2649+
@Test
2650+
public void conformanceLevelCacheTest() throws IOException, XMPException {
2651+
String filename = DESTINATION_FOLDER + "simpleDoc.pdf";
2652+
2653+
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(filename));
2654+
XMPMeta xmp = XMPMetaFactory.create();
2655+
xmp.appendArrayItem(XMPConst.NS_DC, "subject",
2656+
new PropertyOptions(PropertyOptions.ARRAY), "Hello World", null);
2657+
pdfDoc.setXmpMetadata(xmp);
2658+
2659+
pdfDoc.addNewPage();
2660+
pdfDoc.close();
2661+
2662+
TestPdfDocumentCache pdfTestDoc = new TestPdfDocumentCache(new PdfReader(filename));
2663+
for(int i = 0; i < 1000; ++i) {
2664+
pdfTestDoc.getReader().getPdfAConformanceLevel();
2665+
}
2666+
Assert.assertEquals(2, pdfTestDoc.getCounter());
2667+
}
2668+
26392669
private static PdfDictionary getTestPdfDictionary() {
26402670
HashMap<PdfName, PdfObject> tmpMap = new HashMap<PdfName, PdfObject>();
26412671
tmpMap.put(new PdfName("b"), new PdfName("c"));
@@ -2650,4 +2680,22 @@ private static byte[] createPdfDocumentForTest() throws IOException {
26502680
return baos.toByteArray();
26512681
}
26522682
}
2683+
2684+
private class TestPdfDocumentCache extends PdfDocument {
2685+
private int getXmpMetadataCounter;
2686+
2687+
public TestPdfDocumentCache(PdfReader pdfReader) {
2688+
super(pdfReader);
2689+
}
2690+
2691+
@Override
2692+
public byte[] getXmpMetadata(boolean createNew) {
2693+
++getXmpMetadataCounter;
2694+
return super.getXmpMetadata(createNew);
2695+
}
2696+
2697+
public int getCounter() {
2698+
return getXmpMetadataCounter;
2699+
}
2700+
}
26532701
}

0 commit comments

Comments
 (0)