Skip to content

Commit 56bf12b

Browse files
authored
Merge pull request #509 from fugerit-org/508-chore-fj-doc-mod-fop-make-accessibility-and-keep-empty-tags-parameters-configurable
feat: new type handler PdfFopTypeNoAccessibilityHandler #508
2 parents a6d9477 + 5c54fd7 commit 56bf12b

File tree

8 files changed

+261
-0
lines changed

8 files changed

+261
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- fj-doc-mod-fop, make accessibility and keep empty tags parameters configurable <https://github.com/fugerit-org/fj-doc/issues/508>
13+
1014
## [8.16.2] - 2025-09-12
1115

1216
### Changed

fj-doc-guide/src/main/docs/asciidoc/chapters/00_2_release_notes.adoc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,21 @@
33

44
Whereas the link:https://github.com/fugerit-org/fj-doc/blob/main/CHANGELOG.md[CHANGELOG] is a detailed list of modifications to project, the release notes just refer to the most important changes.
55

6+
[#doc-release-notes-unreleased]
7+
==== Unreleased
8+
9+
- fj-doc-mod-fop, make accessibility and keep empty tags parameters configurable link:https://github.com/fugerit-org/fj-doc/issues/508[#508]
10+
11+
[#doc-release-notes-8-16-2]
12+
==== Version 8.16.2 [2025-09-12]
13+
14+
- fj-doc-maven-plugin, updated all flavours version link:https://github.com/fugerit-org/fj-doc/issues/498[#498]
15+
16+
[#doc-release-notes-8-16-1]
17+
==== Version 8.16.1 [2025-09-01]
18+
19+
- fj-doc-maven-plugin, updated all flavours version link:https://github.com/fugerit-org/fj-doc/issues/494[#494]
20+
621
[#doc-release-notes-8-16-0]
722
==== Version 8.16.0 [2025-08-22]
823

fj-doc-guide/src/main/docs/asciidoc/chapters/06_2_mod-fop.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,14 @@ For this DocHandler it is possible to customize some attributes, for instance :
6666
| *pdf-ua-mode* anchor:doc-handler-mod-fop-pdf-config-pdf-ua-mode[] | _string_ | | If present, will set pdf-ua-mode, possible values are : _PDF/UA-1_. link:https://github.com/fugerit-org/fj-doc/issues/52[Partially compatible with pdf-a-mode].
6767
| *fop-pool-min* anchor:doc-handler-mod-fop-pdf-config-fop-pool-min[] | _int_ | 0 | If present, it will create a fo user agent pool, this is the minimum size of the pool.
6868
| *fop-pool-max* anchor:doc-handler-mod-fop-pdf-config-fop-pool-max[] | _int_ | 0 | If present, it will create a fo user agent pool, this is the maximum size fo the pool.
69+
| *accessibility* anchor:doc-handler-mod-fop-pdf-config-accessibility[] | _bool_ | true | fopUserAgent.setAccessibility($value); (since 8.16.3)
70+
| *keep-empty-tags* anchor:doc-handler-mod-fop-pdf-config-keep-empty-tags[] | _bool_ | false | fopUserAgent.setKeepEmptyTags($value); (since 8.16.3)
6971
|========================================================================================================================================
7072

7173
NOTE: If *pdf-a-mode* is set, there will be a strict validation of the PDF (i.e. it will be checked if the font are all embedded and the images should comply to link:https://www.adobe.com/uk/acrobat/resources/document-files/pdf-types/pdf-a.html[PDF/A standard]).
7274

75+
TIP: Setting accessibility to 'false' will produce a smaller but less accessible PDF.
76+
7377
[#doc-handler-mod-fop-pdf-config-pdf-a]
7478
==== PDF/A DocHandler
7579

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
[#doc-faq-reducing-fj-doc-mod-fop-pdf-size]
3+
=== Reducing fj-doc-mod-fop PDF size
4+
5+
Module fj-doc-mod-fop is based on link:https://xmlgraphics.apache.org/fop/[Apache FOP].
6+
7+
Sometimes this module can produce relatively big size PF.
8+
9+
Here are some tips to reduce the size.
10+
11+
==== Accessibility
12+
13+
By default, fop user agent has the accessibility flag active.
14+
15+
Since Venus version 8.16.3 it is possible to use the new handler :
16+
17+
[source,java]
18+
----
19+
org.fugerit.java.doc.mod.fop.PdfFopTypeNoAccessibilityHandler
20+
----
21+
22+
Which as the accessibility flag set to 'false' by default.
23+
24+
Alternatively, it is possible to use a new configuration option :
25+
26+
[source,xml]
27+
----
28+
<docHandler id="pdf-fop-config" info="pdf" type="org.fugerit.java.doc.mod.fop.PdfFopTypeHandler">
29+
<docHandlerCustomConfig charset="UTF-8" accessibility='false'/>
30+
</docHandler>
31+
----
32+
33+
Refer to xref:#doc-handler-mod-fop-pdf-config-accessibility[PDF/FO DocHandler] documentation for further info.

fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeHandler.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ public class PdfFopTypeHandler extends FreeMarkerFopTypeHandler {
7272

7373
private static final String ATT_FONT_BASE_CLASSLOADER_PATH = "font-base-classloader-path"; // removed as of v2.0.1
7474

75+
public static final String ATT_ACCESSIBILITY = "accessibility";
7576
public static final boolean DEFAULT_ACCESSIBILITY = true;
7677

78+
public static final String ATT_KEEP_EMPTY_TAGS = "keep-empty-tags";
7779
public static final boolean DEFAULT_KEEP_EMPTY_TAGS = false;
7880

7981
public static final String ATT_FOP_SUPPRESS_EVENTS = "fop-suppress-events";
@@ -242,6 +244,8 @@ protected void handleConfigTag(Element config) throws ConfigException {
242244
this.setSuppressEvents( BooleanUtils.isTrue( props.getProperty( ATT_FOP_SUPPRESS_EVENTS ) ) );
243245
// setup pool
244246
this.setupPool( props );
247+
// extra setup
248+
this.extraSetup( props );
245249
}
246250

247251
private void setupPool( Properties props ) throws ConfigException {
@@ -260,6 +264,19 @@ private void setupPool( Properties props ) throws ConfigException {
260264
}
261265
}
262266

267+
private void extraSetup( Properties props ) throws ConfigException {
268+
String valueAccessibility = props.getProperty( ATT_ACCESSIBILITY );
269+
if ( StringUtils.isNotEmpty( valueAccessibility ) ) {
270+
log.debug( "override accessibility {} -> {}", this.isAccessibility(), valueAccessibility );
271+
this.accessibility = BooleanUtils.isTrue( valueAccessibility );
272+
}
273+
String valueKeepEnptyTags = props.getProperty( ATT_KEEP_EMPTY_TAGS);
274+
if ( StringUtils.isNotEmpty( valueKeepEnptyTags ) ) {
275+
log.debug( "override keep-empty-tags {} -> {}", this.isKeepEmptyTags(), valueKeepEnptyTags );
276+
this.keepEmptyTags = BooleanUtils.isTrue( valueKeepEnptyTags );
277+
}
278+
}
279+
263280
private void setupFopConfigMode( String fopConfigMode, String fopConfigResoverType, String fopConfigClassloaderPath, Element config ) throws ConfigException {
264281
if ( ATT_FOP_CONFIG_MODE_CLASS_LOADER.equalsIgnoreCase( fopConfigMode ) ) {
265282
ConfigException.apply( () -> {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.fugerit.java.doc.mod.fop;
2+
3+
public class PdfFopTypeNoAccessibilityHandler extends PdfFopTypeHandler {
4+
5+
public PdfFopTypeNoAccessibilityHandler() {
6+
super( Boolean.FALSE, DEFAULT_KEEP_EMPTY_TAGS );
7+
}
8+
9+
}

fj-doc-mod-fop/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-mod-fop/reflect-config.json

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,126 @@
421421
"name" : "wait",
422422
"parameterTypes" : [ "long", "int" ]
423423
} ]
424+
}, {
425+
"name" : "org.fugerit.java.doc.mod.fop.PdfFopTypeNoAccessibilityHandler",
426+
"methods" : [ {
427+
"name" : "<init>",
428+
"parameterTypes" : [ ]
429+
}, {
430+
"name" : "configure",
431+
"parameterTypes" : [ "java.util.Properties" ]
432+
}, {
433+
"name" : "configure",
434+
"parameterTypes" : [ "org.w3c.dom.Element" ]
435+
}, {
436+
"name" : "configureProperties",
437+
"parameterTypes" : [ "java.io.InputStream" ]
438+
}, {
439+
"name" : "configureXML",
440+
"parameterTypes" : [ "java.io.InputStream" ]
441+
}, {
442+
"name" : "createKey",
443+
"parameterTypes" : [ "java.lang.String", "java.lang.String" ]
444+
}, {
445+
"name" : "equals",
446+
"parameterTypes" : [ "java.lang.Object" ]
447+
}, {
448+
"name" : "getCharset",
449+
"parameterTypes" : [ ]
450+
}, {
451+
"name" : "getClass",
452+
"parameterTypes" : [ ]
453+
}, {
454+
"name" : "getCustomId",
455+
"parameterTypes" : [ ]
456+
}, {
457+
"name" : "getFopConfig",
458+
"parameterTypes" : [ ]
459+
}, {
460+
"name" : "getFopPoolMax",
461+
"parameterTypes" : [ ]
462+
}, {
463+
"name" : "getFopPoolMin",
464+
"parameterTypes" : [ ]
465+
}, {
466+
"name" : "getFormat",
467+
"parameterTypes" : [ ]
468+
}, {
469+
"name" : "getKey",
470+
"parameterTypes" : [ ]
471+
}, {
472+
"name" : "getKey",
473+
"parameterTypes" : [ ]
474+
}, {
475+
"name" : "getMime",
476+
"parameterTypes" : [ ]
477+
}, {
478+
"name" : "getModule",
479+
"parameterTypes" : [ ]
480+
}, {
481+
"name" : "getPdfAMode",
482+
"parameterTypes" : [ ]
483+
}, {
484+
"name" : "getPdfUAMode",
485+
"parameterTypes" : [ ]
486+
}, {
487+
"name" : "getType",
488+
"parameterTypes" : [ ]
489+
}, {
490+
"name" : "handle",
491+
"parameterTypes" : [ "org.fugerit.java.doc.base.config.DocInput", "org.fugerit.java.doc.base.config.DocOutput" ]
492+
}, {
493+
"name" : "hashCode",
494+
"parameterTypes" : [ ]
495+
}, {
496+
"name" : "isAccessibility",
497+
"parameterTypes" : [ ]
498+
}, {
499+
"name" : "isKeepEmptyTags",
500+
"parameterTypes" : [ ]
501+
}, {
502+
"name" : "isSuppressEvents",
503+
"parameterTypes" : [ ]
504+
}, {
505+
"name" : "notify",
506+
"parameterTypes" : [ ]
507+
}, {
508+
"name" : "notifyAll",
509+
"parameterTypes" : [ ]
510+
}, {
511+
"name" : "setCustomId",
512+
"parameterTypes" : [ "java.lang.String" ]
513+
}, {
514+
"name" : "setFopConfig",
515+
"parameterTypes" : [ "org.fugerit.java.doc.mod.fop.FopConfig" ]
516+
}, {
517+
"name" : "setFopPoolMax",
518+
"parameterTypes" : [ "int" ]
519+
}, {
520+
"name" : "setFopPoolMin",
521+
"parameterTypes" : [ "int" ]
522+
}, {
523+
"name" : "setPdfAMode",
524+
"parameterTypes" : [ "java.lang.String" ]
525+
}, {
526+
"name" : "setPdfUAMode",
527+
"parameterTypes" : [ "java.lang.String" ]
528+
}, {
529+
"name" : "setSuppressEvents",
530+
"parameterTypes" : [ "boolean" ]
531+
}, {
532+
"name" : "toString",
533+
"parameterTypes" : [ ]
534+
}, {
535+
"name" : "wait",
536+
"parameterTypes" : [ ]
537+
}, {
538+
"name" : "wait",
539+
"parameterTypes" : [ "long" ]
540+
}, {
541+
"name" : "wait",
542+
"parameterTypes" : [ "long", "int" ]
543+
} ]
424544
}, {
425545
"name" : "org.fugerit.java.doc.mod.fop.PoolUtils",
426546
"methods" : [ {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package test.org.fugerit.java.doc.mod.fop;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.fugerit.java.core.function.SafeFunction;
5+
import org.fugerit.java.core.lang.helpers.ClassHelper;
6+
import org.fugerit.java.core.xml.dom.DOMIO;
7+
import org.fugerit.java.doc.base.config.DocInput;
8+
import org.fugerit.java.doc.base.config.DocOutput;
9+
import org.fugerit.java.doc.base.config.DocTypeHandler;
10+
import org.fugerit.java.doc.mod.fop.FreeMarkerFopTypeHandlerUTF8;
11+
import org.fugerit.java.doc.mod.fop.InitFopHandler;
12+
import org.fugerit.java.doc.mod.fop.PdfFopTypeHandler;
13+
import org.fugerit.java.doc.mod.fop.PdfFopTypeNoAccessibilityHandler;
14+
import org.junit.jupiter.api.Assertions;
15+
import org.junit.jupiter.api.BeforeAll;
16+
import org.junit.jupiter.api.Test;
17+
import org.w3c.dom.Element;
18+
import test.org.fugerit.java.BasicTest;
19+
20+
import java.io.FileOutputStream;
21+
import java.io.InputStreamReader;
22+
23+
@Slf4j
24+
class TestNoAccessibility extends BasicTest {
25+
26+
private boolean testHelper( String testCase, DocTypeHandler handler ) {
27+
boolean ok = false;
28+
try ( InputStreamReader reader = new InputStreamReader( ClassHelper.loadFromDefaultClassLoader( "sample/doc_alt_01.xml" ) );
29+
FileOutputStream fos = new FileOutputStream( "target/test_no_accessibilit-"+testCase+"."+handler.getType() ) ) {
30+
handler.handle( DocInput.newInput( handler.getType(), reader ) , DocOutput.newOutput( fos ) );
31+
ok = true;
32+
log.info( "result {}", ok );
33+
} catch (Exception e) {
34+
this.failEx( e );
35+
}
36+
return ok;
37+
}
38+
39+
private static final DocTypeHandler[] HANDLERS = { PdfFopTypeHandler.HANDLER, new PdfFopTypeNoAccessibilityHandler() };
40+
41+
@Test
42+
void testNoAccessibilityHandler() {
43+
for ( int k=0; k<HANDLERS.length; k++ ) {
44+
boolean ok = this.testHelper( HANDLERS[k].getClass().getSimpleName(), HANDLERS[k]);
45+
Assertions.assertTrue(ok);
46+
}
47+
}
48+
49+
@Test
50+
void testNoAccessibilityConfig() throws Exception {
51+
PdfFopTypeHandler handler = new PdfFopTypeHandler();
52+
this.testHelper( "test-config-pre", handler );
53+
Element config = DOMIO.loadDOMDoc( "<conf><docHandlerCustomConfig accessibility='false' keep-empty-tags='true'/></conf>" ).getDocumentElement();
54+
handler.configure( config );
55+
this.testHelper( "test-config-post", handler );
56+
57+
}
58+
59+
}

0 commit comments

Comments
 (0)