/* JavaCC grammar for the SLING-5449 content repository * initialization language * See https://javacc.java.net/doc/docindex.html for the JavaCC docs */ options { STATIC=false; LOOKAHEAD=3; //FORCE_LA_CHECK=true; //DEBUG_PARSER=true; //DEBUG_LOOKAHEAD=true; } PARSER_BEGIN(RepoInitParserImpl) package org.apache.sling.repoinit.parser.impl; import java.util.List; import java.util.ArrayList; import org.apache.sling.repoinit.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 RepoInitParserImpl { } PARSER_END(RepoInitParserImpl) SKIP : { " " | "\r" | "\t" | < COMMENT: "#" (~["\n"])* "\n" > } TOKEN: { < SET: "set" > | < ACL: "ACL" > | < ON: "on" > | < REMOVE: "remove" > | < ALLOW: "allow" > | < DENY: "deny" > | < FOR: "for" > | < CREATE: "create" > | < DELETE: "delete" > | < SERVICE: "service" > | < PATH: "path" > | < END: "end" > | < USER: "user" > | < NODETYPES: "nodetypes" > | < REGISTER: "register" > | < NAMESPACE: "namespace" > | < START_TEXTBLOCK: "<<===" > : TEXTBLOCK | < LPAREN: "(" > | < RPAREN: ")" > | < COMMA: "," > | < STAR: "*" > /* The order of these fuzzy statements is important (first match wins?) */ | < NAMESPACED_ITEM: (["a"-"z"] | ["A"-"Z"])+ ":" (["a"-"z"] | ["A"-"Z"])+ > | < PATH_STRING: "/" (["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | ["-"] | ["_"] | ["."] | ["/"]) * > | < STRING: (["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | ["-"] | ["_"] | ["."] | ["/"] | [":"]) * > | < EOL: "\n" > } SKIP : { "\r" } TOKEN : { < TEXT : ~[] > | < END_TEXTBLOCK: "===>>" > : DEFAULT } List parse() : {} { { final List result = new ArrayList(); } ( serviceUserStatement(result) | setAclPaths(result) | setAclPrincipals(result) | createPathStatement(result) | registerNamespaceStatement(result) | registerNodetypesStatement(result) | blankLine() ) * { return result; } } void blankLine() : {} { } List principalsList() : { Token t = null; List principals = new ArrayList(); } { t = { principals.add(t.image); } ( t = { principals.add(t.image); } )* { return principals; } } void serviceUserStatement(List result) : { Token t; List principals; } { (t= | t=) principals = principalsList() ( | ) { for(String principal : principals) { if(CREATE == t.kind) { result.add(new CreateServiceUser(principal)); } else { result.add(new DeleteServiceUser(principal)); } } } } List namespacedItemsList() : { Token t = null; List priv = new ArrayList(); } { t = { priv.add(t.image); } ( t = { priv.add(t.image); } )* { return priv; } } List pathsList() : { Token t = null; List paths = new ArrayList(); } { t = { paths.add(t.image); } ( t = { paths.add(t.image); } )* { return paths; } } void createPathStatement(List result) : { CreatePath cp = null; String defaultPrimaryType = null; Token t1 = null; Token t2 = null; } { ( t1 = { defaultPrimaryType = t1.image; } ) ? ( t1 = ( t2 = ) ? { if(cp == null) { cp = new CreatePath(defaultPrimaryType); } cp.addSegment(t1.image, t2 == null ? null : t2.image); t2 = null; } ) + ( | ) { if(cp != null) result.add(cp); } } void setAclPaths(List result) : { List paths; List lines = new ArrayList(); } { paths = pathsList() ( removeStarLine(lines) | userPrivilegesLine(lines) | blankLine() ) + ( | ) { result.add(new SetAclPaths(paths, lines)); } } void removeStarLine(List lines) : { List tmp = null; AclLine line = new AclLine(AclLine.Action.REMOVE_ALL); } { ( tmp = principalsList() { line.setProperty(AclLine.PROP_PRINCIPALS, tmp); } | tmp = pathsList() { line.setProperty(AclLine.PROP_PATHS, tmp); } ) { lines.add(line); } } AclLine privilegesLineOperation() : {} { ( { return new AclLine(AclLine.Action.REMOVE); } | ( { return new AclLine(AclLine.Action.ALLOW); } ) | ( { return new AclLine(AclLine.Action.DENY); } ) ) } void userPrivilegesLine(List lines) : { AclLine line; List tmp; } { line = privilegesLineOperation() tmp = namespacedItemsList() { line.setProperty(AclLine.PROP_PRIVILEGES, tmp); } tmp = principalsList() { line.setProperty(AclLine.PROP_PRINCIPALS, tmp); } { lines.add(line); } } void pathPrivilegesLine(List lines) : { AclLine line; List tmp; } { line = privilegesLineOperation() tmp = namespacedItemsList() { line.setProperty(AclLine.PROP_PRIVILEGES, tmp); } tmp = pathsList() { line.setProperty(AclLine.PROP_PATHS, tmp); } ( tmp = namespacedItemsList() { line.setProperty(AclLine.PROP_NODETYPES, tmp); }) ? { lines.add(line); } } void setAclPrincipals(List result) : { List principals; List lines = new ArrayList(); } { principals = principalsList() ( removeStarLine(lines) | pathPrivilegesLine(lines) | blankLine() ) + ( | ) { result.add(new SetAclPrincipals(principals, lines)); } } void registerNamespaceStatement(List result) : { Token prefix = null; Token uri; } { prefix = uri = { result.add(new RegisterNamespace(prefix.image, uri.image)); } ( | ) } void textBlock(StringBuilder b) : { Token t; } { ( t = { b.append(t.image); } )* } void registerNodetypesStatement(List result) : { StringBuilder b = new StringBuilder(); } { textBlock(b) ( | ) { result.add(new RegisterNodetypes(b.toString())); } }