Skip to content

Commit

Permalink
Merge pull request #92 from OP-TED/release/2.0.0-alpha.1
Browse files Browse the repository at this point in the history
Release 2.0.0-alpha.1
  • Loading branch information
bertrand-lorentz authored Jul 28, 2023
2 parents eafaa82 + ebac474 commit 02c7eab
Show file tree
Hide file tree
Showing 105 changed files with 10,828 additions and 6,898 deletions.
44 changes: 36 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,54 @@
# EFX Toolkit 1.3.0 Release Notes
# EFX Toolkit 2.0.0-alpha.1 Release Notes

_The EFX Toolkit for Java developers is a library that enables the transpilation of [EFX](https://docs.ted.europa.eu/eforms/latest/efx) expressions and templates to different target languages. It also includes an implementation of an EFX-to-XPath transpiler._

---
## In this release:

- Updated the XPath 2.0 parser, XPathContextualizer and XPathScriptGenerator to correctly translate sequences.
- Improved numeric formatting. The EfxTranslator API now includes overloaded methods that permit control of numeric formatting. The existing API has been preserved.
- Improved handling of multilingual text fields by adding automatic selection of the visualisation language.
## In this release

This release:

- Improves translation of EFX-1.
- Adds support for translating EFX-2 expressions and templates.
- Removes support of the obsolete EFX versions included in pre-release versions of the SDK (SDK 0.x.x).
- Introduces some breaking changes in the interfaces that need to be implemented by new translators (SymbolResolver, ScriptGenerator, MarkupGenerator).

## EFX-1 Support

Although this is a pre-release version of the EFX Toolkit, it provides production-level support for EFX-1 transpilation.
EFX-1 is the current version of EFX released with SDK 1. Transpilation of EFX-1 to XPath is on par with the EFX Toolkit 1.3.0.

## EFX-2 Support

The new version of EFX is still under development and will be released with SDK 2.0.0. For more information of EFX-2 see the release notes of the eForms SDK 2.0.0-alpha.1.

## Breaking changes

For users of the Toolkit that have implemented custom transpilers, this release contains a few breaking changes.
More specifically:

- Some additional methods have been added to the SymbolResolver, ScriptGenerator and MarkupGenerator API. As a guide for your implementations please look a the implementations included in the EFX Toolkit for use by the EFX-to-XPath transpilation.
- Some deprecated methods were removed.
- An extensive refactoring in the type management system has rearranged the package structure. As a result some import statements in your code will need to be updated.

Users of the Toolkit that only use the included EFX-to-XPath transpiler will not be affected by the above changes.

## Future development

Further alpha and beta releases of SDK 2 and EFX Toolkit 2 will be issued. While in "alpha" development stage, further braking changes may be introduced. SDK 2 and EFX 2 are expected to continue to be under development util late 2023.

---

You can download the latest EFX Toolkit from Maven Central.
[![Maven Central](https://img.shields.io/maven-central/v/eu.europa.ted.eforms/efx-toolkit-java?label=Download%20&style=flat-square)](https://central.sonatype.com/artifact/eu.europa.ted.eforms/efx-toolkit-java)

Documentation for the EFX Toolkit is available at: https://docs.ted.europa.eu/eforms/latest/efx-toolkit
Documentation for the EFX Toolkit is available at: <https://docs.ted.europa.eu/eforms/latest/efx-toolkit>

---

This version of the EFX Toolkit has a compile-time dependency on the following versions of eForms SDK versions and uses the EFX grammar that each version provides:
- eForms SDK 0.6.x
- eForms SDK 0.7.x

- eForms SDK 1.x.x
- eForms SDK 2.0.0-alpha.1

It also depends on the [eForms Core Java library](https://github.com/OP-TED/eforms-core-java) version 1.0.5.
36 changes: 17 additions & 19 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>efx-toolkit-java</artifactId>
<version>1.3.0</version>
<version>2.0.0-alpha.1</version>
<packaging>jar</packaging>

<name>EFX Toolkit for Java</name>
Expand Down Expand Up @@ -67,7 +67,7 @@
<version.logback>1.2.11</version.logback>
<version.jackson>2.13.4</version.jackson>
<version.jackson-databind>2.13.4.2</version.jackson-databind>
<version.junit-jupiter-api>5.7.2</version.junit-jupiter-api>
<version.junit-jupiter>5.7.2</version.junit-jupiter>
<version.slf4j>1.7.36</version.slf4j>

<!-- Versions - Plugins -->
Expand Down Expand Up @@ -120,7 +120,12 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${version.junit-jupiter-api}</version>
<version>${version.junit-jupiter}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${version.junit-jupiter}</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
Expand All @@ -142,6 +147,11 @@
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
Expand Down Expand Up @@ -246,10 +256,10 @@
<artifactItem>
<groupId>eu.europa.ted.eforms</groupId>
<artifactId>eforms-sdk</artifactId>
<version>1.7.0</version>
<version>2.0.0-alpha.1</version>
<type>jar</type>
<includes>eforms-sdk/efx-grammar/**/*.g4</includes>
<outputDirectory>${sdk.antlr4.dir}/eu/europa/ted/efx/sdk1</outputDirectory>
<outputDirectory>${sdk.antlr4.dir}/eu/europa/ted/efx/sdk2</outputDirectory>
<fileMappers>
<!-- Remove the folder prefix from filenames -->
<org.codehaus.plexus.components.io.filemappers.FlattenFileMapper />
Expand All @@ -258,22 +268,10 @@
<artifactItem>
<groupId>eu.europa.ted.eforms</groupId>
<artifactId>eforms-sdk</artifactId>
<version>0.7.0</version>
<version>1.6.0</version>
<type>jar</type>
<includes>eforms-sdk/efx-grammar/**/*.g4</includes>
<outputDirectory>${sdk.antlr4.dir}/eu/europa/ted/efx/sdk0/v7</outputDirectory>
<fileMappers>
<!-- Remove the folder prefix from filenames -->
<org.codehaus.plexus.components.io.filemappers.FlattenFileMapper />
</fileMappers>
</artifactItem>
<artifactItem>
<groupId>eu.europa.ted.eforms</groupId>
<artifactId>eforms-sdk</artifactId>
<version>0.6.2</version>
<type>jar</type>
<includes>eforms-sdk/efx-grammar/**/*.g4</includes>
<outputDirectory>${sdk.antlr4.dir}/eu/europa/ted/efx/sdk0/v6</outputDirectory>
<outputDirectory>${sdk.antlr4.dir}/eu/europa/ted/efx/sdk1</outputDirectory>
<fileMappers>
<!-- Remove the folder prefix from filenames -->
<org.codehaus.plexus.components.io.filemappers.FlattenFileMapper />
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/eu/europa/ted/eforms/sdk/ComponentFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ private ComponentFactory() {
* Gets the single instance containing the symbols defined in the given version of the eForms SDK.
*
* @param sdkVersion Version of the SDK
* @param sdkRootPath Path to the root of the SDK
* @return The single instance containing the symbols defined in the given version of the eForms
* SDK.
* @throws InstantiationException If the SDK version is not supported.
*/
public static SymbolResolver getSymbolResolver(final String sdkVersion, final Path sdkRootPath)
throws InstantiationException {
Expand Down
88 changes: 77 additions & 11 deletions src/main/java/eu/europa/ted/eforms/sdk/SdkSymbolResolver.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package eu.europa.ted.eforms.sdk;

import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand All @@ -16,11 +17,13 @@
import eu.europa.ted.eforms.sdk.repository.SdkNodeRepository;
import eu.europa.ted.eforms.sdk.resource.SdkResourceLoader;
import eu.europa.ted.efx.interfaces.SymbolResolver;
import eu.europa.ted.efx.model.Expression.PathExpression;
import eu.europa.ted.efx.model.expressions.path.NodePathExpression;
import eu.europa.ted.efx.model.expressions.path.PathExpression;
import eu.europa.ted.efx.model.types.FieldTypes;
import eu.europa.ted.efx.xpath.XPathAttributeLocator;
import eu.europa.ted.efx.xpath.XPathContextualizer;

@SdkComponent(versions = {"0.6", "0.7", "1"},
componentType = SdkComponentType.SYMBOL_RESOLVER)
@SdkComponent(versions = { "1", "2" }, componentType = SdkComponentType.SYMBOL_RESOLVER)
public class SdkSymbolResolver implements SymbolResolver {
protected Map<String, SdkField> fieldById;

Expand All @@ -29,11 +32,13 @@ public class SdkSymbolResolver implements SymbolResolver {
protected Map<String, SdkCodelist> codelistById;

/**
* Builds EFX list from the passed codelist reference. This will lazily compute and cache the
* Builds EFX list from the passed codelist reference. This will lazily compute
* and cache the
* result for reuse as the operation can be costly on some large lists.
*
* @param codelistId A reference to an SDK codelist.
* @return The EFX string representation of the list of all the codes of the referenced codelist.
* @return The EFX string representation of the list of all the codes of the
* referenced codelist.
*/
@Override
public final List<String> expandCodelist(final String codelistId) {
Expand All @@ -47,8 +52,9 @@ public final List<String> expandCodelist(final String codelistId) {
/**
* Private, use getInstance method instead.
*
* @param sdkVersion The version of the SDK.
* @throws InstantiationException
* @param sdkVersion The version of the SDK.
* @param sdkRootPath The path to the root of the SDK.
* @throws InstantiationException If the SDK version is not supported.
*/
public SdkSymbolResolver(final String sdkVersion, final Path sdkRootPath)
throws InstantiationException {
Expand Down Expand Up @@ -93,7 +99,7 @@ public PathExpression getAbsolutePathOfField(final String fieldId) {
throw new ParseCancellationException(
String.format("Unknown field identifier '%s'.", fieldId));
}
return new PathExpression(sdkField.getXpathAbsolute());
return PathExpression.instantiate(sdkField.getXpathAbsolute(), FieldTypes.fromString(sdkField.getType()));
}

/**
Expand All @@ -106,13 +112,14 @@ public PathExpression getAbsolutePathOfNode(final String nodeId) {
if (sdkNode == null) {
throw new ParseCancellationException(String.format("Unknown node identifier '%s'.", nodeId));
}
return new PathExpression(sdkNode.getXpathAbsolute());
return new NodePathExpression(sdkNode.getXpathAbsolute());
}

/**
* Gets the xPath of the given field relative to the given context.
*
* @param fieldId The id of the field for which we want to find the relative xPath.
* @param fieldId The id of the field for which we want to find the relative
* xPath.
* @param contextPath xPath indicating the context.
* @return The xPath of the given field relative to the given context.
*/
Expand All @@ -125,7 +132,8 @@ public PathExpression getRelativePathOfField(String fieldId, PathExpression cont
/**
* Gets the xPath of the given node relative to the given context.
*
* @param nodeId The id of the node for which we want to find the relative xPath.
* @param nodeId The id of the node for which we want to find the relative
* xPath.
* @param contextPath XPath indicating the context.
* @return The XPath of the given node relative to the given context.
*/
Expand Down Expand Up @@ -167,4 +175,62 @@ public String getRootCodelistOfField(final String fieldId) {

return sdkCodelist.getRootCodelistId();
}

@Override
public boolean isAttributeField(final String fieldId) {
if (!additionalFieldInfoMap.containsKey(fieldId)) {
this.cacheAdditionalFieldInfo(fieldId);
}
return additionalFieldInfoMap.get(fieldId).isAttribute;
}

@Override
public String getAttributeNameFromAttributeField(final String fieldId) {
if (!additionalFieldInfoMap.containsKey(fieldId)) {
this.cacheAdditionalFieldInfo(fieldId);
}
return additionalFieldInfoMap.get(fieldId).attributeName;
}

@Override
public PathExpression getAbsolutePathOfFieldWithoutTheAttribute(final String fieldId) {
if (!additionalFieldInfoMap.containsKey(fieldId)) {
this.cacheAdditionalFieldInfo(fieldId);
}
return additionalFieldInfoMap.get(fieldId).pathWithoutAttribute;
}

// #region Temporary helpers ------------------------------------------------

/**
* Temporary workaround to store additional info about fields.
*
* TODO: Move this additional info to SdkField class, and move the XPathAttributeLocator to the eforms-core-library.
*/
class AdditionalFieldInfo {
public boolean isAttribute;
public String attributeName;
public PathExpression pathWithoutAttribute;
}

/**
* Caches the results of xpath parsing to mitigate performance impact.
* This is a temporary solution until we move the additional info to the SdkField class.
*/
Map<String, AdditionalFieldInfo> additionalFieldInfoMap = new HashMap<>();

private void cacheAdditionalFieldInfo(final String fieldId) {
if (additionalFieldInfoMap.containsKey(fieldId)) {
return;
}
var parsedPath = XPathAttributeLocator.findAttribute(this.getAbsolutePathOfField(fieldId));
var info = new AdditionalFieldInfo();
info.isAttribute = parsedPath.hasAttribute();
info.attributeName = parsedPath.getAttributeName();
info.pathWithoutAttribute = parsedPath.getElementPath();
additionalFieldInfoMap.put(fieldId, info);
}

// #endregion Temporary helpers ------------------------------------------------

}
16 changes: 10 additions & 6 deletions src/main/java/eu/europa/ted/efx/EfxTranslator.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ public class EfxTranslator {
* expression to be translated.
* @param expression The EFX expression to translate.
* @param expressionParameters The values of any parameters that the EFX expression requires.
* @param options The options to be used by the EFX expression translator.
* @return The translated expression in the target script language supported by the given
* {@link TranslatorDependencyFactory}.
* @throws InstantiationException
* @throws InstantiationException If the EFX expression translator cannot be instantiated.
*/
public static String translateExpression(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
final String expression, TranslatorOptions options, final String... expressionParameters)
Expand All @@ -64,8 +65,9 @@ public static String translateExpression(final TranslatorDependencyFactory depen
* @param pathname The path to the file containing the EFX template to translate.
* @return The translated template in the target markup language supported by the given
* {@link TranslatorDependencyFactory}.
* @throws IOException
* @throws InstantiationException
* @param options The options to be used by the EFX template translator.
* @throws IOException If the file cannot be read.
* @throws InstantiationException If the EFX template translator cannot be instantiated.
*/
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
final Path pathname, TranslatorOptions options)
Expand All @@ -90,7 +92,8 @@ public static String translateTemplate(final TranslatorDependencyFactory depende
* @param template A string containing the EFX template to translate.
* @return The translated template in the target markup language supported by the given
* {@link TranslatorDependencyFactory}.
* @throws InstantiationException
* @param options The options to be used by the EFX template translator.
* @throws InstantiationException If the EFX template translator cannot be instantiated.
*/
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
final String template, TranslatorOptions options)
Expand All @@ -116,8 +119,9 @@ public static String translateTemplate(final TranslatorDependencyFactory depende
* @param stream An InputStream containing the EFX template to be translated.
* @return The translated template in the target markup language supported by the given
* {@link TranslatorDependencyFactory}.
* @throws IOException
* @throws InstantiationException
* @param options The options to be used by the EFX template translator.
* @throws IOException If the InputStream cannot be read.
* @throws InstantiationException If the EFX template translator cannot be instantiated.
*/
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
final InputStream stream, TranslatorOptions options)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public interface EfxExpressionTranslator {
*
* @param expression A string containing the EFX expression to be translated.
* @param expressionParameters The values of any parameters that the given expression expects.
* @return
* @return The translated expression in the target script language.
*/
String translateExpression(final String expression, final String... expressionParameters);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public interface EfxTemplateTranslator extends EfxExpressionTranslator {
*
* @param pathname The path and filename of the EFX template file to translate.
* @return A string containing the translated template.
* @throws IOException
* @throws IOException If the file cannot be read.
*/
String renderTemplate(Path pathname) throws IOException;

Expand All @@ -47,7 +47,7 @@ public interface EfxTemplateTranslator extends EfxExpressionTranslator {
*
* @param stream An InputStream with the EFX template to be translated.
* @return A string containing the translated template.
* @throws IOException
* @throws IOException If the InputStream cannot be read.
*/
String renderTemplate(InputStream stream) throws IOException;
}
Loading

0 comments on commit 02c7eab

Please sign in to comment.