IDEMPIERE-4824 Boolean Logic Expression Enhancements (#716)
* IDEMPIERE-4824 Boolean Logic Expression Enhancements * IDEMPIERE-4824 Boolean Logic Expression Enhancements Fix handling of conditional variable (i.e @VariableName:DefaultValue@) * IDEMPIERE-4824 Boolean Logic Expression Enhancements Fix unit test launch configuration
This commit is contained in:
parent
2110322149
commit
d7153575e6
|
@ -45,6 +45,7 @@
|
|||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||
<setEntry value="javax.jms@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||
<setEntry value="org.apache.ant@default:default"/>
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||
<setEntry value="javax.jms@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||
<setEntry value="org.apache.ant@default:default"/>
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||
<setEntry value="javax.jms@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||
<setEntry value="org.apache.ant@default:default"/>
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||
<setEntry value="javax.jms@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||
<setEntry value="org.apache.ant@default:default"/>
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||
<setEntry value="javax.jms@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||
<setEntry value="org.apache.ant@default:default"/>
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
|
@ -40,5 +45,6 @@
|
|||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
|
|
@ -57,6 +57,7 @@ Export-Package: bsh,
|
|||
org.idempiere.broadcast,
|
||||
org.idempiere.cache,
|
||||
org.idempiere.distributed,
|
||||
org.idempiere.expression.logic,
|
||||
org.idempiere.fa.service.api,
|
||||
org.idempiere.model,
|
||||
org.idempiere.process
|
||||
|
@ -97,6 +98,13 @@ Import-Package: com.google.zxing,
|
|||
net.sf.cglib.proxy,
|
||||
net.sourceforge.barbecue,
|
||||
net.sourceforge.barbecue.linear.ean,
|
||||
org.antlr.v4.runtime;version="4.9.2",
|
||||
org.antlr.v4.runtime.atn;version="4.9.2",
|
||||
org.antlr.v4.runtime.dfa;version="4.9.2",
|
||||
org.antlr.v4.runtime.misc;version="4.9.2",
|
||||
org.antlr.v4.runtime.tree;version="4.9.2",
|
||||
org.antlr.v4.runtime.tree.pattern;version="4.9.2",
|
||||
org.antlr.v4.runtime.tree.xpath;version="4.9.2",
|
||||
org.apache.activemq;version="5.3.0",
|
||||
org.apache.commons.collections;version="3.2.2",
|
||||
org.apache.commons.collections.keyvalue;version="3.2.2",
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
grammar SimpleBoolean;
|
||||
@header {
|
||||
package org.idempiere.expression.logic;
|
||||
}
|
||||
parse
|
||||
: expression EOF
|
||||
;
|
||||
|
||||
expression
|
||||
: LPAREN expression RPAREN #parenExpression
|
||||
| NOT expression #notExpression
|
||||
| left=expression op=comparator right=expression #comparatorExpression
|
||||
| left=expression op=binary right=expression #binaryExpression
|
||||
| bool #boolExpression
|
||||
| VARIABLE #contextVariables
|
||||
| QTEXT #quotedText
|
||||
| DQTEXT #doubleQuotedText
|
||||
| TEXT #text
|
||||
| DECIMAL #decimalExpression
|
||||
;
|
||||
|
||||
comparator
|
||||
: GT | GE | LT | LE | EQ | NE | RE
|
||||
;
|
||||
|
||||
binary
|
||||
: AND | OR
|
||||
;
|
||||
|
||||
bool
|
||||
: TRUE | FALSE
|
||||
;
|
||||
|
||||
AND : '&' ;
|
||||
OR : '|' ;
|
||||
NOT : '$!';
|
||||
TRUE : 'true' ;
|
||||
FALSE : 'false' ;
|
||||
GT : '>' ;
|
||||
GE : '>=' ;
|
||||
LT : '<' ;
|
||||
LE : '<=' ;
|
||||
EQ : '=' ;
|
||||
NE : [!^] ;
|
||||
RE : '~' ;
|
||||
LPAREN : '(' ;
|
||||
RPAREN : ')' ;
|
||||
DECIMAL : '-'? [0-9]+ ( '.' [0-9]+ )? ;
|
||||
VARIABLE : '@'(.*?)'@' ;
|
||||
QTEXT : ['](.*?)['] ;
|
||||
DQTEXT : ["](.*?)["] ;
|
||||
TEXT : [a-zA-Z_0-9,]+ ;
|
||||
WS : [ \r\t\u000C\n]+ -> skip;
|
|
@ -43,6 +43,7 @@ import org.compiere.util.Msg;
|
|||
import org.compiere.util.Util;
|
||||
import org.idempiere.cache.ImmutableIntPOCache;
|
||||
import org.idempiere.cache.ImmutablePOSupport;
|
||||
import org.idempiere.expression.logic.LogicEvaluator;
|
||||
|
||||
/**
|
||||
* Persistent Column Model
|
||||
|
@ -545,6 +546,12 @@ public class MColumn extends X_AD_Column implements ImmutablePOSupport
|
|||
setSeqNoSelection(next);
|
||||
}
|
||||
|
||||
//validate readonly logic expression
|
||||
if (newRecord || is_ValueChanged(COLUMNNAME_ReadOnlyLogic)) {
|
||||
if (isActive() && !Util.isEmpty(getReadOnlyLogic(), true) && !getReadOnlyLogic().startsWith("@SQL=")) {
|
||||
LogicEvaluator.validate(getReadOnlyLogic());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} // beforeSave
|
||||
|
||||
|
|
|
@ -20,8 +20,10 @@ import java.sql.ResultSet;
|
|||
import java.util.Properties;
|
||||
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Util;
|
||||
import org.idempiere.cache.ImmutableIntPOCache;
|
||||
import org.idempiere.cache.ImmutablePOSupport;
|
||||
import org.idempiere.expression.logic.LogicEvaluator;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -217,6 +219,23 @@ public class MField extends X_AD_Field implements ImmutablePOSupport
|
|||
setIsToolbarButton(null);
|
||||
}
|
||||
|
||||
//validate logic expression
|
||||
if (newRecord || is_ValueChanged(COLUMNNAME_ReadOnlyLogic)) {
|
||||
if (isActive() && !Util.isEmpty(getReadOnlyLogic(), true) && !getReadOnlyLogic().startsWith("@SQL=")) {
|
||||
LogicEvaluator.validate(getReadOnlyLogic());
|
||||
}
|
||||
}
|
||||
if (newRecord || is_ValueChanged(COLUMNNAME_DisplayLogic)) {
|
||||
if (isActive() && !Util.isEmpty(getDisplayLogic(), true) && !getDisplayLogic().startsWith("@SQL=")) {
|
||||
LogicEvaluator.validate(getDisplayLogic());
|
||||
}
|
||||
}
|
||||
if (newRecord || is_ValueChanged(COLUMNNAME_MandatoryLogic)) {
|
||||
if (isActive() && !Util.isEmpty(getMandatoryLogic(), true) && !getMandatoryLogic().startsWith("@SQL=")) {
|
||||
LogicEvaluator.validate(getMandatoryLogic());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} // beforeSave
|
||||
|
||||
|
|
|
@ -23,8 +23,10 @@ import java.util.logging.Level;
|
|||
import org.compiere.util.DB;
|
||||
import org.compiere.util.DisplayType;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Util;
|
||||
import org.idempiere.cache.ImmutableIntPOCache;
|
||||
import org.idempiere.cache.ImmutablePOSupport;
|
||||
import org.idempiere.expression.logic.LogicEvaluator;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -333,6 +335,18 @@ public class MProcessPara extends X_AD_Process_Para implements ImmutablePOSuppor
|
|||
setHelp (element.getHelp());
|
||||
}
|
||||
|
||||
//validate logic expression
|
||||
if (newRecord || is_ValueChanged(COLUMNNAME_ReadOnlyLogic)) {
|
||||
if (isActive() && !Util.isEmpty(getReadOnlyLogic(), true) && !getReadOnlyLogic().startsWith("@SQL=")) {
|
||||
LogicEvaluator.validate(getReadOnlyLogic());
|
||||
}
|
||||
}
|
||||
if (newRecord || is_ValueChanged(COLUMNNAME_DisplayLogic)) {
|
||||
if (isActive() && !Util.isEmpty(getDisplayLogic(), true) && !getDisplayLogic().startsWith("@SQL=")) {
|
||||
LogicEvaluator.validate(getDisplayLogic());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} // beforeSave
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@ import org.compiere.util.CLogger;
|
|||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Msg;
|
||||
import org.compiere.util.Util;
|
||||
import org.idempiere.cache.ImmutablePOCache;
|
||||
import org.idempiere.cache.ImmutablePOSupport;
|
||||
import org.idempiere.expression.logic.LogicEvaluator;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -198,6 +200,24 @@ public class MUserDefField extends X_AD_UserDef_Field implements ImmutablePOSupp
|
|||
setAD_Val_Rule_ID(0);
|
||||
setIsToolbarButton(null);
|
||||
}
|
||||
|
||||
//validate logic expression
|
||||
if (newRecord || is_ValueChanged(COLUMNNAME_ReadOnlyLogic)) {
|
||||
if (isActive() && !Util.isEmpty(getReadOnlyLogic(), true) && !getReadOnlyLogic().startsWith("@SQL=")) {
|
||||
LogicEvaluator.validate(getReadOnlyLogic());
|
||||
}
|
||||
}
|
||||
if (newRecord || is_ValueChanged(COLUMNNAME_DisplayLogic)) {
|
||||
if (isActive() && !Util.isEmpty(getDisplayLogic(), true) && !getDisplayLogic().startsWith("@SQL=")) {
|
||||
LogicEvaluator.validate(getDisplayLogic());
|
||||
}
|
||||
}
|
||||
if (newRecord || is_ValueChanged(COLUMNNAME_MandatoryLogic)) {
|
||||
if (isActive() && !Util.isEmpty(getMandatoryLogic(), true) && !getMandatoryLogic().startsWith("@SQL=")) {
|
||||
LogicEvaluator.validate(getMandatoryLogic());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,17 +16,17 @@
|
|||
*****************************************************************************/
|
||||
package org.compiere.util;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.idempiere.expression.logic.LogicEvaluator;
|
||||
|
||||
|
||||
/**
|
||||
* Expression Evaluator
|
||||
|
@ -82,202 +82,16 @@ public class Evaluator
|
|||
|
||||
/**
|
||||
* Evaluate Logic.
|
||||
* <code>
|
||||
* format := <expression> [<logic> <expression>]
|
||||
* expression := @<context>@<exLogic><value>
|
||||
* logic := <|> | <&>
|
||||
* exLogic := <=> | <!> | <^> | <<> | <>>
|
||||
*
|
||||
* context := any global or window context
|
||||
* value := strings can be with ' or "
|
||||
* logic operators := AND or OR with the prevoius result from left to right
|
||||
*
|
||||
* Example '@AD_Table@=Test | @Language@=GERGER
|
||||
* </code>
|
||||
* @see LogicEvaluator#evaluateLogic(Evaluatee, String)
|
||||
* @param source class implementing get_ValueAsString(variable)
|
||||
* @param logic logic string
|
||||
* @return logic result
|
||||
*/
|
||||
public static boolean evaluateLogic (Evaluatee source, String logic)
|
||||
{
|
||||
// Conditional
|
||||
StringTokenizer st = new StringTokenizer(logic.trim(), "&|", true);
|
||||
int it = st.countTokens();
|
||||
if (((it/2) - ((it+1)/2)) == 0) // only uneven arguments
|
||||
{
|
||||
s_log.severe ("Logic does not comply with format "
|
||||
+ "'<expression> [<logic> <expression>]' => " + logic);
|
||||
return false;
|
||||
}
|
||||
|
||||
String exprStrand = st.nextToken().trim();
|
||||
if (exprStrand.matches("^@\\d+$") || "@P".equals(exprStrand))
|
||||
{
|
||||
exprStrand = exprStrand.concat(st.nextToken());
|
||||
exprStrand = exprStrand.concat(st.nextToken());
|
||||
}
|
||||
|
||||
//boolean retValue = evaluateLogicTuple(source, st.nextToken());
|
||||
boolean retValue = evaluateLogicTuple(source, exprStrand);
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String logOp = st.nextToken().trim();
|
||||
//boolean temp = evaluateLogicTuple(source, st.nextToken());
|
||||
|
||||
exprStrand = st.nextToken().trim();
|
||||
if (exprStrand.matches("^@\\d+$") || "@P".equals(exprStrand))
|
||||
{
|
||||
exprStrand = exprStrand.concat(st.nextToken());
|
||||
exprStrand = exprStrand.concat(st.nextToken());
|
||||
}
|
||||
|
||||
boolean temp = evaluateLogicTuple(source, exprStrand);
|
||||
|
||||
if (logOp.equals("&"))
|
||||
retValue = retValue & temp;
|
||||
else if (logOp.equals("|"))
|
||||
retValue = retValue | temp;
|
||||
else
|
||||
{
|
||||
s_log.log(Level.SEVERE, "Logic operand '|' or '&' expected => " + logic);
|
||||
return false;
|
||||
}
|
||||
} // hasMoreTokens
|
||||
return retValue;
|
||||
return LogicEvaluator.evaluateLogic(source, logic);
|
||||
} // evaluateLogic
|
||||
|
||||
/**
|
||||
* Evaluate @context@=value or @context@!value or @context@^value.
|
||||
* <pre>
|
||||
* value: strips ' and " always (no escape or mid stream)
|
||||
* value: can also be a context variable
|
||||
* </pre>
|
||||
* @param source class implementing get_ValueAsString(variable)
|
||||
* @param logic logic tuple
|
||||
* @return true or false
|
||||
*/
|
||||
private static boolean evaluateLogicTuple (Evaluatee source, String logic)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer (logic.trim(), "!=^><", true);
|
||||
if (st.countTokens() != 3)
|
||||
{
|
||||
s_log.log(Level.SEVERE, "Logic tuple does not comply with format "
|
||||
+ "'@context@=value' where operand could be one of '=!^><' => " + logic);
|
||||
return false;
|
||||
}
|
||||
// First Part
|
||||
String first = st.nextToken().trim(); // get '@tag@'
|
||||
String firstEval = first.trim();
|
||||
if (first.indexOf('@') != -1) // variable
|
||||
{
|
||||
first = first.replace ('@', ' ').trim (); // strip 'tag'
|
||||
// IDEMPIERE-194 Handling null context variable
|
||||
String defaultValue = "";
|
||||
int idx = first.indexOf(":"); // or clause
|
||||
if (idx >= 0)
|
||||
{
|
||||
defaultValue = first.substring(idx+1, first.length());
|
||||
first = first.substring(0, idx);
|
||||
}
|
||||
firstEval = source.get_ValueAsString (first); // replace with it's value
|
||||
if (Util.isEmpty(firstEval) && !Util.isEmpty(defaultValue)) {
|
||||
firstEval = defaultValue;
|
||||
}
|
||||
}
|
||||
//NPE sanity check
|
||||
if (firstEval == null)
|
||||
firstEval = "";
|
||||
|
||||
firstEval = firstEval.replace('\'', ' ').replace('"', ' ').trim(); // strip ' and "
|
||||
|
||||
// Comperator
|
||||
String operand = st.nextToken();
|
||||
|
||||
// Second Part
|
||||
String rightToken = st.nextToken(); // get value
|
||||
String[] list = rightToken.split("[,]");
|
||||
for(String second : list)
|
||||
{
|
||||
String secondEval = second.trim();
|
||||
if (second.indexOf('@') != -1) // variable
|
||||
{
|
||||
second = second.replace('@', ' ').trim(); // strip tag
|
||||
secondEval = source.get_ValueAsString (second); // replace with it's value
|
||||
}
|
||||
secondEval = secondEval.replace('\'', ' ').replace('"', ' ').trim(); // strip ' and "
|
||||
|
||||
// Handling of ID compare (null => 0)
|
||||
if (first.trim().endsWith("_ID") && firstEval.length() == 0)
|
||||
firstEval = "0";
|
||||
if (second.trim().endsWith("_ID") && secondEval.length() == 0)
|
||||
secondEval = "0";
|
||||
|
||||
// Logical Comparison
|
||||
boolean result = evaluateLogicTuple (firstEval, operand, secondEval);
|
||||
//
|
||||
if (s_log.isLoggable(Level.FINEST)) s_log.finest(logic
|
||||
+ " => \"" + firstEval + "\" " + operand + " \"" + secondEval + "\" => " + result);
|
||||
if (result)
|
||||
return true;
|
||||
}
|
||||
//
|
||||
return false;
|
||||
} // evaluateLogicTuple
|
||||
|
||||
/**
|
||||
* Evaluate Logic Tuple
|
||||
* @param value1 value
|
||||
* @param operand operand = ~ ^ ! > <
|
||||
* @param value2
|
||||
* @return evaluation
|
||||
*/
|
||||
private static boolean evaluateLogicTuple (String value1, String operand, String value2)
|
||||
{
|
||||
if (value1 == null || operand == null || value2 == null)
|
||||
return false;
|
||||
|
||||
BigDecimal value1bd = null;
|
||||
BigDecimal value2bd = null;
|
||||
try
|
||||
{
|
||||
if (!value1.startsWith("'"))
|
||||
value1bd = new BigDecimal (value1);
|
||||
if (!value2.startsWith("'"))
|
||||
value2bd = new BigDecimal (value2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
value1bd = null;
|
||||
value2bd = null;
|
||||
}
|
||||
//
|
||||
if (operand.equals("="))
|
||||
{
|
||||
if (value1bd != null && value2bd != null)
|
||||
return value1bd.compareTo(value2bd) == 0;
|
||||
return value1.compareTo(value2) == 0;
|
||||
}
|
||||
else if (operand.equals("<"))
|
||||
{
|
||||
if (value1bd != null && value2bd != null)
|
||||
return value1bd.compareTo(value2bd) < 0;
|
||||
return value1.compareTo(value2) < 0;
|
||||
}
|
||||
else if (operand.equals(">"))
|
||||
{
|
||||
if (value1bd != null && value2bd != null)
|
||||
return value1bd.compareTo(value2bd) > 0;
|
||||
return value1.compareTo(value2) > 0;
|
||||
}
|
||||
else // interpreted as not
|
||||
{
|
||||
if (value1bd != null && value2bd != null)
|
||||
return value1bd.compareTo(value2bd) != 0;
|
||||
return value1.compareTo(value2) != 0;
|
||||
}
|
||||
} // evaluateLogicTuple
|
||||
|
||||
|
||||
/**
|
||||
* Parse String and add variables with @ to the list.
|
||||
* @param list list to be added to
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
/******************************************************************************
|
||||
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms version 2 of the GNU General Public License as published *
|
||||
* by the Free Software Foundation. This program is distributed in the hope *
|
||||
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* See the GNU General Public License for more details. *
|
||||
* You should have received a copy of the GNU General Public License along *
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||
* For the text or an alternative of this public license, you may reach us *
|
||||
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
|
||||
* or via info@compiere.org or http://www.compiere.org/license.html *
|
||||
*****************************************************************************/
|
||||
package org.compiere.util;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
||||
/**
|
||||
* Legacy Logic Expression Evaluator
|
||||
*
|
||||
* @author Jorg Janke
|
||||
* @version $Id: Evaluator.java,v 1.3 2006/07/30 00:54:36 jjanke Exp $
|
||||
* @deprecated
|
||||
*/
|
||||
public final class LegacyLogicEvaluator {
|
||||
|
||||
private final static CLogger s_log = CLogger.getCLogger(LegacyLogicEvaluator.class);
|
||||
|
||||
private LegacyLogicEvaluator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate Logic.
|
||||
* <code>
|
||||
* format := <expression> [<logic> <expression>]
|
||||
* expression := @<context>@<exLogic><value>
|
||||
* logic := <|> | <&>
|
||||
* exLogic := <=> | <!> | <^> | <<> | <>>
|
||||
*
|
||||
* context := any global or window context
|
||||
* value := strings can be with ' or "
|
||||
* logic operators := AND or OR with the prevoius result from left to right
|
||||
*
|
||||
* Example '@AD_Table@=Test | @Language@=GERGER
|
||||
* </code>
|
||||
* @param source class implementing get_ValueAsString(variable)
|
||||
* @param logic logic string
|
||||
* @return logic result
|
||||
*/
|
||||
public static boolean evaluateLogic (Evaluatee source, String logic)
|
||||
{
|
||||
// Conditional
|
||||
StringTokenizer st = new StringTokenizer(logic.trim(), "&|", true);
|
||||
int it = st.countTokens();
|
||||
if (((it/2) - ((it+1)/2)) == 0) // only uneven arguments
|
||||
{
|
||||
s_log.severe ("Logic does not comply with format "
|
||||
+ "'<expression> [<logic> <expression>]' => " + logic);
|
||||
return false;
|
||||
}
|
||||
|
||||
String exprStrand = st.nextToken().trim();
|
||||
if (exprStrand.matches("^@\\d+$") || "@P".equals(exprStrand))
|
||||
{
|
||||
exprStrand = exprStrand.concat(st.nextToken());
|
||||
exprStrand = exprStrand.concat(st.nextToken());
|
||||
}
|
||||
|
||||
//boolean retValue = evaluateLogicTuple(source, st.nextToken());
|
||||
boolean retValue = evaluateLogicTuple(source, exprStrand);
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String logOp = st.nextToken().trim();
|
||||
//boolean temp = evaluateLogicTuple(source, st.nextToken());
|
||||
|
||||
exprStrand = st.nextToken().trim();
|
||||
if (exprStrand.matches("^@\\d+$") || "@P".equals(exprStrand))
|
||||
{
|
||||
exprStrand = exprStrand.concat(st.nextToken());
|
||||
exprStrand = exprStrand.concat(st.nextToken());
|
||||
}
|
||||
|
||||
boolean temp = evaluateLogicTuple(source, exprStrand);
|
||||
|
||||
if (logOp.equals("&"))
|
||||
retValue = retValue & temp;
|
||||
else if (logOp.equals("|"))
|
||||
retValue = retValue | temp;
|
||||
else
|
||||
{
|
||||
s_log.log(Level.SEVERE, "Logic operand '|' or '&' expected => " + logic);
|
||||
return false;
|
||||
}
|
||||
} // hasMoreTokens
|
||||
return retValue;
|
||||
} // evaluateLogic
|
||||
|
||||
/**
|
||||
* Evaluate @context@=value or @context@!value or @context@^value.
|
||||
* <pre>
|
||||
* value: strips ' and " always (no escape or mid stream)
|
||||
* value: can also be a context variable
|
||||
* </pre>
|
||||
* @param source class implementing get_ValueAsString(variable)
|
||||
* @param logic logic tuple
|
||||
* @return true or false
|
||||
*/
|
||||
private static boolean evaluateLogicTuple (Evaluatee source, String logic)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer (logic.trim(), "!=^><", true);
|
||||
if (st.countTokens() != 3)
|
||||
{
|
||||
s_log.log(Level.SEVERE, "Logic tuple does not comply with format "
|
||||
+ "'@context@=value' where operand could be one of '=!^><' => " + logic);
|
||||
return false;
|
||||
}
|
||||
// First Part
|
||||
String first = st.nextToken().trim(); // get '@tag@'
|
||||
String firstEval = first.trim();
|
||||
if (first.indexOf('@') != -1) // variable
|
||||
{
|
||||
first = first.replace ('@', ' ').trim (); // strip 'tag'
|
||||
// IDEMPIERE-194 Handling null context variable
|
||||
String defaultValue = "";
|
||||
int idx = first.indexOf(":"); // or clause
|
||||
if (idx >= 0)
|
||||
{
|
||||
defaultValue = first.substring(idx+1, first.length());
|
||||
first = first.substring(0, idx);
|
||||
}
|
||||
firstEval = source.get_ValueAsString (first); // replace with it's value
|
||||
if (Util.isEmpty(firstEval) && !Util.isEmpty(defaultValue)) {
|
||||
firstEval = defaultValue;
|
||||
}
|
||||
}
|
||||
//NPE sanity check
|
||||
if (firstEval == null)
|
||||
firstEval = "";
|
||||
|
||||
firstEval = firstEval.replace('\'', ' ').replace('"', ' ').trim(); // strip ' and "
|
||||
|
||||
// Comperator
|
||||
String operand = st.nextToken();
|
||||
|
||||
// Second Part
|
||||
String rightToken = st.nextToken(); // get value
|
||||
String[] list = rightToken.split("[,]");
|
||||
for(String second : list)
|
||||
{
|
||||
String secondEval = second.trim();
|
||||
if (second.indexOf('@') != -1) // variable
|
||||
{
|
||||
second = second.replace('@', ' ').trim(); // strip tag
|
||||
secondEval = source.get_ValueAsString (second); // replace with it's value
|
||||
}
|
||||
secondEval = secondEval.replace('\'', ' ').replace('"', ' ').trim(); // strip ' and "
|
||||
|
||||
// Handling of ID compare (null => 0)
|
||||
if (first.trim().endsWith("_ID") && firstEval.length() == 0)
|
||||
firstEval = "0";
|
||||
if (second.trim().endsWith("_ID") && secondEval.length() == 0)
|
||||
secondEval = "0";
|
||||
|
||||
// Logical Comparison
|
||||
boolean result = evaluateLogicTuple (firstEval, operand, secondEval);
|
||||
//
|
||||
if (s_log.isLoggable(Level.FINEST)) s_log.finest(logic
|
||||
+ " => \"" + firstEval + "\" " + operand + " \"" + secondEval + "\" => " + result);
|
||||
if (result)
|
||||
return true;
|
||||
}
|
||||
//
|
||||
return false;
|
||||
} // evaluateLogicTuple
|
||||
|
||||
/**
|
||||
* Evaluate Logic Tuple
|
||||
* @param value1 value
|
||||
* @param operand operand = ~ ^ ! > <
|
||||
* @param value2
|
||||
* @return evaluation
|
||||
*/
|
||||
private static boolean evaluateLogicTuple (String value1, String operand, String value2)
|
||||
{
|
||||
if (value1 == null || operand == null || value2 == null)
|
||||
return false;
|
||||
|
||||
BigDecimal value1bd = null;
|
||||
BigDecimal value2bd = null;
|
||||
try
|
||||
{
|
||||
if (!value1.startsWith("'"))
|
||||
value1bd = new BigDecimal (value1);
|
||||
if (!value2.startsWith("'"))
|
||||
value2bd = new BigDecimal (value2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
value1bd = null;
|
||||
value2bd = null;
|
||||
}
|
||||
//
|
||||
if (operand.equals("="))
|
||||
{
|
||||
if (value1bd != null && value2bd != null)
|
||||
return value1bd.compareTo(value2bd) == 0;
|
||||
return value1.compareTo(value2) == 0;
|
||||
}
|
||||
else if (operand.equals("<"))
|
||||
{
|
||||
if (value1bd != null && value2bd != null)
|
||||
return value1bd.compareTo(value2bd) < 0;
|
||||
return value1.compareTo(value2) < 0;
|
||||
}
|
||||
else if (operand.equals(">"))
|
||||
{
|
||||
if (value1bd != null && value2bd != null)
|
||||
return value1bd.compareTo(value2bd) > 0;
|
||||
return value1.compareTo(value2) > 0;
|
||||
}
|
||||
else // interpreted as not
|
||||
{
|
||||
if (value1bd != null && value2bd != null)
|
||||
return value1bd.compareTo(value2bd) != 0;
|
||||
return value1.compareTo(value2) != 0;
|
||||
}
|
||||
} // evaluateLogicTuple
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.expression.logic;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.compiere.util.Evaluatee;
|
||||
import org.compiere.util.Util;
|
||||
import org.idempiere.expression.logic.SimpleBooleanParser.BinaryContext;
|
||||
import org.idempiere.expression.logic.SimpleBooleanParser.BoolContext;
|
||||
import org.idempiere.expression.logic.SimpleBooleanParser.ComparatorContext;
|
||||
import org.idempiere.expression.logic.SimpleBooleanParser.ComparatorExpressionContext;
|
||||
import org.idempiere.expression.logic.SimpleBooleanParser.ContextVariablesContext;
|
||||
import org.idempiere.expression.logic.SimpleBooleanParser.DoubleQuotedTextContext;
|
||||
import org.idempiere.expression.logic.SimpleBooleanParser.QuotedTextContext;
|
||||
import org.idempiere.expression.logic.SimpleBooleanParser.TextContext;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class EvaluationVisitor extends SimpleBooleanBaseVisitor<Object> {
|
||||
|
||||
private final Evaluatee evaluatee;
|
||||
|
||||
public EvaluationVisitor(Evaluatee evaluatee) {
|
||||
this.evaluatee = evaluatee;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitParse(SimpleBooleanParser.ParseContext ctx) {
|
||||
return super.visit(ctx.expression());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDecimalExpression(SimpleBooleanParser.DecimalExpressionContext ctx) {
|
||||
return new BigDecimal(ctx.DECIMAL().getText());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Object visitQuotedText(QuotedTextContext ctx) {
|
||||
return ctx.QTEXT().getText().replaceAll("[']", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDoubleQuotedText(DoubleQuotedTextContext ctx) {
|
||||
return ctx.DQTEXT().getText().replaceAll("[\"]", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitText(TextContext ctx) {
|
||||
return ctx.TEXT().getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitNotExpression(SimpleBooleanParser.NotExpressionContext ctx) {
|
||||
return !((Boolean) this.visit(ctx.expression()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitParenExpression(SimpleBooleanParser.ParenExpressionContext ctx) {
|
||||
return super.visit(ctx.expression());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitComparatorExpression(SimpleBooleanParser.ComparatorExpressionContext ctx) {
|
||||
if (ctx.op.EQ() != null) {
|
||||
return isEqual(ctx);
|
||||
} else if (ctx.op.LE() != null) {
|
||||
return asBigDecimal(ctx.left).compareTo(asBigDecimal(ctx.right)) <= 0;
|
||||
} else if (ctx.op.GE() != null) {
|
||||
return asBigDecimal(ctx.left).compareTo(asBigDecimal(ctx.right)) >= 0;
|
||||
} else if (ctx.op.LT() != null) {
|
||||
return asBigDecimal(ctx.left).compareTo(asBigDecimal(ctx.right)) < 0;
|
||||
} else if (ctx.op.GT() != null) {
|
||||
return asBigDecimal(ctx.left).compareTo(asBigDecimal(ctx.right)) > 0;
|
||||
} else if (ctx.op.NE() != null) {
|
||||
return !(isEqual(ctx));
|
||||
} else if (ctx.op.RE() != null) {
|
||||
return regularExpressionMatch(ctx);
|
||||
}
|
||||
throw new RuntimeException("not implemented: comparator operator " + ctx.op.getText());
|
||||
}
|
||||
|
||||
//input ~ regex
|
||||
private Boolean regularExpressionMatch(ComparatorExpressionContext ctx) {
|
||||
String left = this.visit(ctx.left).toString();
|
||||
String right = this.visit(ctx.right).toString();
|
||||
return Pattern.matches(right, left);
|
||||
}
|
||||
|
||||
private Boolean isEqual(SimpleBooleanParser.ComparatorExpressionContext ctx) {
|
||||
Object left = this.visit(ctx.left);
|
||||
Object right = this.visit(ctx.right);
|
||||
if (left instanceof String && right instanceof String && !(ctx.right.getText().startsWith("'") && !(ctx.right.getText().startsWith("\"")))) {
|
||||
String rightText = (String) right;
|
||||
if (rightText.indexOf(",") > 0) {
|
||||
return isIn((String)left, rightText);
|
||||
}
|
||||
}
|
||||
if (left instanceof BigDecimal && right instanceof BigDecimal) {
|
||||
return ((BigDecimal)left).compareTo((BigDecimal) right) == 0;
|
||||
} else {
|
||||
String leftStr = left.toString();
|
||||
if (left instanceof BigDecimal) {
|
||||
if (((BigDecimal)left).stripTrailingZeros().scale() <= 0) {
|
||||
leftStr = Integer.toString(((BigDecimal)left).intValue());
|
||||
}
|
||||
}
|
||||
String rightStr = right.toString();
|
||||
if (right instanceof BigDecimal) {
|
||||
if (((BigDecimal)right).stripTrailingZeros().scale() <= 0) {
|
||||
rightStr = Integer.toString(((BigDecimal)right).intValue());
|
||||
}
|
||||
}
|
||||
return leftStr.equals(rightStr);
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean isIn(String left, String rightText) {
|
||||
String[] values = rightText.split("[,]");
|
||||
for(String s : values) {
|
||||
s = s.trim();
|
||||
if ((s.startsWith("'") && s.endsWith("'")) || (s.startsWith("\"") && s.endsWith("\"")))
|
||||
s = s.substring(1, s.length()-1);
|
||||
if (left.equals(s))
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitBinaryExpression(SimpleBooleanParser.BinaryExpressionContext ctx) {
|
||||
if (ctx.op.AND() != null) {
|
||||
return asBoolean(ctx.left) && asBoolean(ctx.right);
|
||||
} else if (ctx.op.OR() != null) {
|
||||
return asBoolean(ctx.left) || asBoolean(ctx.right);
|
||||
}
|
||||
throw new RuntimeException("not implemented: binary operator " + ctx.op.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitBoolExpression(SimpleBooleanParser.BoolExpressionContext ctx) {
|
||||
return Boolean.valueOf(ctx.getText());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object visitComparator(ComparatorContext ctx) {
|
||||
return super.visitComparator(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitBool(BoolContext ctx) {
|
||||
return super.visitBool(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitBinary(BinaryContext ctx) {
|
||||
return super.visitBinary(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitContextVariables(ContextVariablesContext ctx) {
|
||||
String context = ctx.getText().substring(1, ctx.getText().length()-1);
|
||||
|
||||
// IDEMPIERE-194 Handling null context variable
|
||||
String defaultValue = "";
|
||||
int idx = context.indexOf(":"); // or clause
|
||||
if (idx >= 0)
|
||||
{
|
||||
defaultValue = context.substring(idx+1, context.length());
|
||||
context = context.substring(0, idx);
|
||||
}
|
||||
String value = evaluatee.get_ValueAsString(context);
|
||||
if (Util.isEmpty(value) && !Util.isEmpty(defaultValue)) {
|
||||
value = defaultValue;
|
||||
}
|
||||
if (value == null)
|
||||
value = "";
|
||||
|
||||
if (Util.isEmpty(value, true) && context.endsWith("_ID"))
|
||||
return "0";
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
private boolean asBoolean(SimpleBooleanParser.ExpressionContext ctx) {
|
||||
return (boolean) visit(ctx);
|
||||
}
|
||||
|
||||
private BigDecimal asBigDecimal(SimpleBooleanParser.ExpressionContext ctx) {
|
||||
Object value = visit(ctx);
|
||||
if (value instanceof String)
|
||||
return new BigDecimal((String)value);
|
||||
else if (value instanceof BigDecimal)
|
||||
return (BigDecimal)value;
|
||||
else
|
||||
return new BigDecimal(value.toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.expression.logic;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.misc.ParseCancellationException;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Evaluatee;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public final class LogicEvaluator {
|
||||
|
||||
private final static CLogger s_log = CLogger.getCLogger(LogicEvaluator.class);
|
||||
|
||||
private LogicEvaluator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate Logic.
|
||||
* {@code
|
||||
* format: <negate>(<expression> [<logic> <expression>]).
|
||||
* <negate>: $!.
|
||||
* <expression>: @<context>@<comparison><value>.
|
||||
* <logic>: | or & (Example '@AD_Table@=Test | @Language@=GERGER).
|
||||
* <comparison>: = | ! | ^ | < | > | <= | >= | ~ (Equal, Not Equal, Not Equal, Less Than,
|
||||
* Greater Than, Less Than or Equal, Greater Than or Equal, Regular Expression Match).
|
||||
* <Regular Expression Match>: <input string> ~ '<regular expression>'.
|
||||
* <List>: value1,value2,value3 (Example '@CalculationType@=A,R,S').
|
||||
* <context>: any global or window context.
|
||||
* <value>: strings can be with ' or ".
|
||||
* <logic operators>: AND or OR with the previous result from left to right.
|
||||
* <()>: override the default left to right evaluation order (Example '@GrandTotal@=0 |(@GrandTotal@>0 & @PaymentRule@=X)").
|
||||
*
|
||||
* }
|
||||
* @param source class implementing get_ValueAsString(variable)
|
||||
* @param logic logic string
|
||||
* @return logic result
|
||||
*/
|
||||
public static boolean evaluateLogic (Evaluatee source, String logic) {
|
||||
SimpleBooleanLexer lexer = new SimpleBooleanLexer(CharStreams.fromString(logic));
|
||||
SimpleBooleanParser parser = new SimpleBooleanParser(new CommonTokenStream(lexer));
|
||||
parser.removeErrorListeners();
|
||||
parser.addErrorListener(ThrowingErrorListener.INSTANCE);
|
||||
try {
|
||||
Object result = new EvaluationVisitor(source).visit(parser.parse());
|
||||
if (result != null && result instanceof Boolean) {
|
||||
return (boolean) result;
|
||||
} else {
|
||||
s_log.severe ("Logic does not comply with format "
|
||||
+ "'<expression> [<logic> <expression>]' => " + logic);
|
||||
return false;
|
||||
}
|
||||
} catch (ParseCancellationException e) {
|
||||
s_log.log(Level.SEVERE, "Logic="+logic+" Error="+e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw exception if logic is not valid
|
||||
* @param logic
|
||||
* @throws ParseCancellationException
|
||||
*/
|
||||
public static void validate(String logic) {
|
||||
SimpleBooleanLexer lexer = new SimpleBooleanLexer(CharStreams.fromString(logic));
|
||||
SimpleBooleanParser parser = new SimpleBooleanParser(new CommonTokenStream(lexer));
|
||||
parser.removeErrorListeners();
|
||||
parser.addErrorListener(ThrowingErrorListener.INSTANCE);
|
||||
parser.parse();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
token literal names:
|
||||
null
|
||||
'&'
|
||||
'|'
|
||||
'$!'
|
||||
'true'
|
||||
'false'
|
||||
'>'
|
||||
'>='
|
||||
'<'
|
||||
'<='
|
||||
'='
|
||||
null
|
||||
'~'
|
||||
'('
|
||||
')'
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
|
||||
token symbolic names:
|
||||
null
|
||||
AND
|
||||
OR
|
||||
NOT
|
||||
TRUE
|
||||
FALSE
|
||||
GT
|
||||
GE
|
||||
LT
|
||||
LE
|
||||
EQ
|
||||
NE
|
||||
RE
|
||||
LPAREN
|
||||
RPAREN
|
||||
DECIMAL
|
||||
VARIABLE
|
||||
QTEXT
|
||||
DQTEXT
|
||||
TEXT
|
||||
WS
|
||||
|
||||
rule names:
|
||||
parse
|
||||
expression
|
||||
comparator
|
||||
binary
|
||||
bool
|
||||
|
||||
|
||||
atn:
|
||||
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 22, 50, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 29, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 39, 10, 3, 12, 3, 14, 3, 42, 11, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 2, 3, 4, 7, 2, 4, 6, 8, 10, 2, 5, 3, 2, 8, 14, 3, 2, 3, 4, 3, 2, 6, 7, 2, 53, 2, 12, 3, 2, 2, 2, 4, 28, 3, 2, 2, 2, 6, 43, 3, 2, 2, 2, 8, 45, 3, 2, 2, 2, 10, 47, 3, 2, 2, 2, 12, 13, 5, 4, 3, 2, 13, 14, 7, 2, 2, 3, 14, 3, 3, 2, 2, 2, 15, 16, 8, 3, 1, 2, 16, 17, 7, 15, 2, 2, 17, 18, 5, 4, 3, 2, 18, 19, 7, 16, 2, 2, 19, 29, 3, 2, 2, 2, 20, 21, 7, 5, 2, 2, 21, 29, 5, 4, 3, 11, 22, 29, 5, 10, 6, 2, 23, 29, 7, 18, 2, 2, 24, 29, 7, 19, 2, 2, 25, 29, 7, 20, 2, 2, 26, 29, 7, 21, 2, 2, 27, 29, 7, 17, 2, 2, 28, 15, 3, 2, 2, 2, 28, 20, 3, 2, 2, 2, 28, 22, 3, 2, 2, 2, 28, 23, 3, 2, 2, 2, 28, 24, 3, 2, 2, 2, 28, 25, 3, 2, 2, 2, 28, 26, 3, 2, 2, 2, 28, 27, 3, 2, 2, 2, 29, 40, 3, 2, 2, 2, 30, 31, 12, 10, 2, 2, 31, 32, 5, 6, 4, 2, 32, 33, 5, 4, 3, 11, 33, 39, 3, 2, 2, 2, 34, 35, 12, 9, 2, 2, 35, 36, 5, 8, 5, 2, 36, 37, 5, 4, 3, 10, 37, 39, 3, 2, 2, 2, 38, 30, 3, 2, 2, 2, 38, 34, 3, 2, 2, 2, 39, 42, 3, 2, 2, 2, 40, 38, 3, 2, 2, 2, 40, 41, 3, 2, 2, 2, 41, 5, 3, 2, 2, 2, 42, 40, 3, 2, 2, 2, 43, 44, 9, 2, 2, 2, 44, 7, 3, 2, 2, 2, 45, 46, 9, 3, 2, 2, 46, 9, 3, 2, 2, 2, 47, 48, 9, 4, 2, 2, 48, 11, 3, 2, 2, 2, 5, 28, 38, 40]
|
|
@ -0,0 +1,33 @@
|
|||
QTEXT=17
|
||||
OR=2
|
||||
LT=8
|
||||
LPAREN=13
|
||||
TRUE=4
|
||||
DECIMAL=15
|
||||
TEXT=19
|
||||
RPAREN=14
|
||||
EQ=10
|
||||
GT=6
|
||||
NOT=3
|
||||
RE=12
|
||||
VARIABLE=16
|
||||
AND=1
|
||||
NE=11
|
||||
LE=9
|
||||
FALSE=5
|
||||
DQTEXT=18
|
||||
WS=20
|
||||
GE=7
|
||||
'false'=5
|
||||
')'=14
|
||||
'('=13
|
||||
'&'=1
|
||||
'<='=9
|
||||
'>'=6
|
||||
'~'=12
|
||||
'$!'=3
|
||||
'='=10
|
||||
'|'=2
|
||||
'<'=8
|
||||
'>='=7
|
||||
'true'=4
|
|
@ -0,0 +1,115 @@
|
|||
// Generated from SimpleBoolean.g4 by ANTLR 4.4
|
||||
|
||||
package org.idempiere.expression.logic;
|
||||
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link SimpleBooleanVisitor},
|
||||
* which can be extended to create a visitor which only needs to handle a subset
|
||||
* of the available methods.
|
||||
*
|
||||
* @param <T> The return type of the visit operation. Use {@link Void} for
|
||||
* operations with no return type.
|
||||
*/
|
||||
public class SimpleBooleanBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements SimpleBooleanVisitor<T> {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitBoolExpression(@NotNull SimpleBooleanParser.BoolExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitBool(@NotNull SimpleBooleanParser.BoolContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitNotExpression(@NotNull SimpleBooleanParser.NotExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitParse(@NotNull SimpleBooleanParser.ParseContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitParenExpression(@NotNull SimpleBooleanParser.ParenExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitDoubleQuotedText(@NotNull SimpleBooleanParser.DoubleQuotedTextContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitBinaryExpression(@NotNull SimpleBooleanParser.BinaryExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitComparator(@NotNull SimpleBooleanParser.ComparatorContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitDecimalExpression(@NotNull SimpleBooleanParser.DecimalExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitBinary(@NotNull SimpleBooleanParser.BinaryContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitContextVariables(@NotNull SimpleBooleanParser.ContextVariablesContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitText(@NotNull SimpleBooleanParser.TextContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitQuotedText(@NotNull SimpleBooleanParser.QuotedTextContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitComparatorExpression(@NotNull SimpleBooleanParser.ComparatorExpressionContext ctx) { return visitChildren(ctx); }
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
token literal names:
|
||||
null
|
||||
'&'
|
||||
'|'
|
||||
'$!'
|
||||
'true'
|
||||
'false'
|
||||
'>'
|
||||
'>='
|
||||
'<'
|
||||
'<='
|
||||
'='
|
||||
null
|
||||
'~'
|
||||
'('
|
||||
')'
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
|
||||
token symbolic names:
|
||||
null
|
||||
AND
|
||||
OR
|
||||
NOT
|
||||
TRUE
|
||||
FALSE
|
||||
GT
|
||||
GE
|
||||
LT
|
||||
LE
|
||||
EQ
|
||||
NE
|
||||
RE
|
||||
LPAREN
|
||||
RPAREN
|
||||
DECIMAL
|
||||
VARIABLE
|
||||
QTEXT
|
||||
DQTEXT
|
||||
TEXT
|
||||
WS
|
||||
|
||||
rule names:
|
||||
AND
|
||||
OR
|
||||
NOT
|
||||
TRUE
|
||||
FALSE
|
||||
GT
|
||||
GE
|
||||
LT
|
||||
LE
|
||||
EQ
|
||||
NE
|
||||
RE
|
||||
LPAREN
|
||||
RPAREN
|
||||
DECIMAL
|
||||
VARIABLE
|
||||
QTEXT
|
||||
DQTEXT
|
||||
TEXT
|
||||
WS
|
||||
|
||||
channel names:
|
||||
DEFAULT_TOKEN_CHANNEL
|
||||
HIDDEN
|
||||
|
||||
mode names:
|
||||
DEFAULT_MODE
|
||||
|
||||
atn:
|
||||
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 22, 136, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 5, 16, 83, 10, 16, 3, 16, 6, 16, 86, 10, 16, 13, 16, 14, 16, 87, 3, 16, 3, 16, 6, 16, 92, 10, 16, 13, 16, 14, 16, 93, 5, 16, 96, 10, 16, 3, 17, 3, 17, 7, 17, 100, 10, 17, 12, 17, 14, 17, 103, 11, 17, 3, 17, 3, 17, 3, 18, 3, 18, 7, 18, 109, 10, 18, 12, 18, 14, 18, 112, 11, 18, 3, 18, 3, 18, 3, 19, 3, 19, 7, 19, 118, 10, 19, 12, 19, 14, 19, 121, 11, 19, 3, 19, 3, 19, 3, 20, 6, 20, 126, 10, 20, 13, 20, 14, 20, 127, 3, 21, 6, 21, 131, 10, 21, 13, 21, 14, 21, 132, 3, 21, 3, 21, 4, 110, 119, 2, 22, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 3, 2, 9, 4, 2, 35, 35, 96, 96, 3, 2, 50, 59, 8, 2, 37, 38, 50, 59, 67, 92, 97, 97, 99, 124, 128, 128, 3, 2, 41, 41, 3, 2, 36, 36, 7, 2, 46, 46, 50, 59, 67, 92, 97, 97, 99, 124, 5, 2, 11, 12, 14, 15, 34, 34, 2, 144, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 3, 43, 3, 2, 2, 2, 5, 45, 3, 2, 2, 2, 7, 47, 3, 2, 2, 2, 9, 50, 3, 2, 2, 2, 11, 55, 3, 2, 2, 2, 13, 61, 3, 2, 2, 2, 15, 63, 3, 2, 2, 2, 17, 66, 3, 2, 2, 2, 19, 68, 3, 2, 2, 2, 21, 71, 3, 2, 2, 2, 23, 73, 3, 2, 2, 2, 25, 75, 3, 2, 2, 2, 27, 77, 3, 2, 2, 2, 29, 79, 3, 2, 2, 2, 31, 82, 3, 2, 2, 2, 33, 97, 3, 2, 2, 2, 35, 106, 3, 2, 2, 2, 37, 115, 3, 2, 2, 2, 39, 125, 3, 2, 2, 2, 41, 130, 3, 2, 2, 2, 43, 44, 7, 40, 2, 2, 44, 4, 3, 2, 2, 2, 45, 46, 7, 126, 2, 2, 46, 6, 3, 2, 2, 2, 47, 48, 7, 38, 2, 2, 48, 49, 7, 35, 2, 2, 49, 8, 3, 2, 2, 2, 50, 51, 7, 118, 2, 2, 51, 52, 7, 116, 2, 2, 52, 53, 7, 119, 2, 2, 53, 54, 7, 103, 2, 2, 54, 10, 3, 2, 2, 2, 55, 56, 7, 104, 2, 2, 56, 57, 7, 99, 2, 2, 57, 58, 7, 110, 2, 2, 58, 59, 7, 117, 2, 2, 59, 60, 7, 103, 2, 2, 60, 12, 3, 2, 2, 2, 61, 62, 7, 64, 2, 2, 62, 14, 3, 2, 2, 2, 63, 64, 7, 64, 2, 2, 64, 65, 7, 63, 2, 2, 65, 16, 3, 2, 2, 2, 66, 67, 7, 62, 2, 2, 67, 18, 3, 2, 2, 2, 68, 69, 7, 62, 2, 2, 69, 70, 7, 63, 2, 2, 70, 20, 3, 2, 2, 2, 71, 72, 7, 63, 2, 2, 72, 22, 3, 2, 2, 2, 73, 74, 9, 2, 2, 2, 74, 24, 3, 2, 2, 2, 75, 76, 7, 128, 2, 2, 76, 26, 3, 2, 2, 2, 77, 78, 7, 42, 2, 2, 78, 28, 3, 2, 2, 2, 79, 80, 7, 43, 2, 2, 80, 30, 3, 2, 2, 2, 81, 83, 7, 47, 2, 2, 82, 81, 3, 2, 2, 2, 82, 83, 3, 2, 2, 2, 83, 85, 3, 2, 2, 2, 84, 86, 9, 3, 2, 2, 85, 84, 3, 2, 2, 2, 86, 87, 3, 2, 2, 2, 87, 85, 3, 2, 2, 2, 87, 88, 3, 2, 2, 2, 88, 95, 3, 2, 2, 2, 89, 91, 7, 48, 2, 2, 90, 92, 9, 3, 2, 2, 91, 90, 3, 2, 2, 2, 92, 93, 3, 2, 2, 2, 93, 91, 3, 2, 2, 2, 93, 94, 3, 2, 2, 2, 94, 96, 3, 2, 2, 2, 95, 89, 3, 2, 2, 2, 95, 96, 3, 2, 2, 2, 96, 32, 3, 2, 2, 2, 97, 101, 7, 66, 2, 2, 98, 100, 9, 4, 2, 2, 99, 98, 3, 2, 2, 2, 100, 103, 3, 2, 2, 2, 101, 99, 3, 2, 2, 2, 101, 102, 3, 2, 2, 2, 102, 104, 3, 2, 2, 2, 103, 101, 3, 2, 2, 2, 104, 105, 7, 66, 2, 2, 105, 34, 3, 2, 2, 2, 106, 110, 9, 5, 2, 2, 107, 109, 11, 2, 2, 2, 108, 107, 3, 2, 2, 2, 109, 112, 3, 2, 2, 2, 110, 111, 3, 2, 2, 2, 110, 108, 3, 2, 2, 2, 111, 113, 3, 2, 2, 2, 112, 110, 3, 2, 2, 2, 113, 114, 9, 5, 2, 2, 114, 36, 3, 2, 2, 2, 115, 119, 9, 6, 2, 2, 116, 118, 11, 2, 2, 2, 117, 116, 3, 2, 2, 2, 118, 121, 3, 2, 2, 2, 119, 120, 3, 2, 2, 2, 119, 117, 3, 2, 2, 2, 120, 122, 3, 2, 2, 2, 121, 119, 3, 2, 2, 2, 122, 123, 9, 6, 2, 2, 123, 38, 3, 2, 2, 2, 124, 126, 9, 7, 2, 2, 125, 124, 3, 2, 2, 2, 126, 127, 3, 2, 2, 2, 127, 125, 3, 2, 2, 2, 127, 128, 3, 2, 2, 2, 128, 40, 3, 2, 2, 2, 129, 131, 9, 8, 2, 2, 130, 129, 3, 2, 2, 2, 131, 132, 3, 2, 2, 2, 132, 130, 3, 2, 2, 2, 132, 133, 3, 2, 2, 2, 133, 134, 3, 2, 2, 2, 134, 135, 8, 21, 2, 2, 135, 42, 3, 2, 2, 2, 12, 2, 82, 87, 93, 95, 101, 110, 119, 127, 132, 3, 8, 2, 2]
|
|
@ -0,0 +1,111 @@
|
|||
// Generated from SimpleBoolean.g4 by ANTLR 4.4
|
||||
|
||||
package org.idempiere.expression.logic;
|
||||
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class SimpleBooleanLexer extends Lexer {
|
||||
static { RuntimeMetaData.checkVersion("4.4", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
AND=1, OR=2, NOT=3, TRUE=4, FALSE=5, GT=6, GE=7, LT=8, LE=9, EQ=10, NE=11,
|
||||
RE=12, LPAREN=13, RPAREN=14, DECIMAL=15, VARIABLE=16, QTEXT=17, DQTEXT=18,
|
||||
TEXT=19, WS=20;
|
||||
public static String[] modeNames = {
|
||||
"DEFAULT_MODE"
|
||||
};
|
||||
|
||||
public static final String[] tokenNames = {
|
||||
"'\\u0000'", "'\\u0001'", "'\\u0002'", "'\\u0003'", "'\\u0004'", "'\\u0005'",
|
||||
"'\\u0006'", "'\\u0007'", "'\b'", "'\t'", "'\n'", "'\\u000B'", "'\f'",
|
||||
"'\r'", "'\\u000E'", "'\\u000F'", "'\\u0010'", "'\\u0011'", "'\\u0012'",
|
||||
"'\\u0013'", "'\\u0014'"
|
||||
};
|
||||
public static final String[] ruleNames = {
|
||||
"AND", "OR", "NOT", "TRUE", "FALSE", "GT", "GE", "LT", "LE", "EQ", "NE",
|
||||
"RE", "LPAREN", "RPAREN", "DECIMAL", "VARIABLE", "QTEXT", "DQTEXT", "TEXT",
|
||||
"WS"
|
||||
};
|
||||
|
||||
|
||||
public SimpleBooleanLexer(CharStream input) {
|
||||
super(input);
|
||||
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "SimpleBoolean.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getTokenNames() { return tokenNames; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public String[] getModeNames() { return modeNames; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\26\u0088\b\1\4\2"+
|
||||
"\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+
|
||||
"\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+
|
||||
"\t\22\4\23\t\23\4\24\t\24\4\25\t\25\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\5\3"+
|
||||
"\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\b\3\b\3\b\3\t\3\t\3\n"+
|
||||
"\3\n\3\n\3\13\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\20\5\20S\n\20"+
|
||||
"\3\20\6\20V\n\20\r\20\16\20W\3\20\3\20\6\20\\\n\20\r\20\16\20]\5\20`\n"+
|
||||
"\20\3\21\3\21\7\21d\n\21\f\21\16\21g\13\21\3\21\3\21\3\22\3\22\7\22m\n"+
|
||||
"\22\f\22\16\22p\13\22\3\22\3\22\3\23\3\23\7\23v\n\23\f\23\16\23y\13\23"+
|
||||
"\3\23\3\23\3\24\6\24~\n\24\r\24\16\24\177\3\25\6\25\u0083\n\25\r\25\16"+
|
||||
"\25\u0084\3\25\3\25\5enw\2\26\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13"+
|
||||
"\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26\3\2\b\4\2##``"+
|
||||
"\3\2\62;\3\2))\3\2$$\7\2..\62;C\\aac|\5\2\13\f\16\17\"\"\u0090\2\3\3\2"+
|
||||
"\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17"+
|
||||
"\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2"+
|
||||
"\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3"+
|
||||
"\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\3+\3\2\2\2\5-\3\2\2\2\7/\3\2\2\2\t\62\3"+
|
||||
"\2\2\2\13\67\3\2\2\2\r=\3\2\2\2\17?\3\2\2\2\21B\3\2\2\2\23D\3\2\2\2\25"+
|
||||
"G\3\2\2\2\27I\3\2\2\2\31K\3\2\2\2\33M\3\2\2\2\35O\3\2\2\2\37R\3\2\2\2"+
|
||||
"!a\3\2\2\2#j\3\2\2\2%s\3\2\2\2\'}\3\2\2\2)\u0082\3\2\2\2+,\7(\2\2,\4\3"+
|
||||
"\2\2\2-.\7~\2\2.\6\3\2\2\2/\60\7&\2\2\60\61\7#\2\2\61\b\3\2\2\2\62\63"+
|
||||
"\7v\2\2\63\64\7t\2\2\64\65\7w\2\2\65\66\7g\2\2\66\n\3\2\2\2\678\7h\2\2"+
|
||||
"89\7c\2\29:\7n\2\2:;\7u\2\2;<\7g\2\2<\f\3\2\2\2=>\7@\2\2>\16\3\2\2\2?"+
|
||||
"@\7@\2\2@A\7?\2\2A\20\3\2\2\2BC\7>\2\2C\22\3\2\2\2DE\7>\2\2EF\7?\2\2F"+
|
||||
"\24\3\2\2\2GH\7?\2\2H\26\3\2\2\2IJ\t\2\2\2J\30\3\2\2\2KL\7\u0080\2\2L"+
|
||||
"\32\3\2\2\2MN\7*\2\2N\34\3\2\2\2OP\7+\2\2P\36\3\2\2\2QS\7/\2\2RQ\3\2\2"+
|
||||
"\2RS\3\2\2\2SU\3\2\2\2TV\t\3\2\2UT\3\2\2\2VW\3\2\2\2WU\3\2\2\2WX\3\2\2"+
|
||||
"\2X_\3\2\2\2Y[\7\60\2\2Z\\\t\3\2\2[Z\3\2\2\2\\]\3\2\2\2][\3\2\2\2]^\3"+
|
||||
"\2\2\2^`\3\2\2\2_Y\3\2\2\2_`\3\2\2\2` \3\2\2\2ae\7B\2\2bd\13\2\2\2cb\3"+
|
||||
"\2\2\2dg\3\2\2\2ef\3\2\2\2ec\3\2\2\2fh\3\2\2\2ge\3\2\2\2hi\7B\2\2i\"\3"+
|
||||
"\2\2\2jn\t\4\2\2km\13\2\2\2lk\3\2\2\2mp\3\2\2\2no\3\2\2\2nl\3\2\2\2oq"+
|
||||
"\3\2\2\2pn\3\2\2\2qr\t\4\2\2r$\3\2\2\2sw\t\5\2\2tv\13\2\2\2ut\3\2\2\2"+
|
||||
"vy\3\2\2\2wx\3\2\2\2wu\3\2\2\2xz\3\2\2\2yw\3\2\2\2z{\t\5\2\2{&\3\2\2\2"+
|
||||
"|~\t\6\2\2}|\3\2\2\2~\177\3\2\2\2\177}\3\2\2\2\177\u0080\3\2\2\2\u0080"+
|
||||
"(\3\2\2\2\u0081\u0083\t\7\2\2\u0082\u0081\3\2\2\2\u0083\u0084\3\2\2\2"+
|
||||
"\u0084\u0082\3\2\2\2\u0084\u0085\3\2\2\2\u0085\u0086\3\2\2\2\u0086\u0087"+
|
||||
"\b\25\2\2\u0087*\3\2\2\2\f\2RW]_enw\177\u0084\3\b\2\2";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
|
||||
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
QTEXT=17
|
||||
OR=2
|
||||
LT=8
|
||||
LPAREN=13
|
||||
TRUE=4
|
||||
DECIMAL=15
|
||||
TEXT=19
|
||||
RPAREN=14
|
||||
EQ=10
|
||||
GT=6
|
||||
NOT=3
|
||||
RE=12
|
||||
VARIABLE=16
|
||||
AND=1
|
||||
NE=11
|
||||
LE=9
|
||||
FALSE=5
|
||||
DQTEXT=18
|
||||
WS=20
|
||||
GE=7
|
||||
'false'=5
|
||||
')'=14
|
||||
'('=13
|
||||
'&'=1
|
||||
'<='=9
|
||||
'>'=6
|
||||
'~'=12
|
||||
'$!'=3
|
||||
'='=10
|
||||
'|'=2
|
||||
'<'=8
|
||||
'>='=7
|
||||
'true'=4
|
|
@ -0,0 +1,530 @@
|
|||
// Generated from SimpleBoolean.g4 by ANTLR 4.4
|
||||
|
||||
package org.idempiere.expression.logic;
|
||||
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class SimpleBooleanParser extends Parser {
|
||||
static { RuntimeMetaData.checkVersion("4.4", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
AND=1, OR=2, NOT=3, TRUE=4, FALSE=5, GT=6, GE=7, LT=8, LE=9, EQ=10, NE=11,
|
||||
RE=12, LPAREN=13, RPAREN=14, DECIMAL=15, VARIABLE=16, QTEXT=17, DQTEXT=18,
|
||||
TEXT=19, WS=20;
|
||||
public static final String[] tokenNames = {
|
||||
"<INVALID>", "'&'", "'|'", "'$!'", "'true'", "'false'", "'>'", "'>='",
|
||||
"'<'", "'<='", "'='", "NE", "'~'", "'('", "')'", "DECIMAL", "VARIABLE",
|
||||
"QTEXT", "DQTEXT", "TEXT", "WS"
|
||||
};
|
||||
public static final int
|
||||
RULE_parse = 0, RULE_expression = 1, RULE_comparator = 2, RULE_binary = 3,
|
||||
RULE_bool = 4;
|
||||
public static final String[] ruleNames = {
|
||||
"parse", "expression", "comparator", "binary", "bool"
|
||||
};
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "SimpleBoolean.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getTokenNames() { return tokenNames; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public SimpleBooleanParser(TokenStream input) {
|
||||
super(input);
|
||||
_interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
public static class ParseContext extends ParserRuleContext {
|
||||
public TerminalNode EOF() { return getToken(SimpleBooleanParser.EOF, 0); }
|
||||
public ExpressionContext expression() {
|
||||
return getRuleContext(ExpressionContext.class,0);
|
||||
}
|
||||
public ParseContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_parse; }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitParse(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final ParseContext parse() throws RecognitionException {
|
||||
ParseContext _localctx = new ParseContext(_ctx, getState());
|
||||
enterRule(_localctx, 0, RULE_parse);
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(10); expression(0);
|
||||
setState(11); match(EOF);
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class ExpressionContext extends ParserRuleContext {
|
||||
public ExpressionContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_expression; }
|
||||
|
||||
public ExpressionContext() { }
|
||||
public void copyFrom(ExpressionContext ctx) {
|
||||
super.copyFrom(ctx);
|
||||
}
|
||||
}
|
||||
public static class BinaryExpressionContext extends ExpressionContext {
|
||||
public ExpressionContext left;
|
||||
public BinaryContext op;
|
||||
public ExpressionContext right;
|
||||
public BinaryContext binary() {
|
||||
return getRuleContext(BinaryContext.class,0);
|
||||
}
|
||||
public ExpressionContext expression(int i) {
|
||||
return getRuleContext(ExpressionContext.class,i);
|
||||
}
|
||||
public List<ExpressionContext> expression() {
|
||||
return getRuleContexts(ExpressionContext.class);
|
||||
}
|
||||
public BinaryExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitBinaryExpression(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class DecimalExpressionContext extends ExpressionContext {
|
||||
public TerminalNode DECIMAL() { return getToken(SimpleBooleanParser.DECIMAL, 0); }
|
||||
public DecimalExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitDecimalExpression(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class BoolExpressionContext extends ExpressionContext {
|
||||
public BoolContext bool() {
|
||||
return getRuleContext(BoolContext.class,0);
|
||||
}
|
||||
public BoolExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitBoolExpression(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ContextVariablesContext extends ExpressionContext {
|
||||
public TerminalNode VARIABLE() { return getToken(SimpleBooleanParser.VARIABLE, 0); }
|
||||
public ContextVariablesContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitContextVariables(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class NotExpressionContext extends ExpressionContext {
|
||||
public TerminalNode NOT() { return getToken(SimpleBooleanParser.NOT, 0); }
|
||||
public ExpressionContext expression() {
|
||||
return getRuleContext(ExpressionContext.class,0);
|
||||
}
|
||||
public NotExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitNotExpression(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ParenExpressionContext extends ExpressionContext {
|
||||
public TerminalNode LPAREN() { return getToken(SimpleBooleanParser.LPAREN, 0); }
|
||||
public TerminalNode RPAREN() { return getToken(SimpleBooleanParser.RPAREN, 0); }
|
||||
public ExpressionContext expression() {
|
||||
return getRuleContext(ExpressionContext.class,0);
|
||||
}
|
||||
public ParenExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitParenExpression(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class TextContext extends ExpressionContext {
|
||||
public TerminalNode TEXT() { return getToken(SimpleBooleanParser.TEXT, 0); }
|
||||
public TextContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitText(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class QuotedTextContext extends ExpressionContext {
|
||||
public TerminalNode QTEXT() { return getToken(SimpleBooleanParser.QTEXT, 0); }
|
||||
public QuotedTextContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitQuotedText(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class DoubleQuotedTextContext extends ExpressionContext {
|
||||
public TerminalNode DQTEXT() { return getToken(SimpleBooleanParser.DQTEXT, 0); }
|
||||
public DoubleQuotedTextContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitDoubleQuotedText(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
public static class ComparatorExpressionContext extends ExpressionContext {
|
||||
public ExpressionContext left;
|
||||
public ComparatorContext op;
|
||||
public ExpressionContext right;
|
||||
public ComparatorContext comparator() {
|
||||
return getRuleContext(ComparatorContext.class,0);
|
||||
}
|
||||
public ExpressionContext expression(int i) {
|
||||
return getRuleContext(ExpressionContext.class,i);
|
||||
}
|
||||
public List<ExpressionContext> expression() {
|
||||
return getRuleContexts(ExpressionContext.class);
|
||||
}
|
||||
public ComparatorExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitComparatorExpression(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final ExpressionContext expression() throws RecognitionException {
|
||||
return expression(0);
|
||||
}
|
||||
|
||||
private ExpressionContext expression(int _p) throws RecognitionException {
|
||||
ParserRuleContext _parentctx = _ctx;
|
||||
int _parentState = getState();
|
||||
ExpressionContext _localctx = new ExpressionContext(_ctx, _parentState);
|
||||
ExpressionContext _prevctx = _localctx;
|
||||
int _startState = 2;
|
||||
enterRecursionRule(_localctx, 2, RULE_expression, _p);
|
||||
try {
|
||||
int _alt;
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(26);
|
||||
switch (_input.LA(1)) {
|
||||
case NOT:
|
||||
{
|
||||
_localctx = new NotExpressionContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
|
||||
setState(14); match(NOT);
|
||||
setState(15); expression(9);
|
||||
}
|
||||
break;
|
||||
case LPAREN:
|
||||
{
|
||||
_localctx = new ParenExpressionContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(16); match(LPAREN);
|
||||
setState(17); expression(0);
|
||||
setState(18); match(RPAREN);
|
||||
}
|
||||
break;
|
||||
case TRUE:
|
||||
case FALSE:
|
||||
{
|
||||
_localctx = new BoolExpressionContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(20); bool();
|
||||
}
|
||||
break;
|
||||
case VARIABLE:
|
||||
{
|
||||
_localctx = new ContextVariablesContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(21); match(VARIABLE);
|
||||
}
|
||||
break;
|
||||
case QTEXT:
|
||||
{
|
||||
_localctx = new QuotedTextContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(22); match(QTEXT);
|
||||
}
|
||||
break;
|
||||
case DQTEXT:
|
||||
{
|
||||
_localctx = new DoubleQuotedTextContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(23); match(DQTEXT);
|
||||
}
|
||||
break;
|
||||
case TEXT:
|
||||
{
|
||||
_localctx = new TextContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(24); match(TEXT);
|
||||
}
|
||||
break;
|
||||
case DECIMAL:
|
||||
{
|
||||
_localctx = new DecimalExpressionContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(25); match(DECIMAL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
_ctx.stop = _input.LT(-1);
|
||||
setState(38);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,2,_ctx);
|
||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
if ( _alt==1 ) {
|
||||
if ( _parseListeners!=null ) triggerExitRuleEvent();
|
||||
_prevctx = _localctx;
|
||||
{
|
||||
setState(36);
|
||||
switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) {
|
||||
case 1:
|
||||
{
|
||||
_localctx = new ComparatorExpressionContext(new ExpressionContext(_parentctx, _parentState));
|
||||
((ComparatorExpressionContext)_localctx).left = _prevctx;
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expression);
|
||||
setState(28);
|
||||
if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)");
|
||||
setState(29); ((ComparatorExpressionContext)_localctx).op = comparator();
|
||||
setState(30); ((ComparatorExpressionContext)_localctx).right = expression(9);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
_localctx = new BinaryExpressionContext(new ExpressionContext(_parentctx, _parentState));
|
||||
((BinaryExpressionContext)_localctx).left = _prevctx;
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_expression);
|
||||
setState(32);
|
||||
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
|
||||
setState(33); ((BinaryExpressionContext)_localctx).op = binary();
|
||||
setState(34); ((BinaryExpressionContext)_localctx).right = expression(8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(40);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,2,_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
unrollRecursionContexts(_parentctx);
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class ComparatorContext extends ParserRuleContext {
|
||||
public TerminalNode RE() { return getToken(SimpleBooleanParser.RE, 0); }
|
||||
public TerminalNode GE() { return getToken(SimpleBooleanParser.GE, 0); }
|
||||
public TerminalNode LT() { return getToken(SimpleBooleanParser.LT, 0); }
|
||||
public TerminalNode GT() { return getToken(SimpleBooleanParser.GT, 0); }
|
||||
public TerminalNode LE() { return getToken(SimpleBooleanParser.LE, 0); }
|
||||
public TerminalNode EQ() { return getToken(SimpleBooleanParser.EQ, 0); }
|
||||
public TerminalNode NE() { return getToken(SimpleBooleanParser.NE, 0); }
|
||||
public ComparatorContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_comparator; }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitComparator(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final ComparatorContext comparator() throws RecognitionException {
|
||||
ComparatorContext _localctx = new ComparatorContext(_ctx, getState());
|
||||
enterRule(_localctx, 4, RULE_comparator);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(41);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << GT) | (1L << GE) | (1L << LT) | (1L << LE) | (1L << EQ) | (1L << NE) | (1L << RE))) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
consume();
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class BinaryContext extends ParserRuleContext {
|
||||
public TerminalNode AND() { return getToken(SimpleBooleanParser.AND, 0); }
|
||||
public TerminalNode OR() { return getToken(SimpleBooleanParser.OR, 0); }
|
||||
public BinaryContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_binary; }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitBinary(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final BinaryContext binary() throws RecognitionException {
|
||||
BinaryContext _localctx = new BinaryContext(_ctx, getState());
|
||||
enterRule(_localctx, 6, RULE_binary);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(43);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==AND || _la==OR) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
consume();
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public static class BoolContext extends ParserRuleContext {
|
||||
public TerminalNode FALSE() { return getToken(SimpleBooleanParser.FALSE, 0); }
|
||||
public TerminalNode TRUE() { return getToken(SimpleBooleanParser.TRUE, 0); }
|
||||
public BoolContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
@Override public int getRuleIndex() { return RULE_bool; }
|
||||
@Override
|
||||
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
|
||||
if ( visitor instanceof SimpleBooleanVisitor ) return ((SimpleBooleanVisitor<? extends T>)visitor).visitBool(this);
|
||||
else return visitor.visitChildren(this);
|
||||
}
|
||||
}
|
||||
|
||||
public final BoolContext bool() throws RecognitionException {
|
||||
BoolContext _localctx = new BoolContext(_ctx, getState());
|
||||
enterRule(_localctx, 8, RULE_bool);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(45);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==TRUE || _la==FALSE) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
}
|
||||
consume();
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
_localctx.exception = re;
|
||||
_errHandler.reportError(this, re);
|
||||
_errHandler.recover(this, re);
|
||||
}
|
||||
finally {
|
||||
exitRule();
|
||||
}
|
||||
return _localctx;
|
||||
}
|
||||
|
||||
public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
|
||||
switch (ruleIndex) {
|
||||
case 1: return expression_sempred((ExpressionContext)_localctx, predIndex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private boolean expression_sempred(ExpressionContext _localctx, int predIndex) {
|
||||
switch (predIndex) {
|
||||
case 0: return precpred(_ctx, 8);
|
||||
case 1: return precpred(_ctx, 7);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\26\62\4\2\t\2\4\3"+
|
||||
"\t\3\4\4\t\4\4\5\t\5\4\6\t\6\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"+
|
||||
"\3\3\3\3\3\3\3\3\3\3\3\5\3\35\n\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\7\3"+
|
||||
"\'\n\3\f\3\16\3*\13\3\3\4\3\4\3\5\3\5\3\6\3\6\3\6\2\3\4\7\2\4\6\b\n\2"+
|
||||
"\5\3\2\b\16\3\2\3\4\3\2\6\7\65\2\f\3\2\2\2\4\34\3\2\2\2\6+\3\2\2\2\b-"+
|
||||
"\3\2\2\2\n/\3\2\2\2\f\r\5\4\3\2\r\16\7\2\2\3\16\3\3\2\2\2\17\20\b\3\1"+
|
||||
"\2\20\21\7\5\2\2\21\35\5\4\3\13\22\23\7\17\2\2\23\24\5\4\3\2\24\25\7\20"+
|
||||
"\2\2\25\35\3\2\2\2\26\35\5\n\6\2\27\35\7\22\2\2\30\35\7\23\2\2\31\35\7"+
|
||||
"\24\2\2\32\35\7\25\2\2\33\35\7\21\2\2\34\17\3\2\2\2\34\22\3\2\2\2\34\26"+
|
||||
"\3\2\2\2\34\27\3\2\2\2\34\30\3\2\2\2\34\31\3\2\2\2\34\32\3\2\2\2\34\33"+
|
||||
"\3\2\2\2\35(\3\2\2\2\36\37\f\n\2\2\37 \5\6\4\2 !\5\4\3\13!\'\3\2\2\2\""+
|
||||
"#\f\t\2\2#$\5\b\5\2$%\5\4\3\n%\'\3\2\2\2&\36\3\2\2\2&\"\3\2\2\2\'*\3\2"+
|
||||
"\2\2(&\3\2\2\2()\3\2\2\2)\5\3\2\2\2*(\3\2\2\2+,\t\2\2\2,\7\3\2\2\2-.\t"+
|
||||
"\3\2\2.\t\3\2\2\2/\60\t\4\2\2\60\13\3\2\2\2\5\34&(";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
|
||||
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
// Generated from SimpleBoolean.g4 by ANTLR 4.4
|
||||
|
||||
package org.idempiere.expression.logic;
|
||||
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||
|
||||
/**
|
||||
* This interface defines a complete generic visitor for a parse tree produced
|
||||
* by {@link SimpleBooleanParser}.
|
||||
*
|
||||
* @param <T> The return type of the visit operation. Use {@link Void} for
|
||||
* operations with no return type.
|
||||
*/
|
||||
public interface SimpleBooleanVisitor<T> extends ParseTreeVisitor<T> {
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code boolExpression}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitBoolExpression(@NotNull SimpleBooleanParser.BoolExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SimpleBooleanParser#bool}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitBool(@NotNull SimpleBooleanParser.BoolContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code notExpression}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitNotExpression(@NotNull SimpleBooleanParser.NotExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SimpleBooleanParser#parse}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitParse(@NotNull SimpleBooleanParser.ParseContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code parenExpression}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitParenExpression(@NotNull SimpleBooleanParser.ParenExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code doubleQuotedText}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitDoubleQuotedText(@NotNull SimpleBooleanParser.DoubleQuotedTextContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code binaryExpression}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitBinaryExpression(@NotNull SimpleBooleanParser.BinaryExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SimpleBooleanParser#comparator}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitComparator(@NotNull SimpleBooleanParser.ComparatorContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code decimalExpression}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitDecimalExpression(@NotNull SimpleBooleanParser.DecimalExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SimpleBooleanParser#binary}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitBinary(@NotNull SimpleBooleanParser.BinaryContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code contextVariables}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitContextVariables(@NotNull SimpleBooleanParser.ContextVariablesContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code text}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitText(@NotNull SimpleBooleanParser.TextContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code quotedText}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitQuotedText(@NotNull SimpleBooleanParser.QuotedTextContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code comparatorExpression}
|
||||
* labeled alternative in {@link SimpleBooleanParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitComparatorExpression(@NotNull SimpleBooleanParser.ComparatorExpressionContext ctx);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.expression.logic;
|
||||
|
||||
import org.antlr.v4.runtime.BaseErrorListener;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Recognizer;
|
||||
import org.antlr.v4.runtime.misc.ParseCancellationException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class ThrowingErrorListener extends BaseErrorListener {
|
||||
|
||||
public static final ThrowingErrorListener INSTANCE = new ThrowingErrorListener();
|
||||
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
|
||||
String msg, RecognitionException e) throws ParseCancellationException {
|
||||
throw new ParseCancellationException("line " + line + ":" + charPositionInLine + " " + msg);
|
||||
}
|
||||
}
|
|
@ -48,6 +48,7 @@
|
|||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||
<setEntry value="javax.jms@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||
<setEntry value="org.apache.ant@default:default"/>
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||
<setEntry value="javax.jms@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||
<setEntry value="org.apache.ant@default:default"/>
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||
<setEntry value="javax.jms@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||
<setEntry value="org.apache.ant@default:default"/>
|
||||
|
|
|
@ -560,4 +560,25 @@
|
|||
fragment="true"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.antlr.antlr4-runtime"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="wrapped.com.google.zxing.javase"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="wrapped.dev.samstevens.totp.totp"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
||||
|
|
|
@ -145,6 +145,7 @@
|
|||
<setEntry value="json*20190722.0.0@default:default"/>
|
||||
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.antlr.runtime@default:default"/>
|
||||
<setEntry value="org.aopalliance@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
|
|
|
@ -145,6 +145,7 @@
|
|||
<setEntry value="json*20190722.0.0@default:default"/>
|
||||
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.antlr.runtime@default:default"/>
|
||||
<setEntry value="org.aopalliance@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
|
|
|
@ -81,7 +81,8 @@ osgi.bundles=org.eclipse.equinox.ds@1:start,\
|
|||
org.eclipse.osgi@start,\
|
||||
org.dom4j,\
|
||||
wrapped.com.google.zxing.javase,\
|
||||
wrapped.dev.samstevens.totp.totp
|
||||
wrapped.dev.samstevens.totp.totp,\
|
||||
org.antlr.antlr4-runtime
|
||||
osgi.framework.extensions=
|
||||
osgi.bundles.defaultStartLevel=4
|
||||
osgi.compatibility.bootdelegation=true
|
||||
|
|
|
@ -176,5 +176,11 @@
|
|||
<version>3.4.1</version>
|
||||
<type>jar</type>
|
||||
</location>
|
||||
<location includeSource="true" missingManifest="generate"
|
||||
type="Maven">
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
<version>4.9.2</version>
|
||||
</location>
|
||||
|
||||
</locations>
|
||||
|
|
|
@ -465,19 +465,22 @@
|
|||
<version>1.1.0.Final</version>
|
||||
<type>jar</type>
|
||||
</location>
|
||||
<location includeSource="true" missingManifest="generate"
|
||||
type="Maven">
|
||||
<location includeSource="true" missingManifest="generate" type="Maven">
|
||||
<groupId>dev.samstevens.totp</groupId>
|
||||
<artifactId>totp</artifactId>
|
||||
<version>1.7.1</version>
|
||||
<type>jar</type>
|
||||
</location>
|
||||
<location includeSource="true" missingManifest="generate"
|
||||
type="Maven">
|
||||
<location includeSource="true" missingManifest="generate" type="Maven">
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<type>jar</type>
|
||||
</location>
|
||||
<location includeSource="true" missingManifest="generate" type="Maven">
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
<version>4.9.2</version>
|
||||
</location>
|
||||
</locations>
|
||||
</target>
|
||||
|
|
|
@ -108,6 +108,7 @@
|
|||
<setEntry value="json*20190722.0.0@default:default"/>
|
||||
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
||||
<setEntry value="net.sf.supercsv.super-csv@default:default"/>
|
||||
<setEntry value="org.antlr.antlr4-runtime@default:default"/>
|
||||
<setEntry value="org.antlr.runtime@default:default"/>
|
||||
<setEntry value="org.aopalliance@default:default"/>
|
||||
<setEntry value="org.apache.activemq.activemq-core@default:default"/>
|
||||
|
|
|
@ -0,0 +1,450 @@
|
|||
/***********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Contributors *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301, USA. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - hengsin *
|
||||
**********************************************************************/
|
||||
package org.idempiere.test.base;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.Evaluatee;
|
||||
import org.compiere.util.LegacyLogicEvaluator;
|
||||
import org.idempiere.expression.logic.LogicEvaluator;
|
||||
import org.idempiere.test.AbstractTestCase;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
/**
|
||||
*
|
||||
* @author hengsin
|
||||
*
|
||||
*/
|
||||
public class LogicExpressionTest extends AbstractTestCase {
|
||||
|
||||
private final static ContextEvaluatee evaluatee = new ContextEvaluatee();
|
||||
|
||||
public LogicExpressionTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqual() {
|
||||
|
||||
String expr = "@$Element_AY@='Y'";
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", "Y");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", "N");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", "Y");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", "N");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
expr = "@$Element_AY@=Y";
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", "Y");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", "N");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", "Y");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_AY", "N");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnd() {
|
||||
String expr = "@$Element_BP@=Y & @AnyBPartner@=N";
|
||||
Env.setContext(Env.getCtx(), "$Element_BP", (String)null);
|
||||
Env.setContext(Env.getCtx(), "AnyBPartner", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_BP", "Y");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "AnyBPartner", "Y");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "AnyBPartner", "N");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_BP", "N");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "$Element_BP", (String)null);
|
||||
Env.setContext(Env.getCtx(), "AnyBPartner", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_BP", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "AnyBPartner", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "AnyBPartner", "N");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "$Element_BP", "N");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIn() {
|
||||
String expr = "@LineType@=C&@CalculationType@=A,R,S";
|
||||
Env.setContext(Env.getCtx(), "LineType", (String)null);
|
||||
Env.setContext(Env.getCtx(), "CalculationType", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "LineType", "C");
|
||||
Env.setContext(Env.getCtx(), "CalculationType", "B");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "CalculationType", "A");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "CalculationType", "R");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "CalculationType", "S");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "LineType", "D");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "LineType", (String)null);
|
||||
Env.setContext(Env.getCtx(), "CalculationType", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "LineType", "C");
|
||||
Env.setContext(Env.getCtx(), "CalculationType", "B");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "CalculationType", "A");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "CalculationType", "R");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "CalculationType", "S");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "LineType", "D");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotEqual() {
|
||||
String expr = "@C_Bpartner_ID@!0";
|
||||
Env.setContext(Env.getCtx(), "C_Bpartner_ID", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "C_Bpartner_ID", "0");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "C_Bpartner_ID", "100");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "C_Bpartner_ID", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "C_Bpartner_ID", "0");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "C_Bpartner_ID", "100");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
expr = "@IsOverUnderPayment@=Y & @C_Invoice_ID@^0";
|
||||
Env.setContext(Env.getCtx(), "IsOverUnderPayment", (String)null);
|
||||
Env.setContext(Env.getCtx(), "C_Invoice_ID", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsOverUnderPayment", "Y");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "C_Invoice_ID", "0");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "C_Invoice_ID", "100");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "IsOverUnderPayment", (String)null);
|
||||
Env.setContext(Env.getCtx(), "C_Invoice_ID", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsOverUnderPayment", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "C_Invoice_ID", "0");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "C_Invoice_ID", "100");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrAnd() {
|
||||
String expr = "@IsSold@='Y' | @IsPurchased@='Y' & @IsSummary@='N'";
|
||||
Env.setContext(Env.getCtx(), "IsSold", (String)null);
|
||||
Env.setContext(Env.getCtx(), "IsPurchased", (String)null);
|
||||
Env.setContext(Env.getCtx(), "IsSummary", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSold", "Y");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "N");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsPurchased", "Y");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSold", "N");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "Y");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "IsSold", (String)null);
|
||||
Env.setContext(Env.getCtx(), "IsPurchased", (String)null);
|
||||
Env.setContext(Env.getCtx(), "IsSummary", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSold", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "N");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsPurchased", "Y");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSold", "N");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAndOr() {
|
||||
String expr = "@IsSummary@='N' & @ProductType@=I | @ProductType@=S";
|
||||
Env.setContext(Env.getCtx(), "IsSummary", (String)null);
|
||||
Env.setContext(Env.getCtx(), "ProductType", (String)null);
|
||||
Env.setContext(Env.getCtx(), "ProductType", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "N");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "ProductType", "I");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "ProductType", "S");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "Y");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "IsSummary", (String)null);
|
||||
Env.setContext(Env.getCtx(), "ProductType", (String)null);
|
||||
Env.setContext(Env.getCtx(), "ProductType", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "N");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "ProductType", "I");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "ProductType", "S");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "Y");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAndOrGroup() {
|
||||
String expr = "@IsSummary@='N' & (@ProductType@=I | @ProductType@=S)";
|
||||
Env.setContext(Env.getCtx(), "IsSummary", (String)null);
|
||||
Env.setContext(Env.getCtx(), "ProductType", (String)null);
|
||||
Env.setContext(Env.getCtx(), "ProductType", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "N");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "ProductType", "I");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "ProductType", "S");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrAndGroup() {
|
||||
String expr = "@IsSold@='Y' | (@IsPurchased@='Y' & @IsSummary@='N')";
|
||||
Env.setContext(Env.getCtx(), "IsSold", (String)null);
|
||||
Env.setContext(Env.getCtx(), "IsPurchased", (String)null);
|
||||
Env.setContext(Env.getCtx(), "IsSummary", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSold", "Y");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "N");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsPurchased", "Y");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSold", "N");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSummary", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGT() {
|
||||
String expr = "@IsLot@=Y& @M_LotCtl_ID@ > 0";
|
||||
Env.setContext(Env.getCtx(), "IsLot", (String)null);
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsLot", "Y");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", "0");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", "101");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsLot", "N");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "IsLot", (String)null);
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsLot", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", "0");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", "101");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsLot", "N");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGE() {
|
||||
String expr = "@IsLot@=Y& @M_LotCtl_ID@ >= 100";
|
||||
Env.setContext(Env.getCtx(), "IsLot", (String)null);
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsLot", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", "0");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", "100");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", "99");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLT() {
|
||||
String expr = "@A_Asset_ID@<1&@A_CreateAsset@='Y'";
|
||||
Env.setContext(Env.getCtx(), "A_Asset_ID", (String)null);
|
||||
Env.setContext(Env.getCtx(), "A_CreateAsset", (String)null);
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "A_Asset_ID", "1");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "A_CreateAsset", "Y");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "A_Asset_ID", "0");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "A_Asset_ID", (String)null);
|
||||
Env.setContext(Env.getCtx(), "A_CreateAsset", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "A_Asset_ID", "1");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "A_CreateAsset", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "A_Asset_ID", "0");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLE() {
|
||||
String expr = "@A_Asset_ID@<=1&@A_CreateAsset@='Y'";
|
||||
Env.setContext(Env.getCtx(), "A_Asset_ID", (String)null);
|
||||
Env.setContext(Env.getCtx(), "A_CreateAsset", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "A_Asset_ID", "2");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "A_CreateAsset", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "A_Asset_ID", "1");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegate() {
|
||||
String expr = "$!(@IsLot@=Y & @M_LotCtl_ID@ > 0)";
|
||||
Env.setContext(Env.getCtx(), "IsLot", (String)null);
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", (String)null);
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsLot", "Y");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", "1");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "M_LotCtl_ID", "0");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRE() {
|
||||
String expr = "@Identifier@ ~ '^([a-zA-Z_$][a-zA-Z\\d_$]*)$'";
|
||||
Env.setContext(Env.getCtx(), "Identifier", (String)null);
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "Identifier", "validIdentifier");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "Identifier", "$validIdentifier");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "Identifier", "~inValidIdentifier");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "Identifier", "_validIdentifier");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "Identifier", "0inValidIdentifier");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "Identifier", "validIdentifier0");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidation() {
|
||||
Exception ex = null;
|
||||
String expr = "@IsSummary@='N' & (@ProductType@=I | @ProductType@=S)";
|
||||
try {
|
||||
LogicEvaluator.validate(expr);
|
||||
} catch (Exception e) {
|
||||
ex = e;
|
||||
}
|
||||
assertNull(ex);
|
||||
expr = expr.substring(0, expr.length()-1);
|
||||
try {
|
||||
LogicEvaluator.validate(expr);
|
||||
} catch (Exception e) {
|
||||
ex = e;
|
||||
}
|
||||
assertNotNull(ex);
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConditionalVariable() {
|
||||
String expr = "@IsSOTrx:N@=N | @+IgnoreIsSOTrxInBPInfo:N@=Y";
|
||||
Env.setContext(Env.getCtx(), "IsSOTrx", (String)null);
|
||||
Env.setContext(Env.getCtx(), "+IgnoreIsSOTrxInBPInfo", (String)null);
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSOTrx", "Y");
|
||||
assertFalse(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "+IgnoreIsSOTrxInBPInfo", "Y");
|
||||
assertTrue(LegacyLogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
|
||||
Env.setContext(Env.getCtx(), "IsSOTrx", (String)null);
|
||||
Env.setContext(Env.getCtx(), "+IgnoreIsSOTrxInBPInfo", (String)null);
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "IsSOTrx", "Y");
|
||||
assertFalse(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
Env.setContext(Env.getCtx(), "+IgnoreIsSOTrxInBPInfo", "Y");
|
||||
assertTrue(LogicEvaluator.evaluateLogic(evaluatee, expr));
|
||||
}
|
||||
|
||||
private static class ContextEvaluatee implements Evaluatee {
|
||||
|
||||
@Override
|
||||
public String get_ValueAsString(String variableName) {
|
||||
return Env.getContext(Env.getCtx(), variableName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue