diff --git a/archetype/engine-v2-json/src/main/java/io/helidon/build/archetype/v2/json/ScriptSerializer.java b/archetype/engine-v2-json/src/main/java/io/helidon/build/archetype/v2/json/ScriptSerializer.java index a0fe53a2c..4ac264166 100644 --- a/archetype/engine-v2-json/src/main/java/io/helidon/build/archetype/v2/json/ScriptSerializer.java +++ b/archetype/engine-v2-json/src/main/java/io/helidon/build/archetype/v2/json/ScriptSerializer.java @@ -201,7 +201,13 @@ public VisitResult visitCondition(Condition cond, Script script) { @Override public VisitResult visitConditionBlock(ConditionBlock condition, JsonObjectBuilder arg) { - return evaluate(condition.expression()); + VisitResult result = evaluate(condition.expression()); + BuilderContext builder = stack.peek(); + if (builder != null) { + builder.block.add("if", exprId); + } + exprId = null; + return result; } @Override diff --git a/archetype/engine-v2-json/src/test/java/io/helidon/build/archetype/v2/json/ScriptSerializerTest.java b/archetype/engine-v2-json/src/test/java/io/helidon/build/archetype/v2/json/ScriptSerializerTest.java index f9c3f4064..700318743 100644 --- a/archetype/engine-v2-json/src/test/java/io/helidon/build/archetype/v2/json/ScriptSerializerTest.java +++ b/archetype/engine-v2-json/src/test/java/io/helidon/build/archetype/v2/json/ScriptSerializerTest.java @@ -143,6 +143,17 @@ void testFiltering2() throws IOException { assertThat(jsonDiff(archetypeJson, readJson(expected)), is(EMPTY_JSON_ARRAY)); } + @Test + void testFiltering3() throws IOException { + Path targetDir = targetDir(this.getClass()); + Path sourceDir = targetDir.resolve("test-classes/filtering3"); + Path expected = targetDir.resolve("test-classes/expected/filtering3.json"); + FileSystem fs = VirtualFileSystem.create(sourceDir); + + JsonObject archetypeJson = ScriptSerializer.serialize(fs); + assertThat(jsonDiff(archetypeJson, readJson(expected)), is(EMPTY_JSON_ARRAY)); + } + @Test void testConvertExpression() throws IOException { int id = 1; diff --git a/archetype/engine-v2-json/src/test/resources/expected/filtering3.json b/archetype/engine-v2-json/src/test/resources/expected/filtering3.json new file mode 100644 index 000000000..db010af6b --- /dev/null +++ b/archetype/engine-v2-json/src/test/resources/expected/filtering3.json @@ -0,0 +1,61 @@ +{ + "expressions": { + "1": [ + { + "kind": "literal", + "value": true + } + ], + "2": [ + { + "kind": "literal", + "value": false + }, + { + "kind": "operator", + "value": "!" + }, + { + "kind": "literal", + "value": true + }, + { + "kind": "operator", + "value": "&&" + } + ] + }, + "methods": {}, + "children": [ + { + "kind": "if", + "if": "1", + "children": [ + { + "kind": "step", + "name": "Step1", + "id": "1", + "children": [ + { + "kind": "elseif", + "if": "2", + "children": [ + { + "kind": "inputs", + "children": [ + { + "kind": "boolean", + "name": "Boolean1", + "id": "boolean1", + "default": false + } + ] + } + ] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/archetype/engine-v2-json/src/test/resources/filtering3/main.xml b/archetype/engine-v2-json/src/test/resources/filtering3/main.xml new file mode 100644 index 000000000..78384021d --- /dev/null +++ b/archetype/engine-v2-json/src/test/resources/filtering3/main.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + bar + + + + + + + + + + diff --git a/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/ast/ConditionBlock.java b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/ast/ConditionBlock.java index 784eaefa5..edbbe8a43 100644 --- a/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/ast/ConditionBlock.java +++ b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/ast/ConditionBlock.java @@ -21,10 +21,12 @@ */ public final class ConditionBlock extends Block { private final Expression expression; + private final String rawExpression; private ConditionBlock(Builder builder) { super(builder); this.expression = builder.expression; + this.rawExpression = builder.rawExpression; } /** @@ -47,6 +49,15 @@ public Expression expression() { return expression; } + /** + * Get the raw expression. + * + * @return raw expression + */ + public String rawExpression() { + return rawExpression; + } + @Override public VisitResult accept(Block.Visitor visitor, A arg) { return visitor.visitConditionBlock(this, arg); @@ -62,6 +73,7 @@ public VisitResult acceptAfter(Visitor visitor, A arg) { */ public static final class Builder extends Block.Builder { private Expression expression; + private String rawExpression; private Builder(BuilderInfo info, Kind kind) { super(info, kind); @@ -74,6 +86,7 @@ private Builder(BuilderInfo info, Kind kind) { * @return this builder */ public Builder expression(String expression) { + this.rawExpression = expression; this.expression = Expression.create(expression); return this; } diff --git a/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/util/ClientCompiler.java b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/util/ClientCompiler.java index aaf8e775f..38a83d0b2 100644 --- a/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/util/ClientCompiler.java +++ b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/util/ClientCompiler.java @@ -23,6 +23,7 @@ import io.helidon.build.archetype.engine.v2.ScriptLoader; import io.helidon.build.archetype.engine.v2.ast.Block; import io.helidon.build.archetype.engine.v2.ast.Condition; +import io.helidon.build.archetype.engine.v2.ast.ConditionBlock; import io.helidon.build.archetype.engine.v2.ast.DeclaredBlock; import io.helidon.build.archetype.engine.v2.ast.DeclaredValue; import io.helidon.build.archetype.engine.v2.ast.Input; @@ -137,6 +138,9 @@ public Node.VisitResult visitBlock(Block block, Script script) { builder = Step.builder(builderInfo(block)); } else if (block instanceof Input) { builder = Input.builder(builderInfo, kind); + } else if (block instanceof ConditionBlock) { + builder = ConditionBlock.builder(builderInfo(block), kind) + .expression(((ConditionBlock) block).rawExpression()); } else { builder = Block.builder(builderInfo, kind); } @@ -159,6 +163,9 @@ public Node.VisitResult postVisitBlock(Block block, Script arg) { case VARIABLES: case INVOKE: case INVOKE_DIR: + case IF: + case ELSEIF: + case ELSE: Node.Builder parentBuilder = stack.peek(); if (parentBuilder != null) { parentBuilder.nestedBuilders().remove(builder); diff --git a/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/util/ClientPredicate.java b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/util/ClientPredicate.java index 9a88a6146..bc1d500ea 100644 --- a/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/util/ClientPredicate.java +++ b/archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/util/ClientPredicate.java @@ -17,6 +17,7 @@ package io.helidon.build.archetype.engine.v2.util; import io.helidon.build.archetype.engine.v2.ast.Block; +import io.helidon.build.archetype.engine.v2.ast.ConditionBlock; import io.helidon.build.archetype.engine.v2.ast.Node; import io.helidon.build.archetype.engine.v2.ast.Variable; @@ -52,4 +53,19 @@ public Node.VisitResult visitVariable(Variable variable, Void arg) { } return Node.VisitResult.CONTINUE; } + + @Override + public Node.VisitResult visitConditionBlock(ConditionBlock condition, Void arg) { + if (condition.children().isEmpty()) { + return Node.VisitResult.SKIP_SUBTREE; + } + for (Node node : condition.children()) { + if (node instanceof Block) { + if (((Block) node).kind() != Block.Kind.OUTPUT) { + return Node.VisitResult.CONTINUE; + } + } + } + return Node.VisitResult.SKIP_SUBTREE; + } } diff --git a/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/ControllerTest.java b/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/ControllerTest.java index 5751d6978..ddd5394bb 100644 --- a/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/ControllerTest.java +++ b/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/ControllerTest.java @@ -188,7 +188,7 @@ protected void onVisitStep(Step step, Context context) { } }, script, context); - assertThat(steps, contains("step", "my-step")); + assertThat(steps, contains("step1", "step2")); } @Test diff --git a/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/ScriptLoaderTest.java b/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/ScriptLoaderTest.java index ea330757e..cd527a450 100644 --- a/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/ScriptLoaderTest.java +++ b/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/ScriptLoaderTest.java @@ -846,10 +846,7 @@ public VisitResult visitList(Input.List input, Void arg) { }, arg); } private VisitResult evaluate(Expression expression) { - if (expression.eval()) { - return VisitResult.CONTINUE; - } - return VisitResult.SKIP_SUBTREE; + return expression.eval() ? VisitResult.CONTINUE : VisitResult.SKIP_SUBTREE; } }, script); } diff --git a/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/util/ClientCompilerTest.java b/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/util/ClientCompilerTest.java index f498b9a86..424895e69 100644 --- a/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/util/ClientCompilerTest.java +++ b/archetype/engine-v2/src/test/java/io/helidon/build/archetype/engine/v2/util/ClientCompilerTest.java @@ -16,9 +16,11 @@ package io.helidon.build.archetype.engine.v2.util; import io.helidon.build.archetype.engine.v2.ast.Block; +import io.helidon.build.archetype.engine.v2.ast.ConditionBlock; import io.helidon.build.archetype.engine.v2.ast.Input; import io.helidon.build.archetype.engine.v2.ast.Node; import io.helidon.build.archetype.engine.v2.ast.Node.VisitResult; +import io.helidon.build.archetype.engine.v2.ast.Preset; import io.helidon.build.archetype.engine.v2.ast.Script; import io.helidon.build.archetype.engine.v2.ast.Step; @@ -618,4 +620,63 @@ public VisitResult visitAny(Input input, Void arg) { }, compiledScript); assertThat(index[0], is(12)); } + + @Test + void testCondition() { + Script script = load("compiler/conditions/condition.xml"); + Script compiledScript = ClientCompiler.compile(script, false); + int[] index = new int[]{0}; + walk(new Node.Visitor<>() { + @Override + public VisitResult visitBlock(Block block, Void arg) { + return block.accept(new Block.Visitor<>() { + @Override + public VisitResult visitStep(Step step, Void arg) { + assertThat(++index[0], is(1)); + return VisitResult.CONTINUE; + } + + @Override + public VisitResult visitAny(Block block, Void arg) { + switch (block.kind()) { + case SCRIPT: + break; + case INPUTS: + assertThat(++index[0], is(3)); + break; + default: + fail(String.format("Unexpected block: %s, index=%d", block, index[0])); + } + return VisitResult.CONTINUE; + } + + @Override + public VisitResult visitInput(Input input, Void arg) { + return input.accept(new Input.Visitor<>() { + @Override + public VisitResult visitBoolean(Input.Boolean input, Void arg) { + assertThat(++index[0], is(4)); + assertThat(input.id(), is("boolean1")); + assertThat(input.name(), is("Boolean1")); + return VisitResult.CONTINUE; + } + + @Override + public VisitResult visitAny(Input input, Void arg) { + fail(String.format("Unexpected input: %s, index=%d", block, index[0])); + return VisitResult.CONTINUE; + } + }, arg); + } + + @Override + public VisitResult visitConditionBlock(ConditionBlock condition, Void arg) { + assertThat(++index[0], is(2)); + return VisitResult.CONTINUE; + } + }, arg); + } + }, compiledScript); + assertThat(index[0], is(4)); + } } diff --git a/archetype/engine-v2/src/test/resources/compiler/conditions/condition.xml b/archetype/engine-v2/src/test/resources/compiler/conditions/condition.xml new file mode 100644 index 000000000..0c2a47cf6 --- /dev/null +++ b/archetype/engine-v2/src/test/resources/compiler/conditions/condition.xml @@ -0,0 +1,45 @@ + + + + + + true + + + + + + + bar + + + + + + + + + + + + + + diff --git a/archetype/engine-v2/src/test/resources/controller/conditional-block.xml b/archetype/engine-v2/src/test/resources/controller/conditional-block.xml index c23579c5b..686f84202 100644 --- a/archetype/engine-v2/src/test/resources/controller/conditional-block.xml +++ b/archetype/engine-v2/src/test/resources/controller/conditional-block.xml @@ -61,20 +61,26 @@ success - + my help - + + + + + + + - + @@ -92,12 +98,12 @@ - dummy + bar - dummy + bar value1 @@ -110,13 +116,13 @@ - dummy + foo - dummy + bar value2 diff --git a/archetype/engine-v2/src/test/resources/loader/conditional-block.xml b/archetype/engine-v2/src/test/resources/loader/conditional-block.xml index 622e2b5ea..94ed8ab8e 100644 --- a/archetype/engine-v2/src/test/resources/loader/conditional-block.xml +++ b/archetype/engine-v2/src/test/resources/loader/conditional-block.xml @@ -94,17 +94,17 @@ value2 - failure + foo - failure + foo - failure + foo value3