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:",

Reply via email to