Skip to content
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

Add method overloads to support using qualifiers for SDK components #104

Merged
merged 1 commit into from
Apr 5, 2024
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
75 changes: 68 additions & 7 deletions src/main/java/eu/europa/ted/eforms/sdk/ComponentFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import eu.europa.ted.eforms.sdk.component.SdkComponentFactory;
import eu.europa.ted.eforms.sdk.component.SdkComponentType;
Expand All @@ -19,12 +20,45 @@ private ComponentFactory() {
super();
}

class VersionQualifier {
private final String sdkVersion;
private final String qualifier;

VersionQualifier(String sdkVersion, String qualifier) {
this.sdkVersion = sdkVersion;
this.qualifier = qualifier;
}

@Override
public int hashCode() {
return Objects.hash(sdkVersion, qualifier);
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
VersionQualifier other = (VersionQualifier) obj;
if (!getEnclosingInstance().equals(other.getEnclosingInstance()))
return false;
return Objects.equals(sdkVersion, other.sdkVersion)
&& Objects.equals(qualifier, other.qualifier);
}

private ComponentFactory getEnclosingInstance() {
return ComponentFactory.this;
}
}

/**
* EfxToXpathSymbols is implemented as a "kind-of" singleton. One instance per version of the
* eForms SDK.
* Symbol resolver is a "kind-of" singleton. One instance per version of the
* eForms SDK and per qualifier.
*/
private static final Map<String, SymbolResolver> instances = new HashMap<>();
private static final Map<VersionQualifier, SymbolResolver> instances = new HashMap<>();

