Skip to content

Commit 08c9751

Browse files
committed
Implement architecture for creating PDF/UA document
* Add checkpoint 1 checks for mattarhorn protocol DEVSIX-7895
1 parent 65e57c1 commit 08c9751

File tree

65 files changed

+2438
-151
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2438
-151
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2023 Apryse Group NV
4+
Authors: Apryse Software.
5+
6+
This program is offered under a commercial and under the AGPL license.
7+
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
8+
9+
AGPL licensing:
10+
This program is free software: you can redistribute it and/or modify
11+
it under the terms of the GNU Affero General Public License as published by
12+
the Free Software Foundation, either version 3 of the License, or
13+
(at your option) any later version.
14+
15+
This program is distributed in the hope that it will be useful,
16+
but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
GNU Affero General Public License for more details.
19+
20+
You should have received a copy of the GNU Affero General Public License
21+
along with this program. If not, see <https://www.gnu.org/licenses/>.
22+
*/
23+
package com.itextpdf.commons.datastructures;
24+
25+
/**
26+
* Simple tuple container that holds two elements.
27+
*
28+
* @param <T1> type of the first element
29+
* @param <T2> type of the second element
30+
*/
31+
public class Tuple2<T1, T2> {
32+
private final T1 first;
33+
private final T2 second;
34+
35+
/**
36+
* Creates a new instance of {@link Tuple2} with given elements.
37+
*
38+
* @param first the first element
39+
* @param second the second element
40+
*/
41+
public Tuple2(T1 first, T2 second) {
42+
this.first = first;
43+
this.second = second;
44+
}
45+
46+
/**
47+
* Get the first element.
48+
*
49+
* @return the first element
50+
*/
51+
public T1 getFirst() {
52+
return first;
53+
}
54+
55+
/**
56+
* Get the second element.
57+
*
58+
* @return the second element
59+
*/
60+
public T2 getSecond() {
61+
return second;
62+
}
63+
64+
/**
65+
* {@inheritDoc}
66+
*/
67+
@Override
68+
public String toString() {
69+
return "Tuple2{" +
70+
"first=" + first +
71+
", second=" + second +
72+
'}';
73+
}
74+
}

commons/src/main/java/com/itextpdf/commons/utils/DIContainer.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ public <T> T getInstance(Class<T> clazz) {
8787
return (T) supplier;
8888
}
8989

90-
90+
/**
91+
* Checks if an instance is registered for a class.
92+
* If the class is registered but the value is null, it will still return {@code true}.
93+
*
94+
* @param clazz the class
95+
*
96+
* @return {@code true} if an instance is registered, {@code false} otherwise
97+
*/
98+
public boolean isRegistered(Class<?> clazz) {
99+
return localInstances.containsKey(clazz) || instances.containsKey(clazz);
100+
}
91101
}
92-
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2023 Apryse Group NV
4+
Authors: Apryse Software.
5+
6+
This program is offered under a commercial and under the AGPL license.
7+
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
8+
9+
AGPL licensing:
10+
This program is free software: you can redistribute it and/or modify
11+
it under the terms of the GNU Affero General Public License as published by
12+
the Free Software Foundation, either version 3 of the License, or
13+
(at your option) any later version.
14+
15+
This program is distributed in the hope that it will be useful,
16+
but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
GNU Affero General Public License for more details.
19+
20+
You should have received a copy of the GNU Affero General Public License
21+
along with this program. If not, see <https://www.gnu.org/licenses/>.
22+
*/
23+
package com.itextpdf.commons.datastructures;
24+
25+
import com.itextpdf.test.ExtendedITextTest;
26+
import com.itextpdf.test.annotations.type.UnitTest;
27+
28+
import org.junit.Test;
29+
import org.junit.experimental.categories.Category;
30+
import static org.junit.Assert.assertEquals;
31+
import static org.junit.Assert.assertNull;
32+
33+
@Category(UnitTest.class)
34+
public class Tuple2Test extends ExtendedITextTest {
35+
36+
@Test
37+
public void testTuple2_StringInt() {
38+
Tuple2<String, Integer> tuple = new Tuple2<>("test", 1);
39+
assertEquals("test", tuple.getFirst());
40+
assertEquals(Integer.valueOf(1), tuple.getSecond());
41+
}
42+
43+
@Test
44+
public void testTuple2_ToString() {
45+
Tuple2<String, Integer> tuple = new Tuple2<>("test", 1);
46+
assertEquals("Tuple2{first=test, second=1}", tuple.toString());
47+
}
48+
49+
@Test
50+
public void testTuple2_TestWithNullFirstValue() {
51+
Tuple2<String, Integer> tuple = new Tuple2<>(null, 1);
52+
assertNull(tuple.getFirst());
53+
assertEquals(Integer.valueOf(1), tuple.getSecond());
54+
}
55+
}

