Skip to content

Commit

Permalink
Merge pull request #77 from OP-TED/release/0.9.0
Browse files Browse the repository at this point in the history
Release/0.9.0
  • Loading branch information
bertrand-lorentz authored Jul 31, 2023
2 parents 23e02ee + a018809 commit c4e0799
Show file tree
Hide file tree
Showing 17 changed files with 6,261 additions and 85 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ jobs:
java-version: '11'
distribution: 'adopt'
- name: Build package
run: mvn --batch-mode -s .github/workflows/settings.xml clean install
run: mvn --batch-mode -DM2_SETTINGS=.github/workflows/settings.xml clean install # Property "M2_SETTINGS" is used by the SDK downloader in tests.
6 changes: 3 additions & 3 deletions .github/workflows/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
<profiles>
<profile>
<id>central-repos</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>central</id>
Expand All @@ -25,4 +22,7 @@
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>central-repos</activeProfile>
</activeProfiles>
</settings>
15 changes: 7 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
# eForms Notice Viewer 0.8.0 - Release Notes
# eForms Notice Viewer 0.9.0 - Release Notes

_The eForms Notice Viewer is a sample command line application that demonstrates how you can use the [eForms SDK](https://github.com/OP-TED/eForms-SDK) in a metadata driven application that visualises eForms notices._

---
## In this release:

- Fixed several bugs.
- Improved unit testing.
- Refactored the NoticeViewer class to improve code clarity.
- Added support for improved numeric formatting provided by EFX Toolkit 1.3.0.
- Added support for improved rendering of multilingual text fields provided by EFX Toolkit 1.3.0
This is the first version of the Notice Viewer, that uses the new, pre-release version 2.0.0-alpha.1 of the EFX Toolkit. As a result, the application:

---
- Now supports EFX-2 templates, and therefore can visualise notices created with SDK-2.
- Can no longer visualise notices created with pre-release versions of SDK-1 (SDK 0.x.x).

---

Documentation for this sample application is available at: https://docs.ted.europa.eu/eforms/latest/notice-viewer

This version depends on:
- [EFX toolkit for Java](https://github.com/OP-TED/efx-toolkit-java) version 1.3.0.
- [EFX toolkit for Java](https://github.com/OP-TED/efx-toolkit-java) version 2.0.0-alpha.1.
- [eForms Core for Java](https://github.com/OP-TED/eforms-core-java) library version 1.0.5.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>eu.europa.ted.eforms</groupId>
<artifactId>eforms-notice-viewer</artifactId>
<version>0.8.0</version>
<version>0.9.0</version>

<name>eForms Notice Viewer</name>
<description>eForms Notice Viewer sample application.</description>
Expand Down Expand Up @@ -54,7 +54,7 @@
<maven.compiler.target>${java.version}</maven.compiler.target>

<!-- Versions - eForms -->
<version.efx-toolkit>1.3.0</version.efx-toolkit>
<version.efx-toolkit>2.0.0-alpha.1</version.efx-toolkit>
<version.eforms-core>1.0.5</version.eforms-core>

<!-- Versions - Third-party libraries -->
Expand Down
10 changes: 0 additions & 10 deletions src/main/java/eu/europa/ted/eforms/viewer/DependencyFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ public SymbolResolver createSymbolResolver(String sdkVersion) {
}
}

@Override
public ScriptGenerator createScriptGenerator(String sdkVersion) {
throw new UnsupportedOperationException("Deprecated method, not used: 'createScriptGenerator(sdkVersion)'");
}

@Override
public ScriptGenerator createScriptGenerator(String sdkVersion, TranslatorOptions options) {
try {
Expand All @@ -47,11 +42,6 @@ public ScriptGenerator createScriptGenerator(String sdkVersion, TranslatorOption
}
}

@Override
public MarkupGenerator createMarkupGenerator(String sdkVersion) {
throw new UnsupportedOperationException("Deprecated method, not used: 'createMarkupGenerator(sdkVersion)'");
}

@Override
public MarkupGenerator createMarkupGenerator(String sdkVersion, TranslatorOptions options) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ public String getPrimaryLanguage() {

/**
* @return A list of other languages
* @throws XPathExpressionException
*/
public List<String> getOtherLanguages() throws XPathExpressionException {
return Optional
Expand Down
56 changes: 32 additions & 24 deletions src/main/java/eu/europa/ted/eforms/viewer/NoticeViewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,33 +46,41 @@ private NoticeViewer(Builder builder) {
}

/**
* Creates a HTML file with the contents generated by applying XSL transformation on a notice's
* XML using a XSL template.
* <p>
* Creates a HTML file with the contents generated by applying XSL
* transformation on a notice's XML using a XSL template.
* This XSL template is generated internally, based on SDK files.
* <p>
* The SDK root directory is expected to contain a directory per minor SDK version.
* The SDK root directory is expected to contain a directory per minor SDK
* version.
*
* @param language The language as a two letter code. If set, it will be used as the primary
* language for the translation
* @param viewId An optional SDK view id to used for loading the corresponding EFX template.
* <p>
* This can be used to enforce a custom view like notice summary. It could fail if this
* custom view is not compatible with the notice sub type.
* <p>
* If not given, then the notice sub type ID from the notice XML will be used.
* @param notice A {@link NoticeDocument} object containing the notice's XML contents and metadata
* @return The path of the generated HTML file
* @param sdkRoot Path of the root SDK directory
* @param symbols The {@link DecimalFormat} to use for the translation
* @param forceBuild If true, forces the re-creation of XSL (re-creates cache entries)
* @param language The language as a two letter code. If set, it will be used
* as the primary
* language for the translation
* @param viewId An optional SDK view id to used for loading the
* corresponding EFX template.
* This can be used to enforce a custom view like notice
* summary. It could fail if this
* custom view is not compatible with the notice sub type.
* If not given, then the notice sub type ID from the notice
* XML will be used.
* @param notice A {@link NoticeDocument} object containing the notice's XML
* contents and metadata
* @param outputFile The path of the generated HTML file
* @param sdkRoot Path of the root SDK directory
* @param symbols The {@link DecimalFormat} to use for the translation
* @param forceBuild If true, forces the re-creation of XSL (re-creates cache
* entries)
*
* @return The path of the generated HTML file
* @throws IOException when the XML/XSL contents cannot be loaded
* @throws TransformerException when the XSL transformation fails
* @throws SAXException when the notice XML cannot be parsed
* @throws ParserConfigurationException when the XML parser is not configured properly
* @throws XPathExpressionException when an error occurs while extracting language information
* from the notice document
*
* @throws IOException when the XML/XSL contents cannot be
* loaded
* @throws TransformerException when the XSL transformation fails
* @throws SAXException when the notice XML cannot be parsed
* @throws ParserConfigurationException when the XML parser is not configured
* properly
* @throws XPathExpressionException when an error occurs while extracting
* language information
* from the notice document
*/
public Path generateHtmlFile(final String language, String viewId, final NoticeDocument notice,
final Path outputFile, final Path sdkRoot, final DecimalFormat symbols,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,29 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.tuple.Pair;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import eu.europa.ted.eforms.sdk.component.SdkComponent;
import eu.europa.ted.eforms.sdk.component.SdkComponentType;
import eu.europa.ted.eforms.viewer.enums.FreemarkerTemplate;
import eu.europa.ted.eforms.viewer.util.FreemarkerHelper;
import eu.europa.ted.eforms.viewer.util.xml.XmlHelper;
import eu.europa.ted.efx.interfaces.MarkupGenerator;
import eu.europa.ted.efx.interfaces.TranslatorOptions;
import eu.europa.ted.efx.model.Expression;
import eu.europa.ted.efx.model.Expression.PathExpression;
import eu.europa.ted.efx.model.Expression.StringExpression;
import eu.europa.ted.efx.model.Markup;
import eu.europa.ted.efx.model.expressions.Expression;
import eu.europa.ted.efx.model.expressions.path.PathExpression;
import eu.europa.ted.efx.model.expressions.scalar.NumericExpression;
import eu.europa.ted.efx.model.expressions.scalar.StringExpression;
import eu.europa.ted.efx.model.templates.Markup;

@SdkComponent(versions = {"1"}, componentType = SdkComponentType.MARKUP_GENERATOR)
@SdkComponent(versions = {"1", "2"}, componentType = SdkComponentType.MARKUP_GENERATOR)
public class XslMarkupGenerator implements MarkupGenerator {
private static final Logger logger = LoggerFactory.getLogger(XslMarkupGenerator.class);

Expand All @@ -42,9 +46,9 @@ protected String[] getAssetTypes() {
return new String[] {"business-term", "field", "code", "auxiliary"};
}

private final String translations = Arrays.stream(getAssetTypes())
private final String translations = "(" + Arrays.stream(getAssetTypes())
.map(assetType -> "fn:document(concat('" + assetType + "_' , $LANGUAGE, '.xml'))")
.collect(Collectors.joining(", "));
.collect(Collectors.joining(", ")) + ")";

private static List<String> markupsListToStringList(List<Markup> markupsList) {
return Optional.ofNullable(markupsList).orElse(Collections.emptyList()).stream()
Expand All @@ -62,6 +66,7 @@ private static final Markup generateMarkup(final FreemarkerTemplate template,
Arrays.asList(Optional.ofNullable(params)
.orElseGet(Pair::emptyArray))
.stream()
.filter(pair -> pair.getKey() != null && pair.getValue() != null)
.collect(Collectors.toMap(Pair::getKey, Pair::getValue));

try (StringWriter writer = new StringWriter()) {
Expand Down Expand Up @@ -107,24 +112,37 @@ public Markup renderVariableExpression(final Expression valueReference) {

return generateMarkup(
FreemarkerTemplate.VARIABLE_EXPRESSION,
Pair.of("expression", valueReference.script));
Pair.of("expression", valueReference.getScript()));
}

@Override
public Markup renderLabelFromKey(final StringExpression key) {
return this.renderLabelFromKey(key, NumericExpression.empty());
}

@Override
public Markup renderLabelFromKey(final StringExpression key, NumericExpression quantity) {
logger.trace("Rendering label from key [{}]", key);

return generateMarkup(FreemarkerTemplate.LABEL_FROM_KEY, Pair.of("key", key.script));
return generateMarkup(FreemarkerTemplate.LABEL_FROM_KEY,
Pair.of("key", key.getScript()),
Pair.of("quantity", quantity.getScript()));
}

@Override
public Markup renderLabelFromExpression(final Expression expression) {
return this.renderLabelFromExpression(expression, NumericExpression.empty());
}

@Override
public Markup renderLabelFromExpression(final Expression expression, NumericExpression quantity) {
logger.trace("Rendering label from expression [{}]", expression);

return generateMarkup(
FreemarkerTemplate.LABEL_FROM_EXPRESSION,
Pair.of("expression", expression.script),
Pair.of("labelSuffix", String.valueOf(++variableCounter)));
Pair.of("expression", expression.getScript()),
Pair.of("variableSuffix", String.valueOf(++variableCounter)),
Pair.of("quantity", quantity.getScript()));
}

@Override
Expand All @@ -136,25 +154,31 @@ public Markup renderFreeText(final String freeText) {
}

@Override
public Markup composeFragmentDefinition(final String name, final String number,
final Markup content) {
logger.trace("Composing fragment definition with: name={}, number={}, content={}", name, number,
content);
public Markup renderLineBreak() {
return new Markup("<br/>");
}

@Override
public Markup composeFragmentDefinition(String name, String number, Markup content, Set<String> parameters) {
logger.trace("Composing fragment definition with: name={}, number={}, content={}", name, number, content);

return generateMarkup(
FreemarkerTemplate.FRAGMENT_DEFINITION,
Pair.of("content", content.script),
Pair.of("name", name),
Pair.of("number", number));
Pair.of("number", number),
Pair.of("parameters", parameters));
}

@Override
public Markup renderFragmentInvocation(final String name, final PathExpression context) {
logger.trace("Rendering fragment invocation with: name={}, context={}", name, context.script);
public Markup renderFragmentInvocation(final String name, final PathExpression context, final Set<Pair<String, String>> variables) {
logger.trace("Rendering fragment invocation with: name={}, context={}", name, context.getScript());

return generateMarkup(
FreemarkerTemplate.FRAGMENT_INVOCATION,
Pair.of("context", context.script),
Pair.of("name", name));
Pair.of("context", context.getScript()),
Pair.of("name", name),
Pair.of("variables", variables.stream().map(variable -> new String[] { variable.getKey(), variable.getValue() }).toArray())
);
}
}
10 changes: 5 additions & 5 deletions src/main/java/eu/europa/ted/eforms/viewer/util/CacheHelper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package eu.europa.ted.eforms.viewer.util;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.function.Supplier;
Expand All @@ -10,7 +11,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.europa.ted.eforms.viewer.NoticeViewerConstants;
import eu.europa.ted.efx.model.Markup;
import eu.europa.ted.efx.model.templates.Markup;

/**
* Utility class with methods for managing the caching of objects.
Expand Down Expand Up @@ -122,10 +123,9 @@ public static String computeKey(String... strings) {
Validate.notEmpty(strings, "The array of strings cannot be empty");

try {
String key = new String(
MessageDigest.getInstance("SHA-512")
.digest((StringUtils.join(strings, "###").getBytes())));

byte[] bytes = MessageDigest.getInstance("SHA-512").digest((StringUtils.join(strings, "###").getBytes()));
BigInteger number = new BigInteger(1, bytes);
String key = StringUtils.leftPad(number.toString(16), 32, '0');
logger.trace("Computed key for [{}]: {}", strings, key);

return key;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
- number: Outline number
-->

<xsl:template name='${name}'>
<xsl:template name="${name}">
<#if parameters??>
<#list parameters as parameter>
<xsl:param name="${parameter}" />
</#list>
</#if>
<section title="${name}">
<#if number?has_content>
<xsl:text>${number}&#160;</xsl:text>
Expand Down
11 changes: 8 additions & 3 deletions src/main/resources/templates/xsl_markup/fragment_invocation.ftl
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
<#--
Available variables:
- context: Context path
- name: Content block ID
- name: Content block identifier
- context: Context XPath
- variables: Lits of additional variables (optional)
-->

<xsl:for-each select="${context}">
<xsl:call-template name="${name}"/>
<xsl:call-template name="${name}">
<#list variables as variable>
<xsl:with-param name="${variable[0]}" select = "${variable[1]}" />
</#list>
</xsl:call-template>
</xsl:for-each>
Loading

0 comments on commit c4e0799

Please sign in to comment.