strolch/soql/src/main/java/li/strolch/soql/core/StrolchSOQLListener.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();
}
}