Skip to content

Commit

Permalink
Each element should return a map instead of JSON string where possible
Browse files Browse the repository at this point in the history
to make accessing the JSON easier in MVEL elements.
No two elements should have two names.
  • Loading branch information
Rikkola authored and lucamolteni committed Jun 4, 2024
1 parent 886b787 commit 6d88ca7
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 21 deletions.
13 changes: 7 additions & 6 deletions yard-core/src/main/java/org/kie/yard/core/DTableUnitBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,14 @@ private OnExecute getExecutionAction(String hitPolicy) {
if (hitPolicy == null || Objects.equals("ANY", hitPolicy)) {
return (ruleDefinition, storeHandle) -> {
final RuleCell rc = parseGenericRuleThen(ruleDefinition);
storeHandle.set(rc.value);
Object value = resolveValue(rc.value);
storeHandle.set(value);
};
} else if (Objects.equals("FIRST", hitPolicy)) {
return (ruleDefinition, storeHandle) -> {
if (!storeHandle.isValuePresent()) {
final RuleCell rc = parseGenericRuleThen(ruleDefinition);
storeHandle.set(rc.value);
storeHandle.set(resolveValue(rc.value));
}
};
} else if (Objects.equals("COLLECT", hitPolicy)) {
Expand All @@ -102,22 +103,22 @@ private OnExecute getExecutionAction(String hitPolicy) {
final RuleCell rc = parseGenericRuleThen(ruleDefinition);

if (storeHandle.get() instanceof List list) {
list.add(resolveValue(rc));
list.add(resolveValue(rc.value));
}
};
} else {
throw new UnsupportedOperationException("Not implemented ");
}
}

