Skip to content

Commit 358ecaf

Browse files
authored
Merge pull request #112 from OP-TED/TEDEFO-4367-adds-global-variables-and-functions
Tedefo 4367 adds global variables and functions
2 parents 04d3e7e + 01bac3f commit 358ecaf

26 files changed

+1118
-182
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
<!-- Versions - eForms -->
6262
<version.eforms-sdk-1>1.13.0</version.eforms-sdk-1>
63-
<version.eforms-sdk-2>2.0.0-alpha.1</version.eforms-sdk-2>
63+
<version.eforms-sdk-2>2.0.0-SNAPSHOT</version.eforms-sdk-2>
6464
<version.eforms-core>1.4.0</version.eforms-core>
6565

6666
<!-- Versions - Third-party libraries -->

src/main/java/eu/europa/ted/efx/EfxTranslator.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.io.IOException;
1717
import java.io.InputStream;
1818
import java.nio.file.Path;
19+
1920
import eu.europa.ted.efx.component.EfxTranslatorFactory;
2021
import eu.europa.ted.efx.interfaces.TranslatorDependencyFactory;
2122
import eu.europa.ted.efx.interfaces.TranslatorOptions;
@@ -25,9 +26,15 @@
2526
* an EFX translator to translate EFX expressions and templates.
2627
*/
2728
public class EfxTranslator {
29+
30+
private EfxTranslator() {
31+
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
32+
}
2833

2934
private static TranslatorOptions defaultOptions = EfxTranslatorOptions.DEFAULT;
3035

36+
//#region Translate EFX expressions -----------------------------------------
37+
3138
/**
3239
* Instantiates an EFX expression translator and translates a given expression.
3340
*
@@ -54,6 +61,10 @@ public static String translateExpression(final TranslatorDependencyFactory depen
5461
return translateExpression(dependencyFactory, sdkVersion, expression, defaultOptions, expressionParameters);
5562
}
5663

64+
//#endregion Translate EFX expressions --------------------------------------
65+
66+
//#region Translate EFX templates -------------------------------------------
67+
5768
/**
5869
* Instantiates an EFX template translator and translates the EFX template contained in the given
5970
* file.
@@ -82,6 +93,14 @@ public static String translateTemplate(final TranslatorDependencyFactory depende
8293
return translateTemplate(dependencyFactory, sdkVersion, pathname, defaultOptions);
8394
}
8495

96+
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
97+
final String qualifier,
98+
final Path pathname, TranslatorOptions options)
99+
throws IOException, InstantiationException {
100+
return EfxTranslatorFactory.getEfxTemplateTranslator(sdkVersion, qualifier, dependencyFactory, options)
101+
.renderTemplate(pathname);
102+
}
103+
85104
/**
86105
* Instantiates an EFX template translator and translates the given EFX template.
87106
*
@@ -98,8 +117,7 @@ public static String translateTemplate(final TranslatorDependencyFactory depende
98117
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
99118
final String template, TranslatorOptions options)
100119
throws InstantiationException {
101-
return EfxTranslatorFactory.getEfxTemplateTranslator(sdkVersion, dependencyFactory, options)
102-
.renderTemplate(template);
120+
return translateTemplate(dependencyFactory, sdkVersion, "", template, options);
103121
}
104122

105123
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
@@ -108,6 +126,13 @@ public static String translateTemplate(final TranslatorDependencyFactory depende
108126
return translateTemplate(dependencyFactory, sdkVersion, template, defaultOptions);
109127
}
110128

129+
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
130+
final String qualifier, final String template, TranslatorOptions options)
131+
throws InstantiationException {
132+
return EfxTranslatorFactory.getEfxTemplateTranslator(sdkVersion, qualifier, dependencyFactory, options)
133+
.renderTemplate(template);
134+
}
135+
111136
/**
112137
* Instantiates an EFX template translator and translates the EFX template contained in the given
113138
* InputStream.
@@ -126,13 +151,21 @@ public static String translateTemplate(final TranslatorDependencyFactory depende
126151
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
127152
final InputStream stream, TranslatorOptions options)
128153
throws IOException, InstantiationException {
129-
return EfxTranslatorFactory.getEfxTemplateTranslator(sdkVersion, dependencyFactory, options)
130-
.renderTemplate(stream);
154+
return translateTemplate(dependencyFactory, sdkVersion, "", stream, options);
131155
}
132156

133157
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
134158
final InputStream stream)
135159
throws IOException, InstantiationException {
136160
return translateTemplate(dependencyFactory, sdkVersion, stream, defaultOptions);
137161
}
162+
163+
public static String translateTemplate(final TranslatorDependencyFactory dependencyFactory, final String sdkVersion,
164+
final String qualifier, final InputStream stream, TranslatorOptions options)
165+
throws IOException, InstantiationException {
166+
return EfxTranslatorFactory.getEfxTemplateTranslator(sdkVersion, qualifier, dependencyFactory, options)
167+
.renderTemplate(stream);
168+
}
169+
170+
//#endregion Translate EFX templates ----------------------------------------
138171
}

src/main/java/eu/europa/ted/efx/EfxTranslatorOptions.java

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,50 @@
1010

1111
public class EfxTranslatorOptions implements TranslatorOptions {
1212

13+
/**
14+
* This is the default namespace for user-defined functions (UDFs) in EFX.
15+
* There is no need to change this but we made it customizable anyway.
16+
*
17+
* This setting is relevant mostly for the EFX to XSLT translation process but it can also
18+
* be used for other target languages that need a namespace declaration for UDFs.
19+
*/
20+
public static final String DEFAULT_UDF_NAMESPACE = "efx-udf";
21+
1322
// Change to EfxDecimalFormatSymbols.EFX_DEFAULT to use the decimal format
1423
// preferred by OP (space as thousands separator and comma as decimal separator).
15-
public static final EfxTranslatorOptions DEFAULT = new EfxTranslatorOptions(DecimalFormat.XSL_DEFAULT, Locale.ENGLISH);
24+
public static final EfxTranslatorOptions DEFAULT = new EfxTranslatorOptions(DEFAULT_UDF_NAMESPACE, DecimalFormat.XSL_DEFAULT, Locale.ENGLISH);
1625

1726
private final DecimalFormat symbols;
18-
private Locale primaryLocale;
19-
private ArrayList<Locale> otherLocales;
27+
private final Locale primaryLocale;
28+
private final ArrayList<Locale> otherLocales;
29+
private final String userDefinedFunctionNamespace;
2030

2131
public EfxTranslatorOptions(DecimalFormat symbols) {
22-
this(symbols, Locale.ENGLISH);
32+
this(DEFAULT_UDF_NAMESPACE, symbols);
33+
}
34+
35+
public EfxTranslatorOptions(String udfNamespace, DecimalFormat symbols) {
36+
this(udfNamespace, symbols, Locale.ENGLISH);
2337
}
2438

2539
public EfxTranslatorOptions(DecimalFormat symbols, String primaryLanguage, String... otherLanguages) {
2640
this(symbols, Locale.forLanguageTag(primaryLanguage), Arrays.stream(otherLanguages).map(Locale::forLanguageTag).toArray(Locale[]::new));
2741
}
2842

43+
public EfxTranslatorOptions(String udfNamespace, DecimalFormat symbols, String primaryLanguage, String... otherLanguages) {
44+
this(udfNamespace, symbols, Locale.forLanguageTag(primaryLanguage), Arrays.stream(otherLanguages).map(Locale::forLanguageTag).toArray(Locale[]::new));
45+
}
46+
2947
public EfxTranslatorOptions(DecimalFormat symbols, Locale primaryLocale, Locale... otherLocales) {
48+
this(DEFAULT_UDF_NAMESPACE, symbols, primaryLocale, otherLocales);
49+
}
50+
51+
public EfxTranslatorOptions(String udfNamespace, DecimalFormat symbols, Locale primaryLocale, Locale... otherLocales) {
52+
this.userDefinedFunctionNamespace = udfNamespace;
3053
this.symbols = symbols;
3154
this.primaryLocale = primaryLocale;
3255
this.otherLocales = new ArrayList<>(Arrays.asList(otherLocales));
3356
}
34-
3557

3658
@Override
3759
public DecimalFormat getDecimalFormat() {
@@ -68,8 +90,13 @@ public String[] getAllLanguage3LetterCodes() {
6890
return languages.toArray(new String[0]);
6991
}
7092

71-
public EfxTranslatorOptions withLanguage(String language) {
72-
this.primaryLocale = Locale.forLanguageTag(language);
73-
return this;
93+
/**
94+
* This will be used by the Script Generator when generating script to invoke a user-defined function.
95+
* It will also be used by the Markup Generator to generate the namespace declaration as well as the
96+
* user-defined function definitions.
97+
*/
98+
@Override
99+
public String getUserDefinedFunctionNamespace() {
100+
return this.userDefinedFunctionNamespace;
74101
}
75102
}

src/main/java/eu/europa/ted/efx/interfaces/MarkupGenerator.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package eu.europa.ted.efx.interfaces;
1515

1616
import java.util.List;
17+
import java.util.Map;
1718
import java.util.Set;
1819

1920
import org.apache.commons.lang3.tuple.Pair;
@@ -23,6 +24,7 @@
2324
import eu.europa.ted.efx.model.expressions.scalar.NumericExpression;
2425
import eu.europa.ted.efx.model.expressions.scalar.StringExpression;
2526
import eu.europa.ted.efx.model.templates.Markup;
27+
import eu.europa.ted.efx.model.types.EfxDataType;
2628

2729
/**
2830
* The role of this interface is to allow the reuse of the Sdk6EfxTemplateTranslator to generate
@@ -45,6 +47,39 @@ public interface MarkupGenerator {
4547
*/
4648
Markup composeOutputFile(final List<Markup> content, final List<Markup> fragments);
4749

50+
/**
51+
* Given a body (main content) and a set of fragments, this method returns the full content of the
52+
* target template file.
53+
*
54+
* @param variables the variables to be included in the template file.
55+
* @param functions the functions to be included in the template file.
56+
* @param content the body (main content) of the template.
57+
* @param fragments the fragments to be included in the template file.
58+
* @return the full content of the target template file.
59+
*/
60+
Markup composeOutputFile(List<Markup> globals, final List<Markup> content, final List<Markup> fragments);
61+
62+
/**
63+
* Renders the markup necessary to declare and initialize the variable making it available at runtime.
64+
*
65+
* @param type A subclass of {@link EfxDataType} specifying the type of the variable.
66+
* @param name The name of the variable to be declared.
67+
* @param initialiser The expression used to initialize the variable.
68+
* @return A {@link Markup} object that contains the variable declaration.
69+
*/
70+
Markup renderVariableDeclaration(final Class<? extends EfxDataType> type, final String name, final Expression initialiser);
71+
72+
/**
73+
* Renders the Markup necessary to make the function available at runtime.
74+
*
75+
* @param type A sub-class of EfxDataType that represents the return type of the function.
76+
* @param name The name of the function.
77+
* @param parameters The function parameters as a map of parameter names to their corresponding EfxDataType.
78+
* @param expression The function body (the expression that must be evaluated when the function is invoked).
79+
* @return A Markup object that declares the function.
80+
*/
81+
Markup renderFunctionDeclaration(final Class<? extends EfxDataType> type, final String name, final Map<String, Class<? extends EfxDataType>> parameters, final Expression expression);
82+
4883
/**
4984
* Given an expression (which will eventually, at runtime, evaluate to the value of a field), this
5085
* method returns the template code that dereferences it (retrieves the value) in the target

src/main/java/eu/europa/ted/efx/interfaces/ScriptGenerator.java

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ public <T extends PathExpression> T composeFieldAttributeReference(
110110
*/
111111
public <T extends TypedExpression> T composeVariableReference(String variableName, Class<T> type);
112112

113+
public <T extends TypedExpression> T composeParameterReference(String parameterName, Class<T> type);
114+
113115
public <T extends TypedExpression> T composeVariableDeclaration(String variableName, Class<T> type);
114116

115117
public <T extends TypedExpression> T composeParameterDeclaration(String parameterName, Class<T> type);
@@ -302,9 +304,7 @@ public NumericExpression composeNumericOperation(NumericExpression leftOperand,
302304

303305
public DurationExpression getDurationLiteralEquivalent(final String efxLiteral);
304306

305-
/*
306-
* Numeric Functions
307-
*/
307+
// #region Numeric Functions ------------------------------------------------
308308

309309
public NumericExpression composeCountOperation(final SequenceExpression list);
310310

@@ -314,9 +314,9 @@ public NumericExpression composeNumericOperation(NumericExpression leftOperand,
314314

315315
public NumericExpression composeStringLengthCalculation(StringExpression text);
316316

317-
/*
318-
* String Functions
319-
*/
317+
// #endregion Numeric Functions -------------------------------------------
318+
319+
// #region String Functions -----------------------------------------------
320320

321321
public StringExpression composeStringConcatenation(List<StringExpression> list);
322322

@@ -392,9 +392,9 @@ public StringExpression composeSubstringExtraction(StringExpression text, Numeri
392392
*/
393393
public StringExpression getTextInPreferredLanguage(final PathExpression fieldReference);
394394

395-
/*
396-
* Boolean Functions
397-
*/
395+
// #endregion String Functions ----------------------------------------------
396+
397+
// #region Boolean Functions ------------------------------------------------
398398

399399
public BooleanExpression composeExistsCondition(PathExpression reference);
400400

@@ -404,9 +404,9 @@ public BooleanExpression composeUniqueValueCondition(PathExpression needle,
404404
public BooleanExpression composeSequenceEqualFunction(SequenceExpression one,
405405
SequenceExpression two);
406406

407-
/*
408-
* Date Functions
409-
*/
407+
// #endregion Boolean Functions --------------------------------------------
408+
409+
// #region Date Functions ---------------------------------------------------
410410

411411
public DateExpression composeToDateConversion(StringExpression pop);
412412

@@ -416,17 +416,15 @@ public DateExpression composeAddition(final DateExpression date,
416416
public DateExpression composeSubtraction(final DateExpression date,
417417
final DurationExpression duration);
418418

419-
/*
420-
* Time Functions
421-
*/
419+
//#endregion Date Functions -------------------------------------------------
422420

423-
public TimeExpression composeToTimeConversion(StringExpression pop);
421+
// #region Time Functions ---------------------------------------------------
424422

423+
public TimeExpression composeToTimeConversion(StringExpression pop);
425424

425+
// #endregion Time Functions ------------------------------------------------
426426

427-
/*
428-
* Duration Functions
429-
*/
427+
// #region Duration Functions -----------------------------------------------
430428

431429
public DurationExpression composeToDayTimeDurationConversion(StringExpression text);
432430

@@ -446,9 +444,9 @@ public DurationExpression composeAddition(final DurationExpression left,
446444
public DurationExpression composeSubtraction(final DurationExpression left,
447445
final DurationExpression right);
448446

449-
/*
450-
* Sequence Functions
451-
*/
447+
// #endregion Duration Functions --------------------------------------------
448+
449+
// #region Sequence Functions --------------------------------------------
452450

453451
public <T extends SequenceExpression> T composeDistinctValuesFunction(
454452
T list, Class<T> listType);
@@ -464,4 +462,24 @@ public <T extends SequenceExpression> T composeExceptFunction(T listOne,
464462

465463
public <T extends ScalarExpression> T composeIndexer(SequenceExpression list,
466464
NumericExpression index, Class<T> type);
465+
466+
// #endregion Sequence Functions -----------------------------------------
467+
468+
// #region Function Invocation ------------------------------------------
469+
470+
/**
471+
* Composes a function invocation expression with the specified function name, parameters,
472+
* and return type.
473+
*
474+
* @param <T> The type of the resulting expression, which must extend {@link TypedExpression}.
475+
* @param functionName The name of the function to be invoked.
476+
* @param parameters A list of parameters to be passed to the function, each of which must
477+
* extend {@link TypedExpression}.
478+
* @param type The class object representing the expected return type of the function invocation.
479+
* @return An expression that will invoke the function at runtime.
480+
*/
481+
public <T extends TypedExpression> T composeFunctionInvocation(String functionName,
482+
List<? extends TypedExpression> parameters, Class<T> type);
483+
484+
// #endregion Function Invocation -----------------------------------------
467485
}

src/main/java/eu/europa/ted/efx/interfaces/TranslatorOptions.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ public interface TranslatorOptions {
1212
public String[] getAllLanguage2LetterCodes();
1313

1414
public String[] getAllLanguage3LetterCodes();
15+
16+
public String getUserDefinedFunctionNamespace();
1517
}

0 commit comments

Comments
 (0)