This is an automated email from the ASF dual-hosted git repository. iuliana pushed a commit to branch dsl-edge-cases in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
commit 2c898702af6ca31c12e31e84258aa3ac96070d40 Author: iuliana <[email protected]> AuthorDate: Mon Mar 8 14:10:23 2021 +0000 Added tests for indexed/map access and completed implementation --- .../brooklyn/spi/dsl/BrooklynDslInterpreter.java | 2 +- .../camp/brooklyn/spi/dsl/parse/DslParser.java | 51 +++++++++++++--------- .../camp/brooklyn/spi/dsl/DslYamlTest.java | 17 +++++++- 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java index 0944ab4..11d0781 100644 --- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java +++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java @@ -99,7 +99,7 @@ public class BrooklynDslInterpreter extends PlanInterpreterAdapter { throw new IllegalStateException("Invalid map key function "+f.getFunction()+"; should not have arguments if taking arguments from map"); // means evaluation acts on values - List<Object> args = new ArrayList<Object>(); + List<Object> args = new ArrayList<>(); if (value.getNewValue() instanceof Iterable<?>) { for (Object vi: (Iterable<?>)value.getNewValue()) args.add(vi); diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java index 4a4db66..9d5a195 100644 --- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java +++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/parse/DslParser.java @@ -48,14 +48,15 @@ public class DslParser { public Object next() { int start = index; - boolean isProperty = index > 0 && expression.charAt(index -1) == '['; + boolean isProperty = (index > 0 && (expression.charAt(index -1) == '[' )) || // for [x] syntax - indexes in lists + (index > 1 && (expression.charAt(index -1) == '"' && expression.charAt(index -2) == '[')) ; // for ["x"] syntax - string properties and map keys if (!isProperty) { skipWhitespace(); if (index >= expression.length()) throw new IllegalStateException("Unexpected end of expression to parse, looking for content since position " + start); if (expression.charAt(index) == '"') { - // assume a string + // assume a string, that is why for property syntax using [x] or ["x"], we skip this part int stringStart = index; index++; do { @@ -74,20 +75,19 @@ public class DslParser { List<Object> result = new MutableList<Object>(); int fnStart = index; - // we re-use this property isProperty = expression.charAt(fnStart) == '['; if(!isProperty) { - do { - if (index >= expression.length()) - break; - char c = expression.charAt(index); - if (Character.isJavaIdentifierPart(c)) ; - // these chars also permitted - else if (".:".indexOf(c)>=0) ; - // other things e.g. whitespace, parentheses, etc, skip - else break; - index++; - } while (true); + do { + if (index >= expression.length()) + break; + char c = expression.charAt(index); + if (Character.isJavaIdentifierPart(c)) ; + // these chars also permitted + else if (".:".indexOf(c)>=0) ; + // other things e.g. whitespace, parentheses, etc, skip + else break; + index++; + } while (true); } String fn = isProperty ? "" : expression.substring(fnStart, index); if (fn.length()==0 && !isProperty) @@ -97,27 +97,39 @@ public class DslParser { if (index < expression.length() && ( expression.charAt(index)=='(' || expression.charAt(index)=='[')) { // collect arguments int parenStart = index; - List<Object> args = new MutableList<Object>(); + List<Object> args = new MutableList<>(); + if (expression.charAt(index)=='[' && expression.charAt(index +1)=='"') { index ++;} // for ["x"] syntax needs to be increased to extract the name of the property correctly index ++; do { skipWhitespace(); if (index >= expression.length()) throw new IllegalStateException("Unexpected end of arguments to function '"+fn+"', no close parenthesis matching character at position "+parenStart); char c = expression.charAt(index); + if(isProperty && c =='"') { index++; break; } // increasing the index for ["x"] syntax to account for the presence of the '"' if (c==')'|| c == ']') break; if (c==',') { if (args.isEmpty()) throw new IllegalStateException("Invalid character at position"+index); index++; } else { - if (!args.isEmpty()) + if (!args.isEmpty() && !isProperty) throw new IllegalStateException("Expected , before position"+index); } - args.add(next()); + args.add(next()); // call with first letter of the property } while (true); if (fn.isEmpty()) { - result.add(new PropertyAccess(args.get(0))); + Object arg = args.get(0); + if (arg instanceof FunctionWithArgs) { + FunctionWithArgs holder = (FunctionWithArgs) arg; + if(holder.getArgs() == null || holder.getArgs().isEmpty()) { + result.add(new PropertyAccess(holder.getFunction())); + } else { + throw new IllegalStateException("Expected empty FunctionWithArgs - arguments present!"); + } + } else { + result.add(new PropertyAccess(arg)); + } } else { result.add(new FunctionWithArgs(fn, args)); } @@ -139,7 +151,6 @@ public class DslParser { throw new IllegalStateException("Expected functions following position"+chainStart); } } else if (c=='[') { - // TODO <- create PropertyAccess objects int selectorsStart = index; Object next = next(); if (next instanceof List) { @@ -153,7 +164,7 @@ public class DslParser { return result; } } else { - // it is just a word; return it with args as null + // it is just a word; return it with args as null; return new FunctionWithArgs(fn, null); } } diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslYamlTest.java index 28afe98..4a085e0 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslYamlTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslYamlTest.java @@ -890,10 +890,25 @@ public class DslYamlTest extends AbstractYamlTest { Dumper.dumpInfo(app); assertEquals( getConfigEventually(app, ConfigKeys.newConfigKey(Object.class, "key2")), - "3"); + 3); } @Test + public void testDslSelectorFromMapOfLists() throws Exception { + final Entity app = createAndStartApplication( + "services:", + "- type: " + BasicApplication.class.getName(), + " brooklyn.config:", + " key1: {a: [1,2,3], b: [4,5,6] }", + " key2: $brooklyn:config(\"key1\")[\"b\"][2]"); + Dumper.dumpInfo(app); + assertEquals( + getConfigEventually(app, ConfigKeys.newConfigKey(Object.class, "key2")), + 6); + } + + + @Test public void testDslRecursiveFails() throws Exception { final Entity app = createAndStartApplication( "services:",
