Skip to content

Commit ca85b9f

Browse files
author
Dmitry Radchuk
committed
Refactor OC properties check
DEVSIX-2319
1 parent 3befa1e commit ca85b9f

File tree

7 files changed

+277
-30
lines changed

7 files changed

+277
-30
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,11 @@ public void close() {
874874
xmp.put(PdfName.Filter, ar);
875875
}
876876
}
877+
878+
if (!properties.appendMode && catalog.isOCPropertiesMayHaveChanged()) {
879+
catalog.getPdfObject().put(PdfName.OCProperties, catalog.getOCProperties(false).getPdfObject());
880+
}
881+
877882
checkIsoConformance();
878883

879884
if (getNumberOfPages() == 0) {
@@ -932,7 +937,6 @@ public void close() {
932937
}
933938
} else {
934939
if (catalog.isOCPropertiesMayHaveChanged()) {
935-
catalog.getPdfObject().put(PdfName.OCProperties, catalog.getOCProperties(false).getPdfObject());
936940
catalog.getOCProperties(false).flush();
937941
}
938942
if (catalog.pageLabels != null) {

pdfa/src/main/java/com/itextpdf/pdfa/checker/PdfA2Checker.java

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -618,34 +618,7 @@ protected void checkCatalogValidEntries(PdfDictionary catalogDict) {
618618
throw new PdfAConformanceException(PdfaExceptionMessageConstant.A_CATALOG_DICTIONARY_SHALL_NOT_CONTAIN_ALTERNATEPRESENTATIONS_NAMES_ENTRY);
619619
}
620620

621-
PdfDictionary oCProperties = catalogDict.getAsDictionary(PdfName.OCProperties);
622-
if (oCProperties != null) {
623-
List<PdfDictionary> configList = new ArrayList<>();
624-
PdfDictionary d = oCProperties.getAsDictionary(PdfName.D);
625-
if (d != null) {
626-
configList.add(d);
627-
}
628-
PdfArray configs = oCProperties.getAsArray(PdfName.Configs);
629-
if (configs != null) {
630-
for (PdfObject config : configs) {
631-
configList.add((PdfDictionary) config);
632-
}
633-
}
634-
635-
HashSet<PdfObject> ocgs = new HashSet<>();
636-
PdfArray ocgsArray = oCProperties.getAsArray(PdfName.OCGs);
637-
if (ocgsArray != null) {
638-
for (PdfObject ocg : ocgsArray) {
639-
ocgs.add(ocg);
640-
}
641-
}
642-
643-
HashSet<String> names = new HashSet<>();
644-
645-
for (PdfDictionary config : configList) {
646-
checkCatalogConfig(config, ocgs, names);
647-
}
648-
}
621+
checkOCProperties(catalogDict.getAsDictionary(PdfName.OCProperties));
649622
}
650623

651624
@Override
@@ -829,6 +802,36 @@ protected void checkPageColorsUsages(PdfDictionary pageDict, PdfDictionary pageR
829802
}
830803
}
831804

