org.broadleafcommerce.openadmin.client.translation.grouping.GroupingTranslator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of broadleaf-open-admin-platform Show documentation
Show all versions of broadleaf-open-admin-platform Show documentation
BroadleafCommerce Open Admin Platform
/*
* Copyright 2008-2012 the original author or authors.
*
* Licensed 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.broadleafcommerce.openadmin.client.translation.grouping;
import java.util.Stack;
import org.broadleafcommerce.openadmin.client.translation.IncompatibleMVELTranslationException;
import com.smartgwt.client.types.OperatorId;
/**
*
* @author jfischer
*
*/
public class GroupingTranslator {
public static final String GROUPSTARTCHAR = "(";
public static final String GROUPENDCHAR = ")";
public static final String STATEMENTENDCHAR = ";";
public static final String SPACECHAR = " ";
public Group createGroups(String mvel) throws IncompatibleMVELTranslationException {
mvel = stripWhiteSpace(mvel);
String[] tokens = mvel.trim().split(STATEMENTENDCHAR);
if (tokens.length > 1) {
throw new IncompatibleMVELTranslationException("mvel expressions must resolve to a boolean result. More than one terminated statement has been detected, which does not cumulatively result in a single boolean. Multiple phrases should be strung together into a single expression using standard operators.");
}
Group topGroup = new Group();
topGroup.setIsTopGroup(true);
parseGroups(topGroup, tokens[0]);
return topGroup;
}
protected int findGroupStart(String segment, int startPos) {
int startIndex = -1;
boolean eof = false;
while (!eof) {
startIndex = segment.indexOf(GROUPSTARTCHAR, startPos);
if (startIndex <= 0) {
eof = true;
continue;
}
char preChar = segment.charAt(startIndex-1);
if (preChar == '!' || preChar == '&' || preChar == '|') {
eof = true;
continue;
}
startPos = startIndex + 1;
}
return startIndex;
}
protected int findGroupEnd(String segment, int subgroupStartIndex) throws IncompatibleMVELTranslationException {
Stack leftParenPos = new Stack();
char[] characters = segment.toCharArray();
for (int j=subgroupStartIndex;j 0 && segment.charAt(subgroupStartIndex - 1) == '!') {
if (myGroup.getIsTopGroup()) {
//This is a NOT specified at the topmost level
myGroup.setOperatorType(OperatorId.NOT);
} else {
//This is a NOT specified on a sub group
subGroup.setOperatorType(OperatorId.NOT);
}
}
parseGroups(subGroup, segment.substring(subgroupStartIndex+1, subgroupEndIndex-1).trim());
startPos = subgroupEndIndex;
if (startPos == segment.length()) {
eol = true;
} else {
boolean isAnd = false;
boolean isOr = false;
if (segment.charAt(startPos) == '&') {
isAnd = true;
} else if (segment.charAt(startPos) == '|') {
isOr = true;
}
if (myGroup.getOperatorType() == null) {
setGroupOperator(segment, myGroup, isAnd, isOr, false);
}
if (isAnd || isOr) {
startPos += 2;
}
}
continue;
} else {
if (subgroupStartIndex < 0) {
compilePhrases(segment.substring(startPos, segment.length()).trim(), myGroup, isNegation);
eol = true;
continue;
}
String temp = segment.substring(startPos, subgroupStartIndex);
compilePhrases(temp.trim(), myGroup, isNegation);
startPos = subgroupStartIndex;
continue;
}
}
}
protected void compilePhrases(String segment, Group myGroup, boolean isNegation) throws IncompatibleMVELTranslationException {
if (segment.trim().length() == 0) {
return;
}
String[] andTokens = segment.split("&&");
String[] orTokens = segment.split("\\|\\|");
if (andTokens.length > 1 && orTokens.length > 1) {
throw new IncompatibleMVELTranslationException("Segments that mix logical operators are not compatible with the rules builder: (" + segment + ")");
}
boolean isAnd = false;
boolean isOr = false;
boolean isNot = false;
if (andTokens.length > 1 || segment.indexOf("&&") >= 0) {
isAnd = true;
} else if (orTokens.length > 1 || segment.indexOf("||") >= 0) {
isOr = true;
}
if (isAnd && isNegation) {
isNot = true;
}
if (!isAnd && !isOr && !isNot) {
isAnd = true;
}
setGroupOperator(segment, myGroup, isAnd, isOr, isNot);
String[] tokens;
if (isAnd || isNot) {
tokens = andTokens;
} else {
tokens = orTokens;
}
for (String token : tokens) {
if (token.length() > 0) {
myGroup.getPhrases().add(token);
}
}
}
protected void setGroupOperator(String segment, Group myGroup, boolean isAnd, boolean isOr, boolean isNot) throws IncompatibleMVELTranslationException {
if (myGroup.getOperatorType() == null) {
if (isAnd) {
myGroup.setOperatorType(OperatorId.AND);
} else if (isOr) {
myGroup.setOperatorType(OperatorId.OR);
} else if (isNot) {
myGroup.setOperatorType(OperatorId.NOT);
}
} else {
if (
(isOr && !myGroup.getOperatorType().toString().equals(OperatorId.OR.toString()))
) {
throw new IncompatibleMVELTranslationException("Segment logical operator is not compatible with the group logical operator: (" + segment + ")");
}
}
}
}