diff --git a/pom.xml b/pom.xml
index a8063a6..99666e1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -108,6 +108,13 @@
provided
+
+
+ org.codehaus.groovy
+ groovy-all
+ ${groovy.version}
+
+
org.spockframework
@@ -121,12 +128,6 @@
${cglib.version}test
-
- org.codehaus.groovy
- groovy-all
- ${groovy.version}
- test
- org.objenesisobjenesis
diff --git a/src/main/java/org/powerflows/dmn/engine/configuration/DefaultDecisionEngineConfiguration.java b/src/main/java/org/powerflows/dmn/engine/configuration/DefaultDecisionEngineConfiguration.java
index 742ef6a..ed58371 100644
--- a/src/main/java/org/powerflows/dmn/engine/configuration/DefaultDecisionEngineConfiguration.java
+++ b/src/main/java/org/powerflows/dmn/engine/configuration/DefaultDecisionEngineConfiguration.java
@@ -17,34 +17,40 @@
package org.powerflows.dmn.engine.configuration;
+import lombok.Setter;
+import lombok.experimental.Accessors;
import org.powerflows.dmn.engine.DecisionEngine;
import org.powerflows.dmn.engine.DefaultDecisionEngine;
import org.powerflows.dmn.engine.evaluator.decision.DecisionEvaluator;
import org.powerflows.dmn.engine.evaluator.entry.InputEntryEvaluator;
import org.powerflows.dmn.engine.evaluator.entry.OutputEntryEvaluator;
import org.powerflows.dmn.engine.evaluator.entry.mode.provider.EvaluationModeProviderFactory;
-import org.powerflows.dmn.engine.evaluator.expression.provider.ExpressionEvaluationProviderFactory;
-import org.powerflows.dmn.engine.evaluator.expression.script.DefaultScriptEngineProvider;
-import org.powerflows.dmn.engine.evaluator.expression.script.ScriptEngineProvider;
+import org.powerflows.dmn.engine.evaluator.expression.provider.DefaultExpressionEvaluationProviderFactory;
+import org.powerflows.dmn.engine.evaluator.expression.provider.ExpressionEvaluationConfiguration;
+import org.powerflows.dmn.engine.evaluator.expression.provider.binding.MethodBinding;
import org.powerflows.dmn.engine.evaluator.rule.RuleEvaluator;
import org.powerflows.dmn.engine.evaluator.type.converter.TypeConverterFactory;
-import javax.script.ScriptEngineManager;
+import java.util.Collections;
+import java.util.List;
+@Accessors(chain = true, fluent = true)
public class DefaultDecisionEngineConfiguration implements DecisionEngineConfiguration {
+ @Setter
+ private List methodBindings = Collections.emptyList();
+ private ExpressionEvaluationConfiguration configuration;
private DecisionEvaluator decisionEvaluator;
private RuleEvaluator ruleEvaluator;
private EvaluationModeProviderFactory evaluationModeProviderFactory;
private InputEntryEvaluator inputEntryEvaluator;
private OutputEntryEvaluator outputEntryEvaluator;
- private ScriptEngineProvider scriptEngineProvider;
- private ExpressionEvaluationProviderFactory expressionEvaluationProviderFactory;
+ private DefaultExpressionEvaluationProviderFactory expressionEvaluationProviderFactory;
private TypeConverterFactory typeConverterFactory;
@Override
public DecisionEngine configure() {
- initScriptEngineProvider();
+ initExpressionEvaluation();
initEvaluationProviderFactory();
initTypeConverterFactory();
initEvaluationModeProviderFactory();
@@ -56,18 +62,20 @@ public DecisionEngine configure() {
return new DefaultDecisionEngine(decisionEvaluator);
}
+ private void initExpressionEvaluation() {
+ configuration = ExpressionEvaluationConfiguration.builder()
+ .methodBinding(methodBindings)
+ .build();
+ }
+
private void initEvaluationProviderFactory() {
- expressionEvaluationProviderFactory = new ExpressionEvaluationProviderFactory(scriptEngineProvider);
+ expressionEvaluationProviderFactory = new DefaultExpressionEvaluationProviderFactory(configuration);
}
private void initTypeConverterFactory() {
typeConverterFactory = new TypeConverterFactory();
}
- private void initScriptEngineProvider() {
- scriptEngineProvider = new DefaultScriptEngineProvider(new ScriptEngineManager());
- }
-
private void initEvaluationModeProviderFactory() {
evaluationModeProviderFactory = new EvaluationModeProviderFactory();
}
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/entry/InputEntryEvaluator.java b/src/main/java/org/powerflows/dmn/engine/evaluator/entry/InputEntryEvaluator.java
index e8edd43..d6e0a0a 100644
--- a/src/main/java/org/powerflows/dmn/engine/evaluator/entry/InputEntryEvaluator.java
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/entry/InputEntryEvaluator.java
@@ -22,7 +22,7 @@
import org.powerflows.dmn.engine.evaluator.entry.mode.provider.EvaluationModeProvider;
import org.powerflows.dmn.engine.evaluator.entry.mode.provider.EvaluationModeProviderFactory;
import org.powerflows.dmn.engine.evaluator.expression.provider.ExpressionEvaluationProvider;
-import org.powerflows.dmn.engine.evaluator.expression.provider.ExpressionEvaluationProviderFactory;
+import org.powerflows.dmn.engine.evaluator.expression.provider.DefaultExpressionEvaluationProviderFactory;
import org.powerflows.dmn.engine.evaluator.type.converter.TypeConverter;
import org.powerflows.dmn.engine.evaluator.type.converter.TypeConverterFactory;
import org.powerflows.dmn.engine.evaluator.type.value.SpecifiedTypeValue;
@@ -36,12 +36,12 @@
@Slf4j
public class InputEntryEvaluator {
- private final ExpressionEvaluationProviderFactory expressionEvaluationProviderFactory;
+ private final DefaultExpressionEvaluationProviderFactory expressionEvaluationProviderFactory;
private final TypeConverterFactory typeConverterFactory;
private final EvaluationModeProviderFactory evaluationModeProviderFactory;
- public InputEntryEvaluator(final ExpressionEvaluationProviderFactory expressionEvaluationProviderFactory,
+ public InputEntryEvaluator(final DefaultExpressionEvaluationProviderFactory expressionEvaluationProviderFactory,
final TypeConverterFactory typeConverterFactory,
final EvaluationModeProviderFactory evaluationModeProviderFactory) {
this.expressionEvaluationProviderFactory = expressionEvaluationProviderFactory;
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/entry/OutputEntryEvaluator.java b/src/main/java/org/powerflows/dmn/engine/evaluator/entry/OutputEntryEvaluator.java
index 9560032..676959e 100644
--- a/src/main/java/org/powerflows/dmn/engine/evaluator/entry/OutputEntryEvaluator.java
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/entry/OutputEntryEvaluator.java
@@ -20,7 +20,7 @@
import lombok.extern.slf4j.Slf4j;
import org.powerflows.dmn.engine.evaluator.context.EvaluationContext;
import org.powerflows.dmn.engine.evaluator.expression.provider.ExpressionEvaluationProvider;
-import org.powerflows.dmn.engine.evaluator.expression.provider.ExpressionEvaluationProviderFactory;
+import org.powerflows.dmn.engine.evaluator.expression.provider.DefaultExpressionEvaluationProviderFactory;
import org.powerflows.dmn.engine.evaluator.type.converter.TypeConverter;
import org.powerflows.dmn.engine.evaluator.type.converter.TypeConverterFactory;
import org.powerflows.dmn.engine.model.decision.field.Output;
@@ -32,10 +32,10 @@
@Slf4j
public class OutputEntryEvaluator {
- private final ExpressionEvaluationProviderFactory expressionEvaluationProviderFactory;
+ private final DefaultExpressionEvaluationProviderFactory expressionEvaluationProviderFactory;
private final TypeConverterFactory typeConverterFactory;
- public OutputEntryEvaluator(ExpressionEvaluationProviderFactory expressionEvaluationProviderFactory,
+ public OutputEntryEvaluator(DefaultExpressionEvaluationProviderFactory expressionEvaluationProviderFactory,
final TypeConverterFactory typeConverterFactory) {
this.expressionEvaluationProviderFactory = expressionEvaluationProviderFactory;
this.typeConverterFactory = typeConverterFactory;
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/DefaultExpressionEvaluationProviderFactory.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/DefaultExpressionEvaluationProviderFactory.java
new file mode 100644
index 0000000..a7de1bd
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/DefaultExpressionEvaluationProviderFactory.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider;
+
+import lombok.extern.slf4j.Slf4j;
+import org.powerflows.dmn.engine.model.decision.expression.ExpressionType;
+
+import java.util.EnumMap;
+import java.util.Optional;
+import java.util.ServiceLoader;
+
+@Slf4j
+public class DefaultExpressionEvaluationProviderFactory {
+
+ private static final ServiceLoader serviceLoader = ServiceLoader.load(ExpressionEvaluationProviderFactory.class);
+
+ private final EnumMap factories = new EnumMap<>(ExpressionType.class);
+
+ private final EnumMap providers = new EnumMap<>(ExpressionType.class);
+ private final ExpressionEvaluationConfiguration configuration;
+
+
+ public DefaultExpressionEvaluationProviderFactory() {
+ this(ExpressionEvaluationConfiguration.simpleConfiguration());
+ }
+
+ public DefaultExpressionEvaluationProviderFactory(final ExpressionEvaluationConfiguration configuration) {
+ this.configuration = configuration;
+ serviceLoader.forEach(provider ->
+ provider.supportedExpressionTypes()
+ .forEach(type -> {
+ log.debug("Found ExpressionEvaluationProvider for type {} - {}", type, provider);
+ factories.put(type, provider);
+ }
+ )
+ );
+ }
+
+ public ExpressionEvaluationProvider getInstance(final ExpressionType expressionType) {
+ final ExpressionEvaluationProvider expressionEvaluationProvider = providers.computeIfAbsent(expressionType, key -> Optional
+ .ofNullable(factories.get(key))
+ .map(factory -> factory.createProvider(configuration))
+ .orElse(null)
+ );
+
+ if (expressionEvaluationProvider == null) {
+ throw new IllegalArgumentException("Unknown expression type " + expressionType);
+ }
+
+ return expressionEvaluationProvider;
+ }
+}
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ExpressionEvaluationConfiguration.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ExpressionEvaluationConfiguration.java
new file mode 100644
index 0000000..322b71c
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ExpressionEvaluationConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider;
+
+import lombok.Builder;
+import lombok.Getter;
+import org.powerflows.dmn.engine.evaluator.expression.provider.binding.MethodBinding;
+
+import javax.script.ScriptEngineManager;
+import java.util.Collections;
+import java.util.List;
+
+@Getter
+@Builder
+public class ExpressionEvaluationConfiguration {
+
+ private final List methodBinding;
+ private final ScriptEngineManager scriptEngineManager;
+
+ private ExpressionEvaluationConfiguration(final List methodBinding, final ScriptEngineManager scriptEngineManager) {
+ this.methodBinding = methodBinding == null ? Collections.emptyList() : methodBinding;
+ this.scriptEngineManager = scriptEngineManager == null ? new ScriptEngineManager() : scriptEngineManager;
+ }
+
+ public static ExpressionEvaluationConfiguration simpleConfiguration() {
+ return ExpressionEvaluationConfiguration.builder().build();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ExpressionEvaluationProviderFactory.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ExpressionEvaluationProviderFactory.java
index 273c95f..25ed39d 100644
--- a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ExpressionEvaluationProviderFactory.java
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ExpressionEvaluationProviderFactory.java
@@ -13,35 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.powerflows.dmn.engine.evaluator.expression.provider;
-import org.powerflows.dmn.engine.evaluator.expression.script.ScriptEngineProvider;
import org.powerflows.dmn.engine.model.decision.expression.ExpressionType;
-import java.util.EnumMap;
-
-public class ExpressionEvaluationProviderFactory {
-
- private final EnumMap factories = new EnumMap<>(ExpressionType.class);
-
- public ExpressionEvaluationProviderFactory(final ScriptEngineProvider scriptEngineProvider) {
- final ExpressionEvaluationProvider scriptExpressionEvaluationProvider = new ScriptExpressionEvaluationProvider(scriptEngineProvider);
-
- factories.put(ExpressionType.LITERAL, new LiteralExpressionEvaluationProvider());
- factories.put(ExpressionType.FEEL, new FeelExpressionEvaluationProvider());
- factories.put(ExpressionType.JUEL, new JuelExpressionEvaluationProvider());
- factories.put(ExpressionType.GROOVY, scriptExpressionEvaluationProvider);
- factories.put(ExpressionType.JAVASCRIPT, scriptExpressionEvaluationProvider);
- }
-
- public ExpressionEvaluationProvider getInstance(final ExpressionType expressionType) {
- final ExpressionEvaluationProvider expressionEvaluationProvider = factories.get(expressionType);
+import java.util.List;
- if (expressionEvaluationProvider == null) {
- throw new IllegalArgumentException("Unknown expression type " + expressionType);
- }
+public interface ExpressionEvaluationProviderFactory {
+ ExpressionEvaluationProvider createProvider(ExpressionEvaluationConfiguration configuration);
- return expressionEvaluationProvider;
- }
+ List supportedExpressionTypes();
}
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/FeelExpressionEvaluationProviderFactory.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/FeelExpressionEvaluationProviderFactory.java
new file mode 100644
index 0000000..4917472
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/FeelExpressionEvaluationProviderFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider;
+
+import org.powerflows.dmn.engine.model.decision.expression.ExpressionType;
+
+import java.util.Collections;
+import java.util.List;
+
+public class FeelExpressionEvaluationProviderFactory implements ExpressionEvaluationProviderFactory {
+ private static final List SUPPORTED = Collections.singletonList(ExpressionType.FEEL);
+
+ @Override
+ public ExpressionEvaluationProvider createProvider(final ExpressionEvaluationConfiguration configuration) {
+ return new FeelExpressionEvaluationProvider();
+ }
+
+ @Override
+ public List supportedExpressionTypes() {
+ return SUPPORTED;
+ }
+}
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/GroovyExpressionEvaluationProvider.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/GroovyExpressionEvaluationProvider.java
new file mode 100644
index 0000000..40b6590
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/GroovyExpressionEvaluationProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider;
+
+import lombok.extern.slf4j.Slf4j;
+import org.codehaus.groovy.runtime.MethodClosure;
+import org.powerflows.dmn.engine.evaluator.expression.provider.binding.MethodBinding;
+
+@Slf4j
+class GroovyExpressionEvaluationProvider extends ScriptEngineExpressionEvaluationProvider {
+
+ public GroovyExpressionEvaluationProvider(final ExpressionEvaluationConfiguration configuration) {
+ super(configuration);
+ }
+
+ @Override
+ protected Object createMethodBinding(final MethodBinding methodBinding) {
+ return new MethodClosure(methodBinding, "execute");
+ }
+
+ @Override
+ protected String getEngineName() {
+ return "groovy";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/GroovyExpressionEvaluationProviderFactory.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/GroovyExpressionEvaluationProviderFactory.java
new file mode 100644
index 0000000..213d4ae
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/GroovyExpressionEvaluationProviderFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider;
+
+import org.powerflows.dmn.engine.model.decision.expression.ExpressionType;
+
+import java.util.Collections;
+import java.util.List;
+
+public class GroovyExpressionEvaluationProviderFactory implements ExpressionEvaluationProviderFactory {
+ private static final List SUPPORTED = Collections.singletonList(ExpressionType.GROOVY);
+
+ @Override
+ public ExpressionEvaluationProvider createProvider(final ExpressionEvaluationConfiguration configuration) {
+ return new GroovyExpressionEvaluationProvider(configuration);
+ }
+
+ @Override
+ public List supportedExpressionTypes() {
+ return SUPPORTED;
+ }
+}
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/JavascriptExpressionEvaluationProvider.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/JavascriptExpressionEvaluationProvider.java
new file mode 100644
index 0000000..6effdc8
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/JavascriptExpressionEvaluationProvider.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider;
+
+import org.powerflows.dmn.engine.evaluator.expression.provider.binding.BoundMethod;
+import org.powerflows.dmn.engine.evaluator.expression.provider.binding.MethodBinding;
+
+class JavascriptExpressionEvaluationProvider extends ScriptEngineExpressionEvaluationProvider {
+
+ public JavascriptExpressionEvaluationProvider(final ExpressionEvaluationConfiguration configuration) {
+ super(configuration);
+ }
+
+ @Override
+ protected Object createMethodBinding(final MethodBinding methodBinding) {
+ return (BoundMethod) methodBinding::execute;
+ }
+
+ @Override
+ protected String getEngineName() {
+ return "javascript";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/JavascriptExpressionEvaluationProviderFactory.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/JavascriptExpressionEvaluationProviderFactory.java
new file mode 100644
index 0000000..5605505
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/JavascriptExpressionEvaluationProviderFactory.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider;
+
+import org.powerflows.dmn.engine.model.decision.expression.ExpressionType;
+
+import java.util.Collections;
+import java.util.List;
+
+public class JavascriptExpressionEvaluationProviderFactory implements ExpressionEvaluationProviderFactory {
+
+ private static final List SUPPORTED = Collections.singletonList(ExpressionType.JAVASCRIPT);
+
+ @Override
+ public ExpressionEvaluationProvider createProvider(final ExpressionEvaluationConfiguration configuration) {
+ return new JavascriptExpressionEvaluationProvider(configuration);
+ }
+
+ @Override
+ public List supportedExpressionTypes() {
+ return SUPPORTED;
+ }
+}
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/JuelExpressionEvaluationProviderFactory.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/JuelExpressionEvaluationProviderFactory.java
new file mode 100644
index 0000000..3f037e8
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/JuelExpressionEvaluationProviderFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider;
+
+import org.powerflows.dmn.engine.model.decision.expression.ExpressionType;
+
+import java.util.Collections;
+import java.util.List;
+
+public class JuelExpressionEvaluationProviderFactory implements ExpressionEvaluationProviderFactory {
+ private static final List SUPPORTED = Collections.singletonList(ExpressionType.JUEL);
+
+ @Override
+ public ExpressionEvaluationProvider createProvider(final ExpressionEvaluationConfiguration configuration) {
+ return new JuelExpressionEvaluationProvider();
+ }
+
+ @Override
+ public List supportedExpressionTypes() {
+ return SUPPORTED;
+ }
+}
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/LiteralExpressionEvaluationProviderFactory.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/LiteralExpressionEvaluationProviderFactory.java
new file mode 100644
index 0000000..19a944f
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/LiteralExpressionEvaluationProviderFactory.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider;
+
+import org.powerflows.dmn.engine.model.decision.expression.ExpressionType;
+
+import java.util.Collections;
+import java.util.List;
+
+public class LiteralExpressionEvaluationProviderFactory implements ExpressionEvaluationProviderFactory {
+ private static final List SUPPORTED = Collections.singletonList(ExpressionType.LITERAL);
+
+ @Override
+ public ExpressionEvaluationProvider createProvider(final ExpressionEvaluationConfiguration configuration) {
+ return new LiteralExpressionEvaluationProvider();
+ }
+
+ @Override
+ public List supportedExpressionTypes() {
+ return SUPPORTED;
+ }
+}
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ScriptExpressionEvaluationProvider.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ScriptEngineExpressionEvaluationProvider.java
similarity index 77%
rename from src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ScriptExpressionEvaluationProvider.java
rename to src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ScriptEngineExpressionEvaluationProvider.java
index 7725e23..85f6638 100644
--- a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ScriptExpressionEvaluationProvider.java
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/ScriptEngineExpressionEvaluationProvider.java
@@ -19,7 +19,7 @@
import lombok.extern.slf4j.Slf4j;
import org.powerflows.dmn.engine.evaluator.context.EvaluationContext;
import org.powerflows.dmn.engine.evaluator.exception.EvaluationException;
-import org.powerflows.dmn.engine.evaluator.expression.script.ScriptEngineProvider;
+import org.powerflows.dmn.engine.evaluator.expression.provider.binding.MethodBinding;
import org.powerflows.dmn.engine.evaluator.expression.script.bindings.ContextVariablesBindings;
import org.powerflows.dmn.engine.model.decision.expression.Expression;
import org.powerflows.dmn.engine.model.decision.field.Input;
@@ -27,20 +27,33 @@
import org.powerflows.dmn.engine.model.decision.rule.entry.OutputEntry;
import javax.script.Bindings;
+import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.io.Serializable;
-
+import java.util.stream.Collectors;
@Slf4j
-class ScriptExpressionEvaluationProvider implements ExpressionEvaluationProvider {
+public abstract class ScriptEngineExpressionEvaluationProvider implements ExpressionEvaluationProvider {
+ protected final ScriptEngine scriptEngine;
- private final ScriptEngineProvider scriptEngineProvider;
+ public ScriptEngineExpressionEvaluationProvider(final ExpressionEvaluationConfiguration configuration) {
+ scriptEngine = configuration.getScriptEngineManager().getEngineByName(getEngineName());
+ if (scriptEngine == null) {
+ throw new IllegalStateException("Unsupported script engine: " + getEngineName());
+ }
- public ScriptExpressionEvaluationProvider(final ScriptEngineProvider scriptEngineProvider) {
- this.scriptEngineProvider = scriptEngineProvider;
+ final Bindings bindings = scriptEngine.createBindings();
+ bindings.putAll(configuration.getMethodBinding()
+ .stream()
+ .collect(Collectors.toMap(MethodBinding::name, this::createMethodBinding)));
+ scriptEngine.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
}
+ protected abstract Object createMethodBinding(MethodBinding methodBinding);
+
+ protected abstract String getEngineName();
+
@Override
public Serializable evaluateInput(final Input input, final EvaluationContext evaluationContext) {
log.debug("Starting evaluation of input: {} with evaluation context: {}", input, evaluationContext);
@@ -75,14 +88,12 @@ public Serializable evaluateOutputEntry(final OutputEntry outputEntry, final Eva
}
private Serializable evaluate(final InputEntry inputEntry, final EvaluationContext evaluationContext) {
- final ScriptEngine scriptEngine = scriptEngineProvider.getScriptEngine(inputEntry.getExpression().getType());
final Bindings bindings = ContextVariablesBindings.create(scriptEngine.createBindings(), evaluationContext, inputEntry);
return evaluate(inputEntry.getExpression(), scriptEngine, bindings);
}
private Serializable evaluate(final Expression expression, final EvaluationContext evaluationContext) {
- final ScriptEngine scriptEngine = scriptEngineProvider.getScriptEngine(expression.getType());
final Bindings bindings = ContextVariablesBindings.create(scriptEngine.createBindings(), evaluationContext);
return evaluate(expression, scriptEngine, bindings);
diff --git a/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/binding/AbstractMethodBinding.java b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/binding/AbstractMethodBinding.java
new file mode 100644
index 0000000..15369eb
--- /dev/null
+++ b/src/main/java/org/powerflows/dmn/engine/evaluator/expression/provider/binding/AbstractMethodBinding.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018-present PowerFlows.org - all rights reserved.
+ *
+ * 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 org.powerflows.dmn.engine.evaluator.expression.provider.binding;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.function.Supplier;
+
+public abstract class AbstractMethodBinding implements MethodBinding {
+ private final String name;
+ private final Supplier