initial commit of SOQL, the object query language for strolch
This commit is contained in:
parent
cc66ab67b2
commit
92915b4552
|
@ -17,7 +17,7 @@
|
|||
<inceptionYear>2011</inceptionYear>
|
||||
|
||||
<properties>
|
||||
<warFinalName>planningwebapp</warFinalName>
|
||||
<warFinalName>susi</warFinalName>
|
||||
<tomcat7ServerId>tomcat7.eitchnet.ch</tomcat7ServerId>
|
||||
<tomcat7Url>http://tomcat.eitchnet.ch:8080/manager/text</tomcat7Url>
|
||||
<m2eclipse.wtp.contextRoot>${warFinalName}</m2eclipse.wtp.contextRoot>
|
||||
|
|
|
@ -40,6 +40,10 @@
|
|||
<groupId>li.strolch</groupId>
|
||||
<artifactId>li.strolch.service</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>li.strolch.soql</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
|
|
|
@ -48,7 +48,7 @@ public class ModelQuery {
|
|||
StrolchElementToJsonVisitor visitor = new StrolchElementToJsonVisitor();
|
||||
visitor.flat();
|
||||
|
||||
// TODO do query
|
||||
// TODO MS do query
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
|
@ -16,6 +17,12 @@
|
|||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4</artifactId>
|
||||
<version>4.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Base -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
// Note: parser rules start with lowercase letters, lexer rules with uppercase
|
||||
|
||||
grammar SOQL;
|
||||
|
||||
// the select statement element
|
||||
select_statement
|
||||
: select_clause from_clause (where_clause)? (orderby_clause)?
|
||||
;
|
||||
|
||||
// the select clause
|
||||
select_clause
|
||||
: 'SELECT' ('DISTINCT')? select_expression (',' select_expression)*
|
||||
;
|
||||
|
||||
select_expression
|
||||
: chained_method_expression
|
||||
| object_declaration
|
||||
;
|
||||
|
||||
chained_method_expression
|
||||
: IDENTIFICATION_VARIABLE '.' method_expression ('.' method_expression)*
|
||||
;
|
||||
|
||||
method_expression
|
||||
: method_name method_argument
|
||||
;
|
||||
|
||||
method_name
|
||||
: IDENTIFICATION_VARIABLE
|
||||
;
|
||||
|
||||
method_argument
|
||||
: '()'
|
||||
| '(' var_reference (',' var_reference)* ')'
|
||||
;
|
||||
|
||||
// the from clause parts
|
||||
from_clause
|
||||
: 'FROM' entity_declaration (',' entity_declaration)*
|
||||
;
|
||||
|
||||
entity_declaration
|
||||
: class_declaration object_declaration
|
||||
;
|
||||
|
||||
class_declaration
|
||||
: IDENTIFICATION_VARIABLE
|
||||
;
|
||||
|
||||
object_declaration
|
||||
: IDENTIFICATION_VARIABLE
|
||||
;
|
||||
|
||||
// the where clause parts
|
||||
where_clause
|
||||
: 'WHERE' or_expression
|
||||
;
|
||||
|
||||
or_expression
|
||||
: (and_expression) ('OR' and_expression)*
|
||||
;
|
||||
|
||||
and_expression
|
||||
: (expression_term) ('AND' expression_term)*
|
||||
;
|
||||
|
||||
expression_term
|
||||
: ('NOT')? comparison_expression
|
||||
;
|
||||
|
||||
comparison_expression
|
||||
: chained_method_expression comparison_operator (value_declaration | var_reference | chained_method_expression)
|
||||
;
|
||||
|
||||
comparison_operator
|
||||
: '='
|
||||
| '>'
|
||||
| '>='
|
||||
| '<'
|
||||
| '<='
|
||||
| '<>'
|
||||
;
|
||||
|
||||
var_reference
|
||||
: ':' IDENTIFICATION_VARIABLE
|
||||
;
|
||||
|
||||
value_declaration
|
||||
: '"' IDENTIFICATION_VARIABLE '"'
|
||||
;
|
||||
|
||||
// the ordering part
|
||||
orderby_clause
|
||||
: 'ORDER' 'BY' orderby_item (',' orderby_item)*
|
||||
;
|
||||
|
||||
orderby_item
|
||||
: chained_method_expression ('ASC' | 'DESC')?
|
||||
;
|
||||
|
||||
// lexer rules
|
||||
|
||||
// a word with no blancs
|
||||
IDENTIFICATION_VARIABLE
|
||||
: ('a' .. 'z' | 'A' .. 'Z' | '_') ('a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_')*
|
||||
;
|
||||
|
||||
STRING_VARIABLE
|
||||
: ('a' .. 'z' | 'A' .. 'Z' | '_') ('a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_')*
|
||||
;
|
||||
|
||||
// Whitespaces to be skipped
|
||||
WS
|
||||
: [ \t\r\n] -> skip
|
||||
;
|
|
@ -0,0 +1,51 @@
|
|||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
T__7=8
|
||||
T__8=9
|
||||
T__9=10
|
||||
T__10=11
|
||||
T__11=12
|
||||
T__12=13
|
||||
T__13=14
|
||||
T__14=15
|
||||
T__15=16
|
||||
T__16=17
|
||||
T__17=18
|
||||
T__18=19
|
||||
T__19=20
|
||||
T__20=21
|
||||
T__21=22
|
||||
T__22=23
|
||||
T__23=24
|
||||
IDENTIFICATION_VARIABLE=25
|
||||
STRING_VARIABLE=26
|
||||
WS=27
|
||||
'SELECT'=1
|
||||
'DISTINCT'=2
|
||||
','=3
|
||||
'.'=4
|
||||
'()'=5
|
||||
'('=6
|
||||
')'=7
|
||||
'FROM'=8
|
||||
'WHERE'=9
|
||||
'OR'=10
|
||||
'AND'=11
|
||||
'NOT'=12
|
||||
'='=13
|
||||
'>'=14
|
||||
'>='=15
|
||||
'<'=16
|
||||
'<='=17
|
||||
'<>'=18
|
||||
':'=19
|
||||
'"'=20
|
||||
'ORDER'=21
|
||||
'BY'=22
|
||||
'ASC'=23
|
||||
'DESC'=24
|
|
@ -0,0 +1,291 @@
|
|||
// Generated from SOQL.g4 by ANTLR 4.7
|
||||
package li.strolch.soql.antlr4.generated;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ErrorNode;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link SOQLListener},
|
||||
* which can be extended to create a listener which only needs to handle a subset
|
||||
* of the available methods.
|
||||
*/
|
||||
public class SOQLBaseListener implements SOQLListener {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterSelect_statement(SOQLParser.Select_statementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitSelect_statement(SOQLParser.Select_statementContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterSelect_clause(SOQLParser.Select_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitSelect_clause(SOQLParser.Select_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterSelect_expression(SOQLParser.Select_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitSelect_expression(SOQLParser.Select_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterChained_method_expression(SOQLParser.Chained_method_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitChained_method_expression(SOQLParser.Chained_method_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterMethod_expression(SOQLParser.Method_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitMethod_expression(SOQLParser.Method_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterMethod_name(SOQLParser.Method_nameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitMethod_name(SOQLParser.Method_nameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterMethod_argument(SOQLParser.Method_argumentContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitMethod_argument(SOQLParser.Method_argumentContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterFrom_clause(SOQLParser.From_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitFrom_clause(SOQLParser.From_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterEntity_declaration(SOQLParser.Entity_declarationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitEntity_declaration(SOQLParser.Entity_declarationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterClass_declaration(SOQLParser.Class_declarationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitClass_declaration(SOQLParser.Class_declarationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterObject_declaration(SOQLParser.Object_declarationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitObject_declaration(SOQLParser.Object_declarationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterWhere_clause(SOQLParser.Where_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitWhere_clause(SOQLParser.Where_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterOr_expression(SOQLParser.Or_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitOr_expression(SOQLParser.Or_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterAnd_expression(SOQLParser.And_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitAnd_expression(SOQLParser.And_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterExpression_term(SOQLParser.Expression_termContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitExpression_term(SOQLParser.Expression_termContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterComparison_expression(SOQLParser.Comparison_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitComparison_expression(SOQLParser.Comparison_expressionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterComparison_operator(SOQLParser.Comparison_operatorContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitComparison_operator(SOQLParser.Comparison_operatorContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterVar_reference(SOQLParser.Var_referenceContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitVar_reference(SOQLParser.Var_referenceContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterValue_declaration(SOQLParser.Value_declarationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitValue_declaration(SOQLParser.Value_declarationContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterOrderby_clause(SOQLParser.Orderby_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitOrderby_clause(SOQLParser.Orderby_clauseContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterOrderby_item(SOQLParser.Orderby_itemContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitOrderby_item(SOQLParser.Orderby_itemContext ctx) { }
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterEveryRule(ParserRuleContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitEveryRule(ParserRuleContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void visitTerminal(TerminalNode node) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void visitErrorNode(ErrorNode node) { }
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
// Generated from SOQL.g4 by ANTLR 4.7
|
||||
package li.strolch.soql.antlr4.generated;
|
||||
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link SOQLVisitor},
|
||||
* 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 SOQLBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements SOQLVisitor<T> {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSelect_statement(SOQLParser.Select_statementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSelect_clause(SOQLParser.Select_clauseContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSelect_expression(SOQLParser.Select_expressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitChained_method_expression(SOQLParser.Chained_method_expressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitMethod_expression(SOQLParser.Method_expressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitMethod_name(SOQLParser.Method_nameContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitMethod_argument(SOQLParser.Method_argumentContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitFrom_clause(SOQLParser.From_clauseContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitEntity_declaration(SOQLParser.Entity_declarationContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitClass_declaration(SOQLParser.Class_declarationContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitObject_declaration(SOQLParser.Object_declarationContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitWhere_clause(SOQLParser.Where_clauseContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitOr_expression(SOQLParser.Or_expressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitAnd_expression(SOQLParser.And_expressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitExpression_term(SOQLParser.Expression_termContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitComparison_expression(SOQLParser.Comparison_expressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitComparison_operator(SOQLParser.Comparison_operatorContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitVar_reference(SOQLParser.Var_referenceContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitValue_declaration(SOQLParser.Value_declarationContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitOrderby_clause(SOQLParser.Orderby_clauseContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitOrderby_item(SOQLParser.Orderby_itemContext ctx) { return visitChildren(ctx); }
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
// Generated from SOQL.g4 by ANTLR 4.7
|
||||
package li.strolch.soql.antlr4.generated;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.RuntimeMetaData;
|
||||
import org.antlr.v4.runtime.Vocabulary;
|
||||
import org.antlr.v4.runtime.VocabularyImpl;
|
||||
import org.antlr.v4.runtime.atn.ATN;
|
||||
import org.antlr.v4.runtime.atn.ATNDeserializer;
|
||||
import org.antlr.v4.runtime.atn.LexerATNSimulator;
|
||||
import org.antlr.v4.runtime.atn.PredictionContextCache;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class SOQLLexer extends Lexer {
|
||||
static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
|
||||
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
|
||||
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24,
|
||||
IDENTIFICATION_VARIABLE=25, STRING_VARIABLE=26, WS=27;
|
||||
public static String[] channelNames = {
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||
};
|
||||
|
||||
public static String[] modeNames = {
|
||||
"DEFAULT_MODE"
|
||||
};
|
||||
|
||||
public static final String[] ruleNames = {
|
||||
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
|
||||
"T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16",
|
||||
"T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "IDENTIFICATION_VARIABLE",
|
||||
"STRING_VARIABLE", "WS"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'SELECT'", "'DISTINCT'", "','", "'.'", "'()'", "'('", "')'", "'FROM'",
|
||||
"'WHERE'", "'OR'", "'AND'", "'NOT'", "'='", "'>'", "'>='", "'<'", "'<='",
|
||||
"'<>'", "':'", "'\"'", "'ORDER'", "'BY'", "'ASC'", "'DESC'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, "IDENTIFICATION_VARIABLE", "STRING_VARIABLE", "WS"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #VOCABULARY} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String[] tokenNames;
|
||||
static {
|
||||
tokenNames = new String[_SYMBOLIC_NAMES.length];
|
||||
for (int i = 0; i < tokenNames.length; i++) {
|
||||
tokenNames[i] = VOCABULARY.getLiteralName(i);
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = VOCABULARY.getSymbolicName(i);
|
||||
}
|
||||
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = "<INVALID>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String[] getTokenNames() {
|
||||
return tokenNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public Vocabulary getVocabulary() {
|
||||
return VOCABULARY;
|
||||
}
|
||||
|
||||
|
||||
public SOQLLexer(CharStream input) {
|
||||
super(input);
|
||||
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "SOQL.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public String[] getChannelNames() { return channelNames; }
|
||||
|
||||
@Override
|
||||
public String[] getModeNames() { return modeNames; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\35\u00a1\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\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+
|
||||
"\t\31\4\32\t\32\4\33\t\33\4\34\t\34\3\2\3\2\3\2\3\2\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\4\3\4\3\5\3\5\3\6\3\6\3\6\3\7\3\7\3\b"+
|
||||
"\3\b\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\f\3"+
|
||||
"\f\3\f\3\f\3\r\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\20\3\21\3\21"+
|
||||
"\3\22\3\22\3\22\3\23\3\23\3\23\3\24\3\24\3\25\3\25\3\26\3\26\3\26\3\26"+
|
||||
"\3\26\3\26\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31"+
|
||||
"\3\32\3\32\7\32\u0092\n\32\f\32\16\32\u0095\13\32\3\33\3\33\7\33\u0099"+
|
||||
"\n\33\f\33\16\33\u009c\13\33\3\34\3\34\3\34\3\34\2\2\35\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+\27-\30/\31\61\32\63\33\65\34\67\35\3\2\5\5\2C\\aac|\6\2"+
|
||||
"\62;C\\aac|\5\2\13\f\17\17\"\"\2\u00a2\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\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65"+
|
||||
"\3\2\2\2\2\67\3\2\2\2\39\3\2\2\2\5@\3\2\2\2\7I\3\2\2\2\tK\3\2\2\2\13M"+
|
||||
"\3\2\2\2\rP\3\2\2\2\17R\3\2\2\2\21T\3\2\2\2\23Y\3\2\2\2\25_\3\2\2\2\27"+
|
||||
"b\3\2\2\2\31f\3\2\2\2\33j\3\2\2\2\35l\3\2\2\2\37n\3\2\2\2!q\3\2\2\2#s"+
|
||||
"\3\2\2\2%v\3\2\2\2\'y\3\2\2\2){\3\2\2\2+}\3\2\2\2-\u0083\3\2\2\2/\u0086"+
|
||||
"\3\2\2\2\61\u008a\3\2\2\2\63\u008f\3\2\2\2\65\u0096\3\2\2\2\67\u009d\3"+
|
||||
"\2\2\29:\7U\2\2:;\7G\2\2;<\7N\2\2<=\7G\2\2=>\7E\2\2>?\7V\2\2?\4\3\2\2"+
|
||||
"\2@A\7F\2\2AB\7K\2\2BC\7U\2\2CD\7V\2\2DE\7K\2\2EF\7P\2\2FG\7E\2\2GH\7"+
|
||||
"V\2\2H\6\3\2\2\2IJ\7.\2\2J\b\3\2\2\2KL\7\60\2\2L\n\3\2\2\2MN\7*\2\2NO"+
|
||||
"\7+\2\2O\f\3\2\2\2PQ\7*\2\2Q\16\3\2\2\2RS\7+\2\2S\20\3\2\2\2TU\7H\2\2"+
|
||||
"UV\7T\2\2VW\7Q\2\2WX\7O\2\2X\22\3\2\2\2YZ\7Y\2\2Z[\7J\2\2[\\\7G\2\2\\"+
|
||||
"]\7T\2\2]^\7G\2\2^\24\3\2\2\2_`\7Q\2\2`a\7T\2\2a\26\3\2\2\2bc\7C\2\2c"+
|
||||
"d\7P\2\2de\7F\2\2e\30\3\2\2\2fg\7P\2\2gh\7Q\2\2hi\7V\2\2i\32\3\2\2\2j"+
|
||||
"k\7?\2\2k\34\3\2\2\2lm\7@\2\2m\36\3\2\2\2no\7@\2\2op\7?\2\2p \3\2\2\2"+
|
||||
"qr\7>\2\2r\"\3\2\2\2st\7>\2\2tu\7?\2\2u$\3\2\2\2vw\7>\2\2wx\7@\2\2x&\3"+
|
||||
"\2\2\2yz\7<\2\2z(\3\2\2\2{|\7$\2\2|*\3\2\2\2}~\7Q\2\2~\177\7T\2\2\177"+
|
||||
"\u0080\7F\2\2\u0080\u0081\7G\2\2\u0081\u0082\7T\2\2\u0082,\3\2\2\2\u0083"+
|
||||
"\u0084\7D\2\2\u0084\u0085\7[\2\2\u0085.\3\2\2\2\u0086\u0087\7C\2\2\u0087"+
|
||||
"\u0088\7U\2\2\u0088\u0089\7E\2\2\u0089\60\3\2\2\2\u008a\u008b\7F\2\2\u008b"+
|
||||
"\u008c\7G\2\2\u008c\u008d\7U\2\2\u008d\u008e\7E\2\2\u008e\62\3\2\2\2\u008f"+
|
||||
"\u0093\t\2\2\2\u0090\u0092\t\3\2\2\u0091\u0090\3\2\2\2\u0092\u0095\3\2"+
|
||||
"\2\2\u0093\u0091\3\2\2\2\u0093\u0094\3\2\2\2\u0094\64\3\2\2\2\u0095\u0093"+
|
||||
"\3\2\2\2\u0096\u009a\t\2\2\2\u0097\u0099\t\3\2\2\u0098\u0097\3\2\2\2\u0099"+
|
||||
"\u009c\3\2\2\2\u009a\u0098\3\2\2\2\u009a\u009b\3\2\2\2\u009b\66\3\2\2"+
|
||||
"\2\u009c\u009a\3\2\2\2\u009d\u009e\t\4\2\2\u009e\u009f\3\2\2\2\u009f\u00a0"+
|
||||
"\b\34\2\2\u00a08\3\2\2\2\5\2\u0093\u009a\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,51 @@
|
|||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
T__5=6
|
||||
T__6=7
|
||||
T__7=8
|
||||
T__8=9
|
||||
T__9=10
|
||||
T__10=11
|
||||
T__11=12
|
||||
T__12=13
|
||||
T__13=14
|
||||
T__14=15
|
||||
T__15=16
|
||||
T__16=17
|
||||
T__17=18
|
||||
T__18=19
|
||||
T__19=20
|
||||
T__20=21
|
||||
T__21=22
|
||||
T__22=23
|
||||
T__23=24
|
||||
IDENTIFICATION_VARIABLE=25
|
||||
STRING_VARIABLE=26
|
||||
WS=27
|
||||
'SELECT'=1
|
||||
'DISTINCT'=2
|
||||
','=3
|
||||
'.'=4
|
||||
'()'=5
|
||||
'('=6
|
||||
')'=7
|
||||
'FROM'=8
|
||||
'WHERE'=9
|
||||
'OR'=10
|
||||
'AND'=11
|
||||
'NOT'=12
|
||||
'='=13
|
||||
'>'=14
|
||||
'>='=15
|
||||
'<'=16
|
||||
'<='=17
|
||||
'<>'=18
|
||||
':'=19
|
||||
'"'=20
|
||||
'ORDER'=21
|
||||
'BY'=22
|
||||
'ASC'=23
|
||||
'DESC'=24
|
|
@ -0,0 +1,220 @@
|
|||
// Generated from SOQL.g4 by ANTLR 4.7
|
||||
package li.strolch.soql.antlr4.generated;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
|
||||
/**
|
||||
* This interface defines a complete listener for a parse tree produced by
|
||||
* {@link SOQLParser}.
|
||||
*/
|
||||
public interface SOQLListener extends ParseTreeListener {
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#select_statement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterSelect_statement(SOQLParser.Select_statementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#select_statement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitSelect_statement(SOQLParser.Select_statementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#select_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterSelect_clause(SOQLParser.Select_clauseContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#select_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitSelect_clause(SOQLParser.Select_clauseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#select_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterSelect_expression(SOQLParser.Select_expressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#select_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitSelect_expression(SOQLParser.Select_expressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#chained_method_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterChained_method_expression(SOQLParser.Chained_method_expressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#chained_method_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitChained_method_expression(SOQLParser.Chained_method_expressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#method_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterMethod_expression(SOQLParser.Method_expressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#method_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitMethod_expression(SOQLParser.Method_expressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#method_name}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterMethod_name(SOQLParser.Method_nameContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#method_name}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitMethod_name(SOQLParser.Method_nameContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#method_argument}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterMethod_argument(SOQLParser.Method_argumentContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#method_argument}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitMethod_argument(SOQLParser.Method_argumentContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#from_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterFrom_clause(SOQLParser.From_clauseContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#from_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitFrom_clause(SOQLParser.From_clauseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#entity_declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterEntity_declaration(SOQLParser.Entity_declarationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#entity_declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitEntity_declaration(SOQLParser.Entity_declarationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#class_declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterClass_declaration(SOQLParser.Class_declarationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#class_declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitClass_declaration(SOQLParser.Class_declarationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#object_declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterObject_declaration(SOQLParser.Object_declarationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#object_declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitObject_declaration(SOQLParser.Object_declarationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#where_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterWhere_clause(SOQLParser.Where_clauseContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#where_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitWhere_clause(SOQLParser.Where_clauseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#or_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterOr_expression(SOQLParser.Or_expressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#or_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitOr_expression(SOQLParser.Or_expressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#and_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterAnd_expression(SOQLParser.And_expressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#and_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitAnd_expression(SOQLParser.And_expressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#expression_term}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterExpression_term(SOQLParser.Expression_termContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#expression_term}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitExpression_term(SOQLParser.Expression_termContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#comparison_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterComparison_expression(SOQLParser.Comparison_expressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#comparison_expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitComparison_expression(SOQLParser.Comparison_expressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#comparison_operator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterComparison_operator(SOQLParser.Comparison_operatorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#comparison_operator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitComparison_operator(SOQLParser.Comparison_operatorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#var_reference}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterVar_reference(SOQLParser.Var_referenceContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#var_reference}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitVar_reference(SOQLParser.Var_referenceContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#value_declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterValue_declaration(SOQLParser.Value_declarationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#value_declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitValue_declaration(SOQLParser.Value_declarationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#orderby_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterOrderby_clause(SOQLParser.Orderby_clauseContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#orderby_clause}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitOrderby_clause(SOQLParser.Orderby_clauseContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link SOQLParser#orderby_item}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterOrderby_item(SOQLParser.Orderby_itemContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link SOQLParser#orderby_item}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitOrderby_item(SOQLParser.Orderby_itemContext ctx);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,139 @@
|
|||
// Generated from SOQL.g4 by ANTLR 4.7
|
||||
package li.strolch.soql.antlr4.generated;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||
|
||||
/**
|
||||
* This interface defines a complete generic visitor for a parse tree produced
|
||||
* by {@link SOQLParser}.
|
||||
*
|
||||
* @param <T> The return type of the visit operation. Use {@link Void} for
|
||||
* operations with no return type.
|
||||
*/
|
||||
public interface SOQLVisitor<T> extends ParseTreeVisitor<T> {
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#select_statement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitSelect_statement(SOQLParser.Select_statementContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#select_clause}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitSelect_clause(SOQLParser.Select_clauseContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#select_expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitSelect_expression(SOQLParser.Select_expressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#chained_method_expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitChained_method_expression(SOQLParser.Chained_method_expressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#method_expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitMethod_expression(SOQLParser.Method_expressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#method_name}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitMethod_name(SOQLParser.Method_nameContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#method_argument}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitMethod_argument(SOQLParser.Method_argumentContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#from_clause}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitFrom_clause(SOQLParser.From_clauseContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#entity_declaration}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitEntity_declaration(SOQLParser.Entity_declarationContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#class_declaration}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitClass_declaration(SOQLParser.Class_declarationContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#object_declaration}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitObject_declaration(SOQLParser.Object_declarationContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#where_clause}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitWhere_clause(SOQLParser.Where_clauseContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#or_expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitOr_expression(SOQLParser.Or_expressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#and_expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitAnd_expression(SOQLParser.And_expressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#expression_term}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitExpression_term(SOQLParser.Expression_termContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#comparison_expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitComparison_expression(SOQLParser.Comparison_expressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#comparison_operator}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitComparison_operator(SOQLParser.Comparison_operatorContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#var_reference}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitVar_reference(SOQLParser.Var_referenceContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#value_declaration}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitValue_declaration(SOQLParser.Value_declarationContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#orderby_clause}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitOrderby_clause(SOQLParser.Orderby_clauseContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link SOQLParser#orderby_item}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitOrderby_item(SOQLParser.Orderby_itemContext ctx);
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package li.strolch.soql.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import li.strolch.soql.core.expresssion.SelectClause;
|
||||
import li.strolch.soql.core.expresssion.WhereExpression;
|
||||
|
||||
public class CompiledStatement {
|
||||
|
||||
// the map of entities declared in the FROM clause with their nicknames as keys
|
||||
Map<String, String> entities = new HashMap<>();
|
||||
|
||||
// the decision tree as defined in the WHERE clause
|
||||
WhereExpression whereExpression;
|
||||
|
||||
// the expression evaluating to the selected objects according to the SELECT
|
||||
// clause
|
||||
public SelectClause selectClause;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return List of objects resulting from running the compiled code
|
||||
*/
|
||||
public List<Object> evaluate(Map<String, Object> inputObjects, Map<String, Object> injectedObjects) {
|
||||
|
||||
boolean evaluateWhereExpression = true;
|
||||
if (whereExpression != null) {
|
||||
evaluateWhereExpression = whereExpression.evaluate(inputObjects, injectedObjects);
|
||||
}
|
||||
|
||||
if (evaluateWhereExpression) {
|
||||
return selectClause.evaluate(inputObjects, injectedObjects);
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CompiledStatement [entities=" + entities + ", whereExpression=" + whereExpression + ", selectClause="
|
||||
+ selectClause + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package li.strolch.soql.core;
|
||||
|
||||
public class SOQLEvaluationException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SOQLEvaluationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,264 @@
|
|||
package li.strolch.soql.core;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import li.strolch.soql.antlr4.generated.SOQLBaseListener;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.And_expressionContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Chained_method_expressionContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Class_declarationContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Comparison_expressionContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Expression_termContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Method_argumentContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Method_expressionContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Method_nameContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Object_declarationContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Or_expressionContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Select_clauseContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Select_expressionContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Value_declarationContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Var_referenceContext;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser.Where_clauseContext;
|
||||
import li.strolch.soql.core.expresssion.AndExpression;
|
||||
import li.strolch.soql.core.expresssion.ChainedMethodExpression;
|
||||
import li.strolch.soql.core.expresssion.ComparisonExpression;
|
||||
import li.strolch.soql.core.expresssion.ExpressionTerm;
|
||||
import li.strolch.soql.core.expresssion.IExpression;
|
||||
import li.strolch.soql.core.expresssion.MethodArgumentDeclaration;
|
||||
import li.strolch.soql.core.expresssion.MethodExpression;
|
||||
import li.strolch.soql.core.expresssion.ObjectDeclaration;
|
||||
import li.strolch.soql.core.expresssion.OrExpression;
|
||||
import li.strolch.soql.core.expresssion.ParameterReference;
|
||||
import li.strolch.soql.core.expresssion.SelectClause;
|
||||
import li.strolch.soql.core.expresssion.SelectExpression;
|
||||
import li.strolch.soql.core.expresssion.ValueDeclaration;
|
||||
import li.strolch.soql.core.expresssion.WhereExpression;
|
||||
|
||||
/**
|
||||
* @author msmock
|
||||
*/
|
||||
public class SOQLListener extends SOQLBaseListener {
|
||||
|
||||
// the map of entities declared in the FROM clause with their nicknames as keys
|
||||
private final Map<String, String> entities = new HashMap<>();
|
||||
|
||||
// the definition of the result set from the SELECT clause
|
||||
private SelectClause selectClause;
|
||||
|
||||
// the decision tree as defined in the WHERE clause
|
||||
private WhereExpression whereExpression;
|
||||
|
||||
// pointer to the current parent during parsing
|
||||
private IExpression pointer = null;
|
||||
|
||||
// used to track the entity class Name during parsing
|
||||
private String currentEntity;
|
||||
|
||||
public Map<String, String> getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
||||
public WhereExpression getWhereExpression() {
|
||||
return whereExpression;
|
||||
}
|
||||
|
||||
public SelectClause getSelectClause() {
|
||||
return selectClause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterSelect_clause(Select_clauseContext ctx) {
|
||||
SelectClause selectClause = new SelectClause();
|
||||
pointer = selectClause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitSelect_clause(Select_clauseContext ctx) {
|
||||
this.selectClause = (SelectClause) pointer;
|
||||
pointer = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterSelect_expression(Select_expressionContext ctx) {
|
||||
SelectExpression selectExpression = new SelectExpression();
|
||||
((SelectClause) pointer).addExpression(selectExpression);
|
||||
pointer = selectExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitSelect_expression(Select_expressionContext ctx) {
|
||||
pointer = pointer.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterWhere_clause(Where_clauseContext ctx) {
|
||||
WhereExpression whereExpression = new WhereExpression();
|
||||
pointer = whereExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitWhere_clause(Where_clauseContext ctx) {
|
||||
this.whereExpression = (WhereExpression) pointer;
|
||||
pointer = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract the class declaration in the FROM clause. For example, in 'FROM
|
||||
* Resource res' the class declaration is 'Resource'.
|
||||
*/
|
||||
@Override
|
||||
public void exitClass_declaration(Class_declarationContext ctx) {
|
||||
currentEntity = ctx.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* extract the object declaration in the FROM clause, which defines the lookup
|
||||
* key for the class declaration. For example, in 'FROM Resource res' the object
|
||||
* declaration is 'res'.
|
||||
*/
|
||||
@Override
|
||||
public void exitObject_declaration(Object_declarationContext ctx) {
|
||||
if (pointer instanceof SelectExpression) {
|
||||
ObjectDeclaration expr = new ObjectDeclaration();
|
||||
expr.key = ctx.getText();
|
||||
((SelectExpression) pointer).addExpression(expr);
|
||||
} else if (pointer == null) {
|
||||
String key = ctx.getText();
|
||||
entities.put(key, currentEntity);
|
||||
currentEntity = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* one or expression can have multiple and
|
||||
*/
|
||||
@Override
|
||||
public void enterOr_expression(Or_expressionContext ctx) {
|
||||
OrExpression orExpression = new OrExpression();
|
||||
((WhereExpression) pointer).setOrExpression(orExpression);
|
||||
pointer = orExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* one or expression can have multiple and
|
||||
*/
|
||||
@Override
|
||||
public void enterAnd_expression(And_expressionContext ctx) {
|
||||
AndExpression andExpression = new AndExpression();
|
||||
((OrExpression) pointer).addAndExpression(andExpression);
|
||||
pointer = andExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterExpression_term(Expression_termContext ctx) {
|
||||
|
||||
ExpressionTerm expressionTerm = new ExpressionTerm();
|
||||
((AndExpression) pointer).addExpressionTerm(expressionTerm);
|
||||
pointer = expressionTerm;
|
||||
|
||||
if (ctx.children.get(0).getText().equals("NOT")) {
|
||||
expressionTerm.setNot(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterComparison_expression(Comparison_expressionContext ctx) {
|
||||
ComparisonExpression comparisonExpresion = new ComparisonExpression();
|
||||
comparisonExpresion.setOperator(ctx.children.get(1).getText());
|
||||
((ExpressionTerm) pointer).setComparison(comparisonExpresion);
|
||||
pointer = comparisonExpresion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterChained_method_expression(Chained_method_expressionContext ctx) {
|
||||
|
||||
final ChainedMethodExpression chainedMethodExpression = new ChainedMethodExpression();
|
||||
chainedMethodExpression.setObjectKey(ctx.children.get(0).getText());
|
||||
|
||||
if (pointer instanceof SelectExpression) {
|
||||
((SelectExpression) pointer).addExpression(chainedMethodExpression);
|
||||
} else if (pointer instanceof ComparisonExpression) {
|
||||
((ComparisonExpression) pointer).addOperand(chainedMethodExpression);
|
||||
} else if (pointer instanceof SelectExpression) {
|
||||
((SelectExpression) pointer).addExpression(chainedMethodExpression);
|
||||
}
|
||||
pointer = chainedMethodExpression;
|
||||
}
|
||||
|
||||
// TODO here we are
|
||||
@Override
|
||||
public void enterMethod_expression(Method_expressionContext ctx) {
|
||||
MethodExpression methodExpression = new MethodExpression();
|
||||
((ChainedMethodExpression) pointer).addMethodExpression(methodExpression);
|
||||
pointer = methodExpression;
|
||||
}
|
||||
|
||||
// TODO here we are
|
||||
@Override
|
||||
public void exitMethod_expression(Method_expressionContext ctx) {
|
||||
pointer = pointer.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterMethod_name(Method_nameContext ctx) {
|
||||
if (pointer instanceof MethodExpression) {
|
||||
((MethodExpression) pointer).setMethodName(ctx.getText());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterMethod_argument(Method_argumentContext ctx) {
|
||||
MethodArgumentDeclaration methodArguments = new MethodArgumentDeclaration();
|
||||
((MethodExpression) pointer).setMethodArguments(methodArguments);
|
||||
pointer = methodArguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitMethod_argument(Method_argumentContext ctx) {
|
||||
pointer = pointer.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitChained_method_expression(Chained_method_expressionContext ctx) {
|
||||
pointer = pointer.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterValue_declaration(Value_declarationContext ctx) {
|
||||
ValueDeclaration valueDeclaration = new ValueDeclaration();
|
||||
valueDeclaration.valueAsString = ctx.children.get(1).getText();
|
||||
((ComparisonExpression) pointer).addOperand(valueDeclaration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterVar_reference(Var_referenceContext ctx) {
|
||||
ParameterReference parameterReference = new ParameterReference();
|
||||
parameterReference.varName = ctx.children.get(1).getText();
|
||||
if (pointer instanceof ComparisonExpression) {
|
||||
((ComparisonExpression) pointer).addOperand(parameterReference);
|
||||
} else if (pointer instanceof MethodArgumentDeclaration) {
|
||||
((MethodArgumentDeclaration) pointer).addParameterReference(parameterReference);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitComparison_expression(Comparison_expressionContext ctx) {
|
||||
pointer = pointer.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitExpression_term(Expression_termContext ctx) {
|
||||
pointer = pointer.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitAnd_expression(And_expressionContext ctx) {
|
||||
pointer = pointer.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitOr_expression(Or_expressionContext ctx) {
|
||||
pointer = pointer.getParent();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* Abstract class for all expressions which evaluate to Boolean result
|
||||
*
|
||||
* @author msmock
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractBooleanExpression implements IBooleanExpression {
|
||||
|
||||
IExpression parent;
|
||||
|
||||
@Override
|
||||
public abstract boolean evaluate(Map<String, Object> inputObjects, Map<String, Object> queryParameter);
|
||||
|
||||
@Override
|
||||
public void setParent(IExpression e) {
|
||||
parent = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IExpression getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Abstract class for all expressions which evaluate to other objects than Boolean
|
||||
*
|
||||
* @author msmock
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractObjectExpression implements IObjectExpression {
|
||||
|
||||
IExpression parent;
|
||||
|
||||
@Override
|
||||
public abstract Class<?> getType(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter);
|
||||
|
||||
@Override
|
||||
public abstract Object evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter);
|
||||
|
||||
@Override
|
||||
public void setParent(IExpression e) {
|
||||
parent = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IExpression getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Boolean AND implementation to combine {@link ComparisonExpression} objects
|
||||
*
|
||||
* @author msmock
|
||||
*/
|
||||
public class AndExpression extends AbstractBooleanExpression {
|
||||
|
||||
private List<ExpressionTerm> expressionTerms = new ArrayList<>();
|
||||
|
||||
public void addExpressionTerm(ExpressionTerm e) {
|
||||
expressionTerms.add(e);
|
||||
e.setParent(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false if a child expression returns false
|
||||
*/
|
||||
@Override
|
||||
public boolean evaluate(Map<String, Object> inputObjects, Map<String, Object> queryParameter) {
|
||||
for (ExpressionTerm term : expressionTerms) {
|
||||
if (!term.evaluate(inputObjects, queryParameter))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AndExpression [expressionTerms=" + expressionTerms + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* extract state field value by chained method call
|
||||
*
|
||||
* @author msmock
|
||||
*/
|
||||
public class ChainedMethodExpression extends AbstractObjectExpression {
|
||||
|
||||
private String objectKey;
|
||||
|
||||
private List<MethodExpression> methodExpressions = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public Class<?> getType(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
Object result = evaluate(inputObjects, queryParameter);
|
||||
return result.getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* evaluate by calling the method by name.
|
||||
*/
|
||||
@Override
|
||||
public Object evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
|
||||
final Object inputObject = inputObjects.get(objectKey);
|
||||
|
||||
Object object = inputObject;
|
||||
for (MethodExpression methodExpression : methodExpressions) {
|
||||
methodExpression.setObject(object);
|
||||
object = methodExpression.evaluate(inputObjects, queryParameter);
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
public void setObjectKey(String entityKey) {
|
||||
this.objectKey = entityKey;
|
||||
}
|
||||
|
||||
public void addMethodExpression(MethodExpression methodExpression) {
|
||||
this.methodExpressions.add(methodExpression);
|
||||
methodExpression.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChainedMethodExpression [objectKey=" + objectKey + ", methodExpressions=" + methodExpressions + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import li.strolch.soql.core.SOQLEvaluationException;
|
||||
|
||||
/**
|
||||
* Compares two or more expressions, for example 'a.name = "12345"'
|
||||
*
|
||||
* Currently only the following operators for equality check are supported:
|
||||
*
|
||||
* '=' | '<>' | '>' | '>=' | '<' | '<=' ;
|
||||
*
|
||||
* @author msmock
|
||||
*
|
||||
*/
|
||||
public class ComparisonExpression extends AbstractBooleanExpression {
|
||||
|
||||
private String operator;
|
||||
private List<IObjectExpression> operands = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public boolean evaluate(Map<String, Object> inputObjects, Map<String, Object> queryParameter) {
|
||||
|
||||
boolean result = false;
|
||||
|
||||
switch (operator) {
|
||||
case "=":
|
||||
result = evaluateEquals(inputObjects, queryParameter);
|
||||
break;
|
||||
case "<>":
|
||||
result = !evaluateEquals(inputObjects, queryParameter);
|
||||
break;
|
||||
case ">":
|
||||
result = evaluateMore(inputObjects, queryParameter);
|
||||
break;
|
||||
case "<":
|
||||
result = evaluateLess(inputObjects, queryParameter);
|
||||
break;
|
||||
case ">=":
|
||||
result = !evaluateLess(inputObjects, queryParameter);
|
||||
break;
|
||||
case "<=":
|
||||
result = !evaluateMore(inputObjects, queryParameter);
|
||||
break;
|
||||
default:
|
||||
throw new SOQLEvaluationException("Comparison with operator " + operator + " is not supported yet.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: allow comparison, if the classes do not match. I.e. compare Integer with Double
|
||||
*
|
||||
* @param inputObjects
|
||||
* @param queryParameter
|
||||
* @return
|
||||
*/
|
||||
private boolean evaluateLess(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
|
||||
final Object result_1 = operands.get(0).evaluate(inputObjects, queryParameter);
|
||||
final Object result_2 = operands.get(1).evaluate(inputObjects, queryParameter);
|
||||
|
||||
final Class<?> clazz_1 = result_1.getClass();
|
||||
final Class<?> clazz_2 = result_2.getClass();
|
||||
|
||||
if (!clazz_1.equals(clazz_2)) {
|
||||
throw new SOQLEvaluationException("Operation < not defined for comparison of " + result_1 + " of class "
|
||||
+ clazz_1 + " with " + result_2 + " of class " + clazz_2);
|
||||
}
|
||||
|
||||
if (result_1 instanceof Integer && result_2 instanceof Integer) {
|
||||
return ((Integer) result_1).compareTo((Integer) result_2) < 0;
|
||||
} else if (result_1 instanceof Long && result_2 instanceof Long) {
|
||||
return ((Long) result_1).compareTo((Long) result_2) < 0;
|
||||
} else if (result_1 instanceof Double && result_2 instanceof Double) {
|
||||
return ((Float) result_1).compareTo((Float) result_2) < 0;
|
||||
} else if (result_1 instanceof Double && result_2 instanceof Double) {
|
||||
return ((Double) result_1).compareTo((Double) result_2) < 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean evaluateMore(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
|
||||
final Object result_1 = operands.get(0).evaluate(inputObjects, queryParameter);
|
||||
final Object result_2 = operands.get(1).evaluate(inputObjects, queryParameter);
|
||||
|
||||
final Class<?> clazz_1 = result_1.getClass();
|
||||
final Class<?> clazz_2 = result_2.getClass();
|
||||
|
||||
if (!clazz_1.equals(clazz_2)) {
|
||||
throw new SOQLEvaluationException("Operation < not defined for comparison of " + result_1 + " of class "
|
||||
+ clazz_1 + " with " + result_2 + " of class " + clazz_2);
|
||||
}
|
||||
|
||||
if (result_1 instanceof Integer && result_2 instanceof Integer) {
|
||||
return ((Integer) result_1).compareTo((Integer) result_2) > 0;
|
||||
} else if (result_1 instanceof Long && result_2 instanceof Long) {
|
||||
return ((Long) result_1).compareTo((Long) result_2) > 0;
|
||||
} else if (result_1 instanceof Double && result_2 instanceof Double) {
|
||||
return ((Float) result_1).compareTo((Float) result_2) > 0;
|
||||
} else if (result_1 instanceof Double && result_2 instanceof Double) {
|
||||
return ((Double) result_1).compareTo((Double) result_2) > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the String representation of the operands match
|
||||
*/
|
||||
private boolean evaluateEquals(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
Object result_1 = operands.get(0).evaluate(inputObjects, queryParameter);
|
||||
Object result_2 = operands.get(1).evaluate(inputObjects, queryParameter);
|
||||
return result_1.equals(result_2);
|
||||
}
|
||||
|
||||
public void setOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public void addOperand(IObjectExpression operand) {
|
||||
operands.add(operand);
|
||||
operand.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ComparisonExpression [operator=" + operator + ", operands=" + operands + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* wraps a comparison with an optional boolean inversion
|
||||
*
|
||||
* @author msmock
|
||||
*/
|
||||
public class ExpressionTerm extends AbstractBooleanExpression {
|
||||
|
||||
private boolean not = false;
|
||||
private ComparisonExpression comparisonExpression;
|
||||
|
||||
@Override
|
||||
public boolean evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
boolean result = comparisonExpression.evaluate(inputObjects,queryParameter);
|
||||
return not ? !result : result;
|
||||
}
|
||||
|
||||
public void setNot(boolean not) {
|
||||
this.not = not;
|
||||
}
|
||||
|
||||
public void setComparison(final ComparisonExpression comparison) {
|
||||
this.comparisonExpression = comparison;
|
||||
comparison.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ExpressionTerm [not=" + not + ", comparison=" + comparisonExpression + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author msmock
|
||||
*
|
||||
*/
|
||||
public interface IBooleanExpression extends IExpression {
|
||||
|
||||
boolean evaluate(Map<String, Object> inputObjects, Map<String, Object> queryParameter);
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
public interface IExpression {
|
||||
|
||||
void setParent(IExpression e);
|
||||
|
||||
IExpression getParent();
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface IObjectExpression extends IExpression {
|
||||
|
||||
Object evaluate(Map<String, Object> inputObjects, Map<String, Object> queryParameter);
|
||||
|
||||
Class<?> getType(Map<String, Object> inputObjects, Map<String, Object> queryParameter);
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Expression to wrap a declaration of method arguments
|
||||
*
|
||||
* @author msmock
|
||||
*
|
||||
*/
|
||||
public class MethodArgumentDeclaration extends AbstractObjectExpression {
|
||||
|
||||
private List<ParameterReference> parameterReferences = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public Class<?> getType(Map<String, Object> inputObjects, Map<String, Object> queryParameter) {
|
||||
return List.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evaluate(Map<String, Object> inputObjects, Map<String, Object> queryParameter) {
|
||||
final List<Object> result = new ArrayList<>();
|
||||
for (ParameterReference parameterReference : parameterReferences) {
|
||||
result.add(parameterReference.evaluate(inputObjects, queryParameter));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addParameterReference(final ParameterReference parameterReference) {
|
||||
parameterReferences.add(parameterReference);
|
||||
parameterReference.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MethodArguments [parameterReferences=" + parameterReferences + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import li.strolch.soql.core.SOQLEvaluationException;
|
||||
|
||||
/**
|
||||
* extract state field value by reflection
|
||||
*
|
||||
* @author msmock
|
||||
*/
|
||||
public class MethodExpression extends AbstractObjectExpression {
|
||||
|
||||
private Object object;
|
||||
private String methodName;
|
||||
private MethodArgumentDeclaration methodArguments;
|
||||
|
||||
@Override
|
||||
public Class<?> getType(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
Object result = evaluate(inputObjects, queryParameter);
|
||||
return result.getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* evaluate by calling the method by name.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
|
||||
// analyze the method arguments declaration
|
||||
List<Object> arguments = (List<Object>) methodArguments.evaluate(inputObjects, queryParameter);
|
||||
List<Class<?>> clazzes = new ArrayList<>();
|
||||
for (Object argument : arguments) {
|
||||
clazzes.add(argument.getClass());
|
||||
}
|
||||
|
||||
// now find the method to call
|
||||
Method method = null;
|
||||
try {
|
||||
method = object.getClass().getMethod(methodName, clazzes.toArray(new Class[clazzes.size()]));
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new SOQLEvaluationException("Method " + methodName + " with arguments " + clazzes
|
||||
+ " not declared on object " + object + " of class " + object.getClass());
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Object result;
|
||||
|
||||
// and finally call the method
|
||||
try {
|
||||
result = method.invoke(object, arguments.toArray());
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setObject(Object object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName) {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
public void setMethodArguments(MethodArgumentDeclaration methodArguments) {
|
||||
this.methodArguments = methodArguments;
|
||||
methodArguments.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MethodExpression [object=" + object + ", methodName=" + methodName + ", methodArguments="
|
||||
+ methodArguments + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author msmock
|
||||
*/
|
||||
public class ObjectDeclaration extends AbstractObjectExpression {
|
||||
|
||||
public String key;
|
||||
|
||||
@Override
|
||||
public Object evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
return inputObjects.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType(Map<String, Object> inputObjects, Map<String, Object> queryParameter) {
|
||||
return inputObjects.get(key).getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ObjectDeclaration [key=" + key + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Boolean OR implementation to combine {@link ComparisonExpression} objects
|
||||
*
|
||||
* @author msmock
|
||||
*/
|
||||
public class OrExpression extends AbstractBooleanExpression {
|
||||
|
||||
private List<AndExpression> children = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @return true if at least one child expression returns true
|
||||
*/
|
||||
@Override
|
||||
public boolean evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
for (AndExpression andExpression : children) {
|
||||
if (!andExpression.evaluate(inputObjects, queryParameter))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addAndExpression(final AndExpression andExpression) {
|
||||
children.add(andExpression);
|
||||
andExpression.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OrExpression [children=" + children + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import li.strolch.soql.core.SOQLEvaluationException;
|
||||
|
||||
/**
|
||||
* A reference to a query parameter
|
||||
*
|
||||
* @author msmock
|
||||
*/
|
||||
public class ParameterReference extends AbstractObjectExpression {
|
||||
|
||||
public String varName;
|
||||
|
||||
@Override
|
||||
public Object evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
Object result = queryParameter.get(varName);
|
||||
if (result == null)
|
||||
throw new SOQLEvaluationException("No object with key "+varName+" declared in the query parameter.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType(Map<String, Object> inputObjects, Map<String, Object> queryParameter) {
|
||||
return evaluate(inputObjects, queryParameter).getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VarReference [varName=" + varName + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SelectClause implements IExpression {
|
||||
|
||||
private IExpression parent;
|
||||
private List<IObjectExpression> selectExpressions = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @param inputObjects
|
||||
* @param queryParameter
|
||||
*
|
||||
* @return List of objects from child expression evaluation
|
||||
*/
|
||||
public List<Object> evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
|
||||
final List<Object> results = new ArrayList<>();
|
||||
for (IObjectExpression expr : selectExpressions) {
|
||||
Object evaluate = expr.evaluate(inputObjects, queryParameter);
|
||||
if (evaluate != null) {
|
||||
if (evaluate instanceof List<?>) {
|
||||
results.addAll((List<?>) evaluate);
|
||||
} else {
|
||||
results.add(evaluate);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public void addExpression(final IObjectExpression expression) {
|
||||
selectExpressions.add(expression);
|
||||
expression.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(final IExpression e) {
|
||||
this.parent = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IExpression getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SelectClause [parent=" + parent + ", selectExpressions=" + selectExpressions + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SelectExpression extends AbstractObjectExpression {
|
||||
|
||||
private List<IObjectExpression> children = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @param inputObjects
|
||||
* @param queryParameter
|
||||
*
|
||||
* @return List of objects from child expression evaluation
|
||||
*/
|
||||
@Override
|
||||
public List<Object> evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
|
||||
final List<Object> results = new ArrayList<>();
|
||||
for (IObjectExpression expr : children) {
|
||||
Object evaluate = expr.evaluate(inputObjects, queryParameter);
|
||||
if (evaluate != null)
|
||||
results.add(evaluate);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public void addExpression(final IObjectExpression expression) {
|
||||
children.add(expression);
|
||||
expression.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType(Map<String, Object> inputObjects, Map<String, Object> queryParameter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SelectExpression [children=" + children + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Expression to set a fixed value
|
||||
*
|
||||
* TODO allow blancs in Strings, and support parsing to other objects like int, double, Dates, etc.
|
||||
*
|
||||
* @author msmock
|
||||
*/
|
||||
public class ValueDeclaration extends AbstractObjectExpression {
|
||||
|
||||
public String valueAsString;
|
||||
|
||||
@Override
|
||||
public Object evaluate(final Map<String, Object> inputObjects, final Map<String, Object> queryParameter) {
|
||||
return valueAsString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType(Map<String, Object> inputObjects, Map<String, Object> queryParameter) {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ValueDeclaration [valueAsString=" + valueAsString + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package li.strolch.soql.core.expresssion;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author msmock
|
||||
*/
|
||||
public class WhereExpression extends AbstractBooleanExpression {
|
||||
|
||||
private OrExpression orExpression;
|
||||
|
||||
@Override
|
||||
public boolean evaluate(Map<String, Object> inputObjects, Map<String, Object> queryParameter) {
|
||||
return (orExpression == null) ? true : orExpression.evaluate(inputObjects, queryParameter);
|
||||
}
|
||||
|
||||
public void setOrExpression(OrExpression orExpression) {
|
||||
this.orExpression = orExpression;
|
||||
orExpression.setParent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WhereExpression [orExpression=" + orExpression + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package li.strolch.soql.core;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MockObject {
|
||||
|
||||
String id = "testId";
|
||||
String name = "testName";
|
||||
String type = "testType";
|
||||
|
||||
Map<String, MockParameter> parameter = new HashMap<>();
|
||||
|
||||
int number = 42;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public Object getParameter(String key) {
|
||||
return parameter.get(key);
|
||||
}
|
||||
|
||||
public Object getParameter(String key, String dummy) {
|
||||
return parameter.get(key);
|
||||
}
|
||||
|
||||
public void putParameter(String key, MockParameter value) {
|
||||
this.parameter.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MockObject [id=" + id + ", name=" + name + ", type=" + type + ", number=" + number + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package li.strolch.soql.core;
|
||||
|
||||
public class MockParameter {
|
||||
|
||||
String value = "testValue";
|
||||
String type = "testType";
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MockParameter [value=" + value + ", type=" + type + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,436 @@
|
|||
package li.strolch.soql.core;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.junit.Test;
|
||||
|
||||
import li.strolch.soql.antlr4.generated.SOQLLexer;
|
||||
import li.strolch.soql.antlr4.generated.SOQLParser;
|
||||
|
||||
public class StatementTest {
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private ParseTree parseString(final String s) throws Exception {
|
||||
|
||||
CharStream input = CharStreams.fromString(s);
|
||||
SOQLLexer lexer = new SOQLLexer(input); // create a buffer of tokens pulled from the lexer
|
||||
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer); // create a parser that feeds off the tokens buffer
|
||||
SOQLParser parser = new SOQLParser(tokens);
|
||||
|
||||
ParseTree tree = parser.select_statement(); // begin parsing at block
|
||||
|
||||
System.out.println(tree.toStringTree(parser)); // print LISP-style tree
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tree
|
||||
* @return CompiledSOQLStatement the compiled SOQL statement
|
||||
* @throws Exception
|
||||
*/
|
||||
private CompiledStatement compile(final ParseTree tree) throws Exception {
|
||||
|
||||
final ParseTreeWalker walker = new ParseTreeWalker();
|
||||
final SOQLListener listener = new SOQLListener();
|
||||
walker.walk(listener, tree);
|
||||
|
||||
final CompiledStatement soqlStatement = new CompiledStatement();
|
||||
soqlStatement.entities = listener.getEntities();
|
||||
soqlStatement.whereExpression = listener.getWhereExpression();
|
||||
soqlStatement.selectClause = listener.getSelectClause();
|
||||
|
||||
return soqlStatement;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() throws Exception {
|
||||
|
||||
String s = "SELECT r, a, a.getId() FROM Resource r, Activity a";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
// System.out.println(compiledStatement);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
inputObjects.put("r", new MockObject());
|
||||
inputObjects.put("a", new MockObject());
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
|
||||
final List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(3, result.size());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* positive test of a comparison expression in a WHERE clause
|
||||
*/
|
||||
@Test
|
||||
public void test2() throws Exception {
|
||||
|
||||
String s = "SELECT r FROM Resource r WHERE r.getName() = \"testName\"";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
inputObjects.put("r", new MockObject());
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
|
||||
final List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(1, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* negative test of a comparison expression in a WHERE clause
|
||||
*/
|
||||
@Test
|
||||
public void test3() throws Exception {
|
||||
|
||||
String s = "SELECT r FROM Resource r WHERE r.getName() = \"testNameDiffering\"";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
inputObjects.put("r", new MockObject());
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
|
||||
final List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* positive test of a AND combined comparison expressions in WHERE clause
|
||||
*/
|
||||
@Test
|
||||
public void test4() throws Exception {
|
||||
|
||||
String s = "SELECT r, a FROM Resource r, Activity a WHERE r.getType() = a.getType() AND r.getName() = \"testName\"";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
inputObjects.put("r", new MockObject());
|
||||
inputObjects.put("a", new MockObject());
|
||||
|
||||
final Map<String, Object> parameter = new HashMap<>();
|
||||
|
||||
final List<Object> result = compiledStatement.evaluate(inputObjects, parameter);
|
||||
|
||||
assertEquals(2, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* positive test of a comparison expression with query parameter
|
||||
*/
|
||||
@Test
|
||||
public void test5() throws Exception {
|
||||
|
||||
String s = "SELECT a FROM Activity a WHERE a.getName() = :outer_var";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("outer_var", "testName");
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
inputObjects.put("a", new MockObject());
|
||||
|
||||
final List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(1, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* positive test of a method call in comparison expression of a WHERE clause
|
||||
*/
|
||||
@Test
|
||||
public void test6() throws Exception {
|
||||
|
||||
String s = "SELECT a FROM Activity a WHERE a.getNumber() < :parameter";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
inputObjects.put("a", new MockObject());
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("parameter", 1234);
|
||||
|
||||
final List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(1, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* negative test of a method call in comparison expression of a WHERE clause
|
||||
*/
|
||||
@Test
|
||||
public void test8() throws Exception {
|
||||
|
||||
String s = "SELECT a FROM Activity a WHERE a.getNumber() > :parameter";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
inputObjects.put("a", new MockObject());
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("parameter", 122);
|
||||
|
||||
final List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* negative test of a method call in SELECT statement
|
||||
*/
|
||||
@Test
|
||||
public void test9() throws Exception {
|
||||
|
||||
String s = "SELECT a.getParameter(:param_1) FROM Activity a";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
|
||||
final MockObject a = new MockObject();
|
||||
|
||||
String matchingKey = "pid";
|
||||
a.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
inputObjects.put("a", a);
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
|
||||
List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(1, result.size());
|
||||
|
||||
String nonMatchingKey = "noPid";
|
||||
|
||||
queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", nonMatchingKey);
|
||||
|
||||
result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* positive test of a method call with multiple method arguments
|
||||
*/
|
||||
@Test
|
||||
public void test10() throws Exception {
|
||||
|
||||
String s = "SELECT a.getParameter(:param_1, :param_2) FROM Activity a";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
|
||||
final MockObject a = new MockObject();
|
||||
|
||||
String matchingKey = "pid";
|
||||
a.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
inputObjects.put("a", a);
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
queryParameter.put("param_2", matchingKey);
|
||||
|
||||
List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(1, result.size());
|
||||
|
||||
String nonMatchingKey = "noPid";
|
||||
|
||||
queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", nonMatchingKey);
|
||||
queryParameter.put("param_2", "");
|
||||
|
||||
result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* positive test of a chained method call in SELECT clause
|
||||
*/
|
||||
@Test
|
||||
public void test11() throws Exception {
|
||||
|
||||
String s = "SELECT a.getParameter(:param_1).getType() FROM Activity a";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
|
||||
final MockObject a = new MockObject();
|
||||
|
||||
String matchingKey = "pid";
|
||||
a.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
inputObjects.put("a", a);
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
|
||||
List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(1, result.size());
|
||||
|
||||
assertEquals("testType", result.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* positive test of a chained method call in WHERE clause
|
||||
*/
|
||||
@Test
|
||||
public void test12() throws Exception {
|
||||
|
||||
String s = "SELECT a FROM Activity a WHERE a.getParameter(:param_1).getType() = \"testType\"";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
|
||||
final MockObject a = new MockObject();
|
||||
|
||||
String matchingKey = "pid";
|
||||
a.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
inputObjects.put("a", a);
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
|
||||
List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(1, result.size());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* negative test of a chained method call in WHERE clause
|
||||
*/
|
||||
@Test
|
||||
public void test14() throws Exception {
|
||||
|
||||
String s = "SELECT a FROM Activity a WHERE a.getParameter(:param_1).getType() = :param_2";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
|
||||
final MockObject a = new MockObject();
|
||||
|
||||
final String matchingKey = "pid";
|
||||
a.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
inputObjects.put("a", a);
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
queryParameter.put("param_2", "notMatchingString");
|
||||
|
||||
List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* test an where expression with a NOT inversion
|
||||
*/
|
||||
@Test
|
||||
public void test15() throws Exception {
|
||||
|
||||
String s = "SELECT a FROM Activity a WHERE NOT a.getParameter(:param_1).getType() = :param_2";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
|
||||
final MockObject a = new MockObject();
|
||||
|
||||
final String matchingKey = "pid";
|
||||
a.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
inputObjects.put("a", a);
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
queryParameter.put("param_2", "notMatchingString");
|
||||
|
||||
List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(1, result.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* test an where expression with a NOT inversion
|
||||
*/
|
||||
@Test
|
||||
public void test16() throws Exception {
|
||||
|
||||
String s = "SELECT a FROM Activity a WHERE a.getParameter(:param_1).getType() = :param_2";
|
||||
|
||||
final ParseTree tree = parseString(s);
|
||||
final CompiledStatement compiledStatement = compile(tree);
|
||||
|
||||
final Map<String, Object> inputObjects = new HashMap<>();
|
||||
|
||||
final MockObject a = new MockObject();
|
||||
|
||||
final String matchingKey = "pid";
|
||||
a.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
inputObjects.put("a", a);
|
||||
|
||||
final Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
queryParameter.put("param_2", "testType");
|
||||
|
||||
List<Object> result = compiledStatement.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(1, result.size());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package li.strolch.soql.core.expression;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import li.strolch.soql.core.MockObject;
|
||||
import li.strolch.soql.core.MockParameter;
|
||||
import li.strolch.soql.core.expresssion.ChainedMethodExpression;
|
||||
import li.strolch.soql.core.expresssion.MethodArgumentDeclaration;
|
||||
import li.strolch.soql.core.expresssion.MethodExpression;
|
||||
import li.strolch.soql.core.expresssion.ParameterReference;
|
||||
|
||||
public class ChainedMethodExpressionTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
String matchingKey = "testString";
|
||||
|
||||
// build the message expression
|
||||
ParameterReference parameterReference = new ParameterReference();
|
||||
parameterReference.varName = "param_1";
|
||||
|
||||
MethodArgumentDeclaration argument = new MethodArgumentDeclaration();
|
||||
argument.addParameterReference(parameterReference);
|
||||
|
||||
MethodExpression methodExpression = new MethodExpression();
|
||||
methodExpression.setMethodName("getParameter");
|
||||
methodExpression.setMethodArguments(argument);
|
||||
|
||||
// build the chained expression
|
||||
ChainedMethodExpression chainedMethodExpression = new ChainedMethodExpression();
|
||||
chainedMethodExpression.setObjectKey("a");
|
||||
chainedMethodExpression.addMethodExpression(methodExpression);
|
||||
|
||||
// prepare the runtime objects
|
||||
MockObject mockObject = new MockObject();
|
||||
mockObject.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
Map<String, Object> inputObjects = new HashMap<>();
|
||||
inputObjects.put("a", mockObject);
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
|
||||
// evaluate the chained expression
|
||||
Object result = chainedMethodExpression.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals(MockParameter.class, result.getClass());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChained() {
|
||||
|
||||
String matchingKey = "testString";
|
||||
|
||||
// build the message expression
|
||||
ParameterReference parameterReference = new ParameterReference();
|
||||
parameterReference.varName = "param_1";
|
||||
|
||||
MethodArgumentDeclaration argument = new MethodArgumentDeclaration();
|
||||
argument.addParameterReference(parameterReference);
|
||||
|
||||
MethodExpression methodExpression_1 = new MethodExpression();
|
||||
methodExpression_1.setMethodName("getParameter");
|
||||
methodExpression_1.setMethodArguments(argument);
|
||||
|
||||
MethodExpression methodExpression_2 = new MethodExpression();
|
||||
methodExpression_2.setMethodName("getType");
|
||||
methodExpression_2.setMethodArguments(new MethodArgumentDeclaration());
|
||||
|
||||
// build the chained expression
|
||||
ChainedMethodExpression chainedMethodExpression = new ChainedMethodExpression();
|
||||
chainedMethodExpression.setObjectKey("a");
|
||||
chainedMethodExpression.addMethodExpression(methodExpression_1);
|
||||
chainedMethodExpression.addMethodExpression(methodExpression_2);
|
||||
|
||||
// prepare the runtime objects
|
||||
MockObject mockObject = new MockObject();
|
||||
mockObject.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
Map<String, Object> inputObjects = new HashMap<>();
|
||||
inputObjects.put("a", mockObject);
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
|
||||
// evaluate the chained expression
|
||||
Object result = chainedMethodExpression.evaluate(inputObjects, queryParameter);
|
||||
|
||||
assertEquals("testType", result);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
package li.strolch.soql.core.expression;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import li.strolch.soql.core.expresssion.ComparisonExpression;
|
||||
import li.strolch.soql.core.expresssion.ParameterReference;
|
||||
import li.strolch.soql.core.expresssion.ValueDeclaration;
|
||||
|
||||
public class ComparisonExpressionTest {
|
||||
|
||||
@Test
|
||||
public void testStringMatch() {
|
||||
|
||||
ValueDeclaration vd_1 = new ValueDeclaration();
|
||||
vd_1.valueAsString = "Wes Montgomery";
|
||||
|
||||
ValueDeclaration vd_2 = new ValueDeclaration();
|
||||
vd_2.valueAsString = "Wes Montgomery";
|
||||
|
||||
ComparisonExpression ce = new ComparisonExpression();
|
||||
ce.addOperand(vd_1);
|
||||
ce.addOperand(vd_2);
|
||||
ce.setOperator("=");
|
||||
|
||||
assertTrue(ce.evaluate(null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringNoMatch() {
|
||||
|
||||
ValueDeclaration vd_1 = new ValueDeclaration();
|
||||
vd_1.valueAsString = "Wes Montgomery";
|
||||
|
||||
ValueDeclaration vd_2 = new ValueDeclaration();
|
||||
vd_2.valueAsString = "Charlie Parker";
|
||||
|
||||
ComparisonExpression ce = new ComparisonExpression();
|
||||
ce.addOperand(vd_1);
|
||||
ce.addOperand(vd_2);
|
||||
ce.setOperator("<>");
|
||||
|
||||
assertTrue(ce.evaluate(null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumericMatch() {
|
||||
|
||||
ParameterReference vd_1 = new ParameterReference();
|
||||
vd_1.varName = "a";
|
||||
|
||||
ParameterReference vd_2 = new ParameterReference();
|
||||
vd_2.varName = "b";
|
||||
|
||||
ComparisonExpression ce = new ComparisonExpression();
|
||||
ce.addOperand(vd_1);
|
||||
ce.addOperand(vd_2);
|
||||
ce.setOperator("=");
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 123L);
|
||||
queryParameter.put("b", 123L);
|
||||
|
||||
assertTrue(ce.evaluate(null, queryParameter));
|
||||
|
||||
queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 1L);
|
||||
queryParameter.put("b", 123L);
|
||||
|
||||
assertFalse(ce.evaluate(null, queryParameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumericLess() {
|
||||
|
||||
ParameterReference vd_1 = new ParameterReference();
|
||||
vd_1.varName = "a";
|
||||
|
||||
ParameterReference vd_2 = new ParameterReference();
|
||||
vd_2.varName = "b";
|
||||
|
||||
ComparisonExpression ce = new ComparisonExpression();
|
||||
ce.addOperand(vd_1);
|
||||
ce.addOperand(vd_2);
|
||||
ce.setOperator("<");
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 1L);
|
||||
queryParameter.put("b", 123L);
|
||||
|
||||
assertTrue(ce.evaluate(null, queryParameter));
|
||||
|
||||
queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 123L);
|
||||
queryParameter.put("b", 123L);
|
||||
|
||||
assertFalse(ce.evaluate(null, queryParameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumericMore() {
|
||||
|
||||
ParameterReference vd_1 = new ParameterReference();
|
||||
vd_1.varName = "a";
|
||||
|
||||
ParameterReference vd_2 = new ParameterReference();
|
||||
vd_2.varName = "b";
|
||||
|
||||
ComparisonExpression ce = new ComparisonExpression();
|
||||
ce.addOperand(vd_1);
|
||||
ce.addOperand(vd_2);
|
||||
ce.setOperator(">");
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 123L);
|
||||
queryParameter.put("b", 1L);
|
||||
|
||||
assertTrue(ce.evaluate(null, queryParameter));
|
||||
|
||||
queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 123L);
|
||||
queryParameter.put("b", 123L);
|
||||
|
||||
assertFalse(ce.evaluate(null, queryParameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumericLessEuals() {
|
||||
|
||||
ParameterReference vd_1 = new ParameterReference();
|
||||
vd_1.varName = "a";
|
||||
|
||||
ParameterReference vd_2 = new ParameterReference();
|
||||
vd_2.varName = "b";
|
||||
|
||||
ComparisonExpression ce = new ComparisonExpression();
|
||||
ce.addOperand(vd_1);
|
||||
ce.addOperand(vd_2);
|
||||
ce.setOperator("<=");
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 1L);
|
||||
queryParameter.put("b", 123L);
|
||||
|
||||
assertTrue(ce.evaluate(null, queryParameter));
|
||||
|
||||
queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 123L);
|
||||
queryParameter.put("b", 123L);
|
||||
|
||||
assertTrue(ce.evaluate(null, queryParameter));
|
||||
|
||||
queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 123L);
|
||||
queryParameter.put("b", 1L);
|
||||
|
||||
assertFalse(ce.evaluate(null, queryParameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumericMoreEuals() {
|
||||
|
||||
ParameterReference vd_1 = new ParameterReference();
|
||||
vd_1.varName = "a";
|
||||
|
||||
ParameterReference vd_2 = new ParameterReference();
|
||||
vd_2.varName = "b";
|
||||
|
||||
ComparisonExpression ce = new ComparisonExpression();
|
||||
ce.addOperand(vd_1);
|
||||
ce.addOperand(vd_2);
|
||||
ce.setOperator(">=");
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 123L);
|
||||
queryParameter.put("b", 1L);
|
||||
|
||||
assertTrue(ce.evaluate(null, queryParameter));
|
||||
|
||||
queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 123L);
|
||||
queryParameter.put("b", 123L);
|
||||
|
||||
assertTrue(ce.evaluate(null, queryParameter));
|
||||
|
||||
queryParameter = new HashMap<>();
|
||||
queryParameter.put("a", 1L);
|
||||
queryParameter.put("b", 123L);
|
||||
|
||||
assertFalse(ce.evaluate(null, queryParameter));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package li.strolch.soql.core.expression;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import li.strolch.soql.core.MockObject;
|
||||
import li.strolch.soql.core.MockParameter;
|
||||
import li.strolch.soql.core.expresssion.MethodArgumentDeclaration;
|
||||
import li.strolch.soql.core.expresssion.MethodExpression;
|
||||
import li.strolch.soql.core.expresssion.ParameterReference;
|
||||
|
||||
public class MethodExpressionTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
String matchingKey = "testString";
|
||||
|
||||
MockObject mockObject = new MockObject();
|
||||
mockObject.putParameter(matchingKey, new MockParameter());
|
||||
|
||||
MethodExpression methodExpression = new MethodExpression();
|
||||
methodExpression.setMethodName("getParameter");
|
||||
methodExpression.setObject(mockObject);
|
||||
|
||||
ParameterReference parameterReference = new ParameterReference();
|
||||
parameterReference.varName = "param_1";
|
||||
|
||||
MethodArgumentDeclaration argument = new MethodArgumentDeclaration();
|
||||
argument.addParameterReference(parameterReference);
|
||||
|
||||
methodExpression.setMethodArguments(argument);
|
||||
|
||||
Map<String, Object> queryParameter = new HashMap<>();
|
||||
queryParameter.put("param_1", matchingKey);
|
||||
|
||||
Object result = methodExpression.evaluate(null, queryParameter);
|
||||
|
||||
assertEquals(MockParameter.class, result.getClass());
|
||||
|
||||
}
|
||||
|
||||
}
|
5
pom.xml
5
pom.xml
|
@ -197,6 +197,11 @@
|
|||
<artifactId>li.strolch.privilege</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>li.strolch</groupId>
|
||||
<artifactId>li.strolch.soql</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>li.strolch</groupId>
|
||||
|
|
Loading…
Reference in New Issue