Skip to content

Commit

Permalink
Merge pull request #144 from powerflows/Undesirable-optionals-after-s…
Browse files Browse the repository at this point in the history
…ave-to-YAML-representation

Undesirable optionals after save to YAML representation. Resolved #137
  • Loading branch information
mariuszkumor authored Feb 2, 2019
2 parents b6194ac + 24e8f11 commit 3bbd681
Show file tree
Hide file tree
Showing 19 changed files with 485 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,15 @@ public class Decision implements Serializable {

private static final long serialVersionUID = 1;

public static final HitPolicy DEFAULT_HIT_POLICY = HitPolicy.UNIQUE;
public static final ExpressionType DEFAULT_EXPRESSION_TYPE = ExpressionType.LITERAL;
public static final EvaluationMode DEFAULT_EVALUATION_MODE = EvaluationMode.BOOLEAN;

private String id;
private String name;
private HitPolicy hitPolicy = HitPolicy.UNIQUE;
private ExpressionType expressionType = ExpressionType.LITERAL;
private EvaluationMode evaluationMode = EvaluationMode.BOOLEAN;
private HitPolicy hitPolicy = DEFAULT_HIT_POLICY;
private ExpressionType expressionType = DEFAULT_EXPRESSION_TYPE;
private EvaluationMode evaluationMode = DEFAULT_EVALUATION_MODE;
private List<Input> inputs = new ArrayList<>();
private List<Output> outputs = new ArrayList<>();
private List<Rule> rules = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private static void assignEntriesDefaults(final List<Input> inputs,
if (inputEntry.getExpression().getType() == null) {
setValue(expressionTypeField,
inputEntry.getExpression(),
inputsMap.get(inputEntry.getName()).getExpression().getType());
decisionExpressionType);
}

if (inputEntry.getEvaluationMode() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,6 @@ public B type(ExpressionType type) {

return (B) this;
}

@Override
protected Expression assembleProduct() {
if (product.type == null) {
product.type = ExpressionType.LITERAL;
}

return product;
}
}

public static class Builder extends ExpressionBuilder<Builder> {
Expand Down
21 changes: 13 additions & 8 deletions src/main/java/org/powerflows/dmn/io/yaml/CustomRepresenter.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/
package org.powerflows.dmn.io.yaml;

import org.powerflows.dmn.engine.model.decision.EvaluationMode;
import org.powerflows.dmn.engine.model.decision.expression.ExpressionType;
import org.powerflows.dmn.io.yaml.model.YamlDecision;
import org.powerflows.dmn.io.yaml.model.rule.entry.YamlInputEntry;
import org.powerflows.dmn.io.yaml.model.rule.entry.YamlOutputEntry;
Expand All @@ -42,20 +40,27 @@ class RepresentYamlInputEntry implements Represent {

@Override
public Node representData(Object data) {
if (data instanceof YamlInputEntry && ((YamlInputEntry) data).getExpressionType() == ExpressionType.LITERAL && ((YamlInputEntry) data).getEvaluationMode() == EvaluationMode.BOOLEAN) {
return represent(((YamlInputEntry) data).getExpression());
if (data instanceof YamlInputEntry) {
final YamlInputEntry yie = (YamlInputEntry) data;

if (yie.getEvaluationMode() == null && yie.getExpressionType() == null && yie.getNameAlias() == null) {
return represent(yie.getExpression());
}
}

return representJavaBean(getProperties(data.getClass()), data);
}
}

class RepresentYamlOutputEntry implements Represent {

@Override
public Node representData(Object data) {
if (data instanceof YamlOutputEntry && ((YamlOutputEntry) data).getExpressionType() == ExpressionType.LITERAL) {
return represent(((YamlOutputEntry) data).getExpression());
if (data instanceof YamlOutputEntry) {
final YamlOutputEntry yoe = (YamlOutputEntry) data;

if (yoe.getExpressionType() == null) {
return represent(yoe.getExpression());
}
}

return representJavaBean(getProperties(data.getClass()), data);
Expand All @@ -81,7 +86,7 @@ private boolean isEmpty(final Object propertyValue) {
} else if (propertyValue instanceof String) {
empty = ((String) propertyValue).isEmpty();
} else {
empty = propertyValue == ExpressionType.LITERAL || propertyValue == EvaluationMode.BOOLEAN;
empty = false;
}

return empty;
Expand Down
97 changes: 72 additions & 25 deletions src/main/java/org/powerflows/dmn/io/yaml/YamlDecisionConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@
package org.powerflows.dmn.io.yaml;

import org.powerflows.dmn.engine.model.decision.Decision;
import org.powerflows.dmn.engine.model.decision.EvaluationMode;
import org.powerflows.dmn.engine.model.decision.HitPolicy;
import org.powerflows.dmn.engine.model.decision.expression.ExpressionType;
import org.powerflows.dmn.engine.model.decision.field.Input;
import org.powerflows.dmn.engine.model.decision.field.Output;
import org.powerflows.dmn.engine.model.decision.rule.Rule;
import org.powerflows.dmn.engine.model.decision.rule.entry.InputEntry;
import org.powerflows.dmn.engine.model.decision.rule.entry.OutputEntry;
import org.powerflows.dmn.io.DecisionToExternalModelConverter;
import org.powerflows.dmn.io.yaml.model.YamlDecision;
import org.powerflows.dmn.io.yaml.model.field.YamlFields;
Expand All @@ -38,29 +42,56 @@
import java.util.stream.Collectors;

public class YamlDecisionConverter implements DecisionToExternalModelConverter<YamlDecision> {

@Override
public YamlDecision to(final Decision decision) {
final ExpressionType decisionExpressionType = findDecisionExpressionType(decision);
final EvaluationMode decisionEvaluationMode = Decision.DEFAULT_EVALUATION_MODE.equals(decision.getEvaluationMode()) ? null : decision.getEvaluationMode();
final HitPolicy decisionHitPolicy = Decision.DEFAULT_HIT_POLICY.equals(decision.getHitPolicy()) ? null : decision.getHitPolicy();

final YamlDecision yamlDecision = new YamlDecision();
yamlDecision.setId(decision.getId());
yamlDecision.setName(decision.getName());
yamlDecision.setExpressionType(decision.getExpressionType());
yamlDecision.setEvaluationMode(decision.getEvaluationMode());
yamlDecision.setHitPolicy(decision.getHitPolicy());
yamlDecision.setFields(createFields(decision.getInputs(), decision.getOutputs()));
yamlDecision.setExpressionType(Decision.DEFAULT_EXPRESSION_TYPE.equals(decisionExpressionType) ? null : decisionExpressionType);
yamlDecision.setEvaluationMode(decisionEvaluationMode);
yamlDecision.setHitPolicy(decisionHitPolicy);
yamlDecision.setFields(createFields(decision.getInputs(), decision.getOutputs(), decisionEvaluationMode, decisionExpressionType));

final Map<String, Input> inputsMap = decision.getInputs()
.stream()
.collect(Collectors.toMap(Input::getName, Function.identity()));

yamlDecision.setRules(decision.getRules()
.stream()
.map(rule -> ruleToYamlRule(rule, inputsMap))
.map(rule -> ruleToYamlRule(rule, inputsMap, decisionExpressionType))
.collect(Collectors.toList()));

return yamlDecision;
}

private YamlFields createFields(final List<Input> inputs, final List<Output> outputs) {
private ExpressionType findDecisionExpressionType(final Decision decision) {
final ExpressionType expressionType = decision.getRules().get(0).getInputEntries().get(0).getExpression().getType();

for (Rule rule : decision.getRules()) {
for (InputEntry inputEntry : rule.getInputEntries()) {
if (!expressionType.equals(inputEntry.getExpression().getType())) {
return decision.getExpressionType();
}
}
for (OutputEntry outputEntry : rule.getOutputEntries()) {
if (!expressionType.equals(outputEntry.getExpression().getType())) {
return decision.getExpressionType();
}
}
}

return expressionType;
}

private YamlFields createFields(final List<Input> inputs,
final List<Output> outputs,
final EvaluationMode decisionEvaluationMode,
final ExpressionType decisionExpressionType) {
final YamlFields yamlFields = new YamlFields();
final LinkedHashMap<String, YamlInput> in = new LinkedHashMap<>();
yamlFields.setIn(in);
Expand All @@ -71,19 +102,18 @@ private YamlFields createFields(final List<Input> inputs, final List<Output> out
final YamlInput yamlInput = new YamlInput();
yamlInput.setDescription(input.getDescription());
yamlInput.setType(input.getType());
yamlInput.setEvaluationMode(input.getEvaluationMode());

if (decisionEvaluationMode != null && !decisionEvaluationMode.equals(input.getEvaluationMode())) {
yamlInput.setEvaluationMode(input.getEvaluationMode());
}

if (!Input.DEFAULT_NAME_ALIAS.equals(input.getNameAlias())) {
yamlInput.setNameAlias(input.getNameAlias());
}

if (input.getExpression() != null && input.getExpression().getValue() != null) {
yamlInput.setExpression(input.getExpression().getValue());
yamlInput.setExpressionType(
input.getExpression().getType() == ExpressionType.LITERAL ? null : input
.getExpression()
.getType());

yamlInput.setExpression(input.getExpression().getValue());
if (!decisionExpressionType.equals(input.getExpression().getType())) {
yamlInput.setExpressionType(input.getExpression().getType());
}

in.put(input.getName(), yamlInput);
Expand All @@ -100,7 +130,7 @@ private YamlFields createFields(final List<Input> inputs, final List<Output> out
return yamlFields;
}

private YamlRule ruleToYamlRule(final Rule rule, final Map<String, Input> inputsMap) {
private YamlRule ruleToYamlRule(final Rule rule, final Map<String, Input> inputsMap, final ExpressionType decisionExpressionType) {
final YamlRule yamlRule = new YamlRule();
yamlRule.setDescription(rule.getDescription());
final LinkedHashMap<String, YamlInputEntry> in = new LinkedHashMap<>();
Expand All @@ -109,14 +139,20 @@ private YamlRule ruleToYamlRule(final Rule rule, final Map<String, Input> inputs
yamlRule.setOut(out);

rule.getInputEntries().forEach(inputEntry -> {
final Input input = inputsMap.get(inputEntry.getName());
final YamlInputEntry yamlInputEntry = new YamlInputEntry();
yamlInputEntry.setExpressionType(inputEntry.getExpression().getType());

yamlInputEntry.setExpression(inputEntry.getExpression().getValue());
yamlInputEntry.setEvaluationMode(inputEntry.getEvaluationMode());

final Input input = inputsMap.get(inputEntry.getName());
if (!inputEntry.getExpression().getType().equals(decisionExpressionType)) {
yamlInputEntry.setExpressionType(inputEntry.getExpression().getType());
}

if (inputEntry.getNameAlias() != null && !inputEntry.getNameAlias().equals(input.getNameAlias())) {
if (!input.getEvaluationMode().equals(inputEntry.getEvaluationMode())) {
yamlInputEntry.setEvaluationMode(inputEntry.getEvaluationMode());
}

if (!inputEntry.getNameAlias().equals(input.getNameAlias())) {
yamlInputEntry.setNameAlias(inputEntry.getNameAlias());
}

Expand All @@ -125,7 +161,10 @@ private YamlRule ruleToYamlRule(final Rule rule, final Map<String, Input> inputs

rule.getOutputEntries().forEach(outputEntry -> {
final YamlOutputEntry yamlOutputEntry = new YamlOutputEntry();
yamlOutputEntry.setExpressionType(outputEntry.getExpression().getType());
if (!outputEntry.getExpression().getType().equals(decisionExpressionType)) {
yamlOutputEntry.setExpressionType(outputEntry.getExpression().getType());
}

yamlOutputEntry.setExpression(outputEntry.getExpression().getValue());

out.put(outputEntry.getName(), yamlOutputEntry);
Expand All @@ -138,14 +177,22 @@ private YamlRule ruleToYamlRule(final Rule rule, final Map<String, Input> inputs
public Decision from(final YamlDecision model) {
final Decision.Builder builder = Decision.builder();
builder.id(model.getId())
.name(model.getName())
.expressionType(model.getExpressionType())
.evaluationMode(model.getEvaluationMode())
.hitPolicy(model.getHitPolicy());
.name(model.getName());

if (model.getExpressionType() != null) {
builder.expressionType(model.getExpressionType());
}

if (model.getEvaluationMode() != null) {
builder.evaluationMode(model.getEvaluationMode());
}

if (model.getHitPolicy() != null) {
builder.hitPolicy(model.getHitPolicy());
}

model.getFields().getIn().forEach((name, input) -> builder
.withInput(inputBuilder -> {

if (input.getNameAlias() != null) {
inputBuilder.nameAlias(input.getNameAlias());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
public final class YamlDecision {
private String id;
private String name;
private HitPolicy hitPolicy = HitPolicy.UNIQUE;
private ExpressionType expressionType = ExpressionType.LITERAL;
private EvaluationMode evaluationMode = EvaluationMode.BOOLEAN;
private HitPolicy hitPolicy;
private ExpressionType expressionType;
private EvaluationMode evaluationMode;
private YamlFields fields;
private List<YamlRule> rules;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public final class YamlInput {
private String description;
private String nameAlias;
private ValueType type;
private ExpressionType expressionType = ExpressionType.LITERAL;
private ExpressionType expressionType;
private Object expression;
private EvaluationMode evaluationMode;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public YamlInputEntry() {
}

private String nameAlias;
private ExpressionType expressionType = ExpressionType.LITERAL;
private ExpressionType expressionType;
private Object expression;
private EvaluationMode evaluationMode;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ public YamlOutputEntry(final Object value) {
public YamlOutputEntry() {
}

private ExpressionType expressionType = ExpressionType.LITERAL;
private ExpressionType expressionType;
private Object expression;
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class DecisionSpec extends Specification {

final Expression input1Expression2 = input2.getExpression()
with(input1Expression2) {
getType() == ExpressionType.LITERAL
getType() == someExpressionType
getValue() == null
}

Expand Down Expand Up @@ -494,7 +494,7 @@ class DecisionSpec extends Specification {

final Expression rule2OutputEntry2Expression = rule2OutputEntry2.getExpression()
with(rule2OutputEntry2Expression) {
getType() == ExpressionType.LITERAL
getType() == someExpressionType
getValue() == someRule2OutputEntry2ExpressionValue
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class DecisionUtilSpec extends Specification {
input2.expression.type == ExpressionType.GROOVY
input2.evaluationMode == EvaluationMode.INPUT_COMPARISON

inputEntry1.expression.type == ExpressionType.FEEL
inputEntry1.expression.type == ExpressionType.GROOVY
inputEntry1.evaluationMode == EvaluationMode.BOOLEAN
inputEntry1.nameAlias == input1NameAlias
inputEntry2.expression.type == ExpressionType.LITERAL
Expand Down
Loading

0 comments on commit 3bbd681

Please sign in to comment.