Skip to content

new module to generate documents from a configuration file #391 #392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- [fj-doc-maven-plugin] goal : direct <https://github.com/fugerit-org/fj-doc/issues/391>
- [fj-doc-lib-direct] new module to generate documents from a configuration file <https://github.com/fugerit-org/fj-doc/issues/391>

### Changed

- graalvm '24' instead of '23' for build_fj-doc-native-quarkus_test.yml workflow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.fugerit.java.core.cfg.ConfigurableObject;
import org.fugerit.java.core.cfg.helpers.UnsafeHelper;
import org.fugerit.java.core.cfg.xml.XmlBeanHelper;
import org.fugerit.java.core.function.SafeFunction;
import org.fugerit.java.core.io.helper.StreamHelper;
import org.fugerit.java.core.lang.helpers.BooleanUtils;
import org.fugerit.java.core.lang.helpers.ClassHelper;
Expand Down Expand Up @@ -111,7 +112,15 @@ private FreemarkerDocProcessConfigFacade() {}
return new ConfigRuntimeException(e);
};

public static FreemarkerDocProcessConfig newSimpleConfigMode( String id, String templatePath, String mode ) throws ConfigException {
return newSimpleConfig( id, templatePath, null, mode );
}

public static FreemarkerDocProcessConfig newSimpleConfig( String id, String templatePath, String version ) throws ConfigException {
return newSimpleConfig( id, templatePath, version, null );
}

