Adding support for creating / deleting groups via repoinit (#2)

Fixing as per SLING-8219
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/CreateGroup.java b/src/main/java/org/apache/sling/repoinit/parser/operations/CreateGroup.java
new file mode 100644
index 0000000..7136c65
--- /dev/null
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/CreateGroup.java
@@ -0,0 +1,61 @@
+/*
+ * 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.repoinit.parser.operations;
+
+public class CreateGroup extends Operation {
+    private final String groupname;
+    private final String path;
+
+    /** Operation that creates a group.
+     * @param username the name of the user to create
+     */
+    public CreateGroup(String groupname) {
+        this(groupname,  null);
+    }
+
+    /** Operation that creates a group.
+     * @param username the name of the group to create
+     * @param path optional path
+     */
+    public CreateGroup(String groupname, String path) {
+        this.groupname = groupname;
+        this.path = path;
+    }
+
+    @Override
+    public void accept(OperationVisitor v) {
+        v.visitCreateGroup(this);
+    }
+
+    @Override
+    protected String getParametersDescription() {
+        final StringBuilder sb = new StringBuilder(groupname);
+        if(path != null) {
+            sb.append(" with path ").append(path);
+        }
+        return sb.toString();
+    }
+
+    public String getGroupname() {
+        return groupname;
+    }
+
+    public String getPath() {
+        return path;
+    }
+}
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/DeleteGroup.java b/src/main/java/org/apache/sling/repoinit/parser/operations/DeleteGroup.java
new file mode 100644
index 0000000..be5552c
--- /dev/null
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/DeleteGroup.java
@@ -0,0 +1,43 @@
+/*
+ * 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.repoinit.parser.operations;
+
+public class DeleteGroup extends Operation {
+    private final String groupname;
+
+    /** Operation that deletes a group.
+     * @param username the name of the group to delete
+     */
+    public DeleteGroup(String groupname) {
+        this.groupname = groupname;
+    }
+
+    @Override
+    public void accept(OperationVisitor v) {
+        v.visitDeleteGroup(this);
+    }
+
+    @Override
+    protected String getParametersDescription() {
+        return groupname;
+    }
+
+    public String getGroupname() {
+        return groupname;
+    }
+}
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/OperationVisitor.java b/src/main/java/org/apache/sling/repoinit/parser/operations/OperationVisitor.java
index f84eefb..5912e93 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/OperationVisitor.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/OperationVisitor.java
@@ -21,6 +21,8 @@
 
 @ProviderType
 public interface OperationVisitor {
+    void visitCreateGroup(CreateGroup g);
+    void visitDeleteGroup(DeleteGroup g);
     void visitCreateUser(CreateUser u);
     void visitDeleteUser(DeleteUser u);
     void visitCreateServiceUser(CreateServiceUser s);
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/package-info.java b/src/main/java/org/apache/sling/repoinit/parser/operations/package-info.java
index 6b7e0d7..84d9d11 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/package-info.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/package-info.java
@@ -15,6 +15,6 @@
  * limitations under the License.
  ******************************************************************************/
 
-@org.osgi.annotation.versioning.Version("4.1.0")
+@org.osgi.annotation.versioning.Version("4.2.0")
 package org.apache.sling.repoinit.parser.operations;
 
diff --git a/src/main/javacc/RepoInitGrammar.jjt b/src/main/javacc/RepoInitGrammar.jjt
index af1ab56..43a9a6b 100644
--- a/src/main/javacc/RepoInitGrammar.jjt
+++ b/src/main/javacc/RepoInitGrammar.jjt
@@ -70,6 +70,7 @@
 |   < END: "end" >
 |   < REPOSITORY: "repository" >
 |   < USER: "user" >
+|   < GROUP: "group" >
 |   < NODETYPES: "nodetypes" >
 |   < REGISTER: "register" >
 |   < NAMESPACE: "namespace" >
@@ -135,6 +136,8 @@
         | registerNamespaceStatement(result)
         | registerNodetypesStatement(result)
         | registerPrivilegeStatement(result)
+        | createGroupStatement(result)
+        | deleteGroupStatement(result)
         | createUserStatement(result)
         | deleteUserStatement(result)
         | disableServiceUserStatement(result)
@@ -520,6 +523,37 @@
     }
 }
 
