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 52bef869b2ad4836dd56874ecf208480d2dd710c Author: Bertrand Delacretaz <bdelacre...@apache.org> AuthorDate: Tue Dec 15 12:31:34 2015 +0000 SLING-5355 - initial parser and tests git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/acldef-parser@1720142 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 92 ++++++++++++++++ .../parser/operations/CreateServiceUser.java | 29 +++++ .../parser/operations/DeleteServiceUser.java | 29 +++++ .../sling/acldef/parser/operations/Operation.java | 30 +++++ .../acldef/parser/operations/OperationVisitor.java | 23 ++++ .../parser/operations/ServiceUserOperation.java | 31 ++++++ src/main/javacc/ACLDefinitions.jjt | 121 +++++++++++++++++++++ .../sling/acldef/parser/test/ParserTest.java | 118 ++++++++++++++++++++ src/test/resources/testcases/test-1-output.txt | 4 + src/test/resources/testcases/test-1.txt | 2 + src/test/resources/testcases/test-2-output.txt | 3 + src/test/resources/testcases/test-2.txt | 2 + src/test/resources/testcases/test-3-output.txt | 1 + src/test/resources/testcases/test-3.txt | 10 ++ 14 files changed, 495 insertions(+) diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..ec88c3c --- /dev/null +++ b/pom.xml @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.sling</groupId> + <artifactId>sling</artifactId> + <version>25</version> + <relativePath/> + </parent> + + <artifactId>org.apache.sling.acldef.parser</artifactId> + <packaging>bundle</packaging> + <version>0.0.1-SNAPSHOT</version> + <name>Apache Sling ACL Definitions Parser</name> + <description>Parser for an ACL Definition Language used in Sling</description> + + <scm> + <connection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/acldef-parser</connection> + <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/acldef-parser</developerConnection> + <url>https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/acldef-parser</url> + </scm> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + </plugin> + <plugin> + <groupId>org.apache.rat</groupId> + <artifactId>apache-rat-plugin</artifactId> + <configuration> + <excludes> + <exclude>src/test/resources/testcases/**</exclude> + </excludes> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>javacc-maven-plugin</artifactId> + <version>2.5</version> + <executions> + <execution> + <id>calculator</id> + <configuration> + <sourceDirectory>${basedir}/src/main/javacc</sourceDirectory> + </configuration> + <goals> + <goal>jjtree-javacc</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.5</version> + </dependency> + </dependencies> +</project> diff --git a/src/main/java/org/apache/sling/acldef/parser/operations/CreateServiceUser.java b/src/main/java/org/apache/sling/acldef/parser/operations/CreateServiceUser.java new file mode 100644 index 0000000..fcf60a1 --- /dev/null +++ b/src/main/java/org/apache/sling/acldef/parser/operations/CreateServiceUser.java @@ -0,0 +1,29 @@ +/* + * 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; + +public class CreateServiceUser extends ServiceUserOperation { + public CreateServiceUser(String username) { + super(username); + } + + @Override + public void accept(OperationVisitor v) { + v.visitCreateServiceUser(this); + } +} diff --git a/src/main/java/org/apache/sling/acldef/parser/operations/DeleteServiceUser.java b/src/main/java/org/apache/sling/acldef/parser/operations/DeleteServiceUser.java new file mode 100644 index 0000000..378fdd4 --- /dev/null +++ b/src/main/java/org/apache/sling/acldef/parser/operations/DeleteServiceUser.java @@ -0,0 +1,29 @@ +/* + * 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; + +public class DeleteServiceUser extends ServiceUserOperation { + public DeleteServiceUser(String username) { + super(username); + } + + @Override + public void accept(OperationVisitor v) { + v.visitDeleteServiceUser(this); + } +} diff --git a/src/main/java/org/apache/sling/acldef/parser/operations/Operation.java b/src/main/java/org/apache/sling/acldef/parser/operations/Operation.java new file mode 100644 index 0000000..3c5c6cc --- /dev/null +++ b/src/main/java/org/apache/sling/acldef/parser/operations/Operation.java @@ -0,0 +1,30 @@ +/* + * 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; + +public abstract class Operation { + public abstract void accept(OperationVisitor v); + + protected abstract String getParametersDescription(); + + @Override + public String toString() { + return getClass().getSimpleName() + " " + getParametersDescription(); + } + +} 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 new file mode 100644 index 0000000..2c46128 --- /dev/null +++ b/src/main/java/org/apache/sling/acldef/parser/operations/OperationVisitor.java @@ -0,0 +1,23 @@ +/* + * 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; + +public interface OperationVisitor { + void visitCreateServiceUser(CreateServiceUser s); + void visitDeleteServiceUser(DeleteServiceUser s); +} diff --git a/src/main/java/org/apache/sling/acldef/parser/operations/ServiceUserOperation.java b/src/main/java/org/apache/sling/acldef/parser/operations/ServiceUserOperation.java new file mode 100644 index 0000000..45e4c93 --- /dev/null +++ b/src/main/java/org/apache/sling/acldef/parser/operations/ServiceUserOperation.java @@ -0,0 +1,31 @@ +/* + * 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; + +public abstract class ServiceUserOperation extends Operation { + protected final String username; + + ServiceUserOperation(String username) { + this.username = username; + } + + protected String getParametersDescription() { + return username; + } + +} diff --git a/src/main/javacc/ACLDefinitions.jjt b/src/main/javacc/ACLDefinitions.jjt new file mode 100644 index 0000000..e3ede86 --- /dev/null +++ b/src/main/javacc/ACLDefinitions.jjt @@ -0,0 +1,121 @@ +/* JavaCC grammar for the SLING-5355 ACL definitions language + * See https://javacc.java.net/doc/docindex.html for the JavaCC docs + */ + +options +{ + LOOKAHEAD=2; + STATIC=false; +} + +PARSER_BEGIN(ACLDefinitions) + +package org.apache.sling.acldef.parser; + +import java.util.List; +import java.util.ArrayList; + +import org.apache.sling.acldef.parser.operations.*; + +/* + * 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. + */ + +public class ACLDefinitions +{ + private List<Operation> result = null; +} + +PARSER_END(ACLDefinitions) + +SKIP : +{ + " " +| "\r" +| "\t" +| < COMMENT: "#" (~["\n"])* "\n" > +} + +TOKEN: +{ + < NUMBER: (<DIGIT>)+ ( "." (<DIGIT>)+ )? > +| < DIGIT: ["0"-"9"] > +| < SET: "set" > +| < ACL: "ACL" > +| < ON: "on" > +| < REMOVE: "remove" > +| < ALLOW: "allow" > +| < DENY: "deny" > +| < FOR: "for" > +| < CREATE: "create" > +| < DELETE: "delete" > +| < SERVICE: "service" > +| < USER: "user" > +| < USERNAME: (["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | "_" | "-")+ > +| < COMMA: "," > +| < 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>(); + } + + ( blankLine() | serviceUserStatement() ) * <EOF> + + { return result; } +} + +void blankLine() : +{} +{ + <EOL> +} + +List<String> usernameList() : +{ + Token t = null; + List<String> usernames = new ArrayList<String>(); + +} +{ + t = <USERNAME> { usernames.add(t.image); } + ( <COMMA> t = <USERNAME> { usernames.add(t.image); } )* + { return usernames; } +} + +void serviceUserStatement() : +{ + Token t; + List<String> usernames; +} +{ + (t=<CREATE> | t=<DELETE>) <SERVICE> <USER> usernames = usernameList() (<EOL> | <EOF>) + { + for(String username : usernames) { + if(CREATE == t.kind) { + result.add(new CreateServiceUser(username)); + } else { + result.add(new DeleteServiceUser(username)); + } + } + } +} \ 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 new file mode 100644 index 0000000..caccf99 --- /dev/null +++ b/src/test/java/org/apache/sling/acldef/parser/test/ParserTest.java @@ -0,0 +1,118 @@ +/* + * 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 java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +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.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. + */ +@RunWith(Parameterized.class) +public class ParserTest { + + public static final String DEFAULT_ENCODING = "UTF-8"; + + static class TestCase { + final InputStream input; + final String inputFilename; + final InputStream expected; + final String outputFilename; + + private static final String PREFIX = "/testcases/test-"; + + @Override + public String toString() { + return inputFilename; + } + + private TestCase(int index) { + inputFilename = PREFIX + index + ".txt"; + input = getClass().getResourceAsStream(inputFilename); + outputFilename = PREFIX + index + "-output.txt"; + expected = getClass().getResourceAsStream(outputFilename); + } + + static TestCase build(int index) { + final TestCase result = new TestCase(index); + if(result.input == null || result.expected == null) { + return null; + } + return result; + } + + void close() { + try { + input.close(); + } catch(IOException ignored) { + } + try { + expected.close(); + } catch(IOException ignored) { + } + } + } + + private final TestCase tc; + + @Parameters(name="{0}") + public static Collection<Object[]> data() { + final List<Object []> result = new ArrayList<Object[]>(); + for(int i=0; i < 100; i++) { + final TestCase tc = TestCase.build(i); + if(tc != null) { + result.add(new Object[] { tc }); + } + } + return result; + + } + + public ParserTest(TestCase tc) { + this.tc = tc; + } + + @Test + public void checkResult() throws ParseException, IOException { + final String expected = IOUtils.toString(tc.expected, DEFAULT_ENCODING).trim(); + try { + final StringBuilder sb = new StringBuilder(); + final List<Operation> result = new ACLDefinitions(tc.input).parse(); + for(Operation o : result) { + sb.append(o.toString()).append("\n"); + } + assertEquals(expected, sb.toString().trim()); + } finally { + tc.close(); + } + } +} \ No newline at end of file diff --git a/src/test/resources/testcases/test-1-output.txt b/src/test/resources/testcases/test-1-output.txt new file mode 100644 index 0000000..d4fde81 --- /dev/null +++ b/src/test/resources/testcases/test-1-output.txt @@ -0,0 +1,4 @@ +CreateServiceUser bob +CreateServiceUser alice +CreateServiceUser tom21 +CreateServiceUser lonesome diff --git a/src/test/resources/testcases/test-1.txt b/src/test/resources/testcases/test-1.txt new file mode 100644 index 0000000..1ad451a --- /dev/null +++ b/src/test/resources/testcases/test-1.txt @@ -0,0 +1,2 @@ +create service user bob,alice, tom21 +create service user lonesome \ No newline at end of file diff --git a/src/test/resources/testcases/test-2-output.txt b/src/test/resources/testcases/test-2-output.txt new file mode 100644 index 0000000..d2b3951 --- /dev/null +++ b/src/test/resources/testcases/test-2-output.txt @@ -0,0 +1,3 @@ +CreateServiceUser Mark-21 +DeleteServiceUser Leonardo +DeleteServiceUser Winston_32 \ No newline at end of file diff --git a/src/test/resources/testcases/test-2.txt b/src/test/resources/testcases/test-2.txt new file mode 100644 index 0000000..c0c7b7e --- /dev/null +++ b/src/test/resources/testcases/test-2.txt @@ -0,0 +1,2 @@ +create service user Mark-21 +delete service user Leonardo,Winston_32 \ No newline at end of file diff --git a/src/test/resources/testcases/test-3-output.txt b/src/test/resources/testcases/test-3-output.txt new file mode 100644 index 0000000..0178953 --- /dev/null +++ b/src/test/resources/testcases/test-3-output.txt @@ -0,0 +1 @@ +CreateServiceUser comments_test_passed diff --git a/src/test/resources/testcases/test-3.txt b/src/test/resources/testcases/test-3.txt new file mode 100644 index 0000000..49f1c07 --- /dev/null +++ b/src/test/resources/testcases/test-3.txt @@ -0,0 +1,10 @@ +# +# single-word +# We're testing the comments now +# This is A COMMENT with other things like 12, 34 +# And now for a tag, <ok> ? +# And some punctuation: .,;-_[]+"*ç%&/()=?^`" + # Also with leading whitespace. + +# blank lines work, of course +create service user comments_test_passed \ No newline at end of file -- To stop receiving notification emails like this one, please contact "commits@sling.apache.org" <commits@sling.apache.org>.