package com.alvazan.orm.parser.antlr; import java.util.List; import org.antlr.runtime.tree.CommonTree; public class ExpressionNode implements ParsedNode { /** * In the case where one has a query of where x.size > 5 and x.size < 10, and if this is the x.size > 5 node, we add the x.size < 10 node * to this node so we can do range queries for an optimization to narrow the search down. */ private ExpressionNode leftChild; private ExpressionNode rightChild; private List<ParsedNode> childernForIn; private CommonTree commonNode; private Object state; private String textInSql; private ExpressionNode parent; private JoinMeta joinMeta; private int type; public ExpressionNode(CommonTree expression) { this.type = expression.getType(); this.commonNode = expression; } public ExpressionNode(int nodeType) { this.type = nodeType; } public boolean isBetweenExpression() { return type == NoSqlLexer.BETWEEN; } public boolean isInExpression() { return type == NoSqlLexer.IN; } public int getType() { return type; } public CommonTree getASTNode() { return commonNode; } private void setParent(ExpressionNode p) { this.parent = p; } public void setChild(ChildSide side, ParsedNode child2) { ExpressionNode child = (ExpressionNode) child2; if(side == ChildSide.LEFT) { leftChild = child; } else { rightChild = child; } child.setParent(this); } public void setState(Object state, String textInSql) { this.state = state; this.textInSql = textInSql; } @Override public String getAliasAndColumn() { if(!(state instanceof StateAttribute)) return null; StateAttribute attr = (StateAttribute) state; return attr.getTextInSql(); } public Object getState() { return state; } public String getExpressionAsString(boolean isCalledFromFirstIfBlock) { if(isBetweenExpression() || isBetweenExpression()) { ExpressionNode greaterThan = getGreaterThan(); ExpressionNode lessThan = getLessThan(); if(greaterThan == null || lessThan == null) return "(between not filled in yet)"; //This one is a bit tough, as we can't toString on ONE of the two greaterThanExpression or lessThanExpression as that would be OURSELF and //we woudl infinitely recurse into the getExpressionAsString function :( String greaterThanSign = " < "; if(greaterThan.getType() == NoSqlLexer.GE) greaterThanSign = " <= "; String lessThanSign = " < "; if(lessThan.getType() == NoSqlLexer.LE) lessThanSign = " <= "; ExpressionNode greaterThanLeftCol = greaterThan.getChild(ChildSide.LEFT); ExpressionNode greaterThanRightVar = greaterThan.getChild(ChildSide.RIGHT); ExpressionNode lessThanRightVar = lessThan.getChild(ChildSide.RIGHT); String line = greaterThanRightVar+greaterThanSign+greaterThanLeftCol+lessThanSign+lessThanRightVar; return line; } else if(leftChild != null && rightChild != null) { String joinType = fetchJoinType(); String msg = leftChild.getExpressionAsString(false)+" "+this.commonNode+joinType+" "+rightChild.getExpressionAsString(false); if(getType() == NoSqlLexer.AND || getType() == NoSqlLexer.OR) return "("+msg+")"; return msg; } return textInSql; } private String fetchJoinType() { if(joinMeta != null) { if(joinMeta.getJoinType() == JoinType.INNER) return "(innerjoin)"; else if(joinMeta.getJoinType() == JoinType.LEFT_OUTER) return "(leftjoin)"; } return ""; } @Override public String toString() { return getExpressionAsString(false); } public ExpressionNode getParent() { return parent; } public ExpressionNode getChild(ChildSide side) { if(side == ChildSide.RIGHT) return rightChild; return leftChild; } public ExpressionNode getGreaterThan() { return leftChild; } public ExpressionNode getLessThan() { return rightChild; } @Override public ViewInfoImpl getViewInfo() { if(!(state instanceof StateAttribute)) throw new IllegalStateException("This node is of the wrong type="+this.commonNode.getType()); StateAttribute attr = (StateAttribute) state; return attr.getViewInfo(); } @Override public boolean isAndOrType() { if(commonNode == null) return false; if(commonNode.getType() == NoSqlLexer.AND || commonNode.getType() == NoSqlLexer.OR) return true; return false; } @Override public void setJoinMeta(JoinMeta meta) { this.joinMeta = meta; } @Override public JoinMeta getJoinMeta() { return joinMeta; } @Override public boolean isConstant() { if(getType() == NoSqlLexer.DEC_VAL || getType() == NoSqlLexer.INT_VAL || getType() == NoSqlLexer.STR_VAL || getType() == NoSqlLexer.BOOL_VAL || getType() == NoSqlLexer.NULL) return true; return false; } @Override public boolean isParameter() { if(getType() == NoSqlLexer.PARAMETER_NAME) return true; return false; } @Override public void replace(ParsedNode oldChild, ParsedNode newChild) { if(oldChild == leftChild) { setChild(ChildSide.LEFT, newChild); } else if(oldChild == rightChild) { setChild(ChildSide.RIGHT, newChild); } else throw new IllegalArgumentException("bug, hmmm, oldChild was not a child of this node, what the?"); } @Override public ParsedNode getOppositeChild(ParsedNode child) { if(child == leftChild) return rightChild; else if(child == rightChild) return leftChild; throw new IllegalStateException("bug, should never end up here"); } public List<ParsedNode> getChildrenForIn() { return childernForIn; } public void setChildrenForIn(List<ParsedNode> listOfNode) { childernForIn = listOfNode; } }