forms/src/main/java/com/itextpdf/forms/form/renderer/AbstractFormFieldRenderer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,10 @@ protected PdfAConformanceLevel getConformanceLevel(PdfDocument document) {
289289
if (document == null) {
290290
return null;
291291
}
292-
return document.getConformanceLevel();
292+
if (document.getConformanceLevel() instanceof PdfAConformanceLevel) {
293+
return (PdfAConformanceLevel) document.getConformanceLevel();
294+
}
295+
return null;
293296
}
294297

295298
/**

forms/src/main/java/com/itextpdf/forms/form/renderer/AbstractSelectFieldRenderer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,10 @@ protected PdfAConformanceLevel getConformanceLevel(PdfDocument document) {
242242
if (document == null) {
243243
return null;
244244
}
245-
return document.getConformanceLevel();
245+
if (document.getConformanceLevel() instanceof PdfAConformanceLevel) {
246+
return (PdfAConformanceLevel) document.getConformanceLevel();
247+
}
248+
return null;
246249
}
247250

248251
protected List<IRenderer> getOptionsMarkedSelected(IRenderer optionsSubTree) {

itextcore/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,5 +130,10 @@
130130
<artifactId>bouncy-castle-connector</artifactId>
131131
<version>${project.version}</version>
132132
</dependency>
133+
<dependency>
134+
<groupId>com.itextpdf</groupId>
135+
<artifactId>pdfua</artifactId>
136+
<version>${project.version}</version>
137+
</dependency>
133138
</dependencies>
134139
</project>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2023 Apryse Group NV
4+
Authors: Apryse Software.
5+
6+
This program is offered under a commercial and under the AGPL license.
7+
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
8+
9+
AGPL licensing:
10+
This program is free software: you can redistribute it and/or modify
11+
it under the terms of the GNU Affero General Public License as published by
12+
the Free Software Foundation, either version 3 of the License, or
13+
(at your option) any later version.
14+
15+
This program is distributed in the hope that it will be useful,
16+
but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
GNU Affero General Public License for more details.
19+
20+
You should have received a copy of the GNU Affero General Public License
21+
along with this program. If not, see <https://www.gnu.org/licenses/>.
22+
*/
23+
package com.itextpdf.kernel.pdf;
24+
25+
26+
/**
27+
* Interface for PDF conformance level.
28+
* <p>
29+
*
30+
* Conformance levels are extended PDF specifications that define subsets of PDF
31+
* functionality. An example of a conformance level is PDF/A, which is used for long-term archiving
32+
* and PDF/UA, which is used for accessible documents.
33+
*/
34+
public interface IConformanceLevel {
35+
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ This file is part of the iText (R) project.
2626
* Type of object to conform.
2727
*/
2828
public enum IsoKey {
29+
// PDF/A Enums
2930
CANVAS_STACK,
3031
FILL_COLOR,
3132
EXTENDED_GRAPHICS_STATE,
@@ -40,5 +41,8 @@ public enum IsoKey {
4041
SIGNATURE,
4142
SIGNATURE_TYPE,
4243
CRYPTO,
43-
FONT
44+
FONT,
45+
// PDF/UA Enums
46+
CANVAS_BEGIN_MARKED_CONTENT,
47+
CANVAS_WRITING_CONTENT
4448
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ This file is part of the iText (R) project.
3131
/**
3232
* Enumeration of all the PDF/A conformance levels.
3333
*/
34-
public class PdfAConformanceLevel {
34+
public class PdfAConformanceLevel implements IConformanceLevel {
3535

3636
public static final PdfAConformanceLevel PDF_A_1A = new PdfAConformanceLevel("1", "A");
3737
public static final PdfAConformanceLevel PDF_A_1B = new PdfAConformanceLevel("1", "B");

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

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ This file is part of the iText (R) project.
6060
import com.itextpdf.kernel.pdf.statistics.SizeOfPdfStatisticsEvent;
6161
import com.itextpdf.kernel.pdf.tagging.PdfStructTreeRoot;
6262
import com.itextpdf.kernel.pdf.tagutils.TagStructureContext;
63+
import com.itextpdf.kernel.utils.ValidationContainer;
64+
import com.itextpdf.kernel.utils.ValidationContext;
6365
import com.itextpdf.kernel.xmp.PdfConst;
6466
import com.itextpdf.kernel.xmp.XMPConst;
6567
import com.itextpdf.kernel.xmp.XMPException;
@@ -1153,11 +1155,11 @@ public List<PdfPage> copyPagesTo(int pageFrom, int pageTo, PdfDocument toDocumen
11531155

11541156

11551157
/**
1156-
* Get the {@link PdfAConformanceLevel}
1158+
* Get the {@link IConformanceLevel}
11571159
*
1158-
* @return the {@link PdfAConformanceLevel} will be null if the document is not a PDF/A document
1160+
* @return the {@link IConformanceLevel} will be null if the document does not have a conformance level specified
11591161
*/
1160-
public PdfAConformanceLevel getConformanceLevel() {
1162+
public IConformanceLevel getConformanceLevel() {
11611163
return null;
11621164
}
11631165

@@ -1573,29 +1575,28 @@ public void addOutputIntent(PdfOutputIntent outputIntent) {
15731575

15741576
/**
15751577
* Checks whether PDF document conforms a specific standard.
1576-
* Shall be overridden.
15771578
*
15781579
* @param obj An object to conform.
15791580
* @param key type of object to conform.
15801581
*/
15811582
public void checkIsoConformance(Object obj, IsoKey key) {
1583+
checkIsoConformance(obj, key, null, null);
15821584
}
15831585

15841586
/**
15851587
* Checks whether PDF document conforms a specific standard.
1586-
* Shall be overridden.
15871588
*
15881589
* @param obj an object to conform.
15891590
* @param key type of object to conform.
15901591
* @param resources {@link PdfResources} associated with an object to check.
15911592
* @param contentStream current content stream
15921593
*/
15931594
public void checkIsoConformance(Object obj, IsoKey key, PdfResources resources, PdfStream contentStream) {
1595+
checkIsoConformance(obj, key, resources, contentStream, null);
15941596
}
15951597

15961598
/**
15971599
* Checks whether PDF document conforms a specific standard.
1598-
* Shall be overridden.
15991600
*
16001601
* @param obj an object to conform.
16011602
* @param key type of object to conform.
@@ -1605,6 +1606,14 @@ public void checkIsoConformance(Object obj, IsoKey key, PdfResources resources,
16051606
*/
16061607
public void checkIsoConformance(Object obj, IsoKey key, PdfResources resources, PdfStream contentStream,
16071608
Object extra) {
1609+
if (!this.getDiContainer().isRegistered(ValidationContainer.class)) {
1610+
return;
1611+
}
1612+
ValidationContainer container = this.getDiContainer().getInstance(ValidationContainer.class);
1613+
if (container == null) {
1614+
return;
1615+
}
1616+
container.validate(obj, key, resources, contentStream, extra);
16081617
}
16091618

16101619
/**
@@ -1982,10 +1991,20 @@ protected void storeDestinationToReaddress(PdfDestination destination,
19821991
}
19831992

19841993
/**
1985-
* Checks whether PDF document conforms a specific standard.
1986-
* Shall be overridden.
1994+
* Checks whether PDF document conforms to a specific standard.
19871995
*/
19881996
protected void checkIsoConformance() {
1997+
if (!this.getDiContainer().isRegistered(ValidationContainer.class)) {
1998+
return;
1999+
}
2000+
ValidationContainer container = this.getDiContainer().getInstance(ValidationContainer.class);
2001+
if (container == null) {
2002+
return;
2003+
}
2004+
ValidationContext context = new ValidationContext()
2005+
.withPdfDocument(this)
2006+
.withFonts(getDocumentFonts());
2007+
container.validate(context);
19892008
}
19902009

19912010
/**

0 commit comments

Comments
 (0)