/* JavaCC grammar for the SLING-5449 content repository * initialization language * See https://javacc.java.net/doc/docindex.html for the JavaCC docs * and http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-moz.htm for the FAQ */ 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" > | < DISABLE: "disable" > | < SERVICE: "service" > | < MIXIN: "mixin" > | < PATH: "path" > | < END: "end" > | < REPOSITORY: "repository" > | < USER: "user" > | < NODETYPES: "nodetypes" > | < REGISTER: "register" > | < NAMESPACE: "namespace" > | < WITH: "with" > | < PASSWORD: "password" > | < START_TEXTBLOCK: "<<===" > : TEXTBLOCK | < LPAREN: "(" > | < RPAREN: ")" > | < LCURLY: "{" > | < RCURLY: "}" > | < COMMA: "," > | < DQUOTE: "\"" > | < COLON: ":" > | < STAR: "*" > | < EQUALS: "=" > | < RESTRICTION: "restriction" > | < ACL_OPTIONS: "ACLOptions" > /* 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" > } /* Found out about this syntax later - would make STRING etc. simpler */ TOKEN: { ( "\\" ~[] // escaped chars | ~["\\","\""] //any char but not backslash nor quote )* > } SKIP : { "\r" } TOKEN : { < TEXT : ~[] > | < END_TEXTBLOCK: "===>>" > : DEFAULT } List parse() : {} { { final List result = new ArrayList(); } ( serviceUserStatement(result) | setAclPaths(result) | setAclPrincipals(result) | setAclRepository(result) | createPathStatement(result) | registerNamespaceStatement(result) | registerNodetypesStatement(result) | createUserStatement(result) | deleteUserStatement(result) | disableServiceUserStatement(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; List t3 = null; } { ( t1 = { defaultPrimaryType = t1.image; } ) ? ( t1 = ( t2 = ) ? ( t3 = namespacedItemsList() ) ? ( t2 = t3 = namespacedItemsList() ) ? { if(cp == null) { cp = new CreatePath(defaultPrimaryType); } cp.addSegment(t1.image, t2 == null ? null : t2.image, t3); t2 = null; t3 = null; } ) + ( | ) { if(cp != null) result.add(cp); } } void setAclPaths(List result) : { List paths; List lines = new ArrayList(); List aclOptions; } { paths = pathsList() aclOptions=aclOptions() ( removeStarLine(lines) | userPrivilegesLine(lines) | blankLine() ) + ( | ) { result.add(new SetAclPaths(paths, lines, aclOptions)); } } 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; List restrictions; } { line = privilegesLineOperation() tmp = namespacedItemsList() { line.setProperty(AclLine.PROP_PRIVILEGES, tmp); } tmp = principalsList() { line.setProperty(AclLine.PROP_PRINCIPALS, tmp); } restrictions = parseRestrictions() { line.setRestrictions(restrictions); } { lines.add(line); } } /** * Parses a single restriction value */ void parseRestrictionValue(List values) : { Token t; } { ( t= | t= | t= | t= ) { values.add(t.image); } } /** * parses list of restriction values */ List parseRestrictionValues() : { List values = new ArrayList(); } { ( parseRestrictionValue(values) ) * { return values; } } /** * parses a single restriction */ void parseRestriction(List restrictions) : { Token restrictionProp; List values; } { restrictionProp= values=parseRestrictionValues() { restrictions.add(new RestrictionClause(restrictionProp.image,values)); } } /** * parses list of restrictions */ List parseRestrictions() : { List restrictions = new ArrayList(); } { ( parseRestriction(restrictions) )* { return restrictions; } } void pathPrivilegesLine(List lines) : { AclLine line; List tmp; List restrictions; } { 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); }) ? restrictions = parseRestrictions() { line.setRestrictions(restrictions); } { lines.add(line); } } void aclOption(List options) : { Token t; } { (t= | t=) { options.add(t.image); } } List aclOptions() : { List aclOptionList = new ArrayList(); Token t; } { ( aclOption(aclOptionList) ( aclOption(aclOptionList) )* )? { return aclOptionList; } } void setAclRepository(List result) : { List lines = new ArrayList(); List principals; List privileges; List aclOptions; AclLine line = null; } { principals = principalsList() aclOptions=aclOptions() ( ( ) { line = new AclLine(AclLine.Action.REMOVE_ALL); lines.add(line); } | ( line = privilegesLineOperation() privileges = namespacedItemsList() ) { line.setProperty(AclLine.PROP_PRIVILEGES, privileges); lines.add(line); } | ( blankLine() ) )+ ( | ) { result.add(new SetAclPrincipals(principals, lines, aclOptions)); } } void setAclPrincipals(List result) : { List principals; List lines = new ArrayList(); List aclOptions; } { principals = principalsList() aclOptions=aclOptions() ( removeStarLine(lines) | pathPrivilegesLine(lines) | blankLine() ) + ( | ) { result.add(new SetAclPrincipals(principals, lines, aclOptions)); } } 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())); } } void createUserStatement(List result) : { Token user = null; Token encoding = null; Token password = null; } { ( user = ) ( ( encoding = )? password = )? { result.add(new CreateUser(user.image, (encoding == null ? null : encoding.image), (password == null ? null : password.image) )); } } void deleteUserStatement(List result) : { Token user = null; } { ( user = ) { result.add(new DeleteUser(user.image)); } } void disableServiceUserStatement(List result) : { Token user = null; Token msg = null; } { ( user = ) ( msg = ) { result.add(new DisableServiceUser(user.image, msg == null ? null : msg.image)); } }