+void createGroupStatement(List<Operation> result) :
+{
+    Token group = null;
+    Token encoding = null;
+    String path = null;
+}
+{
+    <CREATE> <GROUP> 
+    ( group = <STRING> )
+    ( path = withPathStatement() ) ?
+
+    {
+        result.add(new CreateGroup(group.image,
+            path
+        ));
+    }
+}
+
+void deleteGroupStatement(List<Operation> result) :
+{
+    Token group = null;
+}
+{
+    <DELETE> <GROUP> 
+    ( group = <STRING> )
+
+    {
+        result.add(new DeleteGroup(group.image));
+    }
+}
+
 void createUserStatement(List<Operation> result) :
 {
     Token user = null;
diff --git a/src/test/java/org/apache/sling/repoinit/parser/test/OperationToStringVisitor.java b/src/test/java/org/apache/sling/repoinit/parser/test/OperationToStringVisitor.java
index 07e8dfb..7887431 100644
--- a/src/test/java/org/apache/sling/repoinit/parser/test/OperationToStringVisitor.java
+++ b/src/test/java/org/apache/sling/repoinit/parser/test/OperationToStringVisitor.java
@@ -22,9 +22,11 @@
 import java.util.List;
 
 import org.apache.sling.repoinit.parser.operations.AclLine;
+import org.apache.sling.repoinit.parser.operations.CreateGroup;
 import org.apache.sling.repoinit.parser.operations.CreatePath;
 import org.apache.sling.repoinit.parser.operations.CreateServiceUser;
 import org.apache.sling.repoinit.parser.operations.CreateUser;
+import org.apache.sling.repoinit.parser.operations.DeleteGroup;
 import org.apache.sling.repoinit.parser.operations.DeleteServiceUser;
 import org.apache.sling.repoinit.parser.operations.DeleteUser;
 import org.apache.sling.repoinit.parser.operations.DisableServiceUser;
@@ -141,4 +143,14 @@
             out.print("ACLOptions="+options);
         }
     }
+
+    @Override
+    public void visitCreateGroup(CreateGroup g) {
+        out.println(g.toString());
+    }
+
+    @Override
+    public void visitDeleteGroup(DeleteGroup g) {
+        out.println(g.toString());
+    }
 }
diff --git a/src/test/resources/testcases/test-62-output.txt b/src/test/resources/testcases/test-62-output.txt
new file mode 100644
index 0000000..0b25ba4
--- /dev/null
+++ b/src/test/resources/testcases/test-62-output.txt
@@ -0,0 +1,2 @@
+CreateGroup groupa
+CreateGroup groupb with path /thePathF
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-62.txt b/src/test/resources/testcases/test-62.txt
new file mode 100644
index 0000000..01ef58d
--- /dev/null
+++ b/src/test/resources/testcases/test-62.txt
@@ -0,0 +1,13 @@
+# Test create group statements
+# 
+# This file should contain a self-explaining example of every repoinit
+# statement, to serve as a general example.
+#
+# Please update the docs at
+# https://sling.apache.org/documentation/bundles/repository-initialization.html
+# if changing this file, it contains a somewhat adapted version of this. And
+# indicate there from which version of which bundles a new feature is available.
+#
+
+create group groupa
+create group groupb with path /thePathF
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-63-output.txt b/src/test/resources/testcases/test-63-output.txt
new file mode 100644
index 0000000..8470121
--- /dev/null
+++ b/src/test/resources/testcases/test-63-output.txt
@@ -0,0 +1 @@
+DeleteGroup groupa
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-63.txt b/src/test/resources/testcases/test-63.txt
new file mode 100644
index 0000000..62296e6
--- /dev/null
+++ b/src/test/resources/testcases/test-63.txt
@@ -0,0 +1,12 @@
+# Test create group statements
+# 
+# This file should contain a self-explaining example of every repoinit
+# statement, to serve as a general example.
+#
+# Please update the docs at
+# https://sling.apache.org/documentation/bundles/repository-initialization.html
+# if changing this file, it contains a somewhat adapted version of this. And
+# indicate there from which version of which bundles a new feature is available.
+#
+
+delete group groupa
\ No newline at end of file