This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.repoinit.parser-1.0.0
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-repoinit-parser.git

commit 73dc48724a81da9d8410fd2ab193a83d09873283
Author: Bertrand Delacretaz <bdelacre...@apache.org>
AuthorDate: Thu Dec 17 12:00:58 2015 +0000

    SLING-5355 - make space for more acldef modules
    
    git-svn-id: 
https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/acldef/parser@1720527
 13f79535-47bb-0310-9956-ffa450edef68
---
 .../{OperationVisitor.java => AclGroupBase.java}   |  28 +++-
 .../sling/acldef/parser/operations/AclLine.java    |  66 ++++++++
 .../acldef/parser/operations/OperationVisitor.java |   2 +
 .../{OperationVisitor.java => SetAclPaths.java}    |  35 +++-
 ...OperationVisitor.java => SetAclPrincipals.java} |  35 +++-
 src/main/javacc/ACLDefinitions.jjt                 | 179 ++++++++++++++++++---
 .../parser/test/OperationToStringVisitor.java      |  81 ++++++++++
 .../sling/acldef/parser/test/ParserTest.java       |  17 +-
 .../acldef/parser/test/ParsingErrorsTest.java      |  89 ++++++++++
 src/test/resources/testcases/test-10-output.txt    |   5 +
 src/test/resources/testcases/test-10.txt           |  10 ++
 src/test/resources/testcases/test-11-output.txt    |   5 +
 src/test/resources/testcases/test-11.txt           |   8 +
 src/test/resources/testcases/test-30-output.txt    |   6 +
 src/test/resources/testcases/test-30.txt           |  12 ++
 src/test/resources/testcases/test-99-output.txt    |  17 ++
 src/test/resources/testcases/test-99.txt           |  28 ++++
 17 files changed, 581 insertions(+), 42 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java 
b/src/main/java/org/apache/sling/acldef/parser/operations/AclGroupBase.java
similarity index 56%
copy from 
src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java
copy to 
src/main/java/org/apache/sling/acldef/parser/operations/AclGroupBase.java
index 2c46128..995d00b 100644
--- 
a/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java
+++ b/src/main/java/org/apache/sling/acldef/parser/operations/AclGroupBase.java
@@ -17,7 +17,27 @@
 
 package org.apache.sling.acldef.parser.operations;
 
-public interface OperationVisitor {
-    void visitCreateServiceUser(CreateServiceUser s);
-    void visitDeleteServiceUser(DeleteServiceUser s);
-}
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/** Base class for operations that group AclLines */
+ abstract class AclGroupBase extends Operation {
+    private final List<AclLine> lines;
+    
+    protected AclGroupBase(List<AclLine> lines) {
+        this.lines = Collections.unmodifiableList(lines);
+    }
+    
+    protected String getParametersDescription() {
+        final StringBuilder sb = new StringBuilder();
+        for(AclLine line : lines) {
+            sb.append("\n  ").append(line.toString());
+        }
+        return sb.toString(); 
+    }
+    
+    public Collection<AclLine> getLines() {
+        return lines;
+    }
+}
\ No newline at end of file
diff --git 
a/src/main/java/org/apache/sling/acldef/parser/operations/AclLine.java 
b/src/main/java/org/apache/sling/acldef/parser/operations/AclLine.java
new file mode 100644
index 0000000..0e47dcd
--- /dev/null
+++ b/src/main/java/org/apache/sling/acldef/parser/operations/AclLine.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sling.acldef.parser.operations;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/** A single "set ACL" line */
+public class AclLine {
+    
+    private final Action action;
+    private static final List<String> EMPTY_LIST = 
Collections.unmodifiableList(new ArrayList<String>());
+    
+    public enum Action {
+        REMOVE,
+        REMOVE_ALL,
+        DENY,
+        ALLOW
+    };
+    
+    private final Map<String, List<String>> properties;
+    
+    public AclLine(Action a) {
+        action = a;
+        properties = new TreeMap<String, List<String>>();
+    }
+    
+    public Action getAction() {
+        return action;
+    }
+    
+    /** Return the named multi-value property, or an empty list
+     *  if not found. 
+     */
+    public List<String> getProperty(String name) {
+        List<String> value = properties.get(name);
+        return value != null ? value : EMPTY_LIST;
+    }
+    
+    public void setProperty(String name, List<String> values) {
+        properties.put(name, Collections.unmodifiableList(values));
+    }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + " " + action + " " + properties;
+    }
+}
diff --git 
a/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java 
b/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java
index 2c46128..898310f 100644
--- 
a/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java
+++ 
b/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java
@@ -20,4 +20,6 @@ package org.apache.sling.acldef.parser.operations;
 public interface OperationVisitor {
     void visitCreateServiceUser(CreateServiceUser s);
     void visitDeleteServiceUser(DeleteServiceUser s);
+    void visitSetAclPrincipal(SetAclPrincipals s);
+    void visitSetAclPaths(SetAclPaths s);
 }
