From 39c621edb43827a441724ab38b4d739c2538c40d Mon Sep 17 00:00:00 2001 From: Octavian Patrascoiu Date: Thu, 23 May 2024 14:20:06 +0100 Subject: [PATCH 1/3] [#614] Native transformer: Move up or add logger to visitors and transformers --- .../com/gs/dmn/ast/visitor/AbstractVisitor.java | 5 ++++- .../java/com/gs/dmn/ast/visitor/NopVisitor.java | 5 +++-- .../com/gs/dmn/ast/visitor/TraversalVisitor.java | 5 +++-- .../interpreter/AbstractDMNInterpreter.java | 11 ++++++++--- .../serialization/SimpleDMNDialectTransformer.java | 9 +++++---- .../transformation/AbstractFileTransformer.java | 6 +++--- .../AbstractTemplateBasedTransformer.java | 2 +- .../MixedItemDefinitionsTransformer.java | 6 +++--- .../dmn/transformation/SimpleDMNTransformer.java | 2 +- .../transformation/SpecialVariableTransformer.java | 7 +++---- .../lazy/SimpleLazyEvaluationDetector.java | 8 ++++---- .../lazy/SparseDecisionDetector.java | 2 +- .../com/gs/dmn/validation/DefaultDMNValidator.java | 8 +++----- .../com/gs/dmn/validation/SimpleDMNValidator.java | 2 +- .../java/com/gs/dmn/validation/SweepValidator.java | 8 +++----- .../com/gs/dmn/validation/TypeRefValidator.java | 8 +++----- .../com/gs/dmn/validation/UniqueNameValidator.java | 14 +++++++------- .../dmn/validation/UniqueRequirementValidator.java | 9 +++------ .../com/gs/dmn/ast/visitor/NopVisitorTest.java | 3 ++- .../gs/dmn/ast/visitor/TraversalVisitorTest.java | 3 ++- .../transformation/AbstractTransformerTest.java | 2 +- .../MixedItemDefinitionsVisitorTest.java | 3 ++- .../SpecialVariableTransformerVisitorTest.java | 3 ++- .../dmn/signavio/rdf2dmn/RDFToDMNTransformer.java | 2 +- .../interpreter/SignavioDMNInterpreter.java | 7 ++++--- .../NormalizeDateTimeLiteralsTransformer.java | 8 +++----- .../transformation/RuleDescriptionTransformer.java | 9 +++------ .../UniqueInformationRequirementTransformer.java | 9 +++------ .../NormalizeDateTimeLiteralsTransformerTest.java | 2 +- .../RuleDescriptionTransformerTest.java | 2 +- 30 files changed, 84 insertions(+), 86 deletions(-) diff --git a/dmn-core/src/main/java/com/gs/dmn/ast/visitor/AbstractVisitor.java b/dmn-core/src/main/java/com/gs/dmn/ast/visitor/AbstractVisitor.java index cfc4ad411..57bfd7afd 100644 --- a/dmn-core/src/main/java/com/gs/dmn/ast/visitor/AbstractVisitor.java +++ b/dmn-core/src/main/java/com/gs/dmn/ast/visitor/AbstractVisitor.java @@ -14,11 +14,14 @@ import com.gs.dmn.ast.Visitor; import com.gs.dmn.error.ErrorHandler; +import com.gs.dmn.log.BuildLogger; public abstract class AbstractVisitor implements Visitor { + protected final BuildLogger logger; protected final ErrorHandler errorHandler; - public AbstractVisitor(ErrorHandler errorHandler) { + public AbstractVisitor(BuildLogger logger, ErrorHandler errorHandler) { + this.logger = logger; this.errorHandler = errorHandler; } } diff --git a/dmn-core/src/main/java/com/gs/dmn/ast/visitor/NopVisitor.java b/dmn-core/src/main/java/com/gs/dmn/ast/visitor/NopVisitor.java index 3c0270b84..a3d7ded94 100644 --- a/dmn-core/src/main/java/com/gs/dmn/ast/visitor/NopVisitor.java +++ b/dmn-core/src/main/java/com/gs/dmn/ast/visitor/NopVisitor.java @@ -15,10 +15,11 @@ import com.gs.dmn.ast.*; import com.gs.dmn.ast.dmndi.*; import com.gs.dmn.error.ErrorHandler; +import com.gs.dmn.log.BuildLogger; public class NopVisitor extends AbstractVisitor { - public NopVisitor(ErrorHandler errorHandler) { - super(errorHandler); + public NopVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-core/src/main/java/com/gs/dmn/ast/visitor/TraversalVisitor.java b/dmn-core/src/main/java/com/gs/dmn/ast/visitor/TraversalVisitor.java index d179506f3..801138c3e 100644 --- a/dmn-core/src/main/java/com/gs/dmn/ast/visitor/TraversalVisitor.java +++ b/dmn-core/src/main/java/com/gs/dmn/ast/visitor/TraversalVisitor.java @@ -15,12 +15,13 @@ import com.gs.dmn.ast.*; import com.gs.dmn.ast.dmndi.*; import com.gs.dmn.error.ErrorHandler; +import com.gs.dmn.log.BuildLogger; import javax.xml.namespace.QName; public class TraversalVisitor extends AbstractVisitor { - public TraversalVisitor(ErrorHandler errorHandler) { - super(errorHandler); + public TraversalVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } // diff --git a/dmn-core/src/main/java/com/gs/dmn/runtime/interpreter/AbstractDMNInterpreter.java b/dmn-core/src/main/java/com/gs/dmn/runtime/interpreter/AbstractDMNInterpreter.java index 19ccad670..917ce2c2e 100644 --- a/dmn-core/src/main/java/com/gs/dmn/runtime/interpreter/AbstractDMNInterpreter.java +++ b/dmn-core/src/main/java/com/gs/dmn/runtime/interpreter/AbstractDMNInterpreter.java @@ -31,6 +31,8 @@ import com.gs.dmn.feel.analysis.syntax.ast.expression.textual.FilterExpression; import com.gs.dmn.feel.analysis.syntax.ast.test.UnaryTests; import com.gs.dmn.feel.lib.FEELLib; +import com.gs.dmn.log.BuildLogger; +import com.gs.dmn.log.Slf4jBuildLogger; import com.gs.dmn.runtime.*; import com.gs.dmn.runtime.annotation.HitPolicy; import com.gs.dmn.runtime.function.DMNFunction; @@ -59,6 +61,8 @@ public static void setEventListener(EventListener eventListener) { private final DMNModelRepository repository; private final EnvironmentFactory environmentFactory; + + protected final BuildLogger logger; protected final ErrorHandler errorHandler; protected final BasicDMNToNativeTransformer dmnTransformer; @@ -69,12 +73,13 @@ public static void setEventListener(EventListener eventListener) { protected InterpreterVisitor visitor; public AbstractDMNInterpreter(BasicDMNToNativeTransformer dmnTransformer, FEELLib feelLib) { + this.logger = new Slf4jBuildLogger(LOGGER); this.errorHandler = new LogErrorHandler(LOGGER); this.dmnTransformer = dmnTransformer; this.repository = dmnTransformer.getDMNModelRepository(); this.environmentFactory = dmnTransformer.getEnvironmentFactory(); this.feelLib = feelLib; - this.visitor = new InterpreterVisitor(this.errorHandler); + this.visitor = new InterpreterVisitor(logger, this.errorHandler); } @Override @@ -529,8 +534,8 @@ protected Result evaluateLiteralExpression(String text, DMNContext context) { } protected class InterpreterVisitor extends NopVisitor implements ReferenceVisitor { - public InterpreterVisitor(ErrorHandler errorHandler) { - super(errorHandler); + public InterpreterVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-core/src/main/java/com/gs/dmn/serialization/SimpleDMNDialectTransformer.java b/dmn-core/src/main/java/com/gs/dmn/serialization/SimpleDMNDialectTransformer.java index acea438fe..c0bb8aff8 100644 --- a/dmn-core/src/main/java/com/gs/dmn/serialization/SimpleDMNDialectTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/serialization/SimpleDMNDialectTransformer.java @@ -27,17 +27,18 @@ public abstract class SimpleDMNDialectTransformer { protected static final Logger LOGGER = LoggerFactory.getLogger(SimpleDMNDialectTransformer.class); - protected final ErrorHandler errorHandler = new LogErrorHandler(LOGGER); protected final BuildLogger logger; + protected final ErrorHandler errorHandler; protected final DMNVersion sourceVersion; protected final DMNVersion targetVersion; protected final DMNVersionTransformerVisitor visitor; public SimpleDMNDialectTransformer(BuildLogger logger, DMNVersion sourceVersion, DMNVersion targetVersion) { this.logger = logger; + this.errorHandler = new LogErrorHandler(LOGGER); this.sourceVersion = sourceVersion; this.targetVersion = targetVersion; - this.visitor = new DMNVersionTransformerVisitor(this.errorHandler, sourceVersion, targetVersion); + this.visitor = new DMNVersionTransformerVisitor(logger, this.errorHandler, sourceVersion, targetVersion); } public TDefinitions transformDefinitions(TDefinitions sourceDefinitions) { @@ -54,8 +55,8 @@ class DMNVersionTransformerVisitor extends TraversalVisitor { private final DMNVersion targetVersion; private TDefinitions definitions; - public DMNVersionTransformerVisitor(ErrorHandler errorHandler, DMNVersion sourceVersion, DMNVersion targetVersion) { - super(errorHandler); + public DMNVersionTransformerVisitor(BuildLogger logger, ErrorHandler errorHandler, DMNVersion sourceVersion, DMNVersion targetVersion) { + super(logger, errorHandler); this.sourceVersion = sourceVersion; this.targetVersion = targetVersion; } diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractFileTransformer.java b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractFileTransformer.java index f01332787..73bb47a15 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractFileTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractFileTransformer.java @@ -21,12 +21,12 @@ import java.nio.file.Path; public abstract class AbstractFileTransformer implements FileTransformer { - protected final InputParameters inputParameters; protected final BuildLogger logger; + protected final InputParameters inputParameters; - protected AbstractFileTransformer(InputParameters inputParameters, BuildLogger logger) { - this.inputParameters = inputParameters; + protected AbstractFileTransformer(BuildLogger logger, InputParameters inputParameters) { this.logger = logger; + this.inputParameters = inputParameters; } @Override diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractTemplateBasedTransformer.java b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractTemplateBasedTransformer.java index e15e5b1e7..19b097877 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractTemplateBasedTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractTemplateBasedTransformer.java @@ -35,7 +35,7 @@ public abstract class AbstractTemplateBasedTransformer extends AbstractFileTrans protected final TemplateProvider templateProvider; protected AbstractTemplateBasedTransformer(TemplateProvider templateProvider, InputParameters inputParameters, BuildLogger logger) { - super(inputParameters, logger); + super(logger, inputParameters); this.templateProvider = templateProvider; } diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/MixedItemDefinitionsTransformer.java b/dmn-core/src/main/java/com/gs/dmn/transformation/MixedItemDefinitionsTransformer.java index f1bbf849c..bacf4ec05 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/MixedItemDefinitionsTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/MixedItemDefinitionsTransformer.java @@ -27,7 +27,7 @@ public class MixedItemDefinitionsTransformer extends SimpleDMNTransformer { private boolean transformRepository = true; - private final Visitor visitor = new MixedItemDefinitionsVisitor<>(new NopErrorHandler()); + private final Visitor visitor = new MixedItemDefinitionsVisitor<>(this.logger, new NopErrorHandler()); public MixedItemDefinitionsTransformer() { this(new Slf4jBuildLogger(LOGGER)); @@ -69,8 +69,8 @@ public Pair> transform(DMNModelRepository re } class MixedItemDefinitionsVisitor extends TraversalVisitor { - public MixedItemDefinitionsVisitor(ErrorHandler errorHandler) { - super(errorHandler); + public MixedItemDefinitionsVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/SimpleDMNTransformer.java b/dmn-core/src/main/java/com/gs/dmn/transformation/SimpleDMNTransformer.java index c8a4c83a5..6cce8301a 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/SimpleDMNTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/SimpleDMNTransformer.java @@ -22,8 +22,8 @@ public abstract class SimpleDMNTransformer implements DMNTransformer { protected static final Logger LOGGER = LoggerFactory.getLogger(SimpleDMNTransformer.class); - protected final ErrorHandler errorHandler = new LogErrorHandler(LOGGER); protected final BuildLogger logger; + protected final ErrorHandler errorHandler = new LogErrorHandler(LOGGER); protected boolean transformRepository = true; public SimpleDMNTransformer() { diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/SpecialVariableTransformer.java b/dmn-core/src/main/java/com/gs/dmn/transformation/SpecialVariableTransformer.java index a7492e0d3..479d3ff09 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/SpecialVariableTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/SpecialVariableTransformer.java @@ -26,7 +26,7 @@ import java.util.List; public class SpecialVariableTransformer extends SimpleDMNTransformer { - private final Visitor visitor = new SpecialVariableTransformerVisitor<>(this.errorHandler); + private final Visitor visitor = new SpecialVariableTransformerVisitor<>(this.logger, this.errorHandler); public SpecialVariableTransformer() { this(new Slf4jBuildLogger(LOGGER)); @@ -69,9 +69,8 @@ public Pair> transform(DMNModelRepository re } class SpecialVariableTransformerVisitor extends TraversalVisitor { - - public SpecialVariableTransformerVisitor(ErrorHandler errorHandler) { - super(errorHandler); + public SpecialVariableTransformerVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/lazy/SimpleLazyEvaluationDetector.java b/dmn-core/src/main/java/com/gs/dmn/transformation/lazy/SimpleLazyEvaluationDetector.java index d4544a7bd..8636ced13 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/lazy/SimpleLazyEvaluationDetector.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/lazy/SimpleLazyEvaluationDetector.java @@ -21,15 +21,15 @@ public abstract class SimpleLazyEvaluationDetector implements LazyEvaluationDetector { protected static final Logger LOGGER = LoggerFactory.getLogger(SparseDecisionDetector.class); - protected final InputParameters inputParameters; protected final BuildLogger logger; + protected final InputParameters inputParameters; protected SimpleLazyEvaluationDetector() { - this(new InputParameters(), new Slf4jBuildLogger(LOGGER)); + this(new Slf4jBuildLogger(LOGGER), new InputParameters()); } - protected SimpleLazyEvaluationDetector(InputParameters inputParameters, BuildLogger logger) { - this.inputParameters = inputParameters; + protected SimpleLazyEvaluationDetector(BuildLogger logger, InputParameters inputParameters) { this.logger = logger; + this.inputParameters = inputParameters; } } diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/lazy/SparseDecisionDetector.java b/dmn-core/src/main/java/com/gs/dmn/transformation/lazy/SparseDecisionDetector.java index 4d2481def..6e9b8e8b6 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/lazy/SparseDecisionDetector.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/lazy/SparseDecisionDetector.java @@ -26,7 +26,7 @@ public SparseDecisionDetector() { } public SparseDecisionDetector(InputParameters inputParameters, BuildLogger logger) { - super(inputParameters, logger); + super(logger, inputParameters); this.sparsityThreshold = inputParameters.getSparsityThreshold(); } diff --git a/dmn-core/src/main/java/com/gs/dmn/validation/DefaultDMNValidator.java b/dmn-core/src/main/java/com/gs/dmn/validation/DefaultDMNValidator.java index 384ab598b..62c3b00e5 100644 --- a/dmn-core/src/main/java/com/gs/dmn/validation/DefaultDMNValidator.java +++ b/dmn-core/src/main/java/com/gs/dmn/validation/DefaultDMNValidator.java @@ -46,7 +46,7 @@ public List validate(DMNModelRepository repository) { return context.getErrors(); } - DefaultDMNValidatorVisitor visitor = new DefaultDMNValidatorVisitor(this.errorHandler, this.logger, this); + DefaultDMNValidatorVisitor visitor = new DefaultDMNValidatorVisitor(this.logger, this.errorHandler, this); for (TDefinitions definitions: repository.getAllDefinitions()) { definitions.accept(visitor, context); } @@ -349,12 +349,10 @@ private void checkChildExpression(TDefinitions definitions, TDRGElement element, } class DefaultDMNValidatorVisitor extends TraversalVisitor { - private final BuildLogger logger; private final DefaultDMNValidator validator; - public DefaultDMNValidatorVisitor(ErrorHandler errorHandler, BuildLogger logger, DefaultDMNValidator validator) { - super(errorHandler); - this.logger = logger; + public DefaultDMNValidatorVisitor(BuildLogger logger, ErrorHandler errorHandler, DefaultDMNValidator validator) { + super(logger, errorHandler); this.validator = validator; } diff --git a/dmn-core/src/main/java/com/gs/dmn/validation/SimpleDMNValidator.java b/dmn-core/src/main/java/com/gs/dmn/validation/SimpleDMNValidator.java index 1a141bcca..39de03a35 100644 --- a/dmn-core/src/main/java/com/gs/dmn/validation/SimpleDMNValidator.java +++ b/dmn-core/src/main/java/com/gs/dmn/validation/SimpleDMNValidator.java @@ -34,8 +34,8 @@ public static String makeError(DMNModelRepository dmnModelRepository, TDefinitio } } - protected final ErrorHandler errorHandler = new LogErrorHandler(LOGGER); protected final BuildLogger logger; + protected final ErrorHandler errorHandler = new LogErrorHandler(LOGGER); protected SimpleDMNValidator() { this(new Slf4jBuildLogger(LOGGER)); diff --git a/dmn-core/src/main/java/com/gs/dmn/validation/SweepValidator.java b/dmn-core/src/main/java/com/gs/dmn/validation/SweepValidator.java index cadae26bc..1a4c27596 100644 --- a/dmn-core/src/main/java/com/gs/dmn/validation/SweepValidator.java +++ b/dmn-core/src/main/java/com/gs/dmn/validation/SweepValidator.java @@ -64,7 +64,7 @@ public List validate(DMNModelRepository dmnModelRepository) { ELTranslator feelTranslator = this.dmnDialectDefinition.createFEELTranslator(dmnModelRepository, this.inputParameters); SweepValidationContext context = new SweepValidationContext(dmnModelRepository, feelTranslator); - SweepValidatorVisitor visitor = new SweepValidatorVisitor(this.errorHandler, this.logger, this); + SweepValidatorVisitor visitor = new SweepValidatorVisitor(this.logger, this.errorHandler, this); for (TDefinitions definitions: dmnModelRepository.getAllDefinitions()) { definitions.accept(visitor, context); } @@ -89,12 +89,10 @@ protected List makeBoundList(List ruleList, int columnIndex, Tab } class SweepValidatorVisitor extends TraversalVisitor { - private final BuildLogger logger; private final SweepValidator validator; - public SweepValidatorVisitor(ErrorHandler errorHandler, BuildLogger logger, SweepValidator validator) { - super(errorHandler); - this.logger = logger; + public SweepValidatorVisitor(BuildLogger logger, ErrorHandler errorHandler, SweepValidator validator) { + super(logger, errorHandler); this.validator = validator; } diff --git a/dmn-core/src/main/java/com/gs/dmn/validation/TypeRefValidator.java b/dmn-core/src/main/java/com/gs/dmn/validation/TypeRefValidator.java index 266f8ef0d..f1d4117b3 100644 --- a/dmn-core/src/main/java/com/gs/dmn/validation/TypeRefValidator.java +++ b/dmn-core/src/main/java/com/gs/dmn/validation/TypeRefValidator.java @@ -73,7 +73,7 @@ public TypeRefValidationContext makeErrorReport(DMNModelRepository dmnModelRepos BasicDMNToJavaTransformer dmnTransformer = this.dmnDialectDefinition.createBasicTransformer(dmnModelRepository, new NopLazyEvaluationDetector(), this.inputParameters); List> errorReport = new ArrayList<>(); TypeRefValidationContext context = new TypeRefValidationContext(dmnModelRepository, dmnTransformer, errorReport); - TypeRefValidatorVisitor visitor = new TypeRefValidatorVisitor(this.errorHandler, this.logger); + TypeRefValidatorVisitor visitor = new TypeRefValidatorVisitor(this.logger, this.errorHandler); for (TDefinitions definitions: dmnModelRepository.getAllDefinitions()) { definitions.accept(visitor, context); } @@ -90,11 +90,9 @@ private Map makeInputParametersMap() { } class TypeRefValidatorVisitor extends TraversalVisitor { - private final BuildLogger logger; - public TypeRefValidatorVisitor(ErrorHandler errorHandler, BuildLogger logger) { - super(errorHandler); - this.logger = logger; + public TypeRefValidatorVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-core/src/main/java/com/gs/dmn/validation/UniqueNameValidator.java b/dmn-core/src/main/java/com/gs/dmn/validation/UniqueNameValidator.java index 951d11733..c2dd30c92 100644 --- a/dmn-core/src/main/java/com/gs/dmn/validation/UniqueNameValidator.java +++ b/dmn-core/src/main/java/com/gs/dmn/validation/UniqueNameValidator.java @@ -13,7 +13,10 @@ package com.gs.dmn.validation; import com.gs.dmn.DMNModelRepository; -import com.gs.dmn.ast.*; +import com.gs.dmn.ast.DMNBaseElement; +import com.gs.dmn.ast.TDMNElement; +import com.gs.dmn.ast.TDefinitions; +import com.gs.dmn.ast.TNamedElement; import com.gs.dmn.ast.visitor.TraversalVisitor; import com.gs.dmn.error.ErrorHandler; import com.gs.dmn.log.BuildLogger; @@ -44,7 +47,7 @@ public List validate(DMNModelRepository repository) { } ValidationContext context = new ValidationContext(repository); - UniqueNameValidatorVisitor visitor = new UniqueNameValidatorVisitor(this.errorHandler, this.logger); + UniqueNameValidatorVisitor visitor = new UniqueNameValidatorVisitor(this.logger, this.errorHandler); for (TDefinitions definitions: repository.getAllDefinitions()) { definitions.accept(visitor, context); } @@ -54,11 +57,8 @@ public List validate(DMNModelRepository repository) { } class UniqueNameValidatorVisitor extends TraversalVisitor { - private final BuildLogger logger; - - public UniqueNameValidatorVisitor(ErrorHandler errorHandler, BuildLogger logger) { - super(errorHandler); - this.logger = logger; + public UniqueNameValidatorVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-core/src/main/java/com/gs/dmn/validation/UniqueRequirementValidator.java b/dmn-core/src/main/java/com/gs/dmn/validation/UniqueRequirementValidator.java index e825b778e..bfd04a56a 100644 --- a/dmn-core/src/main/java/com/gs/dmn/validation/UniqueRequirementValidator.java +++ b/dmn-core/src/main/java/com/gs/dmn/validation/UniqueRequirementValidator.java @@ -42,7 +42,7 @@ public List validate(DMNModelRepository repository) { } ValidationContext context = new ValidationContext(repository); - UniqueRequirementValidatorVisitor visitor = new UniqueRequirementValidatorVisitor(this.errorHandler, this.logger); + UniqueRequirementValidatorVisitor visitor = new UniqueRequirementValidatorVisitor(this.logger, this.errorHandler); for (TDefinitions definitions: repository.getAllDefinitions()) { definitions.accept(visitor, context); } @@ -52,11 +52,8 @@ public List validate(DMNModelRepository repository) { } class UniqueRequirementValidatorVisitor extends TraversalVisitor { - private final BuildLogger logger; - - public UniqueRequirementValidatorVisitor(ErrorHandler errorHandler, BuildLogger logger) { - super(errorHandler); - this.logger = logger; + public UniqueRequirementValidatorVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-core/src/test/java/com/gs/dmn/ast/visitor/NopVisitorTest.java b/dmn-core/src/test/java/com/gs/dmn/ast/visitor/NopVisitorTest.java index 775cd66dc..5061bd49e 100644 --- a/dmn-core/src/test/java/com/gs/dmn/ast/visitor/NopVisitorTest.java +++ b/dmn-core/src/test/java/com/gs/dmn/ast/visitor/NopVisitorTest.java @@ -15,6 +15,7 @@ import com.gs.dmn.ast.TDefinitions; import com.gs.dmn.ast.Visitor; import com.gs.dmn.error.NopErrorHandler; +import com.gs.dmn.log.NopBuildLogger; import com.gs.dmn.serialization.DMNMarshaller; import com.gs.dmn.serialization.xstream.DMNMarshallerFactory; import org.junit.jupiter.api.Test; @@ -26,7 +27,7 @@ public class NopVisitorTest { private final DMNMarshaller marshaller = DMNMarshallerFactory.newDefaultMarshaller(); - private final Visitor visitor = new NopVisitor<>(new NopErrorHandler()); + private final Visitor visitor = new NopVisitor<>(new NopBuildLogger(), new NopErrorHandler()); @Test public void visit() throws Exception { diff --git a/dmn-core/src/test/java/com/gs/dmn/ast/visitor/TraversalVisitorTest.java b/dmn-core/src/test/java/com/gs/dmn/ast/visitor/TraversalVisitorTest.java index 4f1a9fb2f..7744efdb9 100644 --- a/dmn-core/src/test/java/com/gs/dmn/ast/visitor/TraversalVisitorTest.java +++ b/dmn-core/src/test/java/com/gs/dmn/ast/visitor/TraversalVisitorTest.java @@ -15,6 +15,7 @@ import com.gs.dmn.ast.TDefinitions; import com.gs.dmn.ast.Visitor; import com.gs.dmn.error.NopErrorHandler; +import com.gs.dmn.log.NopBuildLogger; import com.gs.dmn.serialization.DMNMarshaller; import com.gs.dmn.serialization.xstream.DMNMarshallerFactory; import org.junit.jupiter.api.Test; @@ -26,7 +27,7 @@ public class TraversalVisitorTest { private final DMNMarshaller marshaller = DMNMarshallerFactory.newDefaultMarshaller(); - private final Visitor visitor = new TraversalVisitor<>(new NopErrorHandler()); + private final Visitor visitor = new TraversalVisitor<>(new NopBuildLogger(), new NopErrorHandler()); @Test public void visit() throws Exception { diff --git a/dmn-core/src/test/java/com/gs/dmn/transformation/AbstractTransformerTest.java b/dmn-core/src/test/java/com/gs/dmn/transformation/AbstractTransformerTest.java index 16d410096..a20524085 100644 --- a/dmn-core/src/test/java/com/gs/dmn/transformation/AbstractTransformerTest.java +++ b/dmn-core/src/test/java/com/gs/dmn/transformation/AbstractTransformerTest.java @@ -79,7 +79,7 @@ public void testRelativePath() { class DefaultTransformer extends AbstractFileTransformer { public DefaultTransformer(InputParameters inputParameters, BuildLogger logger) { - super(inputParameters, logger); + super(logger, inputParameters); } @Override diff --git a/dmn-core/src/test/java/com/gs/dmn/transformation/MixedItemDefinitionsVisitorTest.java b/dmn-core/src/test/java/com/gs/dmn/transformation/MixedItemDefinitionsVisitorTest.java index 153327f41..2d3104b29 100644 --- a/dmn-core/src/test/java/com/gs/dmn/transformation/MixedItemDefinitionsVisitorTest.java +++ b/dmn-core/src/test/java/com/gs/dmn/transformation/MixedItemDefinitionsVisitorTest.java @@ -15,6 +15,7 @@ import com.gs.dmn.ast.TDMNElement; import com.gs.dmn.ast.TItemDefinition; import com.gs.dmn.error.NopErrorHandler; +import com.gs.dmn.log.NopBuildLogger; import org.junit.jupiter.api.Test; import javax.xml.namespace.QName; @@ -22,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.*; public class MixedItemDefinitionsVisitorTest { - private final MixedItemDefinitionsVisitor visitor = new MixedItemDefinitionsVisitor<>(new NopErrorHandler()); + private final MixedItemDefinitionsVisitor visitor = new MixedItemDefinitionsVisitor<>(new NopBuildLogger(), new NopErrorHandler()); @Test public void testVisitTypeRef() { diff --git a/dmn-core/src/test/java/com/gs/dmn/transformation/SpecialVariableTransformerVisitorTest.java b/dmn-core/src/test/java/com/gs/dmn/transformation/SpecialVariableTransformerVisitorTest.java index 4429cd474..2d6acd67c 100644 --- a/dmn-core/src/test/java/com/gs/dmn/transformation/SpecialVariableTransformerVisitorTest.java +++ b/dmn-core/src/test/java/com/gs/dmn/transformation/SpecialVariableTransformerVisitorTest.java @@ -2,12 +2,13 @@ import com.gs.dmn.ast.TUnaryTests; import com.gs.dmn.error.NopErrorHandler; +import com.gs.dmn.log.NopBuildLogger; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class SpecialVariableTransformerVisitorTest { - private final SpecialVariableTransformerVisitor visitor = new SpecialVariableTransformerVisitor<>(new NopErrorHandler()); + private final SpecialVariableTransformerVisitor visitor = new SpecialVariableTransformerVisitor<>(new NopBuildLogger(), new NopErrorHandler()); @Test public void testUpdateUnaryTests() { diff --git a/dmn-signavio/src/main/java/com/gs/dmn/signavio/rdf2dmn/RDFToDMNTransformer.java b/dmn-signavio/src/main/java/com/gs/dmn/signavio/rdf2dmn/RDFToDMNTransformer.java index 3dccc8dac..c2a9d86ae 100644 --- a/dmn-signavio/src/main/java/com/gs/dmn/signavio/rdf2dmn/RDFToDMNTransformer.java +++ b/dmn-signavio/src/main/java/com/gs/dmn/signavio/rdf2dmn/RDFToDMNTransformer.java @@ -91,7 +91,7 @@ public static boolean isRDFFile(File file) { private final DMNSerializer dmnSerializer; public RDFToDMNTransformer(InputParameters inputParameters, BuildLogger logger) { - super(inputParameters, logger); + super(logger, inputParameters); this.dialectDefinition = new SignavioDMNDialectDefinition(); this.dmnTransformer = this.dialectDefinition.createBasicTransformer(new SignavioDMNModelRepository(), new NopLazyEvaluationDetector(), inputParameters); this.dmnSerializer = this.dialectDefinition.createDMNSerializer(logger, inputParameters); diff --git a/dmn-signavio/src/main/java/com/gs/dmn/signavio/runtime/interpreter/SignavioDMNInterpreter.java b/dmn-signavio/src/main/java/com/gs/dmn/signavio/runtime/interpreter/SignavioDMNInterpreter.java index d7b828d5d..945015b50 100644 --- a/dmn-signavio/src/main/java/com/gs/dmn/signavio/runtime/interpreter/SignavioDMNInterpreter.java +++ b/dmn-signavio/src/main/java/com/gs/dmn/signavio/runtime/interpreter/SignavioDMNInterpreter.java @@ -20,6 +20,7 @@ import com.gs.dmn.error.ErrorHandler; import com.gs.dmn.feel.interpreter.SignavioFEELInterpreter; import com.gs.dmn.feel.lib.FEELLib; +import com.gs.dmn.log.BuildLogger; import com.gs.dmn.runtime.DMNRuntimeException; import com.gs.dmn.runtime.interpreter.AbstractDMNInterpreter; import com.gs.dmn.runtime.interpreter.EvaluationContext; @@ -44,7 +45,7 @@ public class SignavioDMNInterpreter ext public SignavioDMNInterpreter(BasicDMNToNativeTransformer dmnTransformer, FEELLib feelLib) { super(dmnTransformer, feelLib); this.dmnModelRepository = (SignavioDMNModelRepository) this.getBasicDMNTransformer().getDMNModelRepository(); - this.visitor = new SignavioInterpreterVisitor(this.errorHandler); + this.visitor = new SignavioInterpreterVisitor(this.logger, this.errorHandler); this.elInterpreter = new SignavioFEELInterpreter<>(this); this.typeChecker = new SignavioTypeChecker(dmnTransformer, this.getElInterpreter(), feelLib); } @@ -60,8 +61,8 @@ protected boolean dagOptimisation() { } protected class SignavioInterpreterVisitor extends InterpreterVisitor { - public SignavioInterpreterVisitor(ErrorHandler errorHandler) { - super(errorHandler); + public SignavioInterpreterVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/NormalizeDateTimeLiteralsTransformer.java b/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/NormalizeDateTimeLiteralsTransformer.java index ffab7f721..ee3d6b562 100644 --- a/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/NormalizeDateTimeLiteralsTransformer.java +++ b/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/NormalizeDateTimeLiteralsTransformer.java @@ -51,7 +51,7 @@ public DMNModelRepository transform(DMNModelRepository repository) { return repository; } - NormalizeDateTimeLiteralsVisitor dmnVisitor = new NormalizeDateTimeLiteralsVisitor(this.errorHandler, this.logger); + NormalizeDateTimeLiteralsVisitor dmnVisitor = new NormalizeDateTimeLiteralsVisitor(this.logger, this.errorHandler); TransformationContext context = new TransformationContext(repository); for (TDefinitions definitions: repository.getAllDefinitions()) { definitions.accept(dmnVisitor, context); @@ -79,11 +79,9 @@ public Pair> transform(DMNModelRepository repo class NormalizeDateTimeLiteralsVisitor extends TraversalVisitor { private final MixedJavaTimeFEELLib feelLib = new MixedJavaTimeFEELLib(); - private final BuildLogger logger; - public NormalizeDateTimeLiteralsVisitor(ErrorHandler errorHandler, BuildLogger logger) { - super(errorHandler); - this.logger = logger; + public NormalizeDateTimeLiteralsVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/RuleDescriptionTransformer.java b/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/RuleDescriptionTransformer.java index a0b39876f..c32a857a4 100644 --- a/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/RuleDescriptionTransformer.java +++ b/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/RuleDescriptionTransformer.java @@ -65,7 +65,7 @@ public Pair> transform(DMNModelRepository repo private DMNModelRepository cleanRuleDescription(DMNModelRepository repository, BuildLogger logger) { logger.debug("Clean rule descriptions ..."); - RuleDescriptionVisitor dmnVisitor = new RuleDescriptionVisitor(this.errorHandler, this.logger); + RuleDescriptionVisitor dmnVisitor = new RuleDescriptionVisitor(this.logger, this.errorHandler); TransformationContext context = new TransformationContext(repository); for (TDefinitions definitions: repository.getAllDefinitions()) { definitions.accept(dmnVisitor, context); @@ -87,11 +87,8 @@ class RuleDescriptionVisitor extends TraversalVisitor { PATTERNS.put("\u00A0", " "); } - private final BuildLogger logger; - - public RuleDescriptionVisitor(ErrorHandler errorHandler, BuildLogger logger) { - super(errorHandler); - this.logger = logger; + public RuleDescriptionVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/UniqueInformationRequirementTransformer.java b/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/UniqueInformationRequirementTransformer.java index 83501af14..2a95c6813 100644 --- a/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/UniqueInformationRequirementTransformer.java +++ b/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/UniqueInformationRequirementTransformer.java @@ -62,7 +62,7 @@ public Pair> transform(DMNModelRepository repo } private DMNModelRepository removeDuplicateInformationRequirements(DMNModelRepository repository) { - UniqueInformationRequirementVisitor dmnVisitor = new UniqueInformationRequirementVisitor(this.errorHandler, logger); + UniqueInformationRequirementVisitor dmnVisitor = new UniqueInformationRequirementVisitor(logger, this.errorHandler); TransformationContext context = new TransformationContext(repository); for (TDefinitions definitions: repository.getAllDefinitions()) { definitions.accept(dmnVisitor, context); @@ -73,11 +73,8 @@ private DMNModelRepository removeDuplicateInformationRequirements(DMNModelReposi } class UniqueInformationRequirementVisitor extends TraversalVisitor { - private final BuildLogger logger; - - public UniqueInformationRequirementVisitor(ErrorHandler errorHandler, BuildLogger logger) { - super(errorHandler); - this.logger = logger; + public UniqueInformationRequirementVisitor(BuildLogger logger, ErrorHandler errorHandler) { + super(logger, errorHandler); } @Override diff --git a/dmn-signavio/src/test/java/com/gs/dmn/signavio/transformation/NormalizeDateTimeLiteralsTransformerTest.java b/dmn-signavio/src/test/java/com/gs/dmn/signavio/transformation/NormalizeDateTimeLiteralsTransformerTest.java index c993cecc9..d4b6cec24 100644 --- a/dmn-signavio/src/test/java/com/gs/dmn/signavio/transformation/NormalizeDateTimeLiteralsTransformerTest.java +++ b/dmn-signavio/src/test/java/com/gs/dmn/signavio/transformation/NormalizeDateTimeLiteralsTransformerTest.java @@ -25,7 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; public class NormalizeDateTimeLiteralsTransformerTest extends AbstractSignavioFileTransformerTest { - private final NormalizeDateTimeLiteralsVisitor visitor = new NormalizeDateTimeLiteralsVisitor(new NopErrorHandler(), new NopBuildLogger()); + private final NormalizeDateTimeLiteralsVisitor visitor = new NormalizeDateTimeLiteralsVisitor(new NopBuildLogger(), new NopErrorHandler()); private final NormalizeDateTimeLiteralsTransformer transformer = new NormalizeDateTimeLiteralsTransformer(LOGGER); @Test diff --git a/dmn-signavio/src/test/java/com/gs/dmn/signavio/transformation/RuleDescriptionTransformerTest.java b/dmn-signavio/src/test/java/com/gs/dmn/signavio/transformation/RuleDescriptionTransformerTest.java index fea4c1023..43d3b922f 100644 --- a/dmn-signavio/src/test/java/com/gs/dmn/signavio/transformation/RuleDescriptionTransformerTest.java +++ b/dmn-signavio/src/test/java/com/gs/dmn/signavio/transformation/RuleDescriptionTransformerTest.java @@ -20,7 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class RuleDescriptionTransformerTest extends AbstractSignavioFileTransformerTest { - private final RuleDescriptionVisitor visitor = new RuleDescriptionVisitor(new NopErrorHandler(), new NopBuildLogger()); + private final RuleDescriptionVisitor visitor = new RuleDescriptionVisitor(new NopBuildLogger(), new NopErrorHandler()); private final RuleDescriptionTransformer transformer = new RuleDescriptionTransformer(LOGGER); @Test From 05ce9e7a35f20bc12136ad62ee88dcd195a7c6aa Mon Sep 17 00:00:00 2001 From: Octavian Patrascoiu Date: Thu, 23 May 2024 15:33:55 +0100 Subject: [PATCH 2/3] [#614] Native transformer: Group related code in TemplateProcessor. --- .../TCKTestCasesToJavaJUnitTransformer.java | 11 +- .../AbstractDMNToNativeTransformer.java | 150 ++---------- .../AbstractTemplateBasedTransformer.java | 65 +---- .../DMNToLambdaTransformer.java | 46 +--- .../dmn/transformation/TemplateProcessor.java | 223 ++++++++++++++++++ .../TestLabToJavaJUnitTransformer.java | 12 +- .../SignavioDMNToJavaTransformer.java | 5 +- 7 files changed, 273 insertions(+), 239 deletions(-) create mode 100644 dmn-core/src/main/java/com/gs/dmn/transformation/TemplateProcessor.java diff --git a/dmn-core/src/main/java/com/gs/dmn/tck/TCKTestCasesToJavaJUnitTransformer.java b/dmn-core/src/main/java/com/gs/dmn/tck/TCKTestCasesToJavaJUnitTransformer.java index ccada422f..5e46d55fc 100644 --- a/dmn-core/src/main/java/com/gs/dmn/tck/TCKTestCasesToJavaJUnitTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/tck/TCKTestCasesToJavaJUnitTransformer.java @@ -88,6 +88,7 @@ protected void transformFile(File file, File root, Path outputPath) { } testCasesList = dmnTransformer.transform(basicTransformer.getDMNModelRepository(), testCasesList).getRight(); + TemplateProvider templateProvider = templateProcessor.getTemplateProvider(); for (TestCases testCases: testCasesList) { String javaClassName = testClassName(testCases, basicTransformer); processTemplate(testCases, templateProvider.testBaseTemplatePath(), templateProvider.testTemplateName(), basicTransformer, outputPath, javaClassName); @@ -96,7 +97,7 @@ protected void transformFile(File file, File root, Path outputPath) { generateExtra(basicTransformer, basicTransformer.getDMNModelRepository(), outputPath); watch.stop(); - logger.info("TCK processing time: " + watch.toString()); + logger.info("TCK processing time: " + watch); } catch (Exception e) { throw new DMNRuntimeException(String.format("Error during transforming %s.", file.getName()), e); } @@ -111,16 +112,16 @@ protected void processTemplate(TestCases testCases, String baseTemplatePath, Str String javaPackageName = dmnTransformer.nativeModelPackageName(testCases.getModelName()); String relativeFilePath = javaPackageName.replace('.', '/'); String fileExtension = getFileExtension(); - File outputFile = makeOutputFile(outputPath, relativeFilePath, testClassName, fileExtension); + File outputFile = this.templateProcessor.makeOutputFile(outputPath, relativeFilePath, testClassName, fileExtension); // Make parameters - Map params = makeTemplateParams(testCases, dmnTransformer); + Map params = makeTemplateParams(testCases); params.put("packageName", javaPackageName); params.put("testClassName", testClassName); params.put("decisionBaseClass", decisionBaseClass); // Process template - processTemplate(baseTemplatePath, templateName, params, outputFile, true); + this.templateProcessor.processTemplate(baseTemplatePath, templateName, params, outputFile, true); } catch (Exception e) { throw new DMNRuntimeException(String.format("Cannot process template '%s' for testCases of '%s'", templateName, testCases.getModelName()), e); } @@ -139,7 +140,7 @@ protected String testClassName(TestCases testCases, BasicDMNToNativeTransformer< } } - private Map makeTemplateParams(TestCases testCases, BasicDMNToNativeTransformer dmnTransformer) { + private Map makeTemplateParams(TestCases testCases) { Map params = new HashMap<>(); params.put("testCases", testCases); params.put("tckUtil", tckUtil); diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractDMNToNativeTransformer.java b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractDMNToNativeTransformer.java index 7e4d22db7..5a9ac02a9 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractDMNToNativeTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractDMNToNativeTransformer.java @@ -32,7 +32,10 @@ import java.io.File; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import static com.gs.dmn.serialization.DMNSerializer.isDMNFile; @@ -134,8 +137,9 @@ private void transformItemDefinition(TDefinitions definitions, TItemDefinition i // Generate interface and class String javaInterfaceName = dmnTransformer.itemDefinitionNativeSimpleInterfaceName(itemDefinition); - transformItemDefinition(definitions, itemDefinition, dmnTransformer, this.templateProvider.baseTemplatePath(), this.templateProvider.itemDefinitionInterfaceTemplate(), generatedClasses, outputPath, typePackageName, javaInterfaceName); - transformItemDefinition(definitions, itemDefinition, dmnTransformer, this.templateProvider.baseTemplatePath(), this.templateProvider.itemDefinitionClassTemplate(), generatedClasses, outputPath, typePackageName, dmnTransformer.itemDefinitionNativeClassName(javaInterfaceName)); + TemplateProvider templateProvider = this.templateProcessor.getTemplateProvider(); + transformItemDefinition(definitions, itemDefinition, dmnTransformer, templateProvider.baseTemplatePath(), templateProvider.itemDefinitionInterfaceTemplate(), generatedClasses, outputPath, typePackageName, javaInterfaceName); + transformItemDefinition(definitions, itemDefinition, dmnTransformer, templateProvider.baseTemplatePath(), templateProvider.itemDefinitionClassTemplate(), generatedClasses, outputPath, typePackageName, dmnTransformer.itemDefinitionNativeClassName(javaInterfaceName)); // Process children transformItemDefinitionList(definitions, itemDefinition.getItemComponent(), dmnTransformer, generatedClasses, outputPath); @@ -147,7 +151,7 @@ private void transformItemDefinition(TDefinitions definitions, TItemDefinition i if (generatedClasses.contains(qualifiedName)) { this.logger.warn(String.format("Class '%s' has already been generated", typeName)); } else { - processTemplate(definitions, itemDefinition, baseTemplatePath, itemDefinitionTemplate, dmnTransformer, outputPath, typePackageName, typeName); + this.templateProcessor.processTemplate(definitions, itemDefinition, baseTemplatePath, itemDefinitionTemplate, dmnTransformer, outputPath, typePackageName, typeName); generatedClasses.add(qualifiedName); } } @@ -163,13 +167,14 @@ private void transformBKM(TDefinitions definitions, TBusinessKnowledgeModel bkm, String bkmPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); String bkmClassName = dmnTransformer.drgElementClassName(bkm); + TemplateProvider templateProvider = this.templateProcessor.getTemplateProvider(); checkDuplicate(generatedClasses, bkmPackageName, bkmClassName, dmnTransformer); - processTemplate(definitions, bkm, this.templateProvider.baseTemplatePath(), this.templateProvider.bkmTemplateName(), dmnTransformer, outputPath, bkmPackageName, bkmClassName, decisionBaseClass); + this.templateProcessor.processTemplate(definitions, bkm, templateProvider.baseTemplatePath(), templateProvider.bkmTemplateName(), dmnTransformer, outputPath, bkmPackageName, bkmClassName, decisionBaseClass); if (dmnTransformer.getDMNModelRepository().isDecisionTableExpression(bkm)) { String decisionRuleOutputClassName = dmnTransformer.ruleOutputClassName(bkm); checkDuplicate(generatedClasses, bkmPackageName, decisionRuleOutputClassName, dmnTransformer); - processTemplate(definitions, bkm, this.templateProvider.baseTemplatePath(), this.templateProvider.decisionTableRuleOutputTemplate(), dmnTransformer, outputPath, bkmPackageName, decisionRuleOutputClassName, decisionBaseClass); + this.templateProcessor.processTemplate(definitions, bkm, templateProvider.baseTemplatePath(), templateProvider.decisionTableRuleOutputTemplate(), dmnTransformer, outputPath, bkmPackageName, decisionRuleOutputClassName, decisionBaseClass); } } @@ -184,8 +189,9 @@ private void transformDS(TDefinitions definitions, TDecisionService ds, BasicDMN String dsPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); String dsClassName = dmnTransformer.drgElementClassName(ds); + TemplateProvider templateProvider = this.templateProcessor.getTemplateProvider(); checkDuplicate(generatedClasses, dsPackageName, dsClassName, dmnTransformer); - processTemplate(definitions, ds, this.templateProvider.baseTemplatePath(), this.templateProvider.dsTemplateName(), dmnTransformer, outputPath, dsPackageName, dsClassName, decisionBaseClass); + this.templateProcessor.processTemplate(definitions, ds, templateProvider.baseTemplatePath(), templateProvider.dsTemplateName(), dmnTransformer, outputPath, dsPackageName, dsClassName, decisionBaseClass); } private void transformDecisionList(TDefinitions definitions, List decisions, BasicDMNToNativeTransformer dmnTransformer, List generatedClasses, Path outputPath, String decisionBaseClass) { @@ -199,13 +205,14 @@ private void transformDecision(TDefinitions definitions, TDecision decision, Bas String decisionPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); String decisionClassName = dmnTransformer.drgElementClassName(decision); + TemplateProvider templateProvider = this.templateProcessor.getTemplateProvider(); checkDuplicate(generatedClasses, decisionPackageName, decisionClassName, dmnTransformer); - processTemplate(definitions, decision, this.templateProvider.baseTemplatePath(), this.templateProvider.decisionTemplateName(), dmnTransformer, outputPath, decisionPackageName, decisionClassName, decisionBaseClass); + this.templateProcessor.processTemplate(definitions, decision, templateProvider.baseTemplatePath(), templateProvider.decisionTemplateName(), dmnTransformer, outputPath, decisionPackageName, decisionClassName, decisionBaseClass); if (dmnTransformer.getDMNModelRepository().isDecisionTableExpression(decision)) { String decisionRuleOutputClassName = dmnTransformer.ruleOutputClassName(decision); checkDuplicate(generatedClasses, decisionPackageName, decisionRuleOutputClassName, dmnTransformer); - processTemplate(definitions, decision, this.templateProvider.baseTemplatePath(), this.templateProvider.decisionTableRuleOutputTemplate(), dmnTransformer, outputPath, decisionPackageName, decisionRuleOutputClassName, decisionBaseClass); + this.templateProcessor.processTemplate(definitions, decision, templateProvider.baseTemplatePath(), templateProvider.decisionTableRuleOutputTemplate(), dmnTransformer, outputPath, decisionPackageName, decisionRuleOutputClassName, decisionBaseClass); } } @@ -217,15 +224,14 @@ private void generateProtoFile(TDefinitions definitions, BasicDMNToNativeTransfo try { // Make output file - String protoFileName = DMN_PROTO_FILE_NAME; String modelPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); String relativeFilePath = modelPackageName.replace('.', '/'); String fileExtension = ".proto"; - File outputFile = makeOutputFile(outputPath, relativeFilePath, protoFileName, fileExtension); + File outputFile = this.templateProcessor.makeOutputFile(outputPath, relativeFilePath, DMN_PROTO_FILE_NAME, fileExtension); // Make parameters - Map params = makeProtoTemplateParams(pair.getLeft(), pair.getRight(), modelPackageName, dmnTransformer); - processTemplate(this.templateProvider.baseTemplatePath(), "common/proto.ftl", params, outputFile, false); + Map params = this.templateProcessor.makeProtoTemplateParams(pair.getLeft(), pair.getRight(), modelPackageName, dmnTransformer); + this.templateProcessor.processTemplate(this.templateProcessor.getTemplateProvider().baseTemplatePath(), "common/proto.ftl", params, outputFile, false); } catch (Exception e) { throw new DMNRuntimeException(String.format("Error when generating .proto file for model '%s'", definitions.getName()), e); } @@ -238,11 +244,11 @@ private void generateRegistry(List definitionsList, BasicDMNToNati String modelPackageName = dmnTransformer.nativeRootPackageName(); String relativeFilePath = modelPackageName.replace('.', '/'); String fileExtension = getFileExtension(); - File outputFile = makeOutputFile(outputPath, relativeFilePath, registryClassName, fileExtension); + File outputFile = this.templateProcessor.makeOutputFile(outputPath, relativeFilePath, registryClassName, fileExtension); // Make parameters - Map params = makeModelRegistryTemplateParams(definitionsList, modelPackageName, registryClassName, dmnTransformer); - processTemplate(this.templateProvider.baseTemplatePath(), "common/registry.ftl", params, outputFile, false); + Map params = this.templateProcessor.makeModelRegistryTemplateParams(definitionsList, modelPackageName, registryClassName, dmnTransformer); + this.templateProcessor.processTemplate(this.templateProcessor.getTemplateProvider().baseTemplatePath(), "common/registry.ftl", params, outputFile, false); } catch (Exception e) { throw new DMNRuntimeException("Error when generating registry file for model(s)", e); } @@ -260,116 +266,4 @@ private void checkDuplicate(List generatedClasses, String pkg, String cl generatedClasses.add(qualifiedName); } } - - private void processTemplate(TDefinitions definitions, TItemDefinition itemDefinition, String baseTemplatePath, String templateName, BasicDMNToNativeTransformer dmnTransformer, Path outputPath, String javaPackageName, String javaClassName) { - try { - // Make parameters - Map params = makeTemplateParams(definitions, itemDefinition, javaPackageName, javaClassName, dmnTransformer); - - // Make output file - String relativeFilePath = javaPackageName.replace('.', '/'); - String fileExtension = getFileExtension(); - File outputFile = makeOutputFile(outputPath, relativeFilePath, javaClassName, fileExtension); - - // Process template - processTemplate(baseTemplatePath, templateName, params, outputFile, false); - } catch (Exception e) { - throw new DMNRuntimeException(String.format("Cannot process template '%s' for itemDefinition '%s'", templateName, itemDefinition.getName()), e); - } - } - - private void processTemplate(TDefinitions definitions, TInvocable in, String baseTemplatePath, String templateName, BasicDMNToNativeTransformer dmnTransformer, Path outputPath, String javaPackageName, String javaClassName, String decisionBaseClass) { - try { - // Make parameters - Map params = makeTemplateParams(definitions, in, javaPackageName, javaClassName, decisionBaseClass, dmnTransformer); - - // Make output file - String relativeFilePath = javaPackageName.replace('.', '/'); - String fileExtension = getFileExtension(); - File outputFile = makeOutputFile(outputPath, relativeFilePath, javaClassName, fileExtension); - - // Process template - processTemplate(baseTemplatePath, templateName, params, outputFile, true); - } catch (Exception e) { - throw new DMNRuntimeException(String.format("Cannot process template '%s' for BKM '%s'", templateName, in.getName()), e); - } - } - - private void processTemplate(TDefinitions definitions, TDecision decision, String baseTemplatePath, String templateName, BasicDMNToNativeTransformer dmnTransformer, Path outputPath, String javaPackageName, String javaClassName, String decisionBaseClass) { - try { - // Make parameters - Map params = makeTemplateParams(definitions, decision, javaPackageName, javaClassName, decisionBaseClass, dmnTransformer); - - // Make output file - String relativeFilePath = javaPackageName.replace('.', '/'); - String fileExtension = getFileExtension(); - File outputFile = makeOutputFile(outputPath, relativeFilePath, javaClassName, fileExtension); - - // Process template - processTemplate(baseTemplatePath, templateName, params, outputFile, true); - } catch (Exception e) { - throw new DMNRuntimeException(String.format("Cannot process template '%s' for decision '%s'", templateName, decision.getName()), e); - } - } - - protected abstract String getFileExtension(); - - // - // FreeMarker model methods - // - private Map makeTemplateParams(TDefinitions definitions, TItemDefinition itemDefinition, String javaPackageName, String javaClassName, BasicDMNToNativeTransformer dmnTransformer) { - Map params = new HashMap<>(); - params.put("modelName", definitions.getName()); - params.put("itemDefinition", itemDefinition); - - String qualifiedName = dmnTransformer.qualifiedName(javaPackageName, dmnTransformer.itemDefinitionNativeSimpleInterfaceName(itemDefinition)); - String serializationClass = this.typeDeserializationConfigurer.deserializeTypeAs(qualifiedName); - params.put("serializationClass", serializationClass); - - addCommonParams(params, javaPackageName, javaClassName, dmnTransformer); - return params; - } - - private Map makeTemplateParams(TDefinitions definitions, TInvocable invocable, String javaPackageName, String javaClassName, String decisionBaseClass, BasicDMNToNativeTransformer dmnTransformer) { - Map params = new HashMap<>(); - params.put("modelName", definitions.getName()); - params.put("drgElement", invocable); - params.put("decisionBaseClass", decisionBaseClass); - addCommonParams(params, javaPackageName, javaClassName, dmnTransformer); - return params; - } - - private Map makeTemplateParams(TDefinitions definitions, TDecision decision, String javaPackageName, String javaClassName, String decisionBaseClass, BasicDMNToNativeTransformer dmnTransformer) { - Map params = new HashMap<>(); - params.put("modelName", definitions.getName()); - params.put("drgElement", decision); - params.put("decisionBaseClass", decisionBaseClass); - addCommonParams(params, javaPackageName, javaClassName, dmnTransformer); - return params; - } - - private Map makeProtoTemplateParams(Pair, List> messageTypes, List services, String javaPackageName, BasicDMNToNativeTransformer dmnTransformer) { - Map params = new HashMap<>(); - params.put("protoPackageName", dmnTransformer.protoPackage(javaPackageName)); - params.put("dataTypes", messageTypes.getLeft()); - params.put("responseRequestTypes", messageTypes.getRight()); - params.put("services", services); - params.put("transformer", dmnTransformer); - return params; - } - - private Map makeModelRegistryTemplateParams(List definitionsList, String javaPackageName, String javaClassName, BasicDMNToNativeTransformer dmnTransformer) { - Map params = new HashMap<>(); - params.put("definitionsList", definitionsList); - addCommonParams(params, javaPackageName, javaClassName, dmnTransformer); - return params; - } - - - private void addCommonParams(Map params, String javaPackageName, String javaClassName, BasicDMNToNativeTransformer dmnTransformer) { - params.put("javaPackageName", javaPackageName); - params.put("javaClassName", javaClassName); - params.put("transformer", dmnTransformer); - params.put("modelRepository", dmnTransformer.getDMNModelRepository()); - } } diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractTemplateBasedTransformer.java b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractTemplateBasedTransformer.java index 19b097877..53b5dd282 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractTemplateBasedTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractTemplateBasedTransformer.java @@ -13,73 +13,16 @@ package com.gs.dmn.transformation; import com.gs.dmn.log.BuildLogger; -import com.gs.dmn.transformation.formatter.JavaFormatter; -import com.gs.dmn.transformation.formatter.NopJavaFormatter; +import com.gs.dmn.serialization.DefaultTypeDeserializationConfigurer; import com.gs.dmn.transformation.template.TemplateProvider; -import freemarker.template.*; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; -import java.nio.file.Path; -import java.util.Locale; -import java.util.Map; public abstract class AbstractTemplateBasedTransformer extends AbstractFileTransformer { - private static final Version VERSION = new Version("2.3.23"); - private static final JavaFormatter FORMATTER = new NopJavaFormatter(); - - protected final TemplateProvider templateProvider; + protected final TemplateProcessor templateProcessor; protected AbstractTemplateBasedTransformer(TemplateProvider templateProvider, InputParameters inputParameters, BuildLogger logger) { super(logger, inputParameters); - this.templateProvider = templateProvider; - } - - protected void processTemplate(String baseTemplatePath, String templateName, Map params, File outputFile, boolean formatOutput) throws IOException, TemplateException { - Configuration cfg = makeConfiguration(baseTemplatePath); - Template template = cfg.getTemplate("/" + templateName); - - try (Writer fileWriter = new FileWriter(outputFile)) { - template.process(params, fileWriter); - } - try { - String text = FileUtils.readFileToString(outputFile); - if (formatOutput) { - text = FORMATTER.formatSource(text); - } - FileUtils.write(outputFile, text, false); - } catch (Exception e) { - logger.error(String.format("Formatting error for file %s", outputFile.getName())); - } + this.templateProcessor = new TemplateProcessor(this.logger, templateProvider, getFileExtension(), new DefaultTypeDeserializationConfigurer()); } - private Configuration makeConfiguration(String basePackagePath) { - Configuration cfg = new Configuration(VERSION); - - // Some recommended settings: - cfg.setIncompatibleImprovements(VERSION); - cfg.setDefaultEncoding("UTF-8"); - cfg.setLocale(Locale.US); - cfg.setNumberFormat("#"); - cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); - - // Where do we load the templates from: - cfg.setClassForTemplateLoading(this.getClass(), basePackagePath); - return cfg; - } - - protected File makeOutputFile(Path outputPath, String relativeFilePath, String fileName, String fileExtension) { - String absoluteFilePath = outputPath.toAbsolutePath().toString(); - if (!StringUtils.isBlank(relativeFilePath)) { - absoluteFilePath += "/" + relativeFilePath; - } - absoluteFilePath += "/" + fileName + fileExtension; - File outputFile = new File(absoluteFilePath); - outputFile.getParentFile().mkdirs(); - return outputFile; - } + protected abstract String getFileExtension(); } diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/DMNToLambdaTransformer.java b/dmn-core/src/main/java/com/gs/dmn/transformation/DMNToLambdaTransformer.java index c0a3b809e..e4667322d 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/DMNToLambdaTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/DMNToLambdaTransformer.java @@ -25,19 +25,16 @@ import com.gs.dmn.transformation.lazy.LazyEvaluationDetector; import com.gs.dmn.transformation.template.TemplateProvider; import com.gs.dmn.validation.DMNValidator; -import freemarker.template.*; import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Writer; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class DMNToLambdaTransformer extends AbstractDMNToNativeTransformer { - private static final Version VERSION = new Version("2.3.23"); - public DMNToLambdaTransformer( DMNDialectDefinition dialectDefinition, DMNValidator dmnValidator, @@ -90,7 +87,7 @@ private void generateLambdaRequestHandler(String modelName, Path functionPath, B String javaPackageName = transformer.nativeModelPackageName(modelName); String relativeFilePath = javaPackageName.replace('.', '/'); String fileExtension = ".java"; - File outputFile = makeOutputFile(functionPath, relativeFilePath, outputFileName, fileExtension); + File outputFile = this.templateProcessor.makeOutputFile(functionPath, relativeFilePath, outputFileName, fileExtension); // Make parameters Map params = new HashMap<>(); @@ -99,7 +96,7 @@ private void generateLambdaRequestHandler(String modelName, Path functionPath, B params.put("javaPackageName", javaPackageName); params.put("javaClassName", outputFileName); - processTemplate(baseTemplatePath, templateName, params, outputFile); + this.templateProcessor.processTemplate(baseTemplatePath, templateName, params, outputFile); } catch (Exception e) { throw new DMNRuntimeException(String.format("Cannot generate from template '%s' for element '%s'", templateName, lambdaName), e); } @@ -118,14 +115,14 @@ private void generateLambdaPom(String lambdaFolderName, File outputFolder) { String fileName = "pom"; String fileExtension = ".xml"; String relativeFilePath = ""; - File outputFile = makeOutputFile(outputPath, relativeFilePath, fileName, fileExtension); + File outputFile = this.templateProcessor.makeOutputFile(outputPath, relativeFilePath, fileName, fileExtension); // Make parameters Map params = new HashMap<>(); params.put("lambdaGroupId", "com.gs.dmn"); params.put("lambdaArtifactId", lambdaFolderName); - processTemplate(baseTemplatePath, templateName, params, outputFile); + this.templateProcessor.processTemplate(baseTemplatePath, templateName, params, outputFile); } catch (Exception e) { throw new DMNRuntimeException(String.format("Cannot generate from template '%s' for element '%s'", templateName, lambdaFolderName), e); } @@ -144,7 +141,7 @@ private void generateTemplate(String modelName, String stackName, File outputFol String fileExtension = ".yaml"; String relativeFilePath = ""; Path outputPath = outputFolder.toPath(); - File outputFile = makeOutputFile(outputPath, relativeFilePath, fileName, fileExtension); + File outputFile = this.templateProcessor.makeOutputFile(outputPath, relativeFilePath, fileName, fileExtension); // Make parameters Map params = new HashMap<>(); @@ -152,7 +149,7 @@ private void generateTemplate(String modelName, String stackName, File outputFol params.put("stackName", stackName); params.put("functionResources", functionResources); - processTemplate(baseTemplatePath, templateName, params, outputFile); + this.templateProcessor.processTemplate(baseTemplatePath, templateName, params, outputFile); } catch (Exception e) { throw new RuntimeException(String.format("Cannot generate from template '%s' for '%s'", templateName, modelName), e); } @@ -173,29 +170,6 @@ private List makeFunctionResources(String modelName, BasicDMNT return resources; } - protected void processTemplate(String baseTemplatePath, String templateName, Map params, File outputFile) throws IOException, TemplateException { - Configuration cfg = makeConfiguration(baseTemplatePath); - Template template = cfg.getTemplate("/" + templateName); - - try (Writer fileWriter = new FileWriter(outputFile)) { - template.process(params, fileWriter); - } - } - - private Configuration makeConfiguration(String basePackagePath) { - Configuration cfg = new Configuration(VERSION); - - // Some recommended settings: - cfg.setIncompatibleImprovements(VERSION); - cfg.setDefaultEncoding("UTF-8"); - cfg.setLocale(Locale.US); - cfg.setNumberFormat("#"); - cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); - - // Where do we load the templates from: - cfg.setClassForTemplateLoading(this.getClass(), basePackagePath); - return cfg; - } protected String getAWSBaseTemplatePath() { return "/templates/aws"; diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/TemplateProcessor.java b/dmn-core/src/main/java/com/gs/dmn/transformation/TemplateProcessor.java new file mode 100644 index 000000000..83910380a --- /dev/null +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/TemplateProcessor.java @@ -0,0 +1,223 @@ +/* + * Copyright 2016 Goldman Sachs. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.gs.dmn.transformation; + +import com.gs.dmn.ast.TDecision; +import com.gs.dmn.ast.TDefinitions; +import com.gs.dmn.ast.TInvocable; +import com.gs.dmn.ast.TItemDefinition; +import com.gs.dmn.context.DMNContext; +import com.gs.dmn.el.analysis.semantics.type.Type; +import com.gs.dmn.log.BuildLogger; +import com.gs.dmn.runtime.DMNRuntimeException; +import com.gs.dmn.runtime.Pair; +import com.gs.dmn.serialization.TypeDeserializationConfigurer; +import com.gs.dmn.transformation.basic.BasicDMNToNativeTransformer; +import com.gs.dmn.transformation.formatter.JavaFormatter; +import com.gs.dmn.transformation.formatter.NopJavaFormatter; +import com.gs.dmn.transformation.proto.MessageType; +import com.gs.dmn.transformation.proto.Service; +import com.gs.dmn.transformation.template.TemplateProvider; +import freemarker.template.*; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +public class TemplateProcessor { + private static final Version VERSION = new Version("2.3.23"); + private static final JavaFormatter FORMATTER = new NopJavaFormatter(); + + private final BuildLogger logger; + private final TemplateProvider templateProvider; + private final String fileExtension; + private final TypeDeserializationConfigurer typeDeserializationConfigurer; + + public TemplateProcessor(BuildLogger logger, TemplateProvider templateProvider, String fileExtension, TypeDeserializationConfigurer typeDeserializationConfigurer) { + this.logger = logger; + this.templateProvider = templateProvider; + this.fileExtension = fileExtension; + this.typeDeserializationConfigurer = typeDeserializationConfigurer; + } + + public File makeOutputFile(Path outputPath, String relativeFilePath, String fileName, String fileExtension) { + String absoluteFilePath = outputPath.toAbsolutePath().toString(); + if (!StringUtils.isBlank(relativeFilePath)) { + absoluteFilePath += "/" + relativeFilePath; + } + absoluteFilePath += "/" + fileName + fileExtension; + File outputFile = new File(absoluteFilePath); + outputFile.getParentFile().mkdirs(); + return outputFile; + } + + public void processTemplate(String baseTemplatePath, String templateName, Map params, File outputFile, boolean formatOutput) throws IOException, TemplateException { + processTemplate(baseTemplatePath, templateName, params, outputFile); + try { + String text = FileUtils.readFileToString(outputFile, Charset.defaultCharset()); + if (formatOutput) { + text = FORMATTER.formatSource(text); + } + FileUtils.write(outputFile, text, Charset.defaultCharset(), false); + } catch (Exception e) { + logger.error(String.format("Formatting error for file %s", outputFile.getName())); + } + } + + void processTemplate(String baseTemplatePath, String templateName, Map params, File outputFile) throws IOException, TemplateException { + Configuration cfg = makeConfiguration(baseTemplatePath); + Template template = cfg.getTemplate("/" + templateName); + + try (Writer fileWriter = new FileWriter(outputFile)) { + template.process(params, fileWriter); + } + } + + void processTemplate(TDefinitions definitions, TItemDefinition itemDefinition, String baseTemplatePath, String templateName, BasicDMNToNativeTransformer dmnTransformer, Path outputPath, String javaPackageName, String javaClassName) { + try { + // Make parameters + Map params = makeTemplateParams(definitions, itemDefinition, javaPackageName, javaClassName, dmnTransformer); + + // Make output file + String relativeFilePath = javaPackageName.replace('.', '/'); + String fileExtension = this.fileExtension; + File outputFile = makeOutputFile(outputPath, relativeFilePath, javaClassName, fileExtension); + + // Process template + processTemplate(baseTemplatePath, templateName, params, outputFile, false); + } catch (Exception e) { + throw new DMNRuntimeException(String.format("Cannot process template '%s' for itemDefinition '%s'", templateName, itemDefinition.getName()), e); + } + } + + void processTemplate(TDefinitions definitions, TInvocable in, String baseTemplatePath, String templateName, BasicDMNToNativeTransformer dmnTransformer, Path outputPath, String javaPackageName, String javaClassName, String decisionBaseClass) { + try { + // Make parameters + Map params = makeTemplateParams(definitions, in, javaPackageName, javaClassName, decisionBaseClass, dmnTransformer); + + // Make output file + String relativeFilePath = javaPackageName.replace('.', '/'); + String fileExtension = this.fileExtension; + File outputFile = makeOutputFile(outputPath, relativeFilePath, javaClassName, fileExtension); + + // Process template + processTemplate(baseTemplatePath, templateName, params, outputFile, true); + } catch (Exception e) { + throw new DMNRuntimeException(String.format("Cannot process template '%s' for BKM '%s'", templateName, in.getName()), e); + } + } + + void processTemplate(TDefinitions definitions, TDecision decision, String baseTemplatePath, String templateName, BasicDMNToNativeTransformer dmnTransformer, Path outputPath, String javaPackageName, String javaClassName, String decisionBaseClass) { + try { + // Make parameters + Map params = makeTemplateParams(definitions, decision, javaPackageName, javaClassName, decisionBaseClass, dmnTransformer); + + // Make output file + String relativeFilePath = javaPackageName.replace('.', '/'); + String fileExtension = this.fileExtension; + File outputFile = makeOutputFile(outputPath, relativeFilePath, javaClassName, fileExtension); + + // Process template + processTemplate(baseTemplatePath, templateName, params, outputFile, true); + } catch (Exception e) { + throw new DMNRuntimeException(String.format("Cannot process template '%s' for decision '%s'", templateName, decision.getName()), e); + } + } + + // + // FreeMarker model methods + // + private Configuration makeConfiguration(String basePackagePath) { + Configuration cfg = new Configuration(VERSION); + + // Some recommended settings: + cfg.setIncompatibleImprovements(VERSION); + cfg.setDefaultEncoding("UTF-8"); + cfg.setLocale(Locale.US); + cfg.setNumberFormat("#"); + cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); + + // Where do we load the templates from: + cfg.setClassForTemplateLoading(this.getClass(), basePackagePath); + return cfg; + } + + private Map makeTemplateParams(TDefinitions definitions, TItemDefinition itemDefinition, String javaPackageName, String javaClassName, BasicDMNToNativeTransformer dmnTransformer) { + Map params = new HashMap<>(); + params.put("modelName", definitions.getName()); + params.put("itemDefinition", itemDefinition); + + String qualifiedName = dmnTransformer.qualifiedName(javaPackageName, dmnTransformer.itemDefinitionNativeSimpleInterfaceName(itemDefinition)); + String serializationClass = this.typeDeserializationConfigurer.deserializeTypeAs(qualifiedName); + params.put("serializationClass", serializationClass); + + addCommonParams(params, javaPackageName, javaClassName, dmnTransformer); + return params; + } + + private Map makeTemplateParams(TDefinitions definitions, TInvocable invocable, String javaPackageName, String javaClassName, String decisionBaseClass, BasicDMNToNativeTransformer dmnTransformer) { + Map params = new HashMap<>(); + params.put("modelName", definitions.getName()); + params.put("drgElement", invocable); + params.put("decisionBaseClass", decisionBaseClass); + addCommonParams(params, javaPackageName, javaClassName, dmnTransformer); + return params; + } + + private Map makeTemplateParams(TDefinitions definitions, TDecision decision, String javaPackageName, String javaClassName, String decisionBaseClass, BasicDMNToNativeTransformer dmnTransformer) { + Map params = new HashMap<>(); + params.put("modelName", definitions.getName()); + params.put("drgElement", decision); + params.put("decisionBaseClass", decisionBaseClass); + addCommonParams(params, javaPackageName, javaClassName, dmnTransformer); + return params; + } + + Map makeProtoTemplateParams(Pair, List> messageTypes, List services, String javaPackageName, BasicDMNToNativeTransformer dmnTransformer) { + Map params = new HashMap<>(); + params.put("protoPackageName", dmnTransformer.protoPackage(javaPackageName)); + params.put("dataTypes", messageTypes.getLeft()); + params.put("responseRequestTypes", messageTypes.getRight()); + params.put("services", services); + params.put("transformer", dmnTransformer); + return params; + } + + Map makeModelRegistryTemplateParams(List definitionsList, String javaPackageName, String javaClassName, BasicDMNToNativeTransformer dmnTransformer) { + Map params = new HashMap<>(); + params.put("definitionsList", definitionsList); + addCommonParams(params, javaPackageName, javaClassName, dmnTransformer); + return params; + } + + + private void addCommonParams(Map params, String javaPackageName, String javaClassName, BasicDMNToNativeTransformer dmnTransformer) { + params.put("javaPackageName", javaPackageName); + params.put("javaClassName", javaClassName); + params.put("transformer", dmnTransformer); + params.put("modelRepository", dmnTransformer.getDMNModelRepository()); + } + + public TemplateProvider getTemplateProvider() { + return templateProvider; + } +} diff --git a/dmn-signavio/src/main/java/com/gs/dmn/signavio/testlab/TestLabToJavaJUnitTransformer.java b/dmn-signavio/src/main/java/com/gs/dmn/signavio/testlab/TestLabToJavaJUnitTransformer.java index 820fd04ff..43b287427 100644 --- a/dmn-signavio/src/main/java/com/gs/dmn/signavio/testlab/TestLabToJavaJUnitTransformer.java +++ b/dmn-signavio/src/main/java/com/gs/dmn/signavio/testlab/TestLabToJavaJUnitTransformer.java @@ -111,7 +111,7 @@ protected void transformFile(File file, File root, Path outputPath) { for (TestLab testLab: testLabList) { String javaClassName = testClassName(testLab, this.basicTransformer); - processTemplate(testLab, this.templateProvider.testBaseTemplatePath(), this.templateProvider.testTemplateName(), this.basicTransformer, outputPath, javaClassName); + transformTestLab(testLab, this.templateProcessor.getTemplateProvider().testBaseTemplatePath(), this.templateProcessor.getTemplateProvider().testTemplateName(), this.basicTransformer, outputPath, javaClassName); } watch.stop(); @@ -131,12 +131,12 @@ protected DMNModelRepository readModels(File file) { } } - private void processTemplate(TestLab testLab, String baseTemplatePath, String templateName, BasicDMNToNativeTransformer dmnTransformer, Path outputPath, String testClassName) { + private void transformTestLab(TestLab testLab, String baseTemplatePath, String templateName, BasicDMNToNativeTransformer dmnTransformer, Path outputPath, String testClassName) { try { String javaPackageName = dmnTransformer.nativeModelPackageName(testLab.getModelName()); // Make parameters - Map params = makeTemplateParams(testLab, dmnTransformer); + Map params = makeTemplateParams(testLab); params.put("packageName", javaPackageName); params.put("testClassName", testClassName); params.put("decisionBaseClass", this.decisionBaseClass); @@ -144,10 +144,10 @@ private void processTemplate(TestLab testLab, String baseTemplatePath, String te // Make output file String relativeFilePath = javaPackageName.replace('.', '/'); String fileExtension = getFileExtension(); - File outputFile = makeOutputFile(outputPath, relativeFilePath, testClassName, fileExtension); + File outputFile = this.templateProcessor.makeOutputFile(outputPath, relativeFilePath, testClassName, fileExtension); // Process template - processTemplate(baseTemplatePath, templateName, params, outputFile, true); + this.templateProcessor.processTemplate(baseTemplatePath, templateName, params, outputFile, true); } catch (Exception e) { throw new DMNRuntimeException(String.format("Cannot process TestLab template '%s' for '%s'", templateName, testLab.getRootDecisionId()), e); } @@ -169,7 +169,7 @@ private String testClassName(BasicDMNToNativeTransformer dmnTr } } - private Map makeTemplateParams(TestLab testLab, BasicDMNToNativeTransformer dmnTransformer) { + private Map makeTemplateParams(TestLab testLab) { Map params = new HashMap<>(); params.put("testLab", testLab); params.put("testLabUtil", this.testLabUtil); diff --git a/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/SignavioDMNToJavaTransformer.java b/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/SignavioDMNToJavaTransformer.java index 699c6cdf6..0c43cd629 100644 --- a/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/SignavioDMNToJavaTransformer.java +++ b/dmn-signavio/src/main/java/com/gs/dmn/signavio/transformation/SignavioDMNToJavaTransformer.java @@ -62,8 +62,7 @@ protected String getFileExtension() { protected DMNModelRepository readModels(File file) { if (isDMNFile(file)) { TDefinitions result = this.dmnSerializer.readModel(file); - DMNModelRepository repository = new SignavioDMNModelRepository(result, this.schemaNamespace); - return repository; + return new SignavioDMNModelRepository(result, this.schemaNamespace); } else { throw new DMNRuntimeException(String.format("Invalid DMN file %s", file.getAbsoluteFile())); } @@ -90,7 +89,7 @@ private void processManifest(BasicDMNToNativeTransformer dmnTr String modelVersion = this.inputParameters.getModelVersion(); String platformVersion = this.inputParameters.getPlatformVersion(); DMNMetadata manifest = dmnToManifestTransformer.toManifest(dmnNamespace, nativeNamespace, dmnVersion, modelVersion, platformVersion); - File resultFile = makeOutputFile(outputPath, filePath, jsonFileName, fileExtension); + File resultFile = this.templateProcessor.makeOutputFile(outputPath, filePath, jsonFileName, fileExtension); JsonSerializer.OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValue(resultFile, manifest); } catch (Exception e) { throw new DMNRuntimeException("Cannot process manifest file", e); From e4713f9f91491efaa5db242fb293e9be412f9ec3 Mon Sep 17 00:00:00 2001 From: Octavian Patrascoiu Date: Thu, 23 May 2024 15:55:23 +0100 Subject: [PATCH 3/3] [#614] Native transformer: Add native visitor. --- .../AbstractDMNToNativeTransformer.java | 133 +------------ .../transformation/DMNToNativeVisitor.java | 180 ++++++++++++++++++ .../transformation/NativeVisitorContext.java | 27 +++ 3 files changed, 214 insertions(+), 126 deletions(-) create mode 100644 dmn-core/src/main/java/com/gs/dmn/transformation/DMNToNativeVisitor.java create mode 100644 dmn-core/src/main/java/com/gs/dmn/transformation/NativeVisitorContext.java diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractDMNToNativeTransformer.java b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractDMNToNativeTransformer.java index 5a9ac02a9..ea0f44c73 100644 --- a/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractDMNToNativeTransformer.java +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/AbstractDMNToNativeTransformer.java @@ -13,10 +13,11 @@ package com.gs.dmn.transformation; import com.gs.dmn.DMNModelRepository; -import com.gs.dmn.ast.*; +import com.gs.dmn.ast.TDefinitions; import com.gs.dmn.context.DMNContext; import com.gs.dmn.dialect.DMNDialectDefinition; import com.gs.dmn.el.analysis.semantics.type.Type; +import com.gs.dmn.error.LogErrorHandler; import com.gs.dmn.log.BuildLogger; import com.gs.dmn.runtime.DMNRuntimeException; import com.gs.dmn.runtime.Pair; @@ -29,6 +30,8 @@ import com.gs.dmn.transformation.template.TemplateProvider; import com.gs.dmn.validation.DMNValidator; import org.apache.commons.lang3.time.StopWatch; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.nio.file.Path; @@ -40,6 +43,7 @@ import static com.gs.dmn.serialization.DMNSerializer.isDMNFile; public abstract class AbstractDMNToNativeTransformer extends AbstractDMNTransformer implements DMNToNativeTransformer { + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDMNToNativeTransformer.class.getName()); private static final String DMN_PROTO_FILE_NAME = "jdmn"; public static final String DATA_PACKAGE = "type"; @@ -87,23 +91,9 @@ protected void transformFile(File file, File root, Path outputPath) { } protected void transform(BasicDMNToNativeTransformer dmnTransformer, DMNModelRepository dmnModelRepository, Path outputPath) { + DMNToNativeVisitor visitor = new DMNToNativeVisitor(this.logger, new LogErrorHandler(LOGGER), dmnTransformer, dmnModelRepository, this.templateProcessor, outputPath, new ArrayList<>(), this.decisionBaseClass); for(TDefinitions definitions: dmnModelRepository.getAllDefinitions()) { - // Generate data types - List generatedClasses = new ArrayList<>(); - List itemDefinitions = dmnModelRepository.findItemDefinitions(definitions); - transformItemDefinitionList(definitions, itemDefinitions, dmnTransformer, generatedClasses, outputPath); - - // Generate BKMs - List businessKnowledgeModels = dmnModelRepository.findBKMs(definitions); - transformBKMList(definitions, businessKnowledgeModels, dmnTransformer, generatedClasses, outputPath); - - // Generate DSs - List decisionServices = dmnModelRepository.findDSs(definitions); - transformDSList(definitions, decisionServices, dmnTransformer, generatedClasses, outputPath); - - // Generate decisions - List decisions = dmnModelRepository.findDecisions(definitions); - transformDecisionList(definitions, decisions, dmnTransformer, generatedClasses, outputPath, this.decisionBaseClass); + definitions.accept(visitor, new NativeVisitorContext(definitions)); // Generate .proto file generateProtoFile(definitions, dmnTransformer, outputPath); @@ -116,106 +106,6 @@ protected void transform(BasicDMNToNativeTransformer dmnTransf generateExtra(dmnTransformer, dmnModelRepository, outputPath); } - private void transformItemDefinitionList(TDefinitions definitions, List itemDefinitionList, BasicDMNToNativeTransformer dmnTransformer, List generatedClasses, Path outputPath) { - if (itemDefinitionList != null) { - for (TItemDefinition itemDefinition : itemDefinitionList) { - transformItemDefinition(definitions, itemDefinition, dmnTransformer, generatedClasses, outputPath); - } - } - } - - private void transformItemDefinition(TDefinitions definitions, TItemDefinition itemDefinition, BasicDMNToNativeTransformer dmnTransformer, List generatedClasses, Path outputPath) { - if (itemDefinition == null) { - return; - } - - // Complex type - if (dmnTransformer.getDMNModelRepository().hasComponents(itemDefinition)) { - this.logger.debug(String.format("Generating code for ItemDefinition '%s'", itemDefinition.getName())); - - String typePackageName = dmnTransformer.nativeTypePackageName(definitions.getName()); - - // Generate interface and class - String javaInterfaceName = dmnTransformer.itemDefinitionNativeSimpleInterfaceName(itemDefinition); - TemplateProvider templateProvider = this.templateProcessor.getTemplateProvider(); - transformItemDefinition(definitions, itemDefinition, dmnTransformer, templateProvider.baseTemplatePath(), templateProvider.itemDefinitionInterfaceTemplate(), generatedClasses, outputPath, typePackageName, javaInterfaceName); - transformItemDefinition(definitions, itemDefinition, dmnTransformer, templateProvider.baseTemplatePath(), templateProvider.itemDefinitionClassTemplate(), generatedClasses, outputPath, typePackageName, dmnTransformer.itemDefinitionNativeClassName(javaInterfaceName)); - - // Process children - transformItemDefinitionList(definitions, itemDefinition.getItemComponent(), dmnTransformer, generatedClasses, outputPath); - } - } - - private void transformItemDefinition(TDefinitions definitions, TItemDefinition itemDefinition, BasicDMNToNativeTransformer dmnTransformer, String baseTemplatePath, String itemDefinitionTemplate, List generatedClasses, Path outputPath, String typePackageName, String typeName) { - String qualifiedName = dmnTransformer.qualifiedName(typePackageName, typeName); - if (generatedClasses.contains(qualifiedName)) { - this.logger.warn(String.format("Class '%s' has already been generated", typeName)); - } else { - this.templateProcessor.processTemplate(definitions, itemDefinition, baseTemplatePath, itemDefinitionTemplate, dmnTransformer, outputPath, typePackageName, typeName); - generatedClasses.add(qualifiedName); - } - } - - private void transformBKMList(TDefinitions definitions, List bkmList, BasicDMNToNativeTransformer dmnTransformer, List generatedClasses, Path outputPath) { - for (TBusinessKnowledgeModel bkm : bkmList) { - transformBKM(definitions, bkm, dmnTransformer, generatedClasses, outputPath, this.decisionBaseClass); - } - } - - private void transformBKM(TDefinitions definitions, TBusinessKnowledgeModel bkm, BasicDMNToNativeTransformer dmnTransformer, List generatedClasses, Path outputPath, String decisionBaseClass) { - this.logger.debug(String.format("Generating code for BKM '%s'", bkm.getName())); - - String bkmPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); - String bkmClassName = dmnTransformer.drgElementClassName(bkm); - TemplateProvider templateProvider = this.templateProcessor.getTemplateProvider(); - checkDuplicate(generatedClasses, bkmPackageName, bkmClassName, dmnTransformer); - this.templateProcessor.processTemplate(definitions, bkm, templateProvider.baseTemplatePath(), templateProvider.bkmTemplateName(), dmnTransformer, outputPath, bkmPackageName, bkmClassName, decisionBaseClass); - - if (dmnTransformer.getDMNModelRepository().isDecisionTableExpression(bkm)) { - String decisionRuleOutputClassName = dmnTransformer.ruleOutputClassName(bkm); - checkDuplicate(generatedClasses, bkmPackageName, decisionRuleOutputClassName, dmnTransformer); - this.templateProcessor.processTemplate(definitions, bkm, templateProvider.baseTemplatePath(), templateProvider.decisionTableRuleOutputTemplate(), dmnTransformer, outputPath, bkmPackageName, decisionRuleOutputClassName, decisionBaseClass); - } - } - - private void transformDSList(TDefinitions definitions, List dsList, BasicDMNToNativeTransformer dmnTransformer, List generatedClasses, Path outputPath) { - for (TDecisionService ds : dsList) { - transformDS(definitions, ds, dmnTransformer, generatedClasses, outputPath, this.decisionBaseClass); - } - } - - private void transformDS(TDefinitions definitions, TDecisionService ds, BasicDMNToNativeTransformer dmnTransformer, List generatedClasses, Path outputPath, String decisionBaseClass) { - this.logger.debug(String.format("Generating code for DS '%s'", ds.getName())); - - String dsPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); - String dsClassName = dmnTransformer.drgElementClassName(ds); - TemplateProvider templateProvider = this.templateProcessor.getTemplateProvider(); - checkDuplicate(generatedClasses, dsPackageName, dsClassName, dmnTransformer); - this.templateProcessor.processTemplate(definitions, ds, templateProvider.baseTemplatePath(), templateProvider.dsTemplateName(), dmnTransformer, outputPath, dsPackageName, dsClassName, decisionBaseClass); - } - - private void transformDecisionList(TDefinitions definitions, List decisions, BasicDMNToNativeTransformer dmnTransformer, List generatedClasses, Path outputPath, String decisionBaseClass) { - for (TDecision decision : decisions) { - transformDecision(definitions, decision, dmnTransformer, generatedClasses, outputPath, decisionBaseClass); - } - } - - private void transformDecision(TDefinitions definitions, TDecision decision, BasicDMNToNativeTransformer dmnTransformer, List generatedClasses, Path outputPath, String decisionBaseClass) { - this.logger.debug(String.format("Generating code for Decision '%s'", decision.getName())); - - String decisionPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); - String decisionClassName = dmnTransformer.drgElementClassName(decision); - TemplateProvider templateProvider = this.templateProcessor.getTemplateProvider(); - checkDuplicate(generatedClasses, decisionPackageName, decisionClassName, dmnTransformer); - this.templateProcessor.processTemplate(definitions, decision, templateProvider.baseTemplatePath(), templateProvider.decisionTemplateName(), dmnTransformer, outputPath, decisionPackageName, decisionClassName, decisionBaseClass); - - if (dmnTransformer.getDMNModelRepository().isDecisionTableExpression(decision)) { - String decisionRuleOutputClassName = dmnTransformer.ruleOutputClassName(decision); - checkDuplicate(generatedClasses, decisionPackageName, decisionRuleOutputClassName, dmnTransformer); - this.templateProcessor.processTemplate(definitions, decision, templateProvider.baseTemplatePath(), templateProvider.decisionTableRuleOutputTemplate(), dmnTransformer, outputPath, decisionPackageName, decisionRuleOutputClassName, decisionBaseClass); - } - } - private void generateProtoFile(TDefinitions definitions, BasicDMNToNativeTransformer dmnTransformer, Path outputPath) { Pair, List>, List> pair = dmnTransformer.dmnToProto(definitions); if (pair == null) { @@ -257,13 +147,4 @@ private void generateRegistry(List definitionsList, BasicDMNToNati protected void generateExtra(BasicDMNToNativeTransformer dmnTransformer, DMNModelRepository dmnModelRepository, Path outputPath) { } - - private void checkDuplicate(List generatedClasses, String pkg, String className, BasicDMNToNativeTransformer dmnTransformer) { - String qualifiedName = dmnTransformer.qualifiedName(pkg, className); - if (generatedClasses.contains(qualifiedName)) { - throw new DMNRuntimeException(String.format("Class '%s' has already been generated", qualifiedName)); - } else { - generatedClasses.add(qualifiedName); - } - } } diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/DMNToNativeVisitor.java b/dmn-core/src/main/java/com/gs/dmn/transformation/DMNToNativeVisitor.java new file mode 100644 index 000000000..5e68408a3 --- /dev/null +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/DMNToNativeVisitor.java @@ -0,0 +1,180 @@ +/* + * Copyright 2016 Goldman Sachs. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.gs.dmn.transformation; + +import com.gs.dmn.DMNModelRepository; +import com.gs.dmn.ast.*; +import com.gs.dmn.ast.visitor.TraversalVisitor; +import com.gs.dmn.context.DMNContext; +import com.gs.dmn.el.analysis.semantics.type.Type; +import com.gs.dmn.error.LogErrorHandler; +import com.gs.dmn.log.BuildLogger; +import com.gs.dmn.runtime.DMNRuntimeException; +import com.gs.dmn.transformation.basic.BasicDMNToNativeTransformer; + +import java.nio.file.Path; +import java.util.List; + +public class DMNToNativeVisitor extends TraversalVisitor { + private final BasicDMNToNativeTransformer dmnTransformer; + private final DMNModelRepository dmnModelRepository; + private final TemplateProcessor templateProcessor; + private final Path outputPath; + private final List generatedClasses; + private final String decisionBaseClass; + + public DMNToNativeVisitor(BuildLogger logger, LogErrorHandler errorHandler, BasicDMNToNativeTransformer dmnTransformer, DMNModelRepository dmnModelRepository, TemplateProcessor templateProcessor, Path outputPath, List generatedClasses, String decisionBaseClass) { + super(logger, errorHandler); + this.dmnTransformer = dmnTransformer; + this.dmnModelRepository = dmnModelRepository; + this.templateProcessor = templateProcessor; + this.outputPath = outputPath; + this.generatedClasses = generatedClasses; + this.decisionBaseClass = decisionBaseClass; + } + + @Override + public DMNBaseElement visit(TDefinitions element, NativeVisitorContext context) { + // Generate data types + List itemDefinitions = dmnModelRepository.findItemDefinitions(element); + if (itemDefinitions != null) { + for (TItemDefinition itemDefinition : itemDefinitions) { + itemDefinition.accept(this, context); + } + } + + // Generate BKMs + List businessKnowledgeModels = dmnModelRepository.findBKMs(element); + for (TBusinessKnowledgeModel bkm : businessKnowledgeModels) { + bkm.accept(this, context); + } + + // Generate DSs + List decisionServices = dmnModelRepository.findDSs(element); + for (TDecisionService ds : decisionServices) { + ds.accept(this, context); + } + + // Generate decisions + List decisions = dmnModelRepository.findDecisions(element); + for (TDecision decision : decisions) { + decision.accept(this, context); + } + + return element; + } + + @Override + public DMNBaseElement visit(TItemDefinition element, NativeVisitorContext context) { + if (element == null) { + return element; + } + + TDefinitions definitions = context.getDefinitions(); + + // Complex type + if (dmnTransformer.getDMNModelRepository().hasComponents(element)) { + this.logger.debug(String.format("Generating code for ItemDefinition '%s'", element.getName())); + + String typePackageName = dmnTransformer.nativeTypePackageName(definitions.getName()); + + // Generate interface and class + String javaInterfaceName = dmnTransformer.itemDefinitionNativeSimpleInterfaceName(element); + transformItemDefinition(definitions, element, dmnTransformer, templateProcessor.getTemplateProvider().baseTemplatePath(), templateProcessor.getTemplateProvider().itemDefinitionInterfaceTemplate(), generatedClasses, outputPath, typePackageName, javaInterfaceName); + transformItemDefinition(definitions, element, dmnTransformer, templateProcessor.getTemplateProvider().baseTemplatePath(), templateProcessor.getTemplateProvider().itemDefinitionClassTemplate(), generatedClasses, outputPath, typePackageName, dmnTransformer.itemDefinitionNativeClassName(javaInterfaceName)); + + // Process children + List itemDefinitionList = element.getItemComponent(); + if (itemDefinitionList != null) { + for (TItemDefinition itemDefinition1 : itemDefinitionList) { + itemDefinition1.accept(this, context); + } + } + } + + return element; + } + + private void transformItemDefinition(TDefinitions definitions, TItemDefinition itemDefinition, BasicDMNToNativeTransformer dmnTransformer, String baseTemplatePath, String itemDefinitionTemplate, List generatedClasses, Path outputPath, String typePackageName, String typeName) { + String qualifiedName = dmnTransformer.qualifiedName(typePackageName, typeName); + if (generatedClasses.contains(qualifiedName)) { + this.logger.warn(String.format("Class '%s' has already been generated", typeName)); + } else { + templateProcessor.processTemplate(definitions, itemDefinition, baseTemplatePath, itemDefinitionTemplate, dmnTransformer, outputPath, typePackageName, typeName); + generatedClasses.add(qualifiedName); + } + } + + @Override + public DMNBaseElement visit(TBusinessKnowledgeModel element, NativeVisitorContext context) { + this.logger.debug(String.format("Generating code for BKM '%s'", element.getName())); + + TDefinitions definitions = context.getDefinitions(); + + String bkmPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); + String bkmClassName = dmnTransformer.drgElementClassName(element); + checkDuplicate(generatedClasses, bkmPackageName, bkmClassName, dmnTransformer); + templateProcessor.processTemplate(definitions, element, templateProcessor.getTemplateProvider().baseTemplatePath(), templateProcessor.getTemplateProvider().bkmTemplateName(), dmnTransformer, outputPath, bkmPackageName, bkmClassName, decisionBaseClass); + + if (dmnTransformer.getDMNModelRepository().isDecisionTableExpression(element)) { + String decisionRuleOutputClassName = dmnTransformer.ruleOutputClassName(element); + checkDuplicate(generatedClasses, bkmPackageName, decisionRuleOutputClassName, dmnTransformer); + templateProcessor.processTemplate(definitions, element, templateProcessor.getTemplateProvider().baseTemplatePath(), templateProcessor.getTemplateProvider().decisionTableRuleOutputTemplate(), dmnTransformer, outputPath, bkmPackageName, decisionRuleOutputClassName, decisionBaseClass); + } + + return element; + } + + @Override + public DMNBaseElement visit(TDecisionService element, NativeVisitorContext context) { + this.logger.debug(String.format("Generating code for DS '%s'", element.getName())); + + TDefinitions definitions = context.getDefinitions(); + + String dsPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); + String dsClassName = dmnTransformer.drgElementClassName(element); + checkDuplicate(generatedClasses, dsPackageName, dsClassName, dmnTransformer); + templateProcessor.processTemplate(definitions, element, templateProcessor.getTemplateProvider().baseTemplatePath(), templateProcessor.getTemplateProvider().dsTemplateName(), dmnTransformer, outputPath, dsPackageName, dsClassName, decisionBaseClass); + + return element; + } + + @Override + public DMNBaseElement visit(TDecision element, NativeVisitorContext context) { + this.logger.debug(String.format("Generating code for Decision '%s'", element.getName())); + + TDefinitions definitions = context.getDefinitions(); + + String decisionPackageName = dmnTransformer.nativeModelPackageName(definitions.getName()); + String decisionClassName = dmnTransformer.drgElementClassName(element); + checkDuplicate(generatedClasses, decisionPackageName, decisionClassName, dmnTransformer); + templateProcessor.processTemplate(definitions, element, templateProcessor.getTemplateProvider().baseTemplatePath(), templateProcessor.getTemplateProvider().decisionTemplateName(), dmnTransformer, outputPath, decisionPackageName, decisionClassName, decisionBaseClass); + + if (dmnTransformer.getDMNModelRepository().isDecisionTableExpression(element)) { + String decisionRuleOutputClassName = dmnTransformer.ruleOutputClassName(element); + checkDuplicate(generatedClasses, decisionPackageName, decisionRuleOutputClassName, dmnTransformer); + templateProcessor.processTemplate(definitions, element, templateProcessor.getTemplateProvider().baseTemplatePath(), templateProcessor.getTemplateProvider().decisionTableRuleOutputTemplate(), dmnTransformer, outputPath, decisionPackageName, decisionRuleOutputClassName, decisionBaseClass); + } + + return element; + } + + private void checkDuplicate(List generatedClasses, String pkg, String className, BasicDMNToNativeTransformer dmnTransformer) { + String qualifiedName = dmnTransformer.qualifiedName(pkg, className); + if (generatedClasses.contains(qualifiedName)) { + throw new DMNRuntimeException(String.format("Class '%s' has already been generated", qualifiedName)); + } else { + generatedClasses.add(qualifiedName); + } + } +} diff --git a/dmn-core/src/main/java/com/gs/dmn/transformation/NativeVisitorContext.java b/dmn-core/src/main/java/com/gs/dmn/transformation/NativeVisitorContext.java new file mode 100644 index 000000000..823d7ec4a --- /dev/null +++ b/dmn-core/src/main/java/com/gs/dmn/transformation/NativeVisitorContext.java @@ -0,0 +1,27 @@ +/* + * Copyright 2016 Goldman Sachs. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.gs.dmn.transformation; + +import com.gs.dmn.ast.TDefinitions; + +public class NativeVisitorContext { + public NativeVisitorContext(TDefinitions definitions) { + this.definitions = definitions; + } + + private final TDefinitions definitions; + + public TDefinitions getDefinitions() { + return definitions; + } +}