/**
* Gets the single instance containing the symbols defined in the given version of the eForms SDK.
Expand All @@ -37,10 +71,27 @@ private ComponentFactory() {
*/
public static SymbolResolver getSymbolResolver(final String sdkVersion, final Path sdkRootPath)
throws InstantiationException {
return instances.computeIfAbsent(sdkVersion, k -> {
return getSymbolResolver(sdkVersion, "", sdkRootPath);
}

/**
* Gets the single instance containing the symbols defined in the given version of the eForms SDK.
*
* @param sdkVersion Version of the SDK
* @param qualifier Qualifier to choose between several implementations
* @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 String qualifier,
final Path sdkRootPath) throws InstantiationException {
VersionQualifier key = ComponentFactory.INSTANCE.new VersionQualifier(sdkVersion, qualifier);

return instances.computeIfAbsent(key, k -> {
try {
return ComponentFactory.INSTANCE.getComponentImpl(sdkVersion,
SdkComponentType.SYMBOL_RESOLVER, SymbolResolver.class, sdkVersion,
SdkComponentType.SYMBOL_RESOLVER, qualifier, SymbolResolver.class, sdkVersion,
sdkRootPath);
} catch (InstantiationException e) {
throw new RuntimeException(MessageFormat.format(
Expand All @@ -51,13 +102,23 @@ public static SymbolResolver getSymbolResolver(final String sdkVersion, final Pa

public static MarkupGenerator getMarkupGenerator(final String sdkVersion, TranslatorOptions options)
throws InstantiationException {
return getMarkupGenerator(sdkVersion, "", options);
}

public static MarkupGenerator getMarkupGenerator(final String sdkVersion, final String qualifier,
TranslatorOptions options) throws InstantiationException {
return ComponentFactory.INSTANCE.getComponentImpl(sdkVersion,
SdkComponentType.MARKUP_GENERATOR, MarkupGenerator.class, options);
SdkComponentType.MARKUP_GENERATOR, qualifier, MarkupGenerator.class, options);
}

public static ScriptGenerator getScriptGenerator(final String sdkVersion, TranslatorOptions options)
throws InstantiationException {
return getScriptGenerator(sdkVersion, "", options);
}

public static ScriptGenerator getScriptGenerator(final String sdkVersion, final String qualifier,
TranslatorOptions options) throws InstantiationException {
return ComponentFactory.INSTANCE.getComponentImpl(sdkVersion,
SdkComponentType.SCRIPT_GENERATOR, ScriptGenerator.class, options);
SdkComponentType.SCRIPT_GENERATOR, qualifier, ScriptGenerator.class, options);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import eu.europa.ted.eforms.sdk.component.SdkComponentType;
import eu.europa.ted.efx.interfaces.EfxExpressionTranslator;
import eu.europa.ted.efx.interfaces.EfxTemplateTranslator;
import eu.europa.ted.efx.interfaces.MarkupGenerator;
import eu.europa.ted.efx.interfaces.ScriptGenerator;
import eu.europa.ted.efx.interfaces.SymbolResolver;
import eu.europa.ted.efx.interfaces.TranslatorDependencyFactory;
import eu.europa.ted.efx.interfaces.TranslatorOptions;

Expand All @@ -16,17 +19,36 @@ private EfxTranslatorFactory() {

public static EfxExpressionTranslator getEfxExpressionTranslator(final String sdkVersion,
final TranslatorDependencyFactory factory, TranslatorOptions options) throws InstantiationException {
return getEfxExpressionTranslator(sdkVersion, "", factory, options);
}

public static EfxExpressionTranslator getEfxExpressionTranslator(final String sdkVersion,
final String qualifier, final TranslatorDependencyFactory factory, TranslatorOptions options)
throws InstantiationException {

SymbolResolver symbolResolver = factory.createSymbolResolver(sdkVersion, qualifier);
ScriptGenerator scriptGenerator = factory.createScriptGenerator(sdkVersion, qualifier, options);

return EfxTranslatorFactory.INSTANCE.getComponentImpl(sdkVersion,
SdkComponentType.EFX_EXPRESSION_TRANSLATOR, EfxExpressionTranslator.class,
factory.createSymbolResolver(sdkVersion), factory.createScriptGenerator(sdkVersion, options),
factory.createErrorListener());
SdkComponentType.EFX_EXPRESSION_TRANSLATOR, qualifier, EfxExpressionTranslator.class,
symbolResolver, scriptGenerator, factory.createErrorListener());
}

public static EfxTemplateTranslator getEfxTemplateTranslator(final String sdkVersion,
final TranslatorDependencyFactory factory, TranslatorOptions options) throws InstantiationException {
return getEfxTemplateTranslator(sdkVersion, "", factory, options);
}

public static EfxTemplateTranslator getEfxTemplateTranslator(final String sdkVersion,
final String qualifier, final TranslatorDependencyFactory factory, TranslatorOptions options)
throws InstantiationException {

MarkupGenerator markupGenerator = factory.createMarkupGenerator(sdkVersion, qualifier, options);
SymbolResolver symbolResolver = factory.createSymbolResolver(sdkVersion, qualifier);
ScriptGenerator scriptGenerator = factory.createScriptGenerator(sdkVersion, qualifier, options);

return EfxTranslatorFactory.INSTANCE.getComponentImpl(sdkVersion,
SdkComponentType.EFX_TEMPLATE_TRANSLATOR, EfxTemplateTranslator.class,
factory.createMarkupGenerator(sdkVersion, options), factory.createSymbolResolver(sdkVersion),
factory.createScriptGenerator(sdkVersion, options), factory.createErrorListener());
SdkComponentType.EFX_TEMPLATE_TRANSLATOR, qualifier, EfxTemplateTranslator.class,
markupGenerator, symbolResolver, scriptGenerator, factory.createErrorListener());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ public interface TranslatorDependencyFactory {
* @param sdkVersion The version of the SDK that contains the version of the EFX grammar that the
* EFX translator will attempt to translate. This is important as the symbols used in the
* EFX expression are defined in the specific version of the SDK.
* @param qualifier Qualifier to choose between several implementations.
* @return An instance of ScriptGenerator to be used by the EFX translator.
*/
public SymbolResolver createSymbolResolver(String sdkVersion);
public SymbolResolver createSymbolResolver(String sdkVersion, String qualifier);

/**
* Creates a ScriptGenerator instance.
Expand All @@ -50,10 +51,11 @@ public interface TranslatorDependencyFactory {
* @param sdkVersion The version of the SDK that contains the version of the EFX grammar that the
* EFX translator will attempt to translate. This is important as it defines the EFX
* language features that ScriptGenerator instance should be able to handle.
* @param qualifier Qualifier to choose between several implementations.
* @param options The options to be used by the ScriptGenerator.
* @return An instance of ScriptGenerator to be used by the EFX translator.
*/
public ScriptGenerator createScriptGenerator(String sdkVersion, TranslatorOptions options);
public ScriptGenerator createScriptGenerator(String sdkVersion, String qualifier, TranslatorOptions options);

/**
* Creates a MarkupGenerator instance.
Expand All @@ -64,10 +66,11 @@ public interface TranslatorDependencyFactory {
* @param sdkVersion The version of the SDK that contains the version of the EFX grammar that the
* EFX translator will attempt to translate. This is important as it defines the EFX
* language features that MarkupGenerator instance should be able to handle.
* @param qualifier Qualifier to choose between several implementations.
* @param options The options to be used by the MarkupGenerator.
* @return The instance of MarkupGenerator to be used by the EFX translator.
*/
public MarkupGenerator createMarkupGenerator(String sdkVersion, TranslatorOptions options);
public MarkupGenerator createMarkupGenerator(String sdkVersion, String qualifier, TranslatorOptions options);

/**
* Creates an error listener instance.
Expand Down
17 changes: 8 additions & 9 deletions src/test/java/eu/europa/ted/efx/mock/DependencyFactoryMock.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@ private DependencyFactoryMock() {}
Map<String, MarkupGenerator> markupGenerators = new HashMap<>();

@Override
public SymbolResolver createSymbolResolver(String sdkVersion) {
public SymbolResolver createSymbolResolver(String sdkVersion, String qualifier) {
// Ignore the qualifier for unit tests
return SymbolResolverMockFactory.getInstance(sdkVersion);
}

@Override
public ScriptGenerator createScriptGenerator(String sdkVersion, TranslatorOptions options) {
public ScriptGenerator createScriptGenerator(String sdkVersion, String qualifier, TranslatorOptions options) {
// Default hashCode() implementation is OK here
// we just need to distinguish TranslatorOptions instances
String key = sdkVersion + options.hashCode();
String key = sdkVersion + qualifier + options.hashCode();
if (!scriptGenerators.containsKey(key)) {
try {
this.scriptGenerators.put(key, ComponentFactory.getScriptGenerator(sdkVersion, options));
this.scriptGenerators.put(key, ComponentFactory.getScriptGenerator(sdkVersion, qualifier, options));
} catch (InstantiationException e) {
throw new RuntimeException(e.getMessage(), e);
}
Expand All @@ -46,11 +47,9 @@ public ScriptGenerator createScriptGenerator(String sdkVersion, TranslatorOption
}

@Override
public MarkupGenerator createMarkupGenerator(String sdkVersion, TranslatorOptions options) {
if (!this.markupGenerators.containsKey(sdkVersion)) {
this.markupGenerators.put(sdkVersion, new MarkupGeneratorMock());
}
return this.markupGenerators.get(sdkVersion);
public MarkupGenerator createMarkupGenerator(String sdkVersion, String qualifier, TranslatorOptions options) {
String key = sdkVersion + qualifier;
return this.markupGenerators.computeIfAbsent(key, k -> new MarkupGeneratorMock());
}

@Override
Expand Down