From ea680c5140254388e8db85bfaa3b1d824f70255a Mon Sep 17 00:00:00 2001 From: "Matteo Franci a.k.a. Fugerit" Date: Wed, 24 Sep 2025 23:02:00 +0200 Subject: [PATCH 1/4] feat: new type handler PdfFopTypeNoAccessibilityHandler #508 This will usually produce smapper PDF. --- .../fop/PdfFopTypeNoAccessibilityHandler.java | 9 ++++ .../java/doc/mod/fop/TestNoAccessibility.java | 47 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeNoAccessibilityHandler.java create mode 100644 fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestNoAccessibility.java diff --git a/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeNoAccessibilityHandler.java b/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeNoAccessibilityHandler.java new file mode 100644 index 000000000..1011587b5 --- /dev/null +++ b/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeNoAccessibilityHandler.java @@ -0,0 +1,9 @@ +package org.fugerit.java.doc.mod.fop; + +public class PdfFopTypeNoAccessibilityHandler extends PdfFopTypeHandler { + + public PdfFopTypeNoAccessibilityHandler() { + super( Boolean.FALSE, DEFAULT_KEEP_EMPTY_TAGS ); + } + +} diff --git a/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestNoAccessibility.java b/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestNoAccessibility.java new file mode 100644 index 000000000..60be3d3ff --- /dev/null +++ b/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestNoAccessibility.java @@ -0,0 +1,47 @@ +package test.org.fugerit.java.doc.mod.fop; + +import lombok.extern.slf4j.Slf4j; +import org.fugerit.java.core.function.SafeFunction; +import org.fugerit.java.core.lang.helpers.ClassHelper; +import org.fugerit.java.doc.base.config.DocInput; +import org.fugerit.java.doc.base.config.DocOutput; +import org.fugerit.java.doc.base.config.DocTypeHandler; +import org.fugerit.java.doc.mod.fop.FreeMarkerFopTypeHandlerUTF8; +import org.fugerit.java.doc.mod.fop.InitFopHandler; +import org.fugerit.java.doc.mod.fop.PdfFopTypeHandler; +import org.fugerit.java.doc.mod.fop.PdfFopTypeNoAccessibilityHandler; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import test.org.fugerit.java.BasicTest; + +import java.io.FileOutputStream; +import java.io.InputStreamReader; + +@Slf4j +class TestNoAccessibility extends BasicTest { + + private boolean testHelper( DocTypeHandler handler ) { + boolean ok = false; + try ( InputStreamReader reader = new InputStreamReader( ClassHelper.loadFromDefaultClassLoader( "sample/doc_alt_01.xml" ) ); + FileOutputStream fos = new FileOutputStream( "target/test_no_accessibilit-"+handler.getClass().getSimpleName()+"."+handler.getType() ) ) { + handler.handle( DocInput.newInput( handler.getType(), reader ) , DocOutput.newOutput( fos ) ); + ok = true; + log.info( "result {}", ok ); + } catch (Exception e) { + this.failEx( e ); + } + return ok; + } + + private static final DocTypeHandler[] HANDLERS = { PdfFopTypeHandler.HANDLER, new PdfFopTypeNoAccessibilityHandler() }; + + @Test + void testNoAccessibility1() { + for ( int k=0; k Date: Wed, 24 Sep 2025 23:22:00 +0200 Subject: [PATCH 2/4] feat: new config properties for PdfFopTypeHandler #508 "keep-empty-tags" and "accessibility" This will usually produce smaller PDF. --- .../docs/asciidoc/chapters/06_2_mod-fop.adoc | 2 ++ .../java/doc/mod/fop/PdfFopTypeHandler.java | 17 ++++++++++++++++ .../java/doc/mod/fop/TestNoAccessibility.java | 20 +++++++++++++++---- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/fj-doc-guide/src/main/docs/asciidoc/chapters/06_2_mod-fop.adoc b/fj-doc-guide/src/main/docs/asciidoc/chapters/06_2_mod-fop.adoc index 5d79afa67..e1503b0c7 100644 --- a/fj-doc-guide/src/main/docs/asciidoc/chapters/06_2_mod-fop.adoc +++ b/fj-doc-guide/src/main/docs/asciidoc/chapters/06_2_mod-fop.adoc @@ -66,6 +66,8 @@ For this DocHandler it is possible to customize some attributes, for instance : | *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]. | *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. | *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. +| *accessibility* anchor:doc-handler-mod-fop-pdf-config-accessibility[] | _bool_ | true | fopUserAgent.setAccessibility($value); +| *keep-empty-tags* anchor:doc-handler-mod-fop-pdf-config-keep-empty-tags[] | _bool_ | false | fopUserAgent.setKeepEmptyTags($value); |======================================================================================================================================== 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]). diff --git a/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeHandler.java b/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeHandler.java index 7b65da17e..65c05015c 100644 --- a/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeHandler.java +++ b/fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PdfFopTypeHandler.java @@ -72,8 +72,10 @@ public class PdfFopTypeHandler extends FreeMarkerFopTypeHandler { private static final String ATT_FONT_BASE_CLASSLOADER_PATH = "font-base-classloader-path"; // removed as of v2.0.1 + public static final String ATT_ACCESSIBILITY = "accessibility"; public static final boolean DEFAULT_ACCESSIBILITY = true; + public static final String ATT_KEEP_EMPTY_TAGS = "keep-empty-tags"; public static final boolean DEFAULT_KEEP_EMPTY_TAGS = false; public static final String ATT_FOP_SUPPRESS_EVENTS = "fop-suppress-events"; @@ -242,6 +244,8 @@ protected void handleConfigTag(Element config) throws ConfigException { this.setSuppressEvents( BooleanUtils.isTrue( props.getProperty( ATT_FOP_SUPPRESS_EVENTS ) ) ); // setup pool this.setupPool( props ); + // extra setup + this.extraSetup( props ); } private void setupPool( Properties props ) throws ConfigException { @@ -260,6 +264,19 @@ private void setupPool( Properties props ) throws ConfigException { } } + private void extraSetup( Properties props ) throws ConfigException { + String valueAccessibility = props.getProperty( ATT_ACCESSIBILITY ); + if ( StringUtils.isNotEmpty( valueAccessibility ) ) { + log.debug( "override accessibility {} -> {}", this.isAccessibility(), valueAccessibility ); + this.accessibility = BooleanUtils.isTrue( valueAccessibility ); + } + String valueKeepEnptyTags = props.getProperty( ATT_KEEP_EMPTY_TAGS); + if ( StringUtils.isNotEmpty( valueKeepEnptyTags ) ) { + log.debug( "override keep-empty-tags {} -> {}", this.isKeepEmptyTags(), valueKeepEnptyTags ); + this.keepEmptyTags = BooleanUtils.isTrue( valueKeepEnptyTags ); + } + } + private void setupFopConfigMode( String fopConfigMode, String fopConfigResoverType, String fopConfigClassloaderPath, Element config ) throws ConfigException { if ( ATT_FOP_CONFIG_MODE_CLASS_LOADER.equalsIgnoreCase( fopConfigMode ) ) { ConfigException.apply( () -> { diff --git a/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestNoAccessibility.java b/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestNoAccessibility.java index 60be3d3ff..82dfdc9a1 100644 --- a/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestNoAccessibility.java +++ b/fj-doc-mod-fop/src/test/java/test/org/fugerit/java/doc/mod/fop/TestNoAccessibility.java @@ -3,6 +3,7 @@ import lombok.extern.slf4j.Slf4j; import org.fugerit.java.core.function.SafeFunction; import org.fugerit.java.core.lang.helpers.ClassHelper; +import org.fugerit.java.core.xml.dom.DOMIO; import org.fugerit.java.doc.base.config.DocInput; import org.fugerit.java.doc.base.config.DocOutput; import org.fugerit.java.doc.base.config.DocTypeHandler; @@ -13,6 +14,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.w3c.dom.Element; import test.org.fugerit.java.BasicTest; import java.io.FileOutputStream; @@ -21,10 +23,10 @@ @Slf4j class TestNoAccessibility extends BasicTest { - private boolean testHelper( DocTypeHandler handler ) { + private boolean testHelper( String testCase, DocTypeHandler handler ) { boolean ok = false; try ( InputStreamReader reader = new InputStreamReader( ClassHelper.loadFromDefaultClassLoader( "sample/doc_alt_01.xml" ) ); - FileOutputStream fos = new FileOutputStream( "target/test_no_accessibilit-"+handler.getClass().getSimpleName()+"."+handler.getType() ) ) { + FileOutputStream fos = new FileOutputStream( "target/test_no_accessibilit-"+testCase+"."+handler.getType() ) ) { handler.handle( DocInput.newInput( handler.getType(), reader ) , DocOutput.newOutput( fos ) ); ok = true; log.info( "result {}", ok ); @@ -37,11 +39,21 @@ private boolean testHelper( DocTypeHandler handler ) { private static final DocTypeHandler[] HANDLERS = { PdfFopTypeHandler.HANDLER, new PdfFopTypeNoAccessibilityHandler() }; @Test - void testNoAccessibility1() { + void testNoAccessibilityHandler() { for ( int k=0; k" ).getDocumentElement(); + handler.configure( config ); + this.testHelper( "test-config-post", handler ); + + } } From c67ffe4f76053cb3bbad74140e60f49903ad97ce Mon Sep 17 00:00:00 2001 From: "Matteo Franci a.k.a. Fugerit" Date: Wed, 24 Sep 2025 23:22:43 +0200 Subject: [PATCH 3/4] chore(config): update reflect-config.json for PdfFopTypeNoAccessibilityHandler --- .../fj-doc-mod-fop/reflect-config.json | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/fj-doc-mod-fop/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-mod-fop/reflect-config.json b/fj-doc-mod-fop/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-mod-fop/reflect-config.json index 3747c4698..dc8f957d4 100644 --- a/fj-doc-mod-fop/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-mod-fop/reflect-config.json +++ b/fj-doc-mod-fop/src/main/resources/META-INF/native-image/org.fugerit.java/fj-doc-mod-fop/reflect-config.json @@ -421,6 +421,126 @@ "name" : "wait", "parameterTypes" : [ "long", "int" ] } ] +}, { + "name" : "org.fugerit.java.doc.mod.fop.PdfFopTypeNoAccessibilityHandler", + "methods" : [ { + "name" : "", + "parameterTypes" : [ ] + }, { + "name" : "configure", + "parameterTypes" : [ "java.util.Properties" ] + }, { + "name" : "configure", + "parameterTypes" : [ "org.w3c.dom.Element" ] + }, { + "name" : "configureProperties", + "parameterTypes" : [ "java.io.InputStream" ] + }, { + "name" : "configureXML", + "parameterTypes" : [ "java.io.InputStream" ] + }, { + "name" : "createKey", + "parameterTypes" : [ "java.lang.String", "java.lang.String" ] + }, { + "name" : "equals", + "parameterTypes" : [ "java.lang.Object" ] + }, { + "name" : "getCharset", + "parameterTypes" : [ ] + }, { + "name" : "getClass", + "parameterTypes" : [ ] + }, { + "name" : "getCustomId", + "parameterTypes" : [ ] + }, { + "name" : "getFopConfig", + "parameterTypes" : [ ] + }, { + "name" : "getFopPoolMax", + "parameterTypes" : [ ] + }, { + "name" : "getFopPoolMin", + "parameterTypes" : [ ] + }, { + "name" : "getFormat", + "parameterTypes" : [ ] + }, { + "name" : "getKey", + "parameterTypes" : [ ] + }, { + "name" : "getKey", + "parameterTypes" : [ ] + }, { + "name" : "getMime", + "parameterTypes" : [ ] + }, { + "name" : "getModule", + "parameterTypes" : [ ] + }, { + "name" : "getPdfAMode", + "parameterTypes" : [ ] + }, { + "name" : "getPdfUAMode", + "parameterTypes" : [ ] + }, { + "name" : "getType", + "parameterTypes" : [ ] + }, { + "name" : "handle", + "parameterTypes" : [ "org.fugerit.java.doc.base.config.DocInput", "org.fugerit.java.doc.base.config.DocOutput" ] + }, { + "name" : "hashCode", + "parameterTypes" : [ ] + }, { + "name" : "isAccessibility", + "parameterTypes" : [ ] + }, { + "name" : "isKeepEmptyTags", + "parameterTypes" : [ ] + }, { + "name" : "isSuppressEvents", + "parameterTypes" : [ ] + }, { + "name" : "notify", + "parameterTypes" : [ ] + }, { + "name" : "notifyAll", + "parameterTypes" : [ ] + }, { + "name" : "setCustomId", + "parameterTypes" : [ "java.lang.String" ] + }, { + "name" : "setFopConfig", + "parameterTypes" : [ "org.fugerit.java.doc.mod.fop.FopConfig" ] + }, { + "name" : "setFopPoolMax", + "parameterTypes" : [ "int" ] + }, { + "name" : "setFopPoolMin", + "parameterTypes" : [ "int" ] + }, { + "name" : "setPdfAMode", + "parameterTypes" : [ "java.lang.String" ] + }, { + "name" : "setPdfUAMode", + "parameterTypes" : [ "java.lang.String" ] + }, { + "name" : "setSuppressEvents", + "parameterTypes" : [ "boolean" ] + }, { + "name" : "toString", + "parameterTypes" : [ ] + }, { + "name" : "wait", + "parameterTypes" : [ ] + }, { + "name" : "wait", + "parameterTypes" : [ "long" ] + }, { + "name" : "wait", + "parameterTypes" : [ "long", "int" ] + } ] }, { "name" : "org.fugerit.java.doc.mod.fop.PoolUtils", "methods" : [ { From 5c54fd7d6c8c6706d2fef41131c2fd46f4331cb4 Mon Sep 17 00:00:00 2001 From: "Matteo Franci a.k.a. Fugerit" Date: Wed, 24 Sep 2025 23:41:46 +0200 Subject: [PATCH 4/4] docs: changelog, release notes and feature documentation #508 --- CHANGELOG.md | 4 +++ .../asciidoc/chapters/00_2_release_notes.adoc | 15 +++++++++ .../docs/asciidoc/chapters/06_2_mod-fop.adoc | 6 ++-- ..._008-reducing-fj-doc-mod-fop-pdf-size.adoc | 33 +++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 fj-doc-guide/src/main/docs/asciidoc/chapters/07_008-reducing-fj-doc-mod-fop-pdf-size.adoc diff --git a/CHANGELOG.md b/CHANGELOG.md index bfdb23619..cd1e5843f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- fj-doc-mod-fop, make accessibility and keep empty tags parameters configurable + ## [8.16.2] - 2025-09-12 ### Changed diff --git a/fj-doc-guide/src/main/docs/asciidoc/chapters/00_2_release_notes.adoc b/fj-doc-guide/src/main/docs/asciidoc/chapters/00_2_release_notes.adoc index 79611bdd1..36885ed4d 100644 --- a/fj-doc-guide/src/main/docs/asciidoc/chapters/00_2_release_notes.adoc +++ b/fj-doc-guide/src/main/docs/asciidoc/chapters/00_2_release_notes.adoc @@ -3,6 +3,21 @@ 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. +[#doc-release-notes-unreleased] +==== Unreleased + +- fj-doc-mod-fop, make accessibility and keep empty tags parameters configurable link:https://github.com/fugerit-org/fj-doc/issues/508[#508] + +[#doc-release-notes-8-16-2] +==== Version 8.16.2 [2025-09-12] + +- fj-doc-maven-plugin, updated all flavours version link:https://github.com/fugerit-org/fj-doc/issues/498[#498] + +[#doc-release-notes-8-16-1] +==== Version 8.16.1 [2025-09-01] + +- fj-doc-maven-plugin, updated all flavours version link:https://github.com/fugerit-org/fj-doc/issues/494[#494] + [#doc-release-notes-8-16-0] ==== Version 8.16.0 [2025-08-22] diff --git a/fj-doc-guide/src/main/docs/asciidoc/chapters/06_2_mod-fop.adoc b/fj-doc-guide/src/main/docs/asciidoc/chapters/06_2_mod-fop.adoc index e1503b0c7..ba7b93199 100644 --- a/fj-doc-guide/src/main/docs/asciidoc/chapters/06_2_mod-fop.adoc +++ b/fj-doc-guide/src/main/docs/asciidoc/chapters/06_2_mod-fop.adoc @@ -66,12 +66,14 @@ For this DocHandler it is possible to customize some attributes, for instance : | *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]. | *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. | *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. -| *accessibility* anchor:doc-handler-mod-fop-pdf-config-accessibility[] | _bool_ | true | fopUserAgent.setAccessibility($value); -| *keep-empty-tags* anchor:doc-handler-mod-fop-pdf-config-keep-empty-tags[] | _bool_ | false | fopUserAgent.setKeepEmptyTags($value); +| *accessibility* anchor:doc-handler-mod-fop-pdf-config-accessibility[] | _bool_ | true | fopUserAgent.setAccessibility($value); (since 8.16.3) +| *keep-empty-tags* anchor:doc-handler-mod-fop-pdf-config-keep-empty-tags[] | _bool_ | false | fopUserAgent.setKeepEmptyTags($value); (since 8.16.3) |======================================================================================================================================== 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]). +TIP: Setting accessibility to 'false' will produce a smaller but less accessible PDF. + [#doc-handler-mod-fop-pdf-config-pdf-a] ==== PDF/A DocHandler diff --git a/fj-doc-guide/src/main/docs/asciidoc/chapters/07_008-reducing-fj-doc-mod-fop-pdf-size.adoc b/fj-doc-guide/src/main/docs/asciidoc/chapters/07_008-reducing-fj-doc-mod-fop-pdf-size.adoc new file mode 100644 index 000000000..267ff2ae6 --- /dev/null +++ b/fj-doc-guide/src/main/docs/asciidoc/chapters/07_008-reducing-fj-doc-mod-fop-pdf-size.adoc @@ -0,0 +1,33 @@ + +[#doc-faq-reducing-fj-doc-mod-fop-pdf-size] +=== Reducing fj-doc-mod-fop PDF size + +Module fj-doc-mod-fop is based on link:https://xmlgraphics.apache.org/fop/[Apache FOP]. + +Sometimes this module can produce relatively big size PF. + +Here are some tips to reduce the size. + +==== Accessibility + +By default, fop user agent has the accessibility flag active. + +Since Venus version 8.16.3 it is possible to use the new handler : + +[source,java] +---- +org.fugerit.java.doc.mod.fop.PdfFopTypeNoAccessibilityHandler +---- + +Which as the accessibility flag set to 'false' by default. + +Alternatively, it is possible to use a new configuration option : + +[source,xml] +---- + + + +---- + +Refer to xref:#doc-handler-mod-fop-pdf-config-accessibility[PDF/FO DocHandler] documentation for further info.