Skip to content

Commit 12798f7

Browse files
authored
Merge pull request #559 from fugerit-org/558-chore-fj-doc-mod-fop-support-keep-togetjer
558 chore fj doc mod fop support keep togetjer
2 parents 18e4546 + 7b150c0 commit 12798f7

File tree

29 files changed

+2935
-503
lines changed

29 files changed

+2935
-503
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- Image validator based on TwelveMonkeys ImageIO (currently supporting TIFF) <https://github.com/fugerit-org/fj-doc/issues/551>
13+
- fj-doc-mod-fop, new mod-fop-xslt-path property <https://github.com/fugerit-org/fj-doc/issues/558>
1314

1415
### Changed
1516

1617
- quarkus-version set to 3.26.5 across all the modules
1718

19+
### Fixed
20+
21+
- DocInput.getDoc() now reuse docBase
22+
1823
## [8.17.0] - 2025-10-14
1924

2025
### Added

docs/html/doc_meta_info.html

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ <h1 style="font-weight: bold;">Documentation for Venus Doc Format standard meta
2626
<li > <a href="#meta_xls">Properties specific to spreadsheet format (XLS/XLSX)</a>
2727
</li>
2828
<li > <a href="#meta_csv">Properties specific to CSV format</a>
29+
</li>
30+
<li > <a href="#meta_fop">Properties specific to Apache FOP PDF format</a>
2931
</li>
3032
</ol>
3133
<a href="#top">top</a>
@@ -761,6 +763,50 @@ <h2 style="font-weight: bold;">Properties specific to CSV format</h2>
761763
</tbody>
762764
</table>
763765
<a href="#top">top</a>
766+
<span id="meta_fop"></span>
767+
<h2 style="font-weight: bold;">Properties specific to Apache FOP PDF format</h2>
768+
<table style=' width: 100%'>
769+
<thead>
770+
<tr>
771+
<th id="cell_0_0" style=" width: 20%; text-align: center; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
772+
<p style="font-weight: bold;">Name</p>
773+
</th>
774+
<th id="cell_0_1" style=" width: 40%; text-align: center; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
775+
<p style="font-weight: bold;">Description</p>
776+
</th>
777+
<th id="cell_0_2" style=" width: 25%; text-align: center; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
778+
<p style="font-weight: bold;">Supporting handlers</p>
779+
</th>
780+
<th id="cell_0_3" style=" width: 10%; text-align: center; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
781+
<p style="font-weight: bold;">Default</p>
782+
</th>
783+
<th id="cell_0_4" style=" width: 5%; text-align: center; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
784+
<p style="font-weight: bold;">Since</p>
785+
</th>
786+
</tr>
787+
</thead>
788+
<tbody>
789+
<tr>
790+
<td id="cell_0_0" style=" width: 20%; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
791+
<span id="mod-fop-xslt-path"></span>
792+
<p style="font-style: italic;">mod-fop-xslt-path</p>
793+
</td>
794+
<td id="cell_0_1" style=" width: 40%; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
795+
<p>Class loader path to optional XSLT template to apply on transformer. If set fop user agent will use given XSLT in the transformation.</p>
796+
</td>
797+
<td id="cell_0_2" style=" width: 25%; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
798+
<p>fj-doc-mod-fop(pdf), </p>
799+
</td>
800+
<td id="cell_0_3" style=" width: 10%; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
801+
<p></p>
802+
</td>
803+
<td id="cell_0_4" style=" width: 5%; border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 2px;">
804+
<p>8.17.1</p>
805+
</td>
806+
</tr>
807+
</tbody>
808+
</table>
809+
<a href="#top">top</a>
764810
</div>
765811
</body>
766812
</html>