diff --git 
a/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java 
b/src/main/java/org/apache/sling/acldef/parser/operations/SetAclPaths.java
similarity index 51%
copy from 
src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java
copy to src/main/java/org/apache/sling/acldef/parser/operations/SetAclPaths.java
index 2c46128..9b2a4c6 100644
--- 
a/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java
+++ b/src/main/java/org/apache/sling/acldef/parser/operations/SetAclPaths.java
@@ -17,7 +17,34 @@
 
 package org.apache.sling.acldef.parser.operations;
 
-public interface OperationVisitor {
-    void visitCreateServiceUser(CreateServiceUser s);
-    void visitDeleteServiceUser(DeleteServiceUser s);
-}
+import java.util.Collections;
+import java.util.List;
+
+/** Set ACL statement that groups a set of AclLines
+ *  that all refer to the same set of paths.
+ */
+public class SetAclPaths extends AclGroupBase {
+    
+    private final List<String> paths;
+    
+    public SetAclPaths(List<String> paths, List<AclLine> lines) {
+        super(lines);
+        this.paths = Collections.unmodifiableList(paths);
+    }
+    
+    protected String getParametersDescription() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append(paths);
+        sb.append(super.getParametersDescription());
+        return sb.toString(); 
+    }
+    
+    public List<String> getPaths() {
+        return paths;
+    }
+
+    @Override
+    public void accept(OperationVisitor v) {
+        v.visitSetAclPaths(this);
+    }
+}
\ No newline at end of file
diff --git 
a/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java 
b/src/main/java/org/apache/sling/acldef/parser/operations/SetAclPrincipals.java
similarity index 50%
copy from 
src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java
copy to 
src/main/java/org/apache/sling/acldef/parser/operations/SetAclPrincipals.java
index 2c46128..8c79a31 100644
--- 
a/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java
+++ 
b/src/main/java/org/apache/sling/acldef/parser/operations/SetAclPrincipals.java
@@ -17,7 +17,34 @@
 
 package org.apache.sling.acldef.parser.operations;
 
-public interface OperationVisitor {
-    void visitCreateServiceUser(CreateServiceUser s);
-    void visitDeleteServiceUser(DeleteServiceUser s);
-}
+import java.util.Collections;
+import java.util.List;
+
+/** Set ACL statement that groups a set of AclLines
+ *  that all refer to the same set of principals.
+ */
+public class SetAclPrincipals extends AclGroupBase {
+    
+    private final List<String> principals;
+    
+    public SetAclPrincipals(List<String> principals, List<AclLine> lines) {
+        super(lines);
+        this.principals = Collections.unmodifiableList(principals);
+    }
+    
+    protected String getParametersDescription() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append(principals);
+        sb.append(super.getParametersDescription());
+        return sb.toString(); 
+    }
+    
+    public List<String> getPrincipals() {
+        return principals;
+    }
+
+    @Override
+    public void accept(OperationVisitor v) {
+        v.visitSetAclPrincipal(this);
+    }
+}
\ No newline at end of file
diff --git a/src/main/javacc/ACLDefinitions.jjt 
b/src/main/javacc/ACLDefinitions.jjt
index e3ede86..1de9b00 100644
--- a/src/main/javacc/ACLDefinitions.jjt
+++ b/src/main/javacc/ACLDefinitions.jjt
@@ -4,7 +4,7 @@
  
 options
 {
-    LOOKAHEAD=2;
+    LOOKAHEAD=3;
     STATIC=false;
 }
 