private Object resolveValue(final RuleCell rc) {
private Object resolveValue(Object value) {
try {
if (rc.value instanceof String text) {
if (value instanceof String text) {
return jsonMapper.readValue(text, Map.class);
}
} catch (JsonProcessingException ignored) {
}
return rc.value;
return value;
}

private RuleCell parseGenericRuleThen(Rule rule) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@
*/
package org.kie.yard.core;

import javax.script.*;
import java.util.Map;
import java.util.Map.Entry;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class JShellLiteralExpressionInterpreter implements Firable {

private final String name;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.kie.yard.core;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import org.mvel2.MVEL;

import java.util.HashMap;
Expand All @@ -9,6 +29,8 @@ public class MVELLiteralExpressionInterpreter implements Firable {
private final String name;
private final QuotedExprParsed expr;

private final JsonMapper jsonMapper = JsonMapper.builder().build();

public MVELLiteralExpressionInterpreter(final String name,
final QuotedExprParsed expr) {
this.name = name;
Expand All @@ -31,11 +53,20 @@ public int fire(final Map<String, Object> context,
try {
String rewrittenExpression = expr.getRewrittenExpression();
final Object result = MVEL.eval(rewrittenExpression, internalContext);
units.outputs().get(name).set(result);
units.outputs().get(name).set(resolveValue(result));
return 1;
} catch (Exception e) {
throw new RuntimeException("interpretation failed at runtime", e);
// TODO why throw and not return 0?
}
}

private Object resolveValue(Object value) {
try {
if (value instanceof String text) {
return jsonMapper.readValue(text, Map.class);
}
} catch (JsonProcessingException ignored) {
}
return value;
}
}
15 changes: 10 additions & 5 deletions yard-core/src/main/java/org/kie/yard/core/YaRDParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

import org.drools.ruleunits.api.DataSource;
import org.kie.yard.api.model.DecisionLogic;
Expand Down Expand Up @@ -71,8 +70,8 @@ private String read(Reader reader) throws Exception {
int numRead;
while ((numRead = reader.read(buf)) != -1) {
String readData = String.valueOf(buf,
0,
numRead);
0,
numRead);
fileData.append(readData);
buf = new char[1024];
}
Expand All @@ -92,10 +91,16 @@ private YaRDDefinitions parse(String yaml) throws IOException {
}

private void appendUnits(List<Element> list) {
final List<String> existingNames = new ArrayList<>();
for (Element hi : list) {
String nameString = hi.getName();
final String nameString = hi.getName();
if (existingNames.contains(nameString)) {
throw new IllegalArgumentException("Two element definitions with the same name are not allowed.");
} else {
existingNames.add(nameString);
}
LOG.debug("parsing {}", nameString);
Firable decisionLogic = createDecisionLogic(nameString, hi.getLogic());
final Firable decisionLogic = createDecisionLogic(nameString, hi.getLogic());
definitions.units().add(decisionLogic);
}
}
Expand Down
6 changes: 3 additions & 3 deletions yard-core/src/main/java/org/kie/yard/core/YaRDRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,22 @@

public class YaRDRunner {

private final YaRDDefinitions units;
private final YaRDDefinitions definitions;
private final JsonMapper jsonMapper = JsonMapper.builder().build();
private final String name;

public YaRDRunner(final String yaml) throws IOException {
final YaRDParser parser = new YaRDParser(yaml);
name = parser.getModel().getName();
units = parser.getDefinitions();
definitions = parser.getDefinitions();
}

public String getName() {
return name;
}

public Map<String, Object> evaluate(final Map<String, Object> map) {
return units.evaluate(map);
return definitions.evaluate(map);
}

public String evaluate(String jsonInputCxt) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@

import java.util.Map;

import com.fasterxml.jackson.databind.json.JsonMapper;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class DomesticPackagePricesTest
extends TestBase {
Expand All @@ -41,7 +40,8 @@ public void testMPackage() throws Exception {
}
""";
Map<String, Object> outputJSONasMap = evaluate(CTX, FILE_NAME);
assertThat(outputJSONasMap).hasFieldOrPropertyWithValue("Package", "{ \"Size\": \"M\", \"Cost\": 6.90 }");
assertEquals(6.9, ((Map) outputJSONasMap.get("Package")).get("Cost"));
assertEquals("M", ((Map) outputJSONasMap.get("Package")).get("Size"));
}

@Test
Expand All @@ -55,6 +55,7 @@ public void testLPackage() throws Exception {
}
""";
Map<String, Object> outputJSONasMap = evaluate(CTX, FILE_NAME);
assertThat(outputJSONasMap).hasFieldOrPropertyWithValue("Package", "{ \"Size\": \"L\", \"Cost\": 8.90 }");
assertEquals(8.9, ((Map) outputJSONasMap.get("Package")).get("Cost"));
assertEquals("L", ((Map) outputJSONasMap.get("Package")).get("Size"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.kie.yard.core;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertThrows;

public class DublicateElementNameTest
extends TestBase {

private static final String FILE_NAME = "/two-elements-with-duplicate-name.yml";

@Test
public void testNoDublicateNames() throws Exception {
final String CTX = """
{
"Age": 10
}
""";
assertThrows(IllegalArgumentException.class, () ->
evaluate(CTX, FILE_NAME)
);
}
}
59 changes: 59 additions & 0 deletions yard-core/src/test/java/org/kie/yard/core/MVELJSONTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.kie.yard.core;

import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class MVELJSONTest
extends TestBase {

private static final String FILE_NAME = "/mvel-json-dot-access.yml";

@Test
public void testMVELManagesJSONMaps() throws Exception {
final String CTX = """
{
"Work Address":true
}
""";
final Map<String, Object> output = evaluate(CTX, FILE_NAME);

final Map mailingAddress = (Map) output.get("Mailing Address");
assertEquals("Work Street", mailingAddress.get("Street"));
assertEquals(23, mailingAddress.get("Number"));

final List deliveryItemNames = (List) output.get("Delivery Item Names");
assertEquals(3, deliveryItemNames.size());
assertTrue(deliveryItemNames.contains("Work Shoes"));
assertTrue(deliveryItemNames.contains("Work Hat"));
assertTrue(deliveryItemNames.contains("Work Shirt"));

final Map JSONTest= (Map) output.get("JSON Test");
assertEquals("Best Company LTD", JSONTest.get("Company"));

final Map mapTest = (Map) output.get("Map Test");
assertEquals("Hello", mapTest.get("Map"));
}
}
Loading

0 comments on commit 6d88ca7

Please sign in to comment.