fj-doc-base/src/main/java/org/fugerit/java/doc/base/config/DocInput.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ public class DocInput {
1818
private DocBase doc;
1919

2020
public DocBase getDoc() {
21-
DocBase res = doc;
21+
DocBase res = this.doc;
2222
if ( res == null && reader != null ) {
2323
res = DocFacadeSource.getInstance().parseRE( reader, this.getSource() );
24+
this.doc = res;
2425
}
2526
return res;
2627
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ Whereas the link:https://github.com/fugerit-org/fj-doc/blob/main/CHANGELOG.md[CH
66
[#doc-release-notes-unreleased]
77
==== Unreleased
88

9-
- TIFF validtor based on TwelveMonkeys ImageIO link:https://github.com/fugerit-org/fj-doc/issues/551[#551]
9+
- fj-doc-mod-fop, new mod-fop-xslt-path property link:https://github.com/fugerit-org/fj-doc/issues/558[#558]
10+
- fj-doc-val-imageio, TIFF validator based on TwelveMonkeys ImageIO link:https://github.com/fugerit-org/fj-doc/issues/551[#551]
1011
1112
[#doc-release-notes-8-17-0]
1213
==== Version 8.17.0 [2025-10-14]

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,18 @@ NOTE: the PDF/A configuration is not automatically generated by the link:https:/
126126
</docHandler>
127127
----
128128

129+
[#doc-handler-mod-fop-xslt-path]
130+
===== Property 'mod-fop-xslt-path'
131+
132+
If property *mod-fop-xslt-path* is set, it will be used as class loader path
133+
to optional XSLT template to apply on transformer.
134+
Then fop user agent will use given XSLT in the transformation.
135+
136+
[source,xml]
137+
----
138+
<info name="mod-fop-xslt-path">xslt-sample/xslt-sample.xsl</info>
139+
----
140+
129141
[#doc-handler-mod-fop-fo]
130142
==== FO DocHandler
131143

fj-doc-lib-autodoc/src/test/resources/docs/meta_xml/adm_standard_meta_info.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,4 +391,16 @@ the 'value' is the name of the sheet to be created. i.e. 'table-1=sheet1;table-2
391391
</admeta:admMetaInfo>
392392
</admeta:admSection>
393393

394+
<admeta:admSection>
395+
<admeta:name>meta_fop</admeta:name>
396+
<admeta:description>Properties specific to Apache FOP PDF format</admeta:description>
397+
<admeta:admMetaInfo>
398+
<admeta:name>mod-fop-xslt-path</admeta:name>
399+
<admeta:description>Class loader path to optional XSLT template to apply on transformer. If set fop user agent will use given XSLT in the transformation.</admeta:description>
400+
<admeta:since>8.17.1</admeta:since>
401+
<admeta:supportedType>pdf</admeta:supportedType>
402+
<admeta:supportedHandler>fj-doc-mod-fop(pdf)</admeta:supportedHandler>
403+
</admeta:admMetaInfo>
404+
</admeta:admSection>
405+
394406
</admeta:autodocMeta>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.fugerit.java.doc.mod.fop;
2+
3+
public class FopHelperConstants {
4+
5+
private FopHelperConstants() {}
6+
7+
/**
8+
* <a href="https://venusdocs.fugerit.org/docs/html/doc_meta_info.html#mod-fop-xslt-path">See 'mod-fop-xslt-path' documentation</a>
9+
*/
10+
public static final String INFO_KEY_MOD_FOP_XSLT_PATH = "mod-fop-xslt-path";
11+
12+
}

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import javax.xml.transform.Result;
99
import javax.xml.transform.Transformer;
10+
import javax.xml.transform.TransformerConfigurationException;
1011
import javax.xml.transform.TransformerFactory;
1112
import javax.xml.transform.sax.SAXResult;
1213
import javax.xml.transform.stream.StreamSource;
@@ -26,7 +27,10 @@
2627
import org.fugerit.java.core.xml.dom.DOMIO;
2728
import org.fugerit.java.core.xml.dom.DOMUtils;
2829
import org.fugerit.java.doc.base.config.*;
30+
import org.fugerit.java.doc.base.model.DocBase;
2931
import org.fugerit.java.doc.mod.fop.config.FopConfigClassLoaderWrapper;
32+
import org.fugerit.java.doc.mod.fop.utils.ConfigUtils;
33+
import org.fugerit.java.doc.mod.fop.utils.PoolUtils;
3034
import org.w3c.dom.Element;
3135
import org.w3c.dom.NodeList;
3236

@@ -48,7 +52,7 @@ public class PdfFopTypeHandler extends FreeMarkerFopTypeHandler {
4852

4953
public static final String ATT_FOP_CONFIG_CLASSLOADER_PATH = "fop-config-classloader-path";
5054

51-
public static final String ATT_FOP_CONFIG_RESOLVER_TYPE = "fop-config-resover-type";
55+
public static final String ATT_FOP_CONFIG_RESOLVER_TYPE = "fop-config-resolver-type";
5256

5357
public static final String ATT_FOP_CONFIG_RESOLVER_TYPE_DEFAULT = FopConfigClassLoaderWrapper.DEFAULT_RESOURCE_RESOLVER.getClass().getName();
5458

@@ -83,6 +87,8 @@ public class PdfFopTypeHandler extends FreeMarkerFopTypeHandler {
8387

8488
private static final String FOP_CONFIG_ROOT = "fop";
8589

90+
private static final boolean LEGACY_CLASS_LOADER_MODE_CONFIG_HANDLER_FAIL_WITH_EXCEPTION = Boolean.TRUE;
91+
8692
/**
8793
*
8894
*/
@@ -196,6 +202,18 @@ private byte[] getXlsFoContent(DocInput docInput) throws Exception {
196202
}
197203
}
198204

205+
private Transformer newTransformer( TransformerFactory factory, DocBase docBase ) throws TransformerConfigurationException, IOException {
206+
String xsltPath = docBase.getStableInfo().getProperty( FopHelperConstants.INFO_KEY_MOD_FOP_XSLT_PATH );
207+
log.debug( "newTransformer {} -> {}", FopHelperConstants.INFO_KEY_MOD_FOP_XSLT_PATH, xsltPath );
208+
if ( StringUtils.isNotEmpty( xsltPath ) ) {
209+
try ( InputStream is = ClassHelper.loadFromDefaultClassLoader( xsltPath ) ) {
210+
return factory.newTransformer( new StreamSource( is ) );
211+
}
212+
} else {
213+
return factory.newTransformer();
214+
}
215+
}
216+
199217
@SuppressWarnings("unchecked")
200218
@Override
201219
public void handle(DocInput docInput, DocOutput docOutput) throws Exception {
@@ -205,7 +223,7 @@ public void handle(DocInput docInput, DocOutput docOutput) throws Exception {
205223
FopConfigWrap fopWrap = this.fopWrapSupplier.get();
206224
Fop fop = fopWrap.getFopFactory().newFop(MimeConstants.MIME_PDF, fopWrap.getFoUserAgent(), docOutput.getOs());
207225
TransformerFactory factory = TransformerFactory.newInstance();
208-
Transformer transformer = factory.newTransformer();
226+
Transformer transformer = this.newTransformer( factory, docInput.getDoc() );
209227
Result res = new SAXResult(fop.getDefaultHandler());
210228
transformer.transform(xmlSource, res);
211229
this.fopWrapConsumer.accept( fopWrap );
@@ -218,7 +236,7 @@ protected void handleConfigTag(Element config) throws ConfigException {
218236
Properties props = DOMUtils.attributesToProperties( config );
219237
String fopConfigMode = props.getProperty( ATT_FOP_CONFIG_MODE );
220238
String fopConfigClassloaderPath = props.getProperty( ATT_FOP_CONFIG_CLASSLOADER_PATH );
221-
String fopConfigResoverType = props.getProperty( ATT_FOP_CONFIG_RESOLVER_TYPE, ATT_FOP_CONFIG_RESOLVER_TYPE_DEFAULT );
239+
String fopConfigResolverType = props.getProperty( ATT_FOP_CONFIG_RESOLVER_TYPE, ATT_FOP_CONFIG_RESOLVER_TYPE_DEFAULT );
222240
String fontBaseClassloaderPath = props.getProperty( ATT_FONT_BASE_CLASSLOADER_PATH );
223241
String pdfUAModConfig = props.getProperty( ATT_PDF_UA_MODE );
224242
// config pdf ua
@@ -244,11 +262,10 @@ protected void handleConfigTag(Element config) throws ConfigException {
244262
}
245263
// legacy class loader mode
246264
if ( StringUtils.isEmpty( fopConfigMode ) && StringUtils.isNotEmpty( fopConfigClassloaderPath ) && StringUtils.isNotEmpty( fontBaseClassloaderPath ) ) {
247-
log.warn( "Activated legacy ClassLoader mode. it is now deprecated : {}", ATT_FOP_CONFIG_MODE_CLASS_LOADER_LEGACY );
248-
throw new ConfigException( "Depcreated config mode, see github fugerit-org/fj-doc repository, issue 65" );
265+
ConfigUtils.LEGACY_CLASS_LOADER_MODE_CONFIG_HANDLER.accept( LEGACY_CLASS_LOADER_MODE_CONFIG_HANDLER_FAIL_WITH_EXCEPTION );
249266
}
250267
// setup fop config mode
251-
this.setupFopConfigMode(fopConfigMode, fopConfigResoverType, fopConfigClassloaderPath, config);
268+
this.setupFopConfigMode(fopConfigMode, fopConfigResolverType, fopConfigClassloaderPath, config);
252269
// setup suppress events
253270
this.setSuppressEvents( BooleanUtils.isTrue( props.getProperty( ATT_FOP_SUPPRESS_EVENTS ) ) );
254271
// setup pool
@@ -309,8 +326,7 @@ private void setupFopConfigMode( String fopConfigMode, String fopConfigResoverTy
309326
this.fopConfig = fopConfigClassLoaderWrapper;
310327
} );
311328
} else if ( ATT_FOP_CONFIG_MODE_CLASS_LOADER_LEGACY.equalsIgnoreCase( fopConfigMode ) ) {
312-
log.warn( "Activated legacy ClassLoader mode. it is now deprecated : {}", ATT_FOP_CONFIG_MODE_CLASS_LOADER_LEGACY );
313-
throw new ConfigException( "Depcreated config mode, see github fugerit-org/fj-doc repository, issue 65" );
329+
ConfigUtils.LEGACY_CLASS_LOADER_MODE_CONFIG_HANDLER.accept( LEGACY_CLASS_LOADER_MODE_CONFIG_HANDLER_FAIL_WITH_EXCEPTION );
314330
}
315331
}
316332

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.fugerit.java.doc.mod.fop.utils;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.fugerit.java.core.cfg.ConfigException;
5+
import org.fugerit.java.core.cfg.ConfigRuntimeException;
6+
import org.fugerit.java.doc.mod.fop.PdfFopTypeHandler;
7+
8+
import java.util.function.Consumer;
9+
10+
@Slf4j
11+
public class ConfigUtils {
12+
13+
private ConfigUtils() {}
14+
15+
public static final Consumer<Boolean> LEGACY_CLASS_LOADER_MODE_CONFIG_HANDLER = error -> {
16+
log.warn( "Deprecated legacy class loader mode : classloader-legacy" );
17+
if ( error ) {
18+
throw new ConfigRuntimeException( "Deprecated config mode, see github fugerit-org/fj-doc repository, issue 65" );
19+
}
20+
};
21+
22+
}

fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/PoolUtils.java renamed to fj-doc-mod-fop/src/main/java/org/fugerit/java/doc/mod/fop/utils/PoolUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
package org.fugerit.java.doc.mod.fop;
1+
package org.fugerit.java.doc.mod.fop.utils;
22

33
import lombok.extern.slf4j.Slf4j;
44
import org.fugerit.java.core.cfg.ConfigException;
55
import org.fugerit.java.core.function.UnsafeSupplier;
6+
import org.fugerit.java.doc.mod.fop.FopConfigWrap;
67

78
import java.util.List;
89

0 commit comments

Comments
 (0)