@@ -36,7 +36,10 @@ import org.apache.sling.acldef.parser.operations.*;
 
 public class ACLDefinitions
 {
-    private List<Operation> result = null;
+    public static final String PROP_PATHS = "paths";
+    public static final String PROP_PRINCIPALS = "principals";
+    public static final String PROP_PRIVILEGES = "privileges";
+    public static final String PROP_NODETYPES = "nodetypes";
 }
 
 PARSER_END(ACLDefinitions)
@@ -51,9 +54,7 @@ SKIP :
 
 TOKEN:
 {
-    < NUMBER: (<DIGIT>)+ ( "." (<DIGIT>)+ )? >
-|   < DIGIT: ["0"-"9"] >
-|   < SET: "set" >
+    < SET: "set" >
 |   < ACL: "ACL" >
 |   < ON: "on" >
 |   < REMOVE: "remove" >
@@ -63,23 +64,29 @@ TOKEN:
 |   < CREATE: "create" >
 |   < DELETE: "delete" >
 |   < SERVICE: "service" >
+|   < END: "end" >
 |   < USER: "user" >
-|   < USERNAME: (["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | "_" | "-")+ >
+|   < NODETYPES: "nodetypes" >
+|   < PRINCIPAL: (["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | "_" | "-")+ >
 |   < COMMA: "," >
+|   < STAR: "*" >
+|   < NAMESPACED_ITEM: (["a"-"z"] | ["A"-"Z"])+ ":" (["a"-"z"] | ["A"-"Z"])+ >
+|   < PATH: "/" (["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | ["-"] | ["_"] | ["."] | 
["/"]) * >
 |   < EOL: "\n" >
 }
 
 List<Operation> parse() :
 {}
 {
-    {
-        if(result != null) {
-            throw new IllegalStateException("This parser cannot be reused, 
please create a new one");
-        }
-        result = new ArrayList<Operation>();
-    }
+    { final List<Operation> result = new ArrayList<Operation>(); }
     
-    ( blankLine() | serviceUserStatement() ) * <EOF>
+    ( 
+        serviceUserStatement(result) 
+        | setAclPaths(result) 
+        | setAclPrincipals(result) 
+        | blankLine() 
+    ) * 
+    <EOF>
     
     { return result; }
 }
@@ -90,32 +97,154 @@ void blankLine() :
     <EOL>
 }
 
-List<String> usernameList() :
+List<String> principalsList() :
 {
     Token t = null;
-    List<String> usernames = new ArrayList<String>(); 
-    
+    List<String> principals = new ArrayList<String>(); 
 }
 {
-    t = <USERNAME> { usernames.add(t.image); } 
-    ( <COMMA> t = <USERNAME> { usernames.add(t.image); } )* 
-    { return usernames; }
+    t = <PRINCIPAL> { principals.add(t.image); } 
+    ( <COMMA> t = <PRINCIPAL> { principals.add(t.image); } )* 
+    { return principals; }
 }
 
-void serviceUserStatement() :
+void serviceUserStatement(List<Operation> result) :
 {
     Token t;
-    List<String> usernames;
+    List<String> principals;
 }
 {
-    (t=<CREATE> | t=<DELETE>) <SERVICE> <USER> usernames = usernameList() 
(<EOL> | <EOF>)
+    (t=<CREATE> | t=<DELETE>) 
+    <SERVICE> <USER> 
+    principals = principalsList() 
+    (<EOL> | <EOF>)
+    
     {
-        for(String username : usernames) {
+        for(String PRINCIPAL : principals) {
             if(CREATE == t.kind) {
-                result.add(new CreateServiceUser(username));
+                result.add(new CreateServiceUser(PRINCIPAL));
             } else {
-                result.add(new DeleteServiceUser(username));
+                result.add(new DeleteServiceUser(PRINCIPAL));
             }
         } 
     }
+}
+
+List<String> namespacedItemsList() :
+{
+    Token t = null;
+    List<String> priv = new ArrayList<String>(); 
+    
+}
+{
+    t = <NAMESPACED_ITEM> { priv.add(t.image); } 
+    ( <COMMA> t = <NAMESPACED_ITEM> { priv.add(t.image); } )* 
+    { return priv; }
+}
+
+List<String> pathsList() :
+{
+    Token t = null;
+    List<String> paths = new ArrayList<String>(); 
+    
+}
+{
+    t = <PATH> { paths.add(t.image); } 
+    ( <COMMA> t = <PATH> { paths.add(t.image); } )* 
+    { return paths; }
+}
+
+void setAclPaths(List<Operation> result) :
+{
+    List<String> paths;
+    List<AclLine> lines = new ArrayList<AclLine>();
+} 
+{
+    <SET> <ACL> <ON> paths  = pathsList() <EOL>
+    ( removeStarLine(lines) | userPrivilegesLine(lines) | blankLine() ) +
+    <END> 
+    ( <EOL> | <EOF> )
+    
+    {
+        result.add(new SetAclPaths(paths, lines));
+    }
+}
+
+void removeStarLine(List<AclLine> lines) : 
+{
+    List<String> tmp = null;
+    AclLine line = new AclLine(AclLine.Action.REMOVE_ALL);
+}
+{
+    <REMOVE> <STAR> 
+    (
+        <FOR> tmp = principalsList() { line.setProperty(PROP_PRINCIPALS, tmp); 
}
+        
+        | <ON> tmp = pathsList() { line.setProperty(PROP_PATHS, tmp); }
+    )     
+    <EOL>
+    
+    {
+        lines.add(line);
+    }
+}
+
+AclLine privilegesLineOperation() :
+{}
+{
+    ( 
+        <REMOVE>        { return new AclLine(AclLine.Action.REMOVE); }
+        | ( <ALLOW>     { return new AclLine(AclLine.Action.ALLOW); } )
+        | ( <DENY>      { return new AclLine(AclLine.Action.DENY); } )    
+    ) 
+}
+
+void userPrivilegesLine(List<AclLine> lines) :
+{
+    AclLine line;
+    List<String> tmp;
+}
+{
+    line = privilegesLineOperation()
+    tmp = namespacedItemsList() { line.setProperty(PROP_PRIVILEGES, tmp); } 
+    <FOR>
+    tmp = principalsList() { line.setProperty(PROP_PRINCIPALS, tmp); }
+    <EOL>
+
+    {   
+        lines.add(line); 
+    }
+}
+
+void pathPrivilegesLine(List<AclLine> lines) : 
+{
+    AclLine line;
+    List<String> tmp;
+}
+{
+    line = privilegesLineOperation()
+    tmp = namespacedItemsList() { line.setProperty(PROP_PRIVILEGES, tmp); } 
+    <ON> tmp = pathsList() { line.setProperty(PROP_PATHS, tmp); }
+    ( <NODETYPES> tmp = namespacedItemsList() { 
line.setProperty(PROP_NODETYPES, tmp); }) ?
+    <EOL>
+    
+    {    
+        lines.add(line); 
+    }
+}
+
+void setAclPrincipals(List<Operation> result) :
+{
+    List <String> principals;
+    List<AclLine> lines = new ArrayList<AclLine>();
+}
+{
+    <SET> <ACL> <FOR> principals = principalsList() <EOL>
+    ( removeStarLine(lines) | pathPrivilegesLine(lines) | blankLine() ) +
+    <END> 
+    ( <EOL> | <EOF> )
+    
+    {
+        result.add(new SetAclPrincipals(principals, lines));
+    }
 }
\ No newline at end of file
diff --git 
a/src/test/java/org/apache/sling/acldef/parser/test/OperationToStringVisitor.java
 
b/src/test/java/org/apache/sling/acldef/parser/test/OperationToStringVisitor.java
new file mode 100644
index 0000000..fb27655
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/acldef/parser/test/OperationToStringVisitor.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sling.acldef.parser.test;
+
+import java.io.PrintWriter;
+import java.util.Collection;
+
+import org.apache.sling.acldef.parser.operations.AclLine;
+import org.apache.sling.acldef.parser.operations.CreateServiceUser;
+import org.apache.sling.acldef.parser.operations.DeleteServiceUser;
+import org.apache.sling.acldef.parser.operations.OperationVisitor;
+import org.apache.sling.acldef.parser.operations.SetAclPaths;
+import org.apache.sling.acldef.parser.operations.SetAclPrincipals;
+
+/** OperationVisitor that dumps the operations using
+ *  their toString() methods
+ */
+class OperationToStringVisitor implements OperationVisitor {
+
+    private final PrintWriter out;
+    
+    OperationToStringVisitor(PrintWriter pw) {
+        out = pw;
+    }
+    
+    @Override
+    public void visitCreateServiceUser(CreateServiceUser s) {
+        out.println(s.toString());
+    }
+
+    @Override
+    public void visitDeleteServiceUser(DeleteServiceUser s) {
+        out.println(s.toString());
+    }
+
+    @Override
+    public void visitSetAclPrincipal(SetAclPrincipals s) {
+        out.print(s.getClass().getSimpleName());
+        out.print(" for ");
+        for(String p : s.getPrincipals()) {
+            out.print(p);
+            out.print(' ');
+        }
+        out.println();
+        dumpAclLines(s.getLines());
+    }
+    
+    @Override
+    public void visitSetAclPaths(SetAclPaths s) {
+        out.print(s.getClass().getSimpleName());
+        out.print(" on ");
+        for(String p : s.getPaths()) {
+            out.print(p);
+            out.print(' ');
+        }
+        out.println();
+        dumpAclLines(s.getLines());
+    }
+    
+    private void dumpAclLines(Collection<AclLine> c) {
+        for(AclLine line : c) {
+            out.print("  ");
+            out.println(line);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/acldef/parser/test/ParserTest.java 
b/src/test/java/org/apache/sling/acldef/parser/test/ParserTest.java
index caccf99..c76fe20 100644
--- a/src/test/java/org/apache/sling/acldef/parser/test/ParserTest.java
+++ b/src/test/java/org/apache/sling/acldef/parser/test/ParserTest.java
@@ -21,6 +21,8 @@ import static org.junit.Assert.assertEquals;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -29,13 +31,16 @@ import org.apache.commons.io.IOUtils;
 import org.apache.sling.acldef.parser.ACLDefinitions;
 import org.apache.sling.acldef.parser.ParseException;
 import org.apache.sling.acldef.parser.operations.Operation;
+import org.apache.sling.acldef.parser.operations.OperationVisitor;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
-/** Test the parser using our test-* 
- *  input/expected output files.
+/** Test the parser using our test-* input/expected output files. 
+ *  The code of this class doesn't contain any actual tests, it
+ *  just looks for test-*.txt files, parses them and verifies the
+ *  results according to the test-*-output.txt files.
  */
 @RunWith(Parameterized.class)
 public class ParserTest {
@@ -105,12 +110,14 @@ public class ParserTest {
     public void checkResult() throws ParseException, IOException {
         final String expected = IOUtils.toString(tc.expected, 
DEFAULT_ENCODING).trim();
         try {
-            final StringBuilder sb = new StringBuilder();
+            final StringWriter sw = new StringWriter();
+            final OperationVisitor v = new OperationToStringVisitor(new 
PrintWriter(sw)); 
             final List<Operation> result = new 
ACLDefinitions(tc.input).parse(); 
             for(Operation o : result) {
-                sb.append(o.toString()).append("\n");
+                o.accept(v);
             }
-            assertEquals(expected, sb.toString().trim());
+            sw.flush();
+            assertEquals(expected, sw.toString().trim());
         } finally {
             tc.close();
         }
diff --git 
a/src/test/java/org/apache/sling/acldef/parser/test/ParsingErrorsTest.java 
b/src/test/java/org/apache/sling/acldef/parser/test/ParsingErrorsTest.java
new file mode 100644
index 0000000..37cdbd4
--- /dev/null
+++ b/src/test/java/org/apache/sling/acldef/parser/test/ParsingErrorsTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sling.acldef.parser.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.sling.acldef.parser.ACLDefinitions;
+import org.apache.sling.acldef.parser.ParseException;
+import org.apache.sling.acldef.parser.TokenMgrError;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/** Test various parsing errors */
+@RunWith(Parameterized.class)
+public class ParsingErrorsTest {
+
+    private String input;
+    private Class<? extends Throwable> expected;
+    
+    @Parameters
+    public static Collection<Object[]> data() {
+        @SuppressWarnings("serial")
+        final List<Object []> result = new ArrayList<Object []>() {{
+            add(new Object[] { "foo", ParseException.class  });
+            add(new Object[] { "12", ParseException.class  });
+            
+            add(new Object[] { "set ACL on /apps \n remove * for u \n end", 
null });
+            add(new Object[] { "set ACL on /apps \n badkeyword * for u \n 
end", ParseException.class });
+            add(new Object[] { "set ACL on appsWithoutSlash \n remove * for u 
\n end", ParseException.class  });
+            add(new Object[] { "set ACL", ParseException.class  });
+            add(new Object[] { "set ACL \n end", ParseException.class  });
+            
+            add(new Object[] { "create service user bob, alice, tom21", null  
});
+            add(new Object[] { "create service user bob-221_BOB", null  });
+            add(new Object[] { "create service user bob/221", 
ParseException.class  });
+            add(new Object[] { "create service user bob,/alice, tom21", 
ParseException.class  });
+            add(new Object[] { "create service user bob,alice,tom21 # comment 
not allowed here", TokenMgrError.class  });
+            add(new Object[] { "CREATE service user bob, alice, tom21", 
ParseException.class });
+            add(new Object[] { "create SERVICE user bob, alice, tom21", 
ParseException.class });
+        }};
+        return result;
+    }
+    
+    public ParsingErrorsTest(String input, Class<? extends Throwable> 
expected) {
+        this.input = input;
+        this.expected = expected;
+    }
+
+    @Test
+    public void checkResult() throws ParseException, IOException {
+        final StringReader r = new StringReader(input);
+        try {
+            new ACLDefinitions(r).parse();
+            if(expected != null) {
+                fail("Expected a " + expected.getSimpleName() + " for [" + 
input + "]");
+            }
+        } catch(Exception e) {
+            assertEquals(expected, e.getClass());
+        } catch(Error err) {
+            assertEquals(expected, err.getClass());
+        } finally {
+            r.close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-10-output.txt 
b/src/test/resources/testcases/test-10-output.txt
new file mode 100644
index 0000000..c9106ac
--- /dev/null
+++ b/src/test/resources/testcases/test-10-output.txt
@@ -0,0 +1,5 @@
+SetAclPaths on /libs /apps / /content/example.com/some-other_path 
+  AclLine REMOVE_ALL {principals=[user1, user2]}
+  AclLine ALLOW {principals=[user1, user2], privileges=[jcr:read]}
+  AclLine DENY {principals=[user2], privileges=[jcr:write, something:else, 
another:one]}
+  AclLine DENY {principals=[user1], privileges=[jcr:lockManagement]}
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-10.txt 
b/src/test/resources/testcases/test-10.txt
new file mode 100644
index 0000000..db91e9f
--- /dev/null
+++ b/src/test/resources/testcases/test-10.txt
@@ -0,0 +1,10 @@
+# Set ACL example from SLING-5355
+# Without the "with glob" option, we're not planning to support
+# that at this time. 
+set ACL on /libs,/apps, /, /content/example.com/some-other_path
+    remove * for user1,user2
+    allow jcr:read for user1,user2
+
+    deny jcr:write,something:else,another:one for user2
+    deny jcr:lockManagement for user1
+end
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-11-output.txt 
b/src/test/resources/testcases/test-11-output.txt
new file mode 100644
index 0000000..aceed38
--- /dev/null
+++ b/src/test/resources/testcases/test-11-output.txt
@@ -0,0 +1,5 @@
+SetAclPaths on /libs /apps 
+  AclLine REMOVE_ALL {principals=[user1, user2]}
+  AclLine ALLOW {principals=[user1, user2], privileges=[jcr:read]}
+  AclLine REMOVE_ALL {principals=[another]}
+  AclLine ALLOW {principals=[another], privileges=[x:y]}
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-11.txt 
b/src/test/resources/testcases/test-11.txt
new file mode 100644
index 0000000..7d27a2a
--- /dev/null
+++ b/src/test/resources/testcases/test-11.txt
@@ -0,0 +1,8 @@
+# Test multiple remove lines
+set ACL on /libs,/apps
+    remove * for user1,user2
+    allow jcr:read for user1,user2
+
+    remove * for another
+    allow x:y for another
+end
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-30-output.txt 
b/src/test/resources/testcases/test-30-output.txt
new file mode 100644
index 0000000..e619a2f
--- /dev/null
+++ b/src/test/resources/testcases/test-30-output.txt
@@ -0,0 +1,6 @@
+SetAclPrincipals for user1 u2 
+  AclLine REMOVE_ALL {paths=[/libs, /apps]}
+  AclLine ALLOW {paths=[/content], privileges=[jcr:read]}
+  AclLine DENY {paths=[/apps], privileges=[jcr:write]}
+  AclLine DENY {nodetypes=[sling:Folder, nt:unstructured], paths=[/apps, 
/content], privileges=[jcr:lockManagement]}
+  AclLine REMOVE {paths=[/apps], privileges=[jcr:understand, some:other]}
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-30.txt 
b/src/test/resources/testcases/test-30.txt
new file mode 100644
index 0000000..c70f928
--- /dev/null
+++ b/src/test/resources/testcases/test-30.txt
@@ -0,0 +1,12 @@
+# Test the principal-centered ACL syntax
+
+set ACL for user1,u2
+    remove * on /libs,/apps
+    allow jcr:read on /content
+
+    deny jcr:write on /apps
+    
+    # Optional nodetypes clause 
+    deny jcr:lockManagement on /apps, /content nodetypes sling:Folder, 
nt:unstructured   
+    remove jcr:understand,some:other on /apps
+end
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-99-output.txt 
b/src/test/resources/testcases/test-99-output.txt
new file mode 100644
index 0000000..ec98fc4
--- /dev/null
+++ b/src/test/resources/testcases/test-99-output.txt
@@ -0,0 +1,17 @@
+CreateServiceUser user1
+CreateServiceUser u-ser_2
+SetAclPaths on /libs /apps 
+  AclLine REMOVE_ALL {principals=[user1, u-ser_2]}
+  AclLine ALLOW {principals=[user1, u-ser_2], privileges=[jcr:read]}
+  AclLine DENY {principals=[u-ser_2], privileges=[jcr:write]}
+  AclLine DENY {principals=[user1], privileges=[jcr:lockManagement]}
+  AclLine REMOVE {principals=[u3], privileges=[jcr:understand, some:other]}
+CreateServiceUser bob_the_service
+SetAclPaths on /tmp 
+  AclLine ALLOW {principals=[bob_the_service], 
privileges=[some:otherPrivilege]}
+SetAclPrincipals for alice bob fred 
+  AclLine REMOVE_ALL {paths=[/]}
+  AclLine ALLOW {paths=[/content, /var], privileges=[jcr:read]}
+  AclLine DENY {paths=[/content/example.com], privileges=[jcr:write]}
+  AclLine DENY {nodetypes=[example:Page], paths=[/], privileges=[jcr:all]}
+CreateServiceUser the-last-one
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-99.txt 
b/src/test/resources/testcases/test-99.txt
new file mode 100644
index 0000000..67e0949
--- /dev/null
+++ b/src/test/resources/testcases/test-99.txt
@@ -0,0 +1,28 @@
+# Complete example with several intermixed statement types
+
+create service user user1, u-ser_2
+set ACL on /libs,/apps
+    remove * for user1,u-ser_2
+    allow jcr:read for user1,u-ser_2
+
+    deny jcr:write for u-ser_2
+    deny jcr:lockManagement for user1
+    remove jcr:understand,some:other for u3
+end
+
+create service user bob_the_service
+
+# Verify that indent is not required
+set ACL on /tmp
+allow some:otherPrivilege for bob_the_service
+end
+
+set ACL for alice, bob,fred
+    remove * on /
+    allow jcr:read on /content,/var
+    deny jcr:write on /content/example.com
+    deny jcr:all on / nodetypes example:Page
+    
+end
+
+create service user the-last-one
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <commits@sling.apache.org>.

Reply via email to