@@ -31,16 +31,23 @@ This file is part of the iText (R) project.
31
31
import com .itextpdf .kernel .pdf .PdfDictionary ;
32
32
import com .itextpdf .kernel .pdf .PdfDocument ;
33
33
import com .itextpdf .kernel .pdf .PdfName ;
34
+ import com .itextpdf .kernel .pdf .PdfObject ;
34
35
import com .itextpdf .kernel .pdf .PdfResources ;
35
36
import com .itextpdf .kernel .pdf .PdfStream ;
36
37
import com .itextpdf .kernel .pdf .tagging .PdfMcr ;
38
+ import com .itextpdf .kernel .pdf .tagging .PdfNamespace ;
39
+ import com .itextpdf .kernel .pdf .tagging .PdfStructTreeRoot ;
40
+ import com .itextpdf .kernel .pdf .tagging .StandardRoles ;
41
+ import com .itextpdf .kernel .pdf .tagutils .IRoleMappingResolver ;
42
+ import com .itextpdf .kernel .pdf .tagutils .TagStructureContext ;
37
43
import com .itextpdf .kernel .utils .IValidationChecker ;
38
44
import com .itextpdf .kernel .utils .ValidationContext ;
39
45
import com .itextpdf .pdfua .exceptions .PdfUAConformanceException ;
40
46
import com .itextpdf .pdfua .exceptions .PdfUAExceptionMessageConstants ;
41
47
42
48
import java .util .Collection ;
43
49
import java .util .HashSet ;
50
+ import java .util .Map ;
44
51
import java .util .Set ;
45
52
import java .util .Stack ;
46
53
@@ -54,13 +61,16 @@ public class PdfUA1Checker implements IValidationChecker {
54
61
55
62
private final PdfDocument pdfDocument ;
56
63
64
+ private final TagStructureContext tagStructureContext ;
65
+
57
66
/**
58
67
* Creates PdfUA1Checker instance with PDF document which will be validated against PDF/UA-1 standard.
59
68
*
60
69
* @param pdfDocument the document to validate
61
70
*/
62
71
public PdfUA1Checker (PdfDocument pdfDocument ) {
63
72
this .pdfDocument = pdfDocument ;
73
+ this .tagStructureContext = new TagStructureContext (pdfDocument );
64
74
}
65
75
66
76
/**
@@ -69,6 +79,7 @@ public PdfUA1Checker(PdfDocument pdfDocument) {
69
79
@ Override
70
80
public void validateDocument (ValidationContext validationContext ) {
71
81
checkCatalog (validationContext .getPdfDocument ().getCatalog ());
82
+ checkStructureTreeRoot (validationContext .getPdfDocument ().getStructTreeRoot ());
72
83
checkFonts (validationContext .getFonts ());
73
84
}
74
85
@@ -107,13 +118,14 @@ private Stack<Tuple2<PdfName, PdfDictionary>> getTagStack(Object data) {
107
118
}
108
119
109
120
private void checkOnOpeningBeginMarkedContent (Object obj , Object extra ) {
121
+ Tuple2 <PdfName , PdfDictionary > currentBmc = (Tuple2 <PdfName , PdfDictionary >) extra ;
122
+ checkStandardRoleMapping (currentBmc );
123
+
110
124
Stack <Tuple2 <PdfName , PdfDictionary >> stack = getTagStack (obj );
111
125
if (stack .isEmpty ()) {
112
126
return ;
113
127
}
114
128
115
- Tuple2 <PdfName , PdfDictionary > currentBmc = (Tuple2 <PdfName , PdfDictionary >) extra ;
116
-
117
129
boolean isRealContent = isRealContent (currentBmc );
118
130
boolean isArtifact = PdfName .Artifact .equals (currentBmc .getFirst ());
119
131
@@ -125,6 +137,15 @@ private void checkOnOpeningBeginMarkedContent(Object obj, Object extra) {
125
137
}
126
138
}
127
139
140
+ private void checkStandardRoleMapping (Tuple2 <PdfName , PdfDictionary > tag ) {
141
+ final PdfNamespace namespace = tagStructureContext .getDocumentDefaultNamespace ();
142
+ final String role = tag .getFirst ().getValue ();
143
+ if (!StandardRoles .ARTIFACT .equals (role ) && !tagStructureContext .checkIfRoleShallBeMappedToStandardRole (role , namespace )) {
144
+ throw new PdfUAConformanceException (
145
+ MessageFormatUtil .format (PdfUAExceptionMessageConstants .TAG_MAPPING_DOESNT_TERMINATE_WITH_STANDARD_TYPE , role ));
146
+ }
147
+ }
148
+
128
149
private boolean isInsideArtifact (Stack <Tuple2 <PdfName , PdfDictionary >> tagStack ) {
129
150
for (Tuple2 <PdfName , PdfDictionary > tag : tagStack ) {
130
151
if (PdfName .Artifact .equals (tag .getFirst ())) {
@@ -175,6 +196,19 @@ private void checkCatalog(PdfCatalog catalog) {
175
196
}
176
197
}
177
198
199
+ private void checkStructureTreeRoot (PdfStructTreeRoot structTreeRoot ) {
200
+ PdfDictionary roleMap = structTreeRoot .getRoleMap ();
201
+ for (Map .Entry <PdfName , PdfObject > entry : roleMap .entrySet ()) {
202
+ final String role = entry .getKey ().getValue ();
203
+ final IRoleMappingResolver roleMappingResolver = pdfDocument .getTagStructureContext ()
204
+ .getRoleMappingResolver (role );
205
+
206
+ if (roleMappingResolver .currentRoleIsStandard ()) {
207
+ throw new PdfUAConformanceException (PdfUAExceptionMessageConstants .ONE_OR_MORE_STANDARD_ROLE_REMAPPED );
208
+ }
209
+ }
210
+ }
211
+
178
212
private void checkFonts (Collection <PdfFont > fontsInDocument ) {
179
213
Set <String > fontNamesThatAreNotEmbedded = new HashSet <>();
180
214
for (PdfFont font : fontsInDocument ) {
0 commit comments