@@ -103,6 +103,29 @@ public class PdfA4Checker extends PdfA3Checker {
103
103
104
104
private static final Logger LOGGER = LoggerFactory .getLogger (PdfAChecker .class );
105
105
106
+
107
+ private static final Set <PdfName > forbiddenActionsE = Collections
108
+ .unmodifiableSet (new HashSet <>(Arrays .asList (
109
+ PdfName .Launch ,
110
+ PdfName .Sound ,
111
+ PdfName .Movie ,
112
+ PdfName .ResetForm ,
113
+ PdfName .ImportData ,
114
+ PdfName .JavaScript ,
115
+ PdfName .Hide ,
116
+ PdfName .Rendition ,
117
+ PdfName .Trans
118
+ )));
119
+ private static final Set <PdfName > allowedEntriesInAAWhenNonWidget = Collections
120
+ .unmodifiableSet (new HashSet <>(Arrays .asList (
121
+ PdfName .E ,
122
+ PdfName .X ,
123
+ PdfName .D ,
124
+ PdfName .U ,
125
+ PdfName .Fo ,
126
+ PdfName .Bl
127
+ )));
128
+
106
129
/**
107
130
* Creates a PdfA4Checker with the required conformance level
108
131
*
@@ -200,6 +223,36 @@ protected void checkPageTransparency(PdfDictionary pageDict, PdfDictionary pageR
200
223
}
201
224
}
202
225
226
+
227
+ /**
228
+ * Check the conformity of the AA dictionary on catalog level.
229
+ *
230
+ * @param dict the catalog dictionary
231
+ */
232
+ @ Override
233
+ protected void checkCatalogAAConformance (PdfDictionary dict ) {
234
+ final PdfDictionary aa = dict .getAsDictionary (PdfName .AA );
235
+ if (aa != null && hasAAIllegalEntries (aa )) {
236
+ throw new PdfAConformanceException (
237
+ PdfaExceptionMessageConstant .CATALOG_AA_DICTIONARY_SHALL_CONTAIN_ONLY_ALLOWED_KEYS );
238
+ }
239
+ }
240
+
241
+
242
+ /**
243
+ * Check the conformity of the AA dictionary on catalog level.
244
+ *
245
+ * @param dict the catalog dictionary
246
+ */
247
+ @ Override
248
+ protected void checkPageAAConformance (PdfDictionary dict ) {
249
+ final PdfDictionary aa = dict .getAsDictionary (PdfName .AA );
250
+ if (aa != null && hasAAIllegalEntries (aa )) {
251
+ throw new PdfAConformanceException (
252
+ PdfaExceptionMessageConstant .PAGE_AA_DICTIONARY_SHALL_CONTAIN_ONLY_ALLOWED_KEYS );
253
+ }
254
+ }
255
+
203
256
//There are no limits for numbers in pdf-a/4
204
257
/**
205
258
* {@inheritDoc}
@@ -276,6 +329,22 @@ protected Set<PdfName> getAppearanceLessAnnotations() {
276
329
return apLessAnnotations ;
277
330
}
278
331
332
+
333
+ /**
334
+ * Check the conformity of the AA dictionary on widget level.
335
+ *
336
+ * @param dict the widget dictionary
337
+ */
338
+ protected void checkWidgetAAConformance (PdfDictionary dict ) {
339
+ if (!PdfName .Widget .equals (dict .getAsName (PdfName .Subtype )) && dict .containsKey (PdfName .AA )) {
340
+ final PdfObject additionalActions = dict .get (PdfName .AA );
341
+ if (additionalActions .isDictionary () && hasAAIllegalEntries ((PdfDictionary ) additionalActions )) {
342
+ throw new PdfAConformanceException (
343
+ PdfaExceptionMessageConstant .ANNOTATION_AA_DICTIONARY_SHALL_CONTAIN_ONLY_ALLOWED_KEYS );
344
+ }
345
+ }
346
+ }
347
+
279
348
/**
280
349
* {@inheritDoc}
281
350
*/
@@ -285,9 +354,27 @@ protected void checkAnnotationAgainstActions(PdfDictionary annotDic) {
285
354
throw new PdfAConformanceException (
286
355
PdfaExceptionMessageConstant .WIDGET_ANNOTATION_DICTIONARY_OR_FIELD_DICTIONARY_SHALL_NOT_INCLUDE_A_ENTRY );
287
356
}
288
- if (!PdfName .Widget .equals (annotDic .getAsName (PdfName .Subtype )) && annotDic .containsKey (PdfName .AA )) {
289
- throw new PdfAConformanceException (PdfAConformanceException .AN_ANNOTATION_DICTIONARY_SHALL_NOT_CONTAIN_AA_KEY );
357
+ checkWidgetAAConformance (annotDic );
358
+ }
359
+
360
+ private static boolean hasAAIllegalEntries (PdfDictionary aa ) {
361
+ for (final PdfName key : aa .keySet ()) {
362
+ if (!allowedEntriesInAAWhenNonWidget .contains (key )) {
363
+ return true ;
364
+ }
365
+ }
366
+ return false ;
367
+ }
368
+
369
+ /**
370
+ * {@inheritDoc}
371
+ */
372
+ @ Override
373
+ protected Set <PdfName > getForbiddenActions () {
374
+ if ("E" .equals (conformanceLevel .getConformance ())) {
375
+ return forbiddenActionsE ;
290
376
}
377
+ return super .getForbiddenActions ();
291
378
}
292
379
293
380
/**
0 commit comments