231 lines
6.6 KiB
Java
231 lines
6.6 KiB
Java
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.*;
|
|
import li.strolch.soql.core.expresssion.*;
|
|
|
|
/**
|
|
* @author msmock
|
|
*/
|
|
public class StrolchSOQLListener 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) {
|
|
pointer = new 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) {
|
|
pointer = new 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);
|
|
}
|
|
pointer = chainedMethodExpression;
|
|
}
|
|
|
|
@Override
|
|
public void enterMethod_expression(Method_expressionContext ctx) {
|
|
MethodExpression methodExpression = new MethodExpression();
|
|
((ChainedMethodExpression) pointer).addMethodExpression(methodExpression);
|
|
pointer = methodExpression;
|
|
}
|
|
|
|
@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();
|
|
}
|
|
|
|
}
|