public static FreemarkerDocProcessConfig newSimpleConfig( String id, String templatePath, String version, String mode ) throws ConfigException {
return ConfigException.get( () -> {
FreemarkerDocProcessConfig config = new FreemarkerDocProcessConfig();
config.setDefaultChain(
Expand All @@ -122,9 +131,8 @@ public static FreemarkerDocProcessConfig newSimpleConfig( String id, String temp
FreeMarkerConfigStep configStep = new FreeMarkerConfigStep();
Properties configParams = new Properties();
configParams.setProperty( FreeMarkerConfigStep.ATT_FREEMARKER_CONFIG_KEY_PATH , templatePath );
if ( version != null ) {
configParams.setProperty( FreeMarkerConfigStep.ATT_FREEMARKER_CONFIG_KEY_VERSION , version );
}
SafeFunction.applyIfNotNull( mode, () -> configParams.setProperty( FreeMarkerConfigStep.ATT_FREEMARKER_CONFIG_KEY_MODE , mode ) );
SafeFunction.applyIfNotNull( version, () -> configParams.setProperty( FreeMarkerConfigStep.ATT_FREEMARKER_CONFIG_KEY_VERSION , version ) );
configStep.setParam01( id );
configStep.setCustomConfig( convertConfiguration( configParams ) );
defaultChain.getFilterChain().add( configStep );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,12 @@
}, {
"name" : "newSimpleConfig",
"parameterTypes" : [ "java.lang.String", "java.lang.String", "java.lang.String" ]
}, {
"name" : "newSimpleConfig",
"parameterTypes" : [ "java.lang.String", "java.lang.String", "java.lang.String", "java.lang.String" ]
}, {
"name" : "newSimpleConfigMode",
"parameterTypes" : [ "java.lang.String", "java.lang.String", "java.lang.String" ]
}, {
"name" : "notify",
"parameterTypes" : [ ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ class TestFreemarkerDocProcessConfig extends BasicTest {

private static final String MAIN_CONFIG = "fj_doc_test/freemarker-doc-process.xml";

@Test
void testSimpleConfig() throws ConfigException {
FreemarkerDocProcessConfig configFolder = FreemarkerDocProcessConfigFacade.newSimpleConfigMode(
"test-mode", "path/", "folder" );
Assertions.assertNotNull( configFolder );
}

@Test
void testConfigRead001() throws Exception {
String[] configList = { MAIN_CONFIG, "fj_doc_test/freemarker-doc-process-1.xml", "fj_doc_test/freemarker-doc-process-2.xml", "fj_doc_test/freemarker-doc-process-3.xml" };
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
[#maven-plugin-goal-direct]
=== Goal 'direct'

Allow direct generation

==== Verify at command line

[source,shell]
----
mvn org.fugerit.java:fj-doc-maven-plugin:verify -DtemplateBasePath=./src/test/resources/fj_doc_test/template-fail
----

==== Verify at maven build time

[source,xml]
----
<plugin>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-maven-plugin</artifactId>
<version>${fj-doc-version}</version>
<executions>
<execution>
<id>venus-direct</id>
<phase>compile</phase>
<goals>
<goal>direct</goal>
</goals>
</execution>
</executions>
<configuration>
<configPath>${project.basedir}/config/venus-direct-config-1.yaml</configPath>
<outputAll>true</outputAll>
</configuration>
</plugin>
----

==== Goal 'direct' available parameters

[cols="4*", options="header"]
|====================================================================================================================================================================
| parameter | required | default | description
| configPath | true | | Path to the direct generation configuration file
| outputAll | false | | set to 'true' to generate all the output in configuration
| outputId | false | | List of outputId to generate
|====================================================================================================================================================================

==== Goal 'direct' generation configuration file

Here is an edample configuration file :

[source,yaml]
----
---
configId: 'venus-direct-config-1'
templatePath: 'src/test/resources/template/'
templateMode: 'folder'
handlerList:
- type: org.fugerit.java.doc.freemarker.html.FreeMarkerHtmlTypeHandlerUTF8
- type: org.fugerit.java.doc.base.typehandler.markdown.SimpleMarkdownExtTypeHandlerNoCommentsUTF8
chainList: # a template named ${chainId}.ftl must exist in 'templatePath' folder
- chainId: 'test-doc'
dataModel: # inline data model definition
docTitle: 'Venus Direct Extension - Test Doc'
- chainId: 'test-doc-json-data-model'
dataModelJson: 'src/test/resources/data-model/data-model-1.json' # JSON file data model
- chainId: 'test-doc-yaml-data-model'
dataModelYaml: 'src/test/resources/data-model/data-model-1.yaml' # YAML file data model
outputList:
- outputId: 'test-doc-html'
chainId: 'test-doc'
handlerId: 'html' # a valid handler for this output type should be defined (i.e. org.fugerit.java.doc.freemarker.html.FreeMarkerHtmlTypeHandlerUTF8)
file: 'target/test-doc.html'
- outputId: 'test-doc-md'
chainId: 'test-doc'
handlerId: 'md'
file: 'target/test-doc.md'
- outputId: 'test-doc-json-data-model-html'
chainId: 'test-doc-json-data-model'
handlerId: 'html'
file: 'target/test-doc-json-data-model.html'
- outputId: 'test-doc-yaml-data-model-md'
chainId: 'test-doc-yaml-data-model'
handlerId: 'md'
file: 'target/test-doc-json-data-model.md'
----

TIP: _dataModel_ property in chain contains a map that can be used in the template (accessibile as 'dataModel' attribute).

NOTE: Instead of maven plugin gola, it is possible to use [fj-doc-lib-direct] module as a standalone library.
1 change: 1 addition & 0 deletions fj-doc-guide/src/main/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ include::chapters/02_maven_plugin.adoc[]
include::chapters/02_1_maven_plugin_add.adoc[]
include::chapters/02_2_maven_plugin_init.adoc[]
include::chapters/02_3_maven_plugin_verify.adoc[]
include::chapters/02_4_maven_plugin_direct.adoc[]

include::chapters/03_doc_format.adoc[]
include::chapters/03_1_doc_format_xml.adoc[]
Expand Down
69 changes: 69 additions & 0 deletions fj-doc-lib-direct/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<artifactId>fj-doc-lib-direct</artifactId>

<parent>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc</artifactId>
<version>8.12.9-SNAPSHOT</version>
</parent>

<name>fj-doc-lib-direct</name>
<description>API for Direct Document Generation</description>

<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>

<properties>
</properties>

<dependencies>

<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-core</artifactId>
</dependency>

<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-base</artifactId>
</dependency>

<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-base-json</artifactId>
</dependency>

<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-base-yaml</artifactId>
</dependency>

<dependency>
<groupId>org.fugerit.java</groupId>
<artifactId>fj-doc-freemarker</artifactId>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<organization>
<url>https://www.fugerit.org</url>
<name>Fugerit</name>
</organization>

<url>https://www.fugerit.org/perm/venus/</url>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.fugerit.java.doc.lib.direct;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import org.fugerit.java.core.cfg.ConfigRuntimeException;
import org.fugerit.java.core.function.SafeFunction;
import org.fugerit.java.doc.base.config.DocConfig;
import org.fugerit.java.doc.base.process.DocProcessContext;
import org.fugerit.java.doc.freemarker.config.FreeMarkerConfigStep;
import org.fugerit.java.doc.freemarker.html.FreeMarkerHtmlTypeHandlerUTF8;
import org.fugerit.java.doc.freemarker.process.FreemarkerDocProcessConfig;
import org.fugerit.java.doc.freemarker.process.FreemarkerDocProcessConfigFacade;
import org.fugerit.java.doc.lib.direct.config.VenusDirectConfig;
import org.fugerit.java.doc.lib.direct.config.VenusDirectConfigChain;
import org.fugerit.java.doc.lib.direct.config.VenusDirectConfigOutput;

import java.io.File;
import java.io.FileOutputStream;
import java.io.Reader;

public class VenusDirectFacade {

public static final String ATT_DATA_MODEL = "dataModel";

private VenusDirectFacade() {}

private static final ObjectMapper YAML_MAPPER = new YAMLMapper();

public static VenusDirectConfig readConfig( Reader reader ) {
return SafeFunction.get( () -> {
VenusDirectConfig config = YAML_MAPPER.readValue( reader, VenusDirectConfig.class );
config.setupFreemarkerDocProcessConfig();
return config;
} );
}

public static void handleAllOutput(VenusDirectConfig config) {
SafeFunction.applyIfNotNull( config.getOutputList(), () ->
config.getOutputList().forEach( output -> handleOutput( config, output.getOutputId() ) ) );
}

public static void handleOutput(VenusDirectConfig config, String outputId) {
SafeFunction.apply( () -> {
VenusDirectConfigOutput output = config.getOutputMap().get( outputId );
if ( output == null ) {
throw new ConfigRuntimeException( String.format( "Output not found : %s", outputId ) );
}
VenusDirectConfigChain chain = config.getChainMap().get( output.getChainId() );
if ( chain == null ) {
throw new ConfigRuntimeException( String.format( "Chain not found : %s", output.getChainId() ) );
}
DocProcessContext context = DocProcessContext.newContext();
SafeFunction.applyIfNotNull( chain.getDataModel(), () -> context.setAttribute( ATT_DATA_MODEL, chain.getDataModel() ) );
File outputFile = new File( output.getFile() );
try ( FileOutputStream fos = new FileOutputStream( outputFile ) ) {
config.getDocProcessConfig().fullProcess(chain.getChainId(), context, output.getHandlerId(), fos );
}
} );

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.fugerit.java.doc.lib.direct.config;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.fugerit.java.core.cfg.ConfigException;
import org.fugerit.java.core.function.SafeFunction;
import org.fugerit.java.core.lang.helpers.ClassHelper;
import org.fugerit.java.doc.base.config.DocTypeHandler;
import org.fugerit.java.doc.freemarker.process.FreemarkerDocProcessConfig;
import org.fugerit.java.doc.freemarker.process.FreemarkerDocProcessConfigFacade;

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class VenusDirectConfig {

@Getter
private FreemarkerDocProcessConfig docProcessConfig;

@Getter
private Map<String, VenusDirectConfigChain> chainMap;

@Getter
private Map<String, VenusDirectConfigOutput> outputMap;

public void setupFreemarkerDocProcessConfig() throws ConfigException {
log.info( "configId: {}, init", this.getConfigId() );
log.info( "templatePath: {}, templateMode: {}", this.getTemplatePath(), this.getTemplateMode() );
this.docProcessConfig = FreemarkerDocProcessConfigFacade.newSimpleConfigMode(
this.getConfigId(), this.getTemplatePath(), this.getTemplateMode() );
// config handlers
SafeFunction.applyIfNotNull( this.getHandlerList(), () -> {
for ( VenusDirectConfigHandler handler : this.getHandlerList() ) {
String handlerType = handler.getType();
log.info( "configId: {}, handlerType: {}", this.getConfigId(), handlerType );
ConfigException.apply( () ->
this.docProcessConfig.getFacade().registerHandler(
(DocTypeHandler) ClassHelper.newInstance( handlerType ) ) );
}
} );
// config chain
SafeFunction.applyIfNotNull( this.getChainList(),
() -> this.chainMap = this.getChainList().stream().collect( Collectors.toMap( chain -> chain.getChainId(), chain -> chain ) ) );
log.info( "chainMap ids: {}", this.chainMap.keySet() );
// config output
SafeFunction.applyIfNotNull( this.getOutputList(),
() -> this.outputMap = this.getOutputList().stream().collect( Collectors.toMap( output -> output.getOutputId(), output -> output ) ) );
log.info( "outputMap ids: {}", this.outputMap.keySet() );
// config data model
this.chainList.forEach( VenusDirectConfigChain::setupDataModel );
}

@Getter @Setter
private String configId;

@Getter @Setter
private String templatePath;

@Getter @Setter
private String templateMode;

@Getter @Setter
private List<VenusDirectConfigHandler> handlerList;

@Getter @Setter
private List<VenusDirectConfigChain> chainList;

@Getter @Setter
private List<VenusDirectConfigOutput> outputList;


}
Loading
Loading