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="jakarta.xml.bind-api@default:default"/>
|
||||||
<setEntry value="javax.jms@default:default"/>
|
<setEntry value="javax.jms@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.activemq-core@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||||
<setEntry value="org.apache.ant@default:default"/>
|
<setEntry value="org.apache.ant@default:default"/>
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||||
<setEntry value="javax.jms@default:default"/>
|
<setEntry value="javax.jms@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.activemq-core@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||||
<setEntry value="org.apache.ant@default:default"/>
|
<setEntry value="org.apache.ant@default:default"/>
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||||
<setEntry value="javax.jms@default:default"/>
|
<setEntry value="javax.jms@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.activemq-core@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||||
<setEntry value="org.apache.ant@default:default"/>
|
<setEntry value="org.apache.ant@default:default"/>
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||||
<setEntry value="javax.jms@default:default"/>
|
<setEntry value="javax.jms@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.activemq-core@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||||
<setEntry value="org.apache.ant@default:default"/>
|
<setEntry value="org.apache.ant@default:default"/>
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||||
<setEntry value="javax.jms@default:default"/>
|
<setEntry value="javax.jms@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.activemq-core@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||||
<setEntry value="org.apache.ant@default:default"/>
|
<setEntry value="org.apache.ant@default:default"/>
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
<projects>
|
<projects>
|
||||||
</projects>
|
</projects>
|
||||||
<buildSpec>
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
|
@ -40,5 +45,6 @@
|
||||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||||
<nature>org.eclipse.pde.PluginNature</nature>
|
<nature>org.eclipse.pde.PluginNature</nature>
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||||
</natures>
|
</natures>
|
||||||
</projectDescription>
|
</projectDescription>
|
||||||
|
|
|
@ -57,6 +57,7 @@ Export-Package: bsh,
|
||||||
org.idempiere.broadcast,
|
org.idempiere.broadcast,
|
||||||
org.idempiere.cache,
|
org.idempiere.cache,
|
||||||
org.idempiere.distributed,
|
org.idempiere.distributed,
|
||||||
|
org.idempiere.expression.logic,
|
||||||
org.idempiere.fa.service.api,
|
org.idempiere.fa.service.api,
|
||||||
org.idempiere.model,
|
org.idempiere.model,
|
||||||
org.idempiere.process
|
org.idempiere.process
|
||||||
|
@ -97,6 +98,13 @@ Import-Package: com.google.zxing,
|
||||||
net.sf.cglib.proxy,
|
net.sf.cglib.proxy,
|
||||||
net.sourceforge.barbecue,
|
net.sourceforge.barbecue,
|
||||||
net.sourceforge.barbecue.linear.ean,
|
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.activemq;version="5.3.0",
|
||||||
org.apache.commons.collections;version="3.2.2",
|
org.apache.commons.collections;version="3.2.2",
|
||||||
org.apache.commons.collections.keyvalue;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.compiere.util.Util;
|
||||||
import org.idempiere.cache.ImmutableIntPOCache;
|
import org.idempiere.cache.ImmutableIntPOCache;
|
||||||
import org.idempiere.cache.ImmutablePOSupport;
|
import org.idempiere.cache.ImmutablePOSupport;
|
||||||
|
import org.idempiere.expression.logic.LogicEvaluator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Persistent Column Model
|
* Persistent Column Model
|
||||||
|
@ -545,6 +546,12 @@ public class MColumn extends X_AD_Column implements ImmutablePOSupport
|
||||||
setSeqNoSelection(next);
|
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;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,10 @@ import java.sql.ResultSet;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Util;
|
||||||
import org.idempiere.cache.ImmutableIntPOCache;
|
import org.idempiere.cache.ImmutableIntPOCache;
|
||||||
import org.idempiere.cache.ImmutablePOSupport;
|
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);
|
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;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,10 @@ import java.util.logging.Level;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.DisplayType;
|
import org.compiere.util.DisplayType;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Util;
|
||||||
import org.idempiere.cache.ImmutableIntPOCache;
|
import org.idempiere.cache.ImmutableIntPOCache;
|
||||||
import org.idempiere.cache.ImmutablePOSupport;
|
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());
|
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;
|
return true;
|
||||||
} // beforeSave
|
} // beforeSave
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,10 @@ import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.Msg;
|
import org.compiere.util.Msg;
|
||||||
|
import org.compiere.util.Util;
|
||||||
import org.idempiere.cache.ImmutablePOCache;
|
import org.idempiere.cache.ImmutablePOCache;
|
||||||
import org.idempiere.cache.ImmutablePOSupport;
|
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);
|
setAD_Val_Rule_ID(0);
|
||||||
setIsToolbarButton(null);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,17 +16,17 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package org.compiere.util;
|
package org.compiere.util;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.StringTokenizer;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.idempiere.expression.logic.LogicEvaluator;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expression Evaluator
|
* Expression Evaluator
|
||||||
|
@ -82,202 +82,16 @@ public class Evaluator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluate Logic.
|
* Evaluate Logic.
|
||||||
* <code>
|
* @see LogicEvaluator#evaluateLogic(Evaluatee, String)
|
||||||
* 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 source class implementing get_ValueAsString(variable)
|
||||||
* @param logic logic string
|
* @param logic logic string
|
||||||
* @return logic result
|
* @return logic result
|
||||||
*/
|
*/
|
||||||
public static boolean evaluateLogic (Evaluatee source, String logic)
|
public static boolean evaluateLogic (Evaluatee source, String logic)
|
||||||
{
|
{
|
||||||
// Conditional
|
return LogicEvaluator.evaluateLogic(source, logic);
|
||||||
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
|
} // 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.
|
* Parse String and add variables with @ to the list.
|
||||||
* @param list list to be added to
|
* @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="jakarta.xml.bind-api@default:default"/>
|
||||||
<setEntry value="javax.jms@default:default"/>
|
<setEntry value="javax.jms@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.activemq-core@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||||
<setEntry value="org.apache.ant@default:default"/>
|
<setEntry value="org.apache.ant@default:default"/>
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||||
<setEntry value="javax.jms@default:default"/>
|
<setEntry value="javax.jms@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.activemq-core@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||||
<setEntry value="org.apache.ant@default:default"/>
|
<setEntry value="org.apache.ant@default:default"/>
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
<setEntry value="jakarta.xml.bind-api@default:default"/>
|
||||||
<setEntry value="javax.jms@default:default"/>
|
<setEntry value="javax.jms@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.activemq-core@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
<setEntry value="org.apache.activemq.kahadb@default:default"/>
|
||||||
<setEntry value="org.apache.ant@default:default"/>
|
<setEntry value="org.apache.ant@default:default"/>
|
||||||
|
|
|
@ -560,4 +560,25 @@
|
||||||
fragment="true"
|
fragment="true"
|
||||||
unpack="false"/>
|
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>
|
</feature>
|
||||||
|
|
|
@ -145,6 +145,7 @@
|
||||||
<setEntry value="json*20190722.0.0@default:default"/>
|
<setEntry value="json*20190722.0.0@default:default"/>
|
||||||
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.antlr.runtime@default:default"/>
|
||||||
<setEntry value="org.aopalliance@default:default"/>
|
<setEntry value="org.aopalliance@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.activemq-core@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="json*20190722.0.0@default:default"/>
|
||||||
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.antlr.runtime@default:default"/>
|
||||||
<setEntry value="org.aopalliance@default:default"/>
|
<setEntry value="org.aopalliance@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.activemq-core@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.eclipse.osgi@start,\
|
||||||
org.dom4j,\
|
org.dom4j,\
|
||||||
wrapped.com.google.zxing.javase,\
|
wrapped.com.google.zxing.javase,\
|
||||||
wrapped.dev.samstevens.totp.totp
|
wrapped.dev.samstevens.totp.totp,\
|
||||||
|
org.antlr.antlr4-runtime
|
||||||
osgi.framework.extensions=
|
osgi.framework.extensions=
|
||||||
osgi.bundles.defaultStartLevel=4
|
osgi.bundles.defaultStartLevel=4
|
||||||
osgi.compatibility.bootdelegation=true
|
osgi.compatibility.bootdelegation=true
|
||||||
|
|
|
@ -176,5 +176,11 @@
|
||||||
<version>3.4.1</version>
|
<version>3.4.1</version>
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
</location>
|
</location>
|
||||||
|
<location includeSource="true" missingManifest="generate"
|
||||||
|
type="Maven">
|
||||||
|
<groupId>org.antlr</groupId>
|
||||||
|
<artifactId>antlr4-runtime</artifactId>
|
||||||
|
<version>4.9.2</version>
|
||||||
|
</location>
|
||||||
|
|
||||||
</locations>
|
</locations>
|
||||||
|
|
|
@ -465,19 +465,22 @@
|
||||||
<version>1.1.0.Final</version>
|
<version>1.1.0.Final</version>
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
</location>
|
</location>
|
||||||
<location includeSource="true" missingManifest="generate"
|
<location includeSource="true" missingManifest="generate" type="Maven">
|
||||||
type="Maven">
|
<groupId>dev.samstevens.totp</groupId>
|
||||||
<groupId>dev.samstevens.totp</groupId>
|
<artifactId>totp</artifactId>
|
||||||
<artifactId>totp</artifactId>
|
<version>1.7.1</version>
|
||||||
<version>1.7.1</version>
|
<type>jar</type>
|
||||||
<type>jar</type>
|
|
||||||
</location>
|
</location>
|
||||||
<location includeSource="true" missingManifest="generate"
|
<location includeSource="true" missingManifest="generate" type="Maven">
|
||||||
type="Maven">
|
<groupId>com.google.zxing</groupId>
|
||||||
<groupId>com.google.zxing</groupId>
|
<artifactId>javase</artifactId>
|
||||||
<artifactId>javase</artifactId>
|
<version>3.4.1</version>
|
||||||
<version>3.4.1</version>
|
<type>jar</type>
|
||||||
<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>
|
</location>
|
||||||
</locations>
|
</locations>
|
||||||
</target>
|
</target>
|
||||||
|
|
|
@ -108,6 +108,7 @@
|
||||||
<setEntry value="json*20190722.0.0@default:default"/>
|
<setEntry value="json*20190722.0.0@default:default"/>
|
||||||
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
<setEntry value="net.sf.jasperreports.engine@default:default"/>
|
||||||
<setEntry value="net.sf.supercsv.super-csv@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.antlr.runtime@default:default"/>
|
||||||
<setEntry value="org.aopalliance@default:default"/>
|
<setEntry value="org.aopalliance@default:default"/>
|
||||||
<setEntry value="org.apache.activemq.activemq-core@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