805+
private void checkOCProperties(PdfDictionary oCProperties) {
806+
if (oCProperties != null) {
807+
List<PdfDictionary> configList = new ArrayList<>();
808+
PdfDictionary d = oCProperties.getAsDictionary(PdfName.D);
809+
if (d != null) {
810+
configList.add(d);
811+
}
812+
PdfArray configs = oCProperties.getAsArray(PdfName.Configs);
813+
if (configs != null) {
814+
for (PdfObject config : configs) {
815+
configList.add((PdfDictionary) config);
816+
}
817+
}
818+
819+
HashSet<PdfObject> ocgs = new HashSet<>();
820+
PdfArray ocgsArray = oCProperties.getAsArray(PdfName.OCGs);
821+
if (ocgsArray != null) {
822+
for (PdfObject ocg : ocgsArray) {
823+
ocgs.add(ocg);
824+
}
825+
}
826+
827+
HashSet<String> names = new HashSet<>();
828+
829+
for (PdfDictionary config : configList) {
830+
checkCatalogConfig(config, ocgs, names);
831+
}
832+
}
833+
}
834+
832835
@Override
833836
protected void checkImage(PdfStream image, PdfDictionary currentColorSpaces) {
834837
PdfColorSpace colorSpace = null;
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
package com.itextpdf.pdfa;
2+
3+
import com.itextpdf.kernel.pdf.PdfAConformanceLevel;
4+
import com.itextpdf.kernel.pdf.PdfArray;
5+
import com.itextpdf.kernel.pdf.PdfDictionary;
6+
import com.itextpdf.kernel.pdf.PdfDocument;
7+
import com.itextpdf.kernel.pdf.PdfName;
8+
import com.itextpdf.kernel.pdf.PdfOutputIntent;
9+
import com.itextpdf.kernel.pdf.PdfReader;
10+
import com.itextpdf.kernel.pdf.PdfString;
11+
import com.itextpdf.kernel.pdf.PdfWriter;
12+
import com.itextpdf.kernel.pdf.StampingProperties;
13+
import com.itextpdf.kernel.utils.CompareTool;
14+
import com.itextpdf.pdfa.exceptions.PdfAConformanceException;
15+
import com.itextpdf.pdfa.exceptions.PdfaExceptionMessageConstant;
16+
import com.itextpdf.test.ExtendedITextTest;
17+
import com.itextpdf.test.annotations.type.IntegrationTest;
18+
import com.itextpdf.test.pdfa.VeraPdfValidator;
19+
import org.junit.Assert;
20+
import org.junit.BeforeClass;
21+
import org.junit.Test;
22+
import org.junit.experimental.categories.Category;
23+
24+
import java.io.FileInputStream;
25+
import java.io.FileNotFoundException;
26+
import java.io.IOException;
27+
import java.io.InputStream;
28+
29+
@Category(IntegrationTest.class)
30+
public class PdfA2OCPropertiesTest extends ExtendedITextTest {
31+
public static final String SOURCE_FOLDER = "./src/test/resources/com/itextpdf/pdfa/";
32+
public static final String DESTINATION_FOLDER = "./target/test/com/itextpdf/pdfa/PdfA2OCPropertiesTest/";
33+
34+
@BeforeClass
35+
public static void beforeClass() {
36+
createOrClearDestinationFolder(DESTINATION_FOLDER);
37+
}
38+
39+
@Test
40+
public void checkNameEntryShouldBeUniqueBetweenDefaultAndAdditionalConfigsTest() throws FileNotFoundException {
41+
String outPdf = DESTINATION_FOLDER + "pdfA2b_ocPropertiesCheck01.pdf";
42+
PdfWriter writer = new PdfWriter(outPdf);
43+
InputStream is = new FileInputStream(SOURCE_FOLDER + "sRGB Color Space Profile.icm");
44+
PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is));
45+
doc.addNewPage();
46+
47+
PdfDictionary ocProperties = new PdfDictionary();
48+
PdfDictionary d = new PdfDictionary();
49+
d.put(PdfName.Name, new PdfString("CustomName"));
50+
PdfArray configs = new PdfArray();
51+
PdfDictionary config = new PdfDictionary();
52+
config.put(PdfName.Name, new PdfString("CustomName"));
53+
configs.add(config);
54+
ocProperties.put(PdfName.D, d);
55+
ocProperties.put(PdfName.Configs, configs);
56+
57+
doc.getCatalog().put(PdfName.OCProperties, ocProperties);
58+
59+
Exception e = Assert.assertThrows(PdfAConformanceException.class,
60+
() -> doc.close()
61+
);
62+
Assert.assertEquals(PdfaExceptionMessageConstant.VALUE_OF_NAME_ENTRY_SHALL_BE_UNIQUE_AMONG_ALL_OPTIONAL_CONTENT_CONFIGURATION_DICTIONARIES,
63+
e.getMessage());
64+
}
65+
66+
@Test
67+
public void checkAsKeyInContentConfigDictTest() throws FileNotFoundException {
68+
String outPdf = DESTINATION_FOLDER + "pdfA2b_ocPropertiesCheck02.pdf";
69+
PdfWriter writer = new PdfWriter(outPdf);
70+
InputStream is = new FileInputStream(SOURCE_FOLDER + "sRGB Color Space Profile.icm");
71+
PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is));
72+
doc.addNewPage();
73+
74+
PdfDictionary ocProperties = new PdfDictionary();
75+
PdfArray configs = new PdfArray();
76+
PdfDictionary config = new PdfDictionary();
77+
config.put(PdfName.Name, new PdfString("CustomName"));
78+
config.put(PdfName.AS, new PdfArray());
79+
configs.add(config);
80+
ocProperties.put(PdfName.Configs, configs);
81+
82+
doc.getCatalog().put(PdfName.OCProperties, ocProperties);
83+
84+
Exception e = Assert.assertThrows(PdfAConformanceException.class,
85+
() -> doc.close()
86+
);
87+
Assert.assertEquals(PdfaExceptionMessageConstant.THE_AS_KEY_SHALL_NOT_APPEAR_IN_ANY_OPTIONAL_CONTENT_CONFIGURATION_DICTIONARY,
88+
e.getMessage());
89+
}
90+
91+
92+
@Test
93+
public void checkNameEntryShouldBeUniqueBetweenAdditionalConfigsTest() throws FileNotFoundException {
94+
String outPdf = DESTINATION_FOLDER + "pdfA2b_ocPropertiesCheck03.pdf";
95+
PdfWriter writer = new PdfWriter(outPdf);
96+
InputStream is = new FileInputStream(SOURCE_FOLDER + "sRGB Color Space Profile.icm");
97+
PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is));
98+
doc.addNewPage();
99+
100+
PdfDictionary ocProperties = new PdfDictionary();
101+
PdfDictionary d = new PdfDictionary();
102+
d.put(PdfName.Name, new PdfString("CustomName"));
103+
PdfArray configs = new PdfArray();
104+
PdfDictionary config = new PdfDictionary();
105+
config.put(PdfName.Name, new PdfString("CustomName1"));
106+
configs.add(config);
107+
config = new PdfDictionary();
108+
config.put(PdfName.Name, new PdfString("CustomName1"));
109+
configs.add(config);
110+
ocProperties.put(PdfName.D, d);
111+
ocProperties.put(PdfName.Configs, configs);
112+
113+
doc.getCatalog().put(PdfName.OCProperties, ocProperties);
114+
115+
Exception e = Assert.assertThrows(PdfAConformanceException.class,
116+
() -> doc.close()
117+
);
118+
Assert.assertEquals(PdfaExceptionMessageConstant.VALUE_OF_NAME_ENTRY_SHALL_BE_UNIQUE_AMONG_ALL_OPTIONAL_CONTENT_CONFIGURATION_DICTIONARIES,
119+
e.getMessage());
120+
}
121+
122+
@Test
123+
public void checkOCCDContainNameTest() throws FileNotFoundException {
124+
String outPdf = DESTINATION_FOLDER + "pdfA2b_ocPropertiesCheck04.pdf";
125+
PdfWriter writer = new PdfWriter(outPdf);
126+
InputStream is = new FileInputStream(SOURCE_FOLDER + "sRGB Color Space Profile.icm");
127+
PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is));
128+
doc.addNewPage();
129+
130+
PdfDictionary ocProperties = new PdfDictionary();
131+
PdfDictionary d = new PdfDictionary();
132+
PdfArray configs = new PdfArray();
133+
PdfDictionary config = new PdfDictionary();
134+
config.put(PdfName.Name, new PdfString("CustomName1"));
135+
configs.add(config);
136+
config = new PdfDictionary();
137+
config.put(PdfName.Name, new PdfString("CustomName2"));
138+
configs.add(config);
139+
ocProperties.put(PdfName.D, d);
140+
ocProperties.put(PdfName.Configs, configs);
141+
142+
doc.getCatalog().put(PdfName.OCProperties, ocProperties);
143+
144+
Exception e = Assert.assertThrows(PdfAConformanceException.class,
145+
() -> doc.close()
146+
);
147+
Assert.assertEquals(PdfaExceptionMessageConstant.OPTIONAL_CONTENT_CONFIGURATION_DICTIONARY_SHALL_CONTAIN_NAME_ENTRY,
148+
e.getMessage());
149+
}
150+
151+
@Test
152+
public void checkOrderArrayContainsReferencesToAllOCGsTest() throws FileNotFoundException {
153+
String outPdf = DESTINATION_FOLDER + "pdfA2b_ocPropertiesCheck05.pdf";
154+
PdfWriter writer = new PdfWriter(outPdf);
155+
InputStream is = new FileInputStream(SOURCE_FOLDER + "sRGB Color Space Profile.icm");
156+
PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is));
157+
doc.addNewPage();
158+
159+
PdfDictionary ocProperties = new PdfDictionary();
160+
PdfDictionary d = new PdfDictionary();
161+
d.put(PdfName.Name, new PdfString("CustomName"));
162+
PdfArray configs = new PdfArray();
163+
PdfDictionary config = new PdfDictionary();
164+
config.put(PdfName.Name, new PdfString("CustomName1"));
165+
PdfArray order = new PdfArray();
166+
PdfDictionary orderItem = new PdfDictionary();
167+
orderItem.put(PdfName.Name, new PdfString("CustomName2"));
168+
order.add(orderItem);
169+
PdfDictionary orderItem1 = new PdfDictionary();
170+
orderItem1.put(PdfName.Name, new PdfString("CustomName3"));
171+
config.put(PdfName.Order, order);
172+
173+
PdfArray ocgs = new PdfArray();
174+
ocgs.add(orderItem);
175+
ocgs.add(orderItem1);
176+
177+
ocProperties.put(PdfName.OCGs, ocgs);
178+
179+
configs.add(config);
180+
181+
ocProperties.put(PdfName.D, d);
182+
ocProperties.put(PdfName.Configs, configs);
183+
184+
doc.getCatalog().put(PdfName.OCProperties, ocProperties);
185+
186+
Exception e = Assert.assertThrows(PdfAConformanceException.class,
187+
() -> doc.close()
188+
);
189+
Assert.assertEquals(PdfaExceptionMessageConstant.ORDER_ARRAY_SHALL_CONTAIN_REFERENCES_TO_ALL_OCGS, e.getMessage());
190+
}
191+
192+
@Test
193+
public void checkDocWithOCGsWithoutOptionalOrderEntryTest() throws IOException, InterruptedException {
194+
String outPdf = DESTINATION_FOLDER + "pdfA2b_ocPropertiesCheck06.pdf";
195+
String cmpPdf = SOURCE_FOLDER + "cmp_pdfA2b_ocPropertiesCheck06.pdf";
196+
PdfWriter writer = new PdfWriter(outPdf);
197+
InputStream is = new FileInputStream(SOURCE_FOLDER + "sRGB Color Space Profile.icm");
198+
PdfADocument doc = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_2B, new PdfOutputIntent("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", is));
199+
doc.addNewPage();
200+
201+
PdfDictionary ocProperties = new PdfDictionary();
202+
203+
PdfDictionary d = new PdfDictionary();
204+
d.put(PdfName.Name, new PdfString("CustomName"));
205+
206+
PdfDictionary orderItem = new PdfDictionary();
207+
orderItem.put(PdfName.Name, new PdfString("CustomName2"));
208+
209+
PdfArray ocgs = new PdfArray();
210+
ocgs.add(orderItem);
211+
212+
ocProperties.put(PdfName.OCGs, ocgs);
213+
ocProperties.put(PdfName.D, d);
214+
215+
doc.getCatalog().put(PdfName.OCProperties, ocProperties);
216+
doc.close();
217+
Assert.assertNull(new CompareTool().compareByContent(outPdf, cmpPdf, DESTINATION_FOLDER, "diff01_"));
218+
Assert.assertNull(new VeraPdfValidator().validate(outPdf)); // Android-Conversion-Skip-Line (TODO DEVSIX-7377 introduce pdf\a validation on Android)
219+
}
220+
221+
@Test
222+
public void appendModeWithOCGsTest() throws IOException, InterruptedException {
223+
String outPdf = DESTINATION_FOLDER + "pdfA2b_ocPropertiesCheck07.pdf";
224+
String cmpPdf = SOURCE_FOLDER + "cmp_pdfA2b_ocPropertiesCheck07.pdf";
225+
String filename = SOURCE_FOLDER + "cmp_pdfA2b_ocPropertiesCheck06.pdf";
226+
StampingProperties props = new StampingProperties();
227+
props.useAppendMode();
228+
229+
PdfDocument doc = new PdfDocument(new PdfReader(filename), new PdfWriter(outPdf), props);
230+
PdfDictionary ocProperties = (PdfDictionary) doc.getCatalog().getPdfObject().get(PdfName.OCProperties);
231+
232+
PdfArray configs = new PdfArray();
233+
PdfDictionary config = new PdfDictionary();
234+
config.put(PdfName.Name, new PdfString("CustomName1"));
235+
configs.add(config);
236+
ocProperties.put(PdfName.Configs, configs);
237+
doc.close();
238+
Assert.assertNull(new CompareTool().compareByContent(outPdf, cmpPdf, DESTINATION_FOLDER, "diff01_"));
239+
Assert.assertNull(new VeraPdfValidator().validate(outPdf)); // Android-Conversion-Skip-Line (TODO DEVSIX-7377 introduce pdf\a validation on Android)
240+
}
241+
}

pdfa/src/test/java/com/itextpdf/pdfa/checker/PdfA2CheckerTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ This file is part of the iText (R) project.
2525
import com.itextpdf.commons.utils.MessageFormatUtil;
2626
import com.itextpdf.kernel.colors.Color;
2727
import com.itextpdf.kernel.colors.PatternColor;
28-
import com.itextpdf.kernel.geom.Rectangle;
2928
import com.itextpdf.kernel.pdf.PdfAConformanceLevel;
3029
import com.itextpdf.kernel.pdf.PdfArray;
3130
import com.itextpdf.kernel.pdf.PdfBoolean;
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)