| /* JavaCC grammar for the SLING-5449 content repository |
| * initialization language |
| * See https://javacc.github.io/javacc/ for the most recent docs, |
| * including links to grammar examples |
| * See http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-moz.htm for a FAQ from 2011 |
| * See also http://eriklievaart.com/web/javacc1.html (from 2014) for additional information |
| */ |
| |
| 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" > |
| | < ACE: "ACE" > |
| | < ON: "on" > |
| | < TO: "to" > |
| | < FROM: "from" > |
| | < REMOVE: "remove" > |
| | < ALLOW: "allow" > |
| | < DENY: "deny" > |
| | < FOR: "for" > |
| | < CREATE: "create" > |
| | < DELETE: "delete" > |
| | < DISABLE: "disable" > |
| | < ENSURE: "ensure" > |
| | < SERVICE: "service" > |
| | < ADD: "add" > |
| | < MIXIN: "mixin" > |
| | < PATH: "path" > |
| | < NODE: "node" > |
| | < NODES: "nodes" > |
| | < END: "end" > |
| | < REPOSITORY: "repository" > |
| | < PRINCIPAL: "principal" > |
| | < USER: "user" > |
| | < GROUP: "group" > |
| | < NODETYPES: "nodetypes" > |
| | < REGISTER: "register" > |
| | < NAMESPACE: "namespace" > |
| | < PRIVILEGE: "privilege" > |
| | < WITH: "with" > |
| | < ABSTRACT: "abstract" > |
| | < PASSWORD: "password" > |
| | < START_TEXTBLOCK: "<<===" > : TEXTBLOCK |
| | < LPAREN: "(" > |
| | < RPAREN: ")" > |
| | < LCURLY: "{" > |
| | < RCURLY: "}" > |
| | < MULTI: "[]" > |
| | < COMMA: "," > |
| | < DQUOTE: "\"" > |
| | < COLON: ":" > |
| | < STAR: "*" > |
| | < EQUALS: "=" > |
| | < RESTRICTION: "restriction" > |
| | < ACL_OPTIONS: "ACLOptions" > |
| | < PROPERTIES: "properties" > |
| | < SETDEF: "default" > |
| | < FORCED: "forced" > |
| |
| /* 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"] | ["-"] | ["_"] | ["."] | ["@"] | [":"] | ["+"] | ["/"]) * > |
| | < PATH_REPOSITORY: ":repository" > |
| | < STRING: (["a"-"z"] | ["A"-"Z"] | ["0"-"9"] | ["-"] | ["_"] | ["."] | ["/"] | [":"] | ["*"]) + > |
| | < EOL: "\n" > |
| } |
| |
| /* Found out about this syntax later - would make STRING etc. simpler */ |
| TOKEN: { |
| <QUOTED: |
| <DQUOTE> |
| ( |
| "\\" ~[] // escaped chars |
| | |
| ~["\\","\""] //any char but not backslash nor quote |
| )* |
| <DQUOTE> |
| > |
| } |
| |
| <TEXTBLOCK> SKIP : |
| { |
| "\r" |
| } |
| |
| <TEXTBLOCK> TOKEN : |
| { |
| < TEXT : ~[] > |
| | < END_TEXTBLOCK: "===>>" > : DEFAULT |
| } |
| |
| List<Operation> parse() : |
| {} |
| { |
| { final List<Operation> result = new ArrayList<Operation>(); } |
| |
| ( |
| serviceUserStatement(result) |
| | setAclPaths(result) |
| | setAclPrincipals(result) |
| | setAclPrincipalBased(result) |
| | ensureAclPrincipalBased(result) |
| | setAclRepository(result) |
| | deleteAclPaths(result) |
| | deleteAclPrincipals(result) |
| | deleteAclPrincipalBased(result) |
| | removeAcePaths(result) |
| | removeAcePrincipals(result) |
| | removeAcePrincipalBased(result) |
| | createPathStatement(result) |
| | ensureNodesStatement(result) |
| | addMixins(result) |
| | removeMixins(result) |
| | registerNamespaceStatement(result) |
| | registerNodetypesStatement(result) |
| | registerPrivilegeStatement(result) |
| | createGroupStatement(result) |
| | deleteGroupStatement(result) |
| | createUserStatement(result) |
| | deleteUserStatement(result) |
| | disableUserStatement(result) |
| | addToGroupStatement(result) |
| | removeFromGroupStatement(result) |
| | setPropertiesStatement(result) |
| | blankLine() |
| ) * |
| <EOF> |
| |
| { return result; } |
| } |
| |
| void blankLine() : |
| {} |
| { |
| <EOL> |
| } |
| |
| List<String> principalsList() : |
| { |
| Token t = null; |
| List<String> principals = new ArrayList<String>(); |
| } |
| { |
| t = quotableString() { principals.add(t.image); } |
| ( <COMMA> t = quotableString() { principals.add(t.image); } )* |
| { return principals; } |
| } |
| |
| WithPathOptions withPathStatement() : |
| { |
| Token path = null; |
| Token forced = null; |
| } |
| { |
| /* accept relative (string) or absolute path */ |
| <WITH> (forced=<FORCED>)? <PATH> ( path=<STRING> | path=<PATH_STRING> ) |
| { return new WithPathOptions(path.image, forced != null); } |
| } |
| |
| void serviceUserStatement(List<Operation> result) : |
| { |
| Token t; |
| List<String> principals; |
| WithPathOptions wpopt = null; |
| } |
| { |
| (t=<CREATE> | t=<DELETE>) |
| <SERVICE> <USER> |
| principals = principalsList() |
| ( wpopt = withPathStatement() ) ? |
| (<EOL> | <EOF>) |
| |
| { |
| for(String principal : principals) { |
| if(CREATE == t.kind) { |
| result.add(new CreateServiceUser(principal, wpopt)); |
| } else { |
| 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> privilegesList() : |
| { |
| Token t = null; |
| List<String> priv = new ArrayList<String>(); |
| } |
| { |
| ( t=<NAMESPACED_ITEM> | t=<STRING> ) { priv.add(t.image); } |
| ( <COMMA> ( t=<NAMESPACED_ITEM> | t=<STRING> ) { priv.add(t.image); } )* |
| { return priv; } |
| } |
| |
| String usernameList() : |
| { |
| List<String> names = new ArrayList<String>(); |
| Token t = null; |
| } |
| { |
| ( t = quotableString() ) { names.add(t.image); } |
| // disable lists for now, not supported downstream |
| // ( <COMMA> t = <STRING> { names.add(t.image); }) * |
| |
| { |
| return String.join(",", names); |
| } |
| } |
| |
| String pathExpression() : |
| { |
| Token t = null; |
| Token tf = null; |
| String usernames = null; |
| final StringBuilder sb = new StringBuilder(); |
| } |
| { |
| ( |
| tf = <STRING> <LPAREN> usernames = usernameList() <RPAREN> ( t = <PATH_STRING> ) ? |
| | ( t = <PATH_STRING> |
| | t = <PATH_REPOSITORY> ) |
| ) |
| { |
| if(tf != null) { |
| sb.append(':').append(tf.image).append(':').append(usernames).append('#'); |
| } |
| if(t != null) { |
| sb.append(t.image); |
| } |
| } |
| |
| { return sb.toString(); } |
| } |
| |
| List<String> pathsList() : |
| { |
| String pathExpr = null; |
| List<String> paths = new ArrayList<String>(); |
| } |
| { |
| ( pathExpr = pathExpression() ) { paths.add(pathExpr); } |
| ( <COMMA> ( pathExpr = pathExpression() ) { paths.add(pathExpr); } )* |
| { return paths; } |
| } |
| |
| void createPathStatement(List<Operation> result) : |
| { |
| CreatePath cp = null; |
| String defaultPrimaryType = null; |
| Token t1 = null; |
| Token t2 = null; |
| List<String> t3 = null; |
| List<PropertyLine> lines = new ArrayList<PropertyLine>(); |
| } |
| { |
| <CREATE> <PATH> |
| ( <LPAREN> t1 = <NAMESPACED_ITEM> <RPAREN> { defaultPrimaryType = t1.image; } ) ? |
| |
| ( t1 = <PATH_STRING> ( <LPAREN> t2 = <NAMESPACED_ITEM> <RPAREN> ) ? |
| ( <LPAREN> <MIXIN> t3 = namespacedItemsList() <RPAREN>) ? |
| ( <LPAREN> t2 = <NAMESPACED_ITEM> <MIXIN> t3 = namespacedItemsList() <RPAREN>) ? |
| { |
| if(cp == null) { |
| cp = new CreatePath(defaultPrimaryType); |
| } |
| cp.addSegment(t1.image, t2 == null ? null : t2.image, t3); |
| t2 = null; |
| t3 = null; |
| } |
| ) + |
| ( <WITH> <PROPERTIES> <EOL> |
| ( propertyLine(lines) | blankLine() ) + |
| { |
| cp.setPropertyLines(lines); |
| } |
| <END> |
| )? |
| (<EOL> | <EOF>) |
| |
| { if(cp != null) result.add(cp); } |
| } |
| |
| // similar to createPath but with stricter semantics of also changing types of existing nodes |
| void ensureNodesStatement(List<Operation> result) : |
| { |
| EnsureNodes en = null; |
| String defaultPrimaryType = null; |
| Token t1 = null; |
| Token t2 = null; |
| List<String> t3 = null; |
| List<PropertyLine> lines = new ArrayList<PropertyLine>(); |
| } |
| { |
| <ENSURE> <NODES> |
| ( <LPAREN> t1 = <NAMESPACED_ITEM> <RPAREN> { defaultPrimaryType = t1.image; } ) ? |
| |
| ( t1 = <PATH_STRING> ( <LPAREN> t2 = <NAMESPACED_ITEM> <RPAREN> ) ? |
| ( <LPAREN> <MIXIN> t3 = namespacedItemsList() <RPAREN>) ? |
| ( <LPAREN> t2 = <NAMESPACED_ITEM> <MIXIN> t3 = namespacedItemsList() <RPAREN>) ? |
| { |
| if(en == null) { |
| en = new EnsureNodes(defaultPrimaryType); |
| } |
| en.addSegment(t1.image, t2 == null ? null : t2.image, t3); |
| t2 = null; |
| t3 = null; |
| } |
| ) + |
| ( <WITH> <PROPERTIES> <EOL> |
| ( propertyLine(lines) | blankLine() ) + |
| { |
| en.setPropertyLines(lines); |
| } |
| <END> |
| )? |
| (<EOL> | <EOF>) |
| |
| { if(en != null) result.add(en); } |
| } |
| |
| void addMixins(List<Operation> result) : |
| { |
| List<String> mixins = null; |
| List<String> paths = null; |
| } |
| { |
| <ADD> <MIXIN> |
| mixins = namespacedItemsList() |
| <TO> |
| paths = pathsList() |
| |
| { |
| result.add(new AddMixins(mixins, paths)); |
| } |
| } |
| |
| void removeMixins(List<Operation> result) : |
| { |
| List<String> mixins = null; |
| List<String> paths = null; |
| } |
| { |
| <REMOVE> <MIXIN> |
| mixins = namespacedItemsList() |
| <FROM> |
| paths = pathsList() |
| |
| { |
| result.add(new RemoveMixins(mixins, paths)); |
| } |
| } |
| |
| void setAclPaths(List<Operation> result) : |
| { |
| List<String> paths; |
| List<AclLine> lines = new ArrayList<AclLine>(); |
| List<String> aclOptions; |
| } |
| { |
| <SET> <ACL> <ON> paths = pathsList() aclOptions=aclOptions() <EOL> |
| ( removeStarLine(lines) | userPrivilegesLine(lines, true) | blankLine() ) + |
| <END> |
| ( <EOL> | <EOF> ) |
| |
| { |
| result.add(new SetAclPaths(paths, lines, aclOptions)); |
| } |
| } |
| |
| void removeStarLine(List<AclLine> lines) : |
| { |
| List<String> tmp = null; |
| AclLine line = new AclLine(AclLine.Action.REMOVE_ALL); |
| } |
| { |
| <REMOVE> <STAR> |
| ( |
| <FOR> tmp = principalsList() { line.setProperty(AclLine.PROP_PRINCIPALS, tmp); } |
| |
| | <ON> tmp = pathsList() { line.setProperty(AclLine.PROP_PATHS, tmp); } |
| ) |
| <EOL> |
| |
| { |
| lines.add(line); |
| } |
| } |
| |
| AclLine privilegesLineOperation(boolean supportsRemoveAction) : |
| { |
| } |
| { |
| ( |
| <REMOVE> { |
| if (supportsRemoveAction) { |
| return new AclLine(AclLine.Action.REMOVE); |
| } else { |
| throw new ParseException("REMOVE action not supported with 'remove acl' statements."); |
| }} |
| | ( <ALLOW> { return new AclLine(AclLine.Action.ALLOW); } ) |
| | ( <DENY> { return new AclLine(AclLine.Action.DENY); } ) |
| ) |
| } |
| |
| void userPrivilegesLine(List<AclLine> lines, boolean supportsRemoveAction) : |
| { |
| AclLine line; |
| List<String> tmp; |
| List<RestrictionClause> restrictions; |
| } |
| { |
| line = privilegesLineOperation(supportsRemoveAction) |
| tmp = privilegesList() { line.setProperty(AclLine.PROP_PRIVILEGES, tmp); } |
| <FOR> |
| tmp = principalsList() { line.setProperty(AclLine.PROP_PRINCIPALS, tmp); } |
| restrictions = restrictions() { line.setRestrictions(restrictions); } |
| <EOL> |
| |
| { |
| lines.add(line); |
| } |
| } |
| /** |
| * A single restriction value |
| */ |
| void restrictionValue(List<String> values) : |
| { |
| Token t; |
| } |
| { |
| <COMMA> ( t=<STAR> | t=<NAMESPACED_ITEM> | t=<PATH_STRING> | t=<STRING> ) |
| { |
| values.add(t.image); |
| } |
| } |
| |
| /** |
| * A list of restriction values |
| */ |
| List<String> restrictionValues() : |
| { |
| List<String> values = new ArrayList<String>(); |
| } |
| { |
| ( restrictionValue(values) ) * |
| |
| { |
| return values; |
| } |
| |
| } |
| |
| |
| /** |
| * A single restriction |
| */ |
| void restriction(List<RestrictionClause> restrictions) : |
| { |
| Token restrictionProp; |
| List<String> values; |
| } |
| { |
| <RESTRICTION> |
| <LPAREN> restrictionProp=<NAMESPACED_ITEM> values=restrictionValues() <RPAREN> |
| |
| { |
| restrictions.add(new RestrictionClause(restrictionProp.image,values)); |
| } |
| } |
| |
| /** |
| * A list of restrictions |
| */ |
| List<RestrictionClause> restrictions() : |
| { |
| List<RestrictionClause> restrictions = new ArrayList<RestrictionClause>(); |
| } |
| { |
| ( restriction(restrictions) )* |
| |
| { |
| return restrictions; |
| } |
| } |
| |
| void pathPrivilegesLine(List<AclLine> lines, boolean supportsRemoveAction) : |
| { |
| AclLine line; |
| List<String> tmp; |
| List<RestrictionClause> restrictions; |
| } |
| { |
| line = privilegesLineOperation(supportsRemoveAction) |
| tmp = namespacedItemsList() { line.setProperty(AclLine.PROP_PRIVILEGES, tmp); } |
| <ON> tmp = pathsList() { line.setProperty(AclLine.PROP_PATHS, tmp); } |
| ( <NODETYPES> tmp = namespacedItemsList() { line.setProperty(AclLine.PROP_NODETYPES, tmp); }) ? |
| restrictions = restrictions() { line.setRestrictions(restrictions); } |
| <EOL> |
| |
| { |
| lines.add(line); |
| } |
| } |
| void aclOption(List<String> options) : |
| { |
| Token t; |
| } |
| { |
| (t=<NAMESPACED_ITEM> | t=<STRING>) |
| { |
| options.add(t.image); |
| } |
| } |
| List<String> aclOptions() : |
| { |
| List<String> aclOptionList = new ArrayList<String>(); |
| Token t; |
| } |
| { |
| ( <LPAREN> <ACL_OPTIONS> <EQUALS> aclOption(aclOptionList) ( <COMMA> aclOption(aclOptionList) )* <RPAREN> )? |
| |
| { |
| return aclOptionList; |
| } |
| } |
| |
| void setAclRepository(List<Operation> result) : |
| { |
| List<AclLine> lines = new ArrayList<AclLine>(); |
| List<String> principals; |
| List<String> privileges; |
| List<String> aclOptions; |
| AclLine line = null; |
| |
| } |
| { |
| <SET> <REPOSITORY> <ACL> <FOR> principals = principalsList() aclOptions=aclOptions() <EOL> |
| ( |
| ( <REMOVE> <STAR> ) |
| { |
| line = new AclLine(AclLine.Action.REMOVE_ALL); |
| lines.add(line); |
| } |
| | ( line = privilegesLineOperation(true) privileges = namespacedItemsList() ) |
| { |
| line.setProperty(AclLine.PROP_PRIVILEGES, privileges); |
| lines.add(line); |
| } |
| | ( blankLine() ) |
| )+ |
| <END> |
| ( <EOL> | <EOF> ) |
| |
| { |
| result.add(new SetAclPrincipals(principals, lines, aclOptions)); |
| } |
| } |
| |
| void setAclPrincipals(List<Operation> result) : |
| { |
| List <String> principals; |
| List<AclLine> lines = new ArrayList<AclLine>(); |
| List<String> aclOptions; |
| } |
| { |
| <SET> <ACL> <FOR> principals = principalsList() aclOptions=aclOptions() <EOL> |
| ( removeStarLine(lines) | pathPrivilegesLine(lines, true) | blankLine() ) + |
| <END> |
| ( <EOL> | <EOF> ) |
| |
| { |
| result.add(new SetAclPrincipals(principals, lines, aclOptions)); |
| } |
| } |
| |
| void setAclPrincipalBased(List<Operation> result) : |
| { |
| List <String> principals; |
| List<AclLine> lines = new ArrayList<AclLine>(); |
| List<String> aclOptions; |
| } |
| { |
| <SET> <PRINCIPAL> <ACL> <FOR> principals = principalsList() aclOptions=aclOptions() <EOL> |
| ( removeStarLine(lines) | pathPrivilegesLine(lines, true) | blankLine() ) + |
| <END> |
| ( <EOL> | <EOF> ) |
| |
| { |
| result.add(new SetAclPrincipalBased(principals, lines, aclOptions)); |
| } |
| } |
| |
| void ensureAclPrincipalBased(List<Operation> result) : |
| { |
| List <String> principals; |
| List<AclLine> lines = new ArrayList<AclLine>(); |
| List<String> aclOptions; |
| } |
| { |
| <ENSURE> <PRINCIPAL> <ACL> <FOR> principals = principalsList() aclOptions=aclOptions() <EOL> |
| ( removeStarLine(lines) | pathPrivilegesLine(lines, true) | blankLine() ) + |
| <END> |
| ( <EOL> | <EOF> ) |
| |
| { |
| result.add(new EnsureAclPrincipalBased(principals, lines, aclOptions)); |
| } |
| } |
| |
| void removeAcePaths(List<Operation> result) : |
| { |
| List<String> paths; |
| List<AclLine> lines = new ArrayList<AclLine>(); |
| } |
| { |
| <REMOVE> <ACE> <ON> paths = pathsList()<EOL> |
| ( userPrivilegesLine(lines, false) | blankLine() ) + |
| <END> |
| ( <EOL> | <EOF> ) |
| |
| { |
| result.add(new RemoveAcePaths(paths, lines)); |
| } |
| } |
| |
| void removeAcePrincipals(List<Operation> result) : |
| { |
| List <String> principals; |
| List<AclLine> lines = new ArrayList<AclLine>(); |
| } |
| { |
| <REMOVE> <ACE> <FOR> principals = principalsList()<EOL> |
| ( pathPrivilegesLine(lines, false) | blankLine() ) + |
| <END> |
| ( <EOL> | <EOF> ) |
| |
| { |
| result.add(new RemoveAcePrincipals(principals, lines)); |
| } |
| } |
| |
| void removeAcePrincipalBased(List<Operation> result) : |
| { |
| List <String> principals; |
| List<AclLine> lines = new ArrayList<AclLine>(); |
| } |
| { |
| <REMOVE> <PRINCIPAL> <ACE> <FOR> principals = principalsList()<EOL> |
| ( pathPrivilegesLine(lines, false) | blankLine() ) + |
| <END> |
| ( <EOL> | <EOF> ) |
| |
| { |
| result.add(new RemoveAcePrincipalBased(principals, lines)); |
| } |
| } |
| |
| void deleteAclPaths(List<Operation> result) : |
| { |
| List<String> paths; |
| } |
| { |
| <DELETE> <ACL> <ON> paths = pathsList() |
| ( <EOL> | <EOF> ) |
| { |
| result.add(new DeleteAclPaths(paths)); |
| } |
| } |
| |
| void deleteAclPrincipals(List<Operation> result) : |
| { |
| List <String> principals; |
| } |
| { |
| <DELETE> <ACL> <FOR> principals = principalsList() |
| ( <EOL> | <EOF> ) |
| { |
| result.add(new DeleteAclPrincipals(principals)); |
| } |
| } |
| |
| void deleteAclPrincipalBased(List<Operation> result) : |
| { |
| List <String> principals; |
| } |
| { |
| <DELETE> <PRINCIPAL> <ACL> <FOR> principals = principalsList() |
| ( <EOL> | <EOF> ) |
| { |
| result.add(new DeleteAclPrincipalBased(principals)); |
| } |
| } |
| |
| void registerNamespaceStatement(List<Operation> result) : |
| { |
| Token prefix = null; |
| Token uri; |
| } |
| { |
| <REGISTER> <NAMESPACE> |
| <LPAREN> prefix = <STRING> <RPAREN> |
| uri = quotableString() |
| |
| { |
| result.add(new RegisterNamespace(prefix.image, uri.image)); |
| } |
| |
| (<EOL> | <EOF>) |
| } |
| |
| void registerPrivilegeStatement(List<Operation> result) : |
| { |
| Token privilege; |
| boolean isAbstract = false; |
| List<String> aggregates = new ArrayList<String>(); |
| } |
| { |
| <REGISTER> ((<ABSTRACT>) {isAbstract = true;})? <PRIVILEGE> (privilege = <STRING> | privilege = <NAMESPACED_ITEM>) (<WITH> aggregates = privilegesList())? |
| { |
| result.add(new RegisterPrivilege(privilege.image, isAbstract, aggregates)); |
| } |
| (<EOL> | <EOF>) |
| } |
| |
| void textBlock(StringBuilder b) : |
| { |
| Token t; |
| } |
| { |
| <START_TEXTBLOCK> |
| ( t = <TEXT> { b.append(t.image); } )* |
| <END_TEXTBLOCK> |
| } |
| |
| void registerNodetypesStatement(List<Operation> result) : |
| { |
| StringBuilder b = new StringBuilder(); |
| } |
| { |
| <REGISTER> <NODETYPES> <EOL> |
| textBlock(b) |
| (<EOL> | <EOF>) |
| { |
| result.add(new RegisterNodetypes(b.toString())); |
| } |
| } |
| |
| void createGroupStatement(List<Operation> result) : |
| { |
| Token group = null; |
| Token encoding = null; |
| WithPathOptions wpopt = null; |
| } |
| { |
| <CREATE> <GROUP> |
| ( group = quotableString() ) |
| ( wpopt = withPathStatement() ) ? |
| |
| { |
| result.add(new CreateGroup(group.image, wpopt)); |
| } |
| } |
| |
| void deleteGroupStatement(List<Operation> result) : |
| { |
| Token group = null; |
| } |
| { |
| <DELETE> <GROUP> |
| ( group = quotableString() ) |
| |
| { |
| result.add(new DeleteGroup(group.image)); |
| } |
| } |
| |
| void createUserStatement(List<Operation> result) : |
| { |
| Token user = null; |
| Token encoding = null; |
| Token password = null; |
| WithPathOptions wpopt = null; |
| } |
| { |
| <CREATE> <USER> |
| ( user = <STRING> ) |
| ( wpopt = withPathStatement() ) ? |
| ( <WITH> <PASSWORD> ( <LCURLY> encoding = <STRING> <RCURLY> )? password = <STRING> )? |
| |
| { |
| result.add(new CreateUser(user.image, |
| (encoding == null ? null : encoding.image), |
| (password == null ? null : password.image), |
| wpopt |
| )); |
| } |
| } |
| |
| void deleteUserStatement(List<Operation> result) : |
| { |
| Token user = null; |
| } |
| { |
| <DELETE> <USER> |
| ( user = <STRING> ) |
| |
| { |
| result.add(new DeleteUser(user.image)); |
| } |
| } |
| |
| Token quotedString() : |
| { |
| Token t = null; |
| } |
| { |
| ( t = <QUOTED> ) |
| { |
| // Remove start/end quotes + escaping backslash for double quotes |
| final String unescaped = t.image.trim() |
| .replaceAll("^\"|\"$", "") |
| .replaceAll("\\\\\"", "\"") |
| .replaceAll("\\\\\\\\", "\\\\") |
| ; |
| return new Token(t.kind, unescaped); |
| } |
| } |
| |
| void disableUserStatement(List<Operation> result) : |
| { |
| Token user = null; |
| Token msg = null; |
| Token isServiceUser = null; |
| } |
| { |
| <DISABLE> ( isServiceUser = <SERVICE> )? <USER> |
| ( user = <STRING> ) |
| ( <COLON> msg = quotedString() ) |
| { |
| DisableServiceUser dsu = new DisableServiceUser(user.image, msg.image); |
| dsu.setServiceUser(isServiceUser != null); |
| result.add(dsu); |
| } |
| } |
| |
| void addToGroupStatement(List<Operation> result) : |
| { |
| List <String> members; |
| Token t; |
| Token group = null; |
| } |
| { |
| <ADD> |
| members = principalsList() |
| <TO> <GROUP> |
| group = quotableString() |
| |
| { |
| result.add(new AddGroupMembers(members, group.image)); |
| } |
| } |
| |
| void removeFromGroupStatement(List<Operation> result) : |
| { |
| List <String> members; |
| Token t; |
| Token group = null; |
| } |
| { |
| <REMOVE> |
| members = principalsList() |
| <FROM> <GROUP> |
| group = quotableString() |
| |
| { |
| result.add(new RemoveGroupMembers(members, group.image)); |
| } |
| } |
| |
| Token quotableString() : |
| { |
| Token t = null; |
| } |
| { |
| (t = <STRING> | t = quotedString() ) { return t; } |
| } |
| |
| Token propertyValue() : |
| { |
| Token t = null; |
| } |
| { |
| (t = <STRING> | t = quotedString() | t = <PATH_STRING> | t = <NAMESPACED_ITEM> ) { return t; } |
| } |
| |
| List<String> propertyValuesList() : |
| { |
| Token t = null; |
| List<String> values = new ArrayList<String>(); |
| } |
| { |
| (( t = propertyValue() ) { values.add(t.image); })? |
| ( <COMMA> ( t = propertyValue() ) { values.add(t.image); } )* |
| { return values; } |
| } |
| |
| void propertyLine(List<PropertyLine> lines) : |
| { |
| Token name = null; |
| Token type = null; |
| List<String> values; |
| Token t = null; |
| boolean isDefault = false; |
| } |
| { |
| (t = <SET> | t = <SETDEF> {isDefault = true;} ) |
| ( name = <STRING> | name = <NAMESPACED_ITEM>) |
| ( <LCURLY> ( type = <STRING> ) <RCURLY> | <LCURLY> ( type = <STRING> ) <MULTI> <RCURLY> )? |
| <TO> ( values = propertyValuesList() ) |
| <EOL> |
| { |
| lines.add(new PropertyLine(name.image, type == null ? null : type.image, values, isDefault)); |
| } |
| } |
| |
| void setPropertiesStatement(List<Operation> result) : |
| { |
| List<PropertyLine> lines = new ArrayList<PropertyLine>(); |
| List<String> paths; |
| } |
| { |
| <SET> <PROPERTIES> <ON> ( paths = pathsList() ) <EOL> |
| ( propertyLine(lines) | blankLine() ) + |
| <END> |
| ( <EOL> | <EOF> ) |
| { |
| result.add(new SetProperties(paths, lines)); |
| } |
| } |