diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/Bid.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/Bid.java index 144fe2df30a9d1df146bd4dab364cbd022b8d5b8..620582ce8e1e11e3bfbdc97afc475f36ec13d876 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/Bid.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/Bid.java @@ -1,11 +1,13 @@ package nl.han.aim.asd.veilveilig.ast; import lombok.Builder; +import lombok.NoArgsConstructor; import nl.han.aim.asd.veilveilig.ast.ASTNode; import java.util.ArrayList; @Builder +@NoArgsConstructor public class Bid extends ASTNode { private final ArrayList<ASTNode> children = new ArrayList<>(); diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/Budget.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/Budget.java index 74fa26cab440c12220ee4ee4b484d50d59db8a0d..2cc45d6ed37631d1590f28a6f599a0dc8cec0a08 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/Budget.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/Budget.java @@ -2,9 +2,12 @@ package nl.han.aim.asd.veilveilig.ast; import lombok.Builder; +import lombok.NoArgsConstructor; + import java.util.ArrayList; @Builder +@NoArgsConstructor public class Budget extends ASTNode{ private final ArrayList<ASTNode> children = new ArrayList<>(); diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/ExceedBudget.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/ExceedBudget.java index 723c8ef7f8305de17aa6dfedbb364aaedbae9dcf..66ab873c223a23aecda29de80264371ee8ec3e54 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/ExceedBudget.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/ExceedBudget.java @@ -1,10 +1,12 @@ package nl.han.aim.asd.veilveilig.ast; import lombok.Builder; +import lombok.NoArgsConstructor; import java.util.ArrayList; @Builder +@NoArgsConstructor public class ExceedBudget extends ASTNode{ private final ArrayList<ASTNode> children = new ArrayList<>(); diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/Lot.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/Lot.java index d470511d224574189bf807ee777a8868be37feee..73d18d3422dec9d5c70cab00f04519f2c8599a3e 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/Lot.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/Lot.java @@ -1,10 +1,11 @@ package nl.han.aim.asd.veilveilig.ast; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; +import lombok.*; @Builder +@Getter +@Setter +@AllArgsConstructor public class Lot extends ASTNode { public int lotNumber; diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/Price.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/Price.java index c37ff94d7899c84b8c7cf093e0d90d03b2f57954..f48fc36ff725ef3cb63d6aaaff35a06b76738016 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/Price.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/Price.java @@ -1,10 +1,13 @@ package nl.han.aim.asd.veilveilig.ast; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; @Builder @Getter +@AllArgsConstructor public class Price extends ASTNode { private double priceValue; @@ -12,4 +15,8 @@ public class Price extends ASTNode { public String getNodeLabel() { return "Price: " + priceValue; } + + public double getPrice() { + return priceValue; + } } \ No newline at end of file diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/Strategy.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/Strategy.java index 546f4e749c2df9b6f73afb44ba7c732f22c9d0ea..671121a766047ddb6ecccb49bcb9448f63790eb0 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/Strategy.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/Strategy.java @@ -1,11 +1,13 @@ package nl.han.aim.asd.veilveilig.ast; import lombok.Builder; +import lombok.NoArgsConstructor; import java.util.ArrayList; @Builder +@NoArgsConstructor public class Strategy extends ASTNode { private final ArrayList<ASTNode> children = new ArrayList<>(); diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/Value.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/Value.java index c2d1cb87b13ae3e1a63573f632e474105a0181e5..1183dfd7b51ec1134c76d9c95749cc76ce142837 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/Value.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/Value.java @@ -2,10 +2,12 @@ package nl.han.aim.asd.veilveilig.ast; import lombok.Builder; +import lombok.NoArgsConstructor; import java.util.ArrayList; @Builder +@NoArgsConstructor public class Value extends ASTNode{ private final ArrayList<ASTNode> children = new ArrayList<>(); diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/CompetitorCondition.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/CompetitorCondition.java index 8e6713cfc13e2c23999f29436ba411bd5a32b0f8..bed8fa39814449e1b030884de28e6da8c79ac20e 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/CompetitorCondition.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/CompetitorCondition.java @@ -1,12 +1,14 @@ package nl.han.aim.asd.veilveilig.ast.condition; import lombok.Builder; +import lombok.NoArgsConstructor; import nl.han.aim.asd.veilveilig.ast.ASTNode; import java.util.ArrayList; @Builder +@NoArgsConstructor public class CompetitorCondition extends ASTNode { private int value; @@ -18,4 +20,12 @@ public class CompetitorCondition extends ASTNode { public String getNodeLabel() { return "Competitor Condition: " + value; } + + public int getVal() { + return value; + } + + public void setVal(int value) { + this.value = value; + } } diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/Condition.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/Condition.java index 32cfc1917b9197333e3a6924a4811855d67a460a..151c541b5538685e7e2e1e8f2940d6586b9c2ff9 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/Condition.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/Condition.java @@ -1,11 +1,13 @@ package nl.han.aim.asd.veilveilig.ast.condition; import lombok.Builder; +import lombok.NoArgsConstructor; import nl.han.aim.asd.veilveilig.ast.ASTNode; import java.util.ArrayList; @Builder +@NoArgsConstructor public class Condition extends ASTNode { private final ArrayList<ASTNode> children = new ArrayList<>(); diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/RoundCondition.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/RoundCondition.java index 03a2f4119e4d65fab702cdd53bc92db2c083235e..bd6a377896a32e34fd2dff1a67314b9486156ee3 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/RoundCondition.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/RoundCondition.java @@ -2,12 +2,14 @@ package nl.han.aim.asd.veilveilig.ast.condition; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import nl.han.aim.asd.veilveilig.ast.*; import java.util.ArrayList; @Builder +@NoArgsConstructor public class RoundCondition extends ASTNode { private final ArrayList<ASTNode> children = new ArrayList<>(); diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/roundindication/RoundIndication.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/roundindication/RoundIndication.java index 6cc980ca12b9245426a75d9b235d5d4bacfa7545..fdbb1206c084b51cf0f5bb95b11802503d95f77a 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/roundindication/RoundIndication.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/condition/roundindication/RoundIndication.java @@ -2,6 +2,7 @@ package nl.han.aim.asd.veilveilig.ast.condition.roundindication; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import nl.han.aim.asd.veilveilig.ast.ASTNode; import java.util.ArrayList; @@ -10,6 +11,7 @@ import java.util.ArrayList; @Builder @Getter @Setter +@NoArgsConstructor public class RoundIndication extends ASTNode { private final ArrayList<ASTNode> children = new ArrayList<>(); diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/DecNumberLiteral.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/DecNumberLiteral.java index d6e87372b1470f74a0aa5e71a59c3bccc1331aa1..6f01d6e0db87aea5eac88cb14c8284d9ef31fa2c 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/DecNumberLiteral.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/DecNumberLiteral.java @@ -1,9 +1,11 @@ package nl.han.aim.asd.veilveilig.ast.literals; import lombok.Builder; +import lombok.NoArgsConstructor; import nl.han.aim.asd.veilveilig.ast.Literal; @Builder +@NoArgsConstructor public class DecNumberLiteral extends Literal { private double value; @@ -16,4 +18,11 @@ public class DecNumberLiteral extends Literal { return "DecNumber Literal: " + value; } + public double getVal() { + return value; + } + + public void setVal(double value) { + this.value = value; + } } diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/PercentageLiteral.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/PercentageLiteral.java index e7b8cebdf883d55605fe4fe7cb726f502f8e8ea6..aa3b2397340706eabfefa2ad642758b83350d9a3 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/PercentageLiteral.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/PercentageLiteral.java @@ -7,6 +7,7 @@ import lombok.Setter; import nl.han.aim.asd.veilveilig.ast.Literal; @Builder +@NoArgsConstructor public class PercentageLiteral extends Literal { private double value; public PercentageLiteral(double value) { @@ -17,6 +18,14 @@ public class PercentageLiteral extends Literal { return "PercentageLiteral: " + this.value; } + public double getPercentage() { + return value; + } + + public void setPercentage(double value) { + this.value = value; + } + @Override public boolean equalsInstance(Object o) { return this == o; diff --git a/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/StringNumberLiteral.java b/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/StringNumberLiteral.java index f361537adb5c14c20dfa529f52a2a24d8727d805..ee16f824d7892d0478ad44c62ee7b2c86ef458b9 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/StringNumberLiteral.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/ast/literals/StringNumberLiteral.java @@ -16,5 +16,7 @@ public class StringNumberLiteral extends Literal { return "String Number Literal: " + value; } - + public String getVal() { + return value; + } } diff --git a/src/main/java/nl/han/aim/asd/veilveilig/generator/Generator.java b/src/main/java/nl/han/aim/asd/veilveilig/generator/Generator.java index 1c2c50441f7dee9cfb2190d24dcde72ebaf6cae0..fc876dabaadfd188f5525976926c5970bc5faae1 100644 --- a/src/main/java/nl/han/aim/asd/veilveilig/generator/Generator.java +++ b/src/main/java/nl/han/aim/asd/veilveilig/generator/Generator.java @@ -1,22 +1,429 @@ package nl.han.aim.asd.veilveilig.generator; -import nl.han.aim.asd.veilveilig.ast.AST; -import nl.han.aim.asd.veilveilig.ast.ASTNode; +import lombok.NonNull; +import nl.han.aim.asd.veilveilig.ast.*; +import nl.han.aim.asd.veilveilig.ast.condition.CompetitorCondition; +import nl.han.aim.asd.veilveilig.ast.condition.Condition; +import nl.han.aim.asd.veilveilig.ast.condition.RoundCondition; +import nl.han.aim.asd.veilveilig.ast.condition.WhileCondition; +import nl.han.aim.asd.veilveilig.ast.condition.roundindication.*; +import nl.han.aim.asd.veilveilig.ast.limit.Limit; +import nl.han.aim.asd.veilveilig.ast.limit.MinSalePrice; +import nl.han.aim.asd.veilveilig.ast.literals.DecNumberLiteral; +import nl.han.aim.asd.veilveilig.ast.literals.NotHighestBid; +import nl.han.aim.asd.veilveilig.ast.literals.PercentageLiteral; +import nl.han.aim.asd.veilveilig.ast.literals.StringNumberLiteral; +import java.util.ArrayList; +import java.util.List; + +/** + * This class generates a JSON string from an AST. + */ public class Generator { private final StringBuilder stringBuilder; + /** + * Constructor of the Generator class. + */ public Generator() { this.stringBuilder = new StringBuilder(); } + /** + * This method generates a JSON string from an AST. + * + * @param ast The AST to generate a JSON string from. + * @return The generated JSON string. + */ public String generate(AST ast) { this.buildString(ast.root); return stringBuilder.toString(); + } + + /** + * To build json for strategies within a node. + * + * @param root The ASTNode to build a JSON string from. + */ + private void buildString(ASTNode root) { + stringBuilder.append("{"); + stringBuilder.append("\"strategies\": ["); + + boolean islastStrategy = false; + for (int i = 0; i < root.getChildren().size(); i++) { + var node = root.getChildren().get(i); + + islastStrategy = checkIfLastStrategy(i, root); + if (node instanceof Strategy) { + buildForStrategy(node, islastStrategy, false); + } + } + stringBuilder.append("]}"); } - private void buildString(ASTNode root) { + /** + * To check if you are at the last strategy in the root its children. + * @param currentIndex + * @param root + * @return + */ + public boolean checkIfLastStrategy(int currentIndex, ASTNode root) { + for (int i = currentIndex+1; i < root.getChildren().size(); i++) { + var node = root.getChildren().get(i); + if (node instanceof Strategy) { + return false; + } + } + return true; + } + + /** + * To see if the current strategy is the last one. When list has multiple different types of nodes. + * @param currentIndex + * @param nodes + * @return + */ + public boolean checkIfLastStrategy(int currentIndex, List<ASTNode> nodes) { + for (int i = currentIndex+1; i < nodes.size(); i++) { + var node = nodes.get(i); + if (node instanceof Strategy) { + return false; + } + } + return true; + } + + /** + * Go through all children in a strategy and build. First check if it is a condition or not. + * @param strategy + * @param isLast + * @param isSubStrategy + */ + private void buildForStrategy(ASTNode strategy, boolean isLast, boolean isSubStrategy) { + var stratText = (isSubStrategy) ? "\"Strategy\": {" : "{"; + stringBuilder.append(stratText); + + var data = conditionsInNode(strategy); + var conditions = data.get(0); // 0 should be the conditions (no tuple in java..) + var bidsLotsLimitsAndSubStrategies = data.get(1); + + if (!conditions.isEmpty()) { + stringBuilder.append("\"conditions\": ["); + for (var i = 0; i < conditions.size(); i++) { + stringBuilder.append("{"); + buildForCondition(conditions.get(i)); + var text = (i == conditions.size() - 1) ? "}" : "},"; + stringBuilder.append(text); + } + stringBuilder.append("]"); + } + + if (!bidsLotsLimitsAndSubStrategies.isEmpty()) { + if (!conditions.isEmpty()) stringBuilder.append(","); // should have added conditions already. + toBuildForOtherTypes(bidsLotsLimitsAndSubStrategies); + } + + var text = isLast ? "}" : "},"; + stringBuilder.append(text); + } + + /** + * Go over every non condition and build for specific instance. + * @param bidsLotsLimitsAndSubStrategies + */ + private void toBuildForOtherTypes(List<ASTNode> bidsLotsLimitsAndSubStrategies) { + var isLastOther = false; + + for (int i = 0; i < bidsLotsLimitsAndSubStrategies.size(); i++) { + if (i == bidsLotsLimitsAndSubStrategies.size() -1) isLastOther = true; + + var value = bidsLotsLimitsAndSubStrategies.get(i); + + if (value instanceof Lot) { + stringBuilder.append("\"Lot\": "); + stringBuilder.append(((Lot) value).getLotNumber()); + } + + if (value instanceof Bid) { + buildForBid((Bid) bidsLotsLimitsAndSubStrategies.get(i)); + } + + if (value instanceof Limit) { + buildForValueAndLimit((Limit) bidsLotsLimitsAndSubStrategies.get(i), "Limit"); + } + + // Creates sub strategies. + if (value instanceof Strategy) { + var isLastStrat = checkIfLastStrategy(i, bidsLotsLimitsAndSubStrategies); + buildForStrategy(bidsLotsLimitsAndSubStrategies.get(i), isLastStrat, true); + } + + if (!isLastOther) stringBuilder.append(","); + } + } + + /** + * If contains Highest bid we do something specific else we assume we only need a Value. + * @param bid + */ + private void buildForBid(Bid bid) { + var containsHighestBid = containsType(bid.getChildren(), NotHighestBid.class); + + for (var i = 0; i < bid.getChildren().size(); i++) { + var child = bid.getChildren().get(i); + + if (child instanceof Value && !containsHighestBid) { // Can either be Value or HighestBid + buildForValueAndLimit((Value)child, "Bid"); + } else if (child instanceof Value) { + buildValueWithHighestBid((Value)child); + } else if (containsHighestBid && bid.getChildren().size() == 1) { + stringBuilder.append("\"Bid\": {\"HighestBid\": true }"); + } + } + } + + /** + * json building when Value and Highest Bid + * @param child + */ + public String buildValueWithHighestBid(Value child) { + stringBuilder.append("\"Bid\": [\"HighestBid\""); + + if (!child.getChildren().isEmpty()) { + stringBuilder.append(","); + } + + for (int i = 0; i < child.getChildren().size(); i++) { + var val = child.getChildren().get(i); + if (val instanceof Price) { + stringBuilder.append(((Price)val).getPrice()); + } + + var text = (i == child.getChildren().size() - 1) ? "" : ","; + stringBuilder.append(text); + } + + stringBuilder.append("]"); + return stringBuilder.toString(); + } + + /** + * Default Json building when Value Field (without HighestBid) Or Limit. + * @param value + * @param arrayName + */ + public String buildForValueAndLimit(@NonNull ASTNode value, String arrayName) { + stringBuilder.append('"').append(arrayName).append('"').append(": {"); + + var isLast = false; + for (var i = 0; i < value.getChildren().size(); i++) { + if (i == value.getChildren().size() -1) isLast = true; + + if (value.getChildren().get(i) instanceof ExceedBudget) { + var exceed = value.getChildren().get(i); + buildForExceed((ExceedBudget)exceed); + } + + if (value.getChildren().get(i) instanceof Lot) { + stringBuilder.append("\"Lot\": "); + stringBuilder.append(((Lot) value.getChildren().get(i)).getLotNumber()); + } + + if (value.getChildren().get(i) instanceof PercentageLiteral) { + stringBuilder.append("\"Percentage\": "); + stringBuilder.append(((PercentageLiteral) value.getChildren().get(i)).getPercentage()); + } + + if (value.getChildren().get(i) instanceof Price) { + stringBuilder.append("\"Amount\": "); + stringBuilder.append(((Price) value.getChildren().get(i)).getPrice()); + } + + if (value.getChildren().get(i) instanceof Steps) { + stringBuilder.append("\"Steps\": "); + stringBuilder.append(true); + } + + if (value.getChildren().get(i) instanceof Budget) { + stringBuilder.append("\"Type\": "); + stringBuilder.append("\"Budget\""); + } + + if (value.getChildren().get(i) instanceof MinSalePrice) { + stringBuilder.append("\"Type\": "); + stringBuilder.append("\"MinSalePrice\""); + } + + if (!isLast) stringBuilder.append(","); + } + + stringBuilder.append("}"); + return stringBuilder.toString(); + } + + /** + * Json building when Exceed Budget is found. + * @param exceed + */ + public String buildForExceed(ExceedBudget exceed) { + for (var j = 0; j < exceed.getChildren().size(); j++) { + + var val = exceed.getChildren().get(j); + + if (val instanceof Budget) { + stringBuilder.append("\"ExceedBudget\": "); + stringBuilder.append(true); + } + + if (val instanceof PercentageLiteral) { + stringBuilder.append("\"Percentage\": "); + stringBuilder.append(((PercentageLiteral)val).getPercentage()); + } + + if (j != exceed.getChildren().size() -1) stringBuilder.append(","); + } + return stringBuilder.toString(); + } + + /** + * Call Builders for all Condition types when Condition Object is found. + * @param astNode + */ + private void buildForCondition(ASTNode astNode) { + var size = astNode.getChildren().size(); + + for (int i = 0; i < size; i++) { + var conditionType = astNode.getChildren().get(i); + + if (conditionType instanceof WhileCondition) { + buildForWhileCondition(); + } + + if (conditionType instanceof RoundCondition) { + buildForRoundCondition((RoundCondition)conditionType); + } + + if (conditionType instanceof Condition) { + buildForCondition(conditionType); + } + + if (conditionType instanceof CompetitorCondition) { + stringBuilder.append("\"Competitor\": "); + stringBuilder.append(((CompetitorCondition) conditionType).getVal()); + } + + if (i != size -1) stringBuilder.append(","); + } + } + + /** + * When Condition is a round condition call Builders. + * @param conditionType + */ + public String buildForRoundCondition(RoundCondition conditionType) { + for (int i = 0; i < conditionType.getChildren().size(); i++) { + var child = conditionType.getChildren().get(i); + if (child instanceof Lot) { + stringBuilder.append("\"Lot\": "); + stringBuilder.append(((Lot) child).getLotNumber()); + } + + if (child instanceof CompetitorCondition) { + stringBuilder.append("\"Competitor\": "); + stringBuilder.append(((CompetitorCondition) child).getVal()); + } + + if (child instanceof RoundIndication) buildForRoundIndication((RoundIndication)child); + if (child instanceof DistributedRoundCondition) { + if (!child.getChildren().isEmpty()) { + stringBuilder.append("\"Distributed\": true,"); + for (var distributedChild : child.getChildren()) { + buildForRoundIndication((RoundIndication) distributedChild); + } + } + } + if (i != conditionType.getChildren().size() -1) stringBuilder.append(","); + } + return stringBuilder.toString(); + } + + /** + * Json parse when condition parent type is of RoundIndication + * @param conditionType + */ + public String buildForRoundIndication(RoundIndication conditionType) { + var size = conditionType.getChildren().size(); + + for (int i = 0; i < size; i++) { + + String data = ""; + var curChild = conditionType.getChildren().get(i); + + if (curChild instanceof CompetitorCondition) { + stringBuilder.append("\"Competitor\": "); + stringBuilder.append(((CompetitorCondition) curChild).getVal()); + } + + if (curChild instanceof FirstRoundIndication) data = "\"firstRound\": true"; + if (curChild instanceof LastRoundIndication) data = "\"lastRound\": true"; + if (curChild instanceof EveryRound) data = "\"everyRound\": true"; + if (curChild instanceof DecNumberLiteral) data = "\"rounds\": " + ((DecNumberLiteral)curChild).getVal(); + if (curChild instanceof StringNumberLiteral) data = "\"rounds\": " + '"'+((StringNumberLiteral)curChild).getVal()+'"'; + + if (i == size - 1) { + stringBuilder.append(data); + } else { + stringBuilder.append(data).append(","); + } + } + return stringBuilder.toString(); + } + + /** + * This will always set NotHighestBidder if the While condition is set. + */ + private void buildForWhileCondition() { + stringBuilder.append("\"NotHighestBid\": true"); + } + + /** + * Filter conditions out of the list. + * @param strategy + * @return + */ + public ArrayList<List<ASTNode>> conditionsInNode(ASTNode strategy) { + List<ASTNode> nodes = new ArrayList<>(); + List<ASTNode> other = new ArrayList<>(); + for (var node : strategy.getChildren()) { + if (node instanceof Condition) nodes.add(node); + else other.add(node); + } + + var list = new ArrayList<List<ASTNode>>(); + list.add(nodes); + list.add(other); + return list; + } + + /** + * Check if list contains class type + * @param list + * @param clazz + * @return + */ + public boolean containsType(List<?> list, Class<?> clazz) { + if (list == null) { + return false; + } + + for (Object obj : list) { + if (clazz.isInstance(obj)) { + return true; + } + } + return false; } } diff --git a/src/test/java/nl/han/aim/asd/veilveilig/parser/ConditionsInNodeTest.java b/src/test/java/nl/han/aim/asd/veilveilig/parser/ConditionsInNodeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3efbca16a6cfb7d272bf0e66fdcefb4c22ca67a4 --- /dev/null +++ b/src/test/java/nl/han/aim/asd/veilveilig/parser/ConditionsInNodeTest.java @@ -0,0 +1,95 @@ +package nl.han.aim.asd.veilveilig.parser; + +import nl.han.aim.asd.veilveilig.ast.ASTNode; +import nl.han.aim.asd.veilveilig.ast.Bid; +import nl.han.aim.asd.veilveilig.ast.Strategy; +import nl.han.aim.asd.veilveilig.ast.condition.Condition; +import nl.han.aim.asd.veilveilig.generator.Generator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +public class ConditionsInNodeTest { + + Generator generator; + + @BeforeEach + public void setup() { + generator = new Generator(); + } + + @Test + public void testConditionsInNode() { + // Arrange + ASTNode conditionNode1 = new Condition(); + ASTNode conditionNode2 = new Condition(); + ASTNode otherNode1 = new Bid(); + ASTNode otherNode2 = new Bid(); + ASTNode strategyNode = new Strategy(); + strategyNode.addChild(conditionNode1); + strategyNode.addChild(conditionNode2); + strategyNode.addChild(otherNode1); + strategyNode.addChild(otherNode2); + + //Act + ArrayList<List<ASTNode>> result = generator.conditionsInNode(strategyNode); + + List<ASTNode> expectedConditions = new ArrayList<>(); + expectedConditions.add(conditionNode1); + expectedConditions.add(conditionNode2); + List<ASTNode> expectedOthers = new ArrayList<>(); + expectedOthers.add(otherNode1); + expectedOthers.add(otherNode2); + ArrayList<List<ASTNode>> expectedResult = new ArrayList<>(); + expectedResult.add(expectedConditions); + expectedResult.add(expectedOthers); + + //Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + public void testConditionsInNodeWithNoChildren() { + // Arrange + ASTNode strategyNode = new Strategy(); + + //Act + ArrayList<List<ASTNode>> result = generator.conditionsInNode(strategyNode); + + List<ASTNode> expectedConditions = new ArrayList<>(); + List<ASTNode> expectedOthers = new ArrayList<>(); + ArrayList<List<ASTNode>> expectedResult = new ArrayList<>(); + expectedResult.add(expectedConditions); + expectedResult.add(expectedOthers); + + //Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + public void testConditionsInNodeWithOnlyOtherNodes() { + // Arrange + ASTNode otherNode1 = new Bid(); + ASTNode otherNode2 = new Bid(); + ASTNode strategyNode = new Strategy(); + strategyNode.addChild(otherNode1); + strategyNode.addChild(otherNode2); + + //Act + ArrayList<List<ASTNode>> result = generator.conditionsInNode(strategyNode); + + List<ASTNode> expectedConditions = new ArrayList<>(); + List<ASTNode> expectedOthers = new ArrayList<>(); + expectedOthers.add(otherNode1); + expectedOthers.add(otherNode2); + ArrayList<List<ASTNode>> expectedResult = new ArrayList<>(); + expectedResult.add(expectedConditions); + expectedResult.add(expectedOthers); + + //Assert + Assertions.assertEquals(expectedResult, result); + } +} diff --git a/src/test/java/nl/han/aim/asd/veilveilig/parser/ContainsTypeTest.java b/src/test/java/nl/han/aim/asd/veilveilig/parser/ContainsTypeTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c7f73953c1fd5493bcfe4a1c70e14c5f28406128 --- /dev/null +++ b/src/test/java/nl/han/aim/asd/veilveilig/parser/ContainsTypeTest.java @@ -0,0 +1,72 @@ +package nl.han.aim.asd.veilveilig.parser; + +import nl.han.aim.asd.veilveilig.generator.Generator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +public class ContainsTypeTest { + + Generator generator; + + @BeforeEach + public void setup() { + generator = new Generator(); + } + + @Test + void testContainsTypeWithMatchingType() { + // Arrange + List<String> stringList = new ArrayList<>(); + stringList.add("Hello"); + stringList.add("World"); + + // Act + boolean result = generator.containsType(stringList, String.class); + + // Assert + Assertions.assertTrue(result); + } + + @Test + void testContainsTypeWithNonMatchingType() { + // Arrange + List<Integer> integerList = new ArrayList<>(); + integerList.add(1); + integerList.add(2); + integerList.add(3); + + // Act + boolean result = generator.containsType(integerList, String.class); + + // Assert + Assertions.assertFalse(result); + } + + @Test + void testContainsTypeWithEmptyList() { + // Arrange + List<Object> emptyList = new ArrayList<>(); + + // Act + boolean result = generator.containsType(emptyList, String.class); + + // Assert + Assertions.assertFalse(result); + } + + @Test + void testContainsTypeWithNullList() { + // Arrange + List<Object> nullList = null; + + // Act + boolean result = generator.containsType(nullList, String.class); + + // Assert + Assertions.assertFalse(result); + } +} \ No newline at end of file diff --git a/src/test/java/nl/han/aim/asd/veilveilig/parser/ExceedBudgetTest.java b/src/test/java/nl/han/aim/asd/veilveilig/parser/ExceedBudgetTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6de7b91f148e572dca551afad81877543cc1d921 --- /dev/null +++ b/src/test/java/nl/han/aim/asd/veilveilig/parser/ExceedBudgetTest.java @@ -0,0 +1,84 @@ +package nl.han.aim.asd.veilveilig.parser; + +import nl.han.aim.asd.veilveilig.ast.Budget; +import nl.han.aim.asd.veilveilig.ast.ExceedBudget; +import nl.han.aim.asd.veilveilig.ast.literals.PercentageLiteral; +import nl.han.aim.asd.veilveilig.generator.Generator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class ExceedBudgetTest { + + Generator generator; + + @BeforeEach + public void setup() { + generator = new Generator(); + } + + @Test + void testBuildForExceedWithBudget() { + // Arrange + ExceedBudget exceed = new ExceedBudget(); + Budget budget = new Budget(); + + exceed.addChild(budget); + + // Act + String expectedResult = "\"ExceedBudget\": true"; + String result = generator.buildForExceed(exceed); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildForExceedWithPercentage() { + // Arrange + ExceedBudget exceed = new ExceedBudget(); + PercentageLiteral percentageLiteral = new PercentageLiteral(); + percentageLiteral.setPercentage(50); + + exceed.addChild(percentageLiteral); + + // Act + String expectedResult = "\"Percentage\": 50.0"; + String result = generator.buildForExceed(exceed); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildForExceedWithBothBudgetAndPercentage() { + // Arrange + ExceedBudget exceed = new ExceedBudget(); + Budget budget = new Budget(); + PercentageLiteral percentageLiteral = new PercentageLiteral(); + percentageLiteral.setPercentage(50); + + exceed.addChild(budget); + exceed.addChild(percentageLiteral); + + // Act + String expectedResult = "\"ExceedBudget\": true,\"Percentage\": 50.0"; + String result = generator.buildForExceed(exceed); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildForExceedWithEmptyExceedBudget() { + // Arrange + ExceedBudget exceed = new ExceedBudget(); + + // Act + String expectedResult = ""; + String result = generator.buildForExceed(exceed); + + // Assert + Assertions.assertEquals(expectedResult, result); + } +} diff --git a/src/test/java/nl/han/aim/asd/veilveilig/parser/LastStrategyTest.java b/src/test/java/nl/han/aim/asd/veilveilig/parser/LastStrategyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..44fef3f010c8b53b80fad50bc92319d89834788f --- /dev/null +++ b/src/test/java/nl/han/aim/asd/veilveilig/parser/LastStrategyTest.java @@ -0,0 +1,74 @@ +package nl.han.aim.asd.veilveilig.parser; + +import nl.han.aim.asd.veilveilig.ast.Strategies; +import nl.han.aim.asd.veilveilig.ast.Strategy; +import nl.han.aim.asd.veilveilig.generator.Generator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class LastStrategyTest { + + Generator generator; + + @BeforeEach + public void setup() { + generator = new Generator(); + } + + @Test + void testCheckIfLastStrategyWithLastStrategy() { + // Arrange + var root = new Strategies(); + Strategy strategy1 = new Strategy(); + Strategy strategy2 = new Strategy(); + + root.addChild(strategy1); + root.addChild(strategy2); + + int currentIndex = 1; + + // Act + boolean expectedResult = true; + boolean result = generator.checkIfLastStrategy(currentIndex, root); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testCheckIfLastStrategyWithNonLastStrategy() { + // Arrange + var root = new Strategies(); + Strategy strategy1 = new Strategy(); + Strategy strategy2 = new Strategy(); + + root.addChild(strategy1); + root.addChild(strategy2); + + int currentIndex = 0; + + // Act + boolean expectedResult = false; + boolean result = generator.checkIfLastStrategy(currentIndex, root); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testCheckIfLastStrategyWithNoStrategies() { + // Arrange + var root = new Strategies(); + + int currentIndex = 0; + + // Act + boolean expectedResult = true; + boolean result = generator.checkIfLastStrategy(currentIndex, root); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + +} \ No newline at end of file diff --git a/src/test/java/nl/han/aim/asd/veilveilig/parser/RoundConditionTest.java b/src/test/java/nl/han/aim/asd/veilveilig/parser/RoundConditionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1073ac8c4a8f54841571777d5cf600e46370d2dd --- /dev/null +++ b/src/test/java/nl/han/aim/asd/veilveilig/parser/RoundConditionTest.java @@ -0,0 +1,58 @@ +package nl.han.aim.asd.veilveilig.parser; + +import nl.han.aim.asd.veilveilig.ast.Lot; +import nl.han.aim.asd.veilveilig.ast.condition.CompetitorCondition; +import nl.han.aim.asd.veilveilig.ast.condition.RoundCondition; +import nl.han.aim.asd.veilveilig.ast.condition.roundindication.FirstRoundIndication; +import nl.han.aim.asd.veilveilig.ast.condition.roundindication.LastRoundIndication; +import nl.han.aim.asd.veilveilig.ast.condition.roundindication.RoundIndication; +import nl.han.aim.asd.veilveilig.generator.Generator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class RoundConditionTest { + + Generator generator; + + @BeforeEach + public void setup() { + generator = new Generator(); + } + + @Test + void testBuildRoundConditionString() { + // Arrange + RoundCondition conditionType = new RoundCondition(); + Lot lot = new Lot(123); + CompetitorCondition competitorCondition = new CompetitorCondition(); + competitorCondition.setVal(1); + RoundIndication roundIndication = new RoundIndication(); + roundIndication.addChild(new FirstRoundIndication()); + roundIndication.addChild(new LastRoundIndication()); + + conditionType.addChild(lot); + conditionType.addChild(competitorCondition); + conditionType.addChild(roundIndication); + + // Act + String expectedResult = "\"Lot\": 123,\"Competitor\": 1,\"firstRound\": true,\"lastRound\": true"; + String result = generator.buildForRoundCondition(conditionType); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildRoundConditionStringWithEmptyConditionType() { + // Arrange + RoundCondition conditionType = new RoundCondition(); + + // Act + String expectedResult = ""; + String result = generator.buildForRoundCondition(conditionType); + + // Assert + Assertions.assertEquals(expectedResult, result); + } +} \ No newline at end of file diff --git a/src/test/java/nl/han/aim/asd/veilveilig/parser/RoundIndicationTest.java b/src/test/java/nl/han/aim/asd/veilveilig/parser/RoundIndicationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..98a1ec1a42347d3a370a37e10d66b890da53d332 --- /dev/null +++ b/src/test/java/nl/han/aim/asd/veilveilig/parser/RoundIndicationTest.java @@ -0,0 +1,55 @@ +package nl.han.aim.asd.veilveilig.parser; + +import nl.han.aim.asd.veilveilig.ast.condition.CompetitorCondition; +import nl.han.aim.asd.veilveilig.ast.condition.roundindication.FirstRoundIndication; +import nl.han.aim.asd.veilveilig.ast.condition.roundindication.RoundIndication; +import nl.han.aim.asd.veilveilig.ast.literals.DecNumberLiteral; +import nl.han.aim.asd.veilveilig.generator.Generator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class RoundIndicationTest { + + Generator generator; + + @BeforeEach + public void setup() { + generator = new Generator(); + } + + @Test + void testBuildRoundIndicationString() { + // Arrange + RoundIndication conditionType = new RoundIndication(); + CompetitorCondition competitorCondition = new CompetitorCondition(); + competitorCondition.setVal(1); + FirstRoundIndication firstRoundIndication = new FirstRoundIndication(); + DecNumberLiteral decNumberLiteral = new DecNumberLiteral(); + decNumberLiteral.setVal(5); + + conditionType.addChild(competitorCondition); + conditionType.addChild(firstRoundIndication); + conditionType.addChild(decNumberLiteral); + + // Act + String expectedResult = "\"Competitor\": 1,\"firstRound\": true,\"rounds\": 5.0"; + String result = generator.buildForRoundIndication(conditionType); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildRoundIndicationStringWithEmptyConditionType() { + // Arrange + RoundIndication conditionType = new RoundIndication(); + + // Act + String expectedResult = ""; + String result = generator.buildForRoundIndication(conditionType); + + // Assert + Assertions.assertEquals(expectedResult, result); + } +} \ No newline at end of file diff --git a/src/test/java/nl/han/aim/asd/veilveilig/parser/ValueAndLimitTest.java b/src/test/java/nl/han/aim/asd/veilveilig/parser/ValueAndLimitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a60bbe74d661dff4fc4cad76c7afffe8a492b65f --- /dev/null +++ b/src/test/java/nl/han/aim/asd/veilveilig/parser/ValueAndLimitTest.java @@ -0,0 +1,87 @@ +package nl.han.aim.asd.veilveilig.parser; + +import nl.han.aim.asd.veilveilig.ast.*; +import nl.han.aim.asd.veilveilig.ast.literals.PercentageLiteral; +import nl.han.aim.asd.veilveilig.generator.Generator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class ValueAndLimitTest { + + Generator generator; + + @BeforeEach + public void setup() { + generator = new Generator(); + } + + @Test + void testBuildForValueAndLimitWithExceedBudget() { + // Arrange + Value value = new Value(); + ExceedBudget exceedBudget = new ExceedBudget(); + Budget budget = new Budget(); + exceedBudget.addChild(budget); + value.addChild(exceedBudget); + + String arrayName = "array1"; + + // Act + String expectedResult = "\"array1\": {\"ExceedBudget\": true}"; + String result = generator.buildForValueAndLimit(value, arrayName); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildForValueAndLimitWithLot() { + // Arrange + Value value = new Value(); + Lot lot = new Lot(123); + value.addChild(lot); + + String arrayName = "array2"; + + // Act + String expectedResult = "\"array2\": {\"Lot\": 123}"; + String result = generator.buildForValueAndLimit(value, arrayName); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildForValueAndLimitWithPercentageLiteral() { + // Arrange + Value value = new Value(); + PercentageLiteral percentageLiteral = new PercentageLiteral(); + percentageLiteral.setPercentage(50); + value.addChild(percentageLiteral); + + String arrayName = "array3"; + + // Act + String expectedResult = "\"array3\": {\"Percentage\": 50.0}"; + String result = generator.buildForValueAndLimit(value, arrayName); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildForValueAndLimitWithEmptyValue() { + // Arrange + Value value = new Value(); + + String arrayName = "array4"; + + // Act + String expectedResult = "\"array4\": {}"; + String result = generator.buildForValueAndLimit(value, arrayName); + + // Assert + Assertions.assertEquals(expectedResult, result); + } +} \ No newline at end of file diff --git a/src/test/java/nl/han/aim/asd/veilveilig/parser/ValueWithHighestBidTest.java b/src/test/java/nl/han/aim/asd/veilveilig/parser/ValueWithHighestBidTest.java new file mode 100644 index 0000000000000000000000000000000000000000..cac69bb74103dd9056f86393b1b68a163a494ace --- /dev/null +++ b/src/test/java/nl/han/aim/asd/veilveilig/parser/ValueWithHighestBidTest.java @@ -0,0 +1,63 @@ +package nl.han.aim.asd.veilveilig.parser; + +import nl.han.aim.asd.veilveilig.ast.Price; +import nl.han.aim.asd.veilveilig.ast.Value; +import nl.han.aim.asd.veilveilig.generator.Generator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class ValueWithHighestBidTest { + + Generator generator; + + @BeforeEach + public void setup() { + generator = new Generator(); + } + + @Test + void testBuildValueWithHighestBidWithPrice() { + // Arrange + Value child = new Value(); + Price price = new Price(100); + child.addChild(price); + + // Act + String expectedResult = "\"Bid\": [\"HighestBid\",100.0]"; + String result = generator.buildValueWithHighestBid(child); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildValueWithHighestBidWithMultiplePrices() { + // Arrange + Value child = new Value(); + Price price1 = new Price(100); + Price price2 = new Price(200); + child.addChild(price1); + child.addChild(price2); + + // Act + String expectedResult = "\"Bid\": [\"HighestBid\",100.0,200.0]"; + String result = generator.buildValueWithHighestBid(child); + + // Assert + Assertions.assertEquals(expectedResult, result); + } + + @Test + void testBuildValueWithHighestBidWithEmptyChild() { + // Arrange + Value child = new Value(); + + // Act + String expectedResult = "\"Bid\": [\"HighestBid\"]"; + String result = generator.buildValueWithHighestBid(child); + + // Assert + Assertions.assertEquals(expectedResult, result); + } +} \ No newline at end of file