for (;;)
{
if (p.parseString("="))
{
processAdditiveExpression();
Node right = stack.pop();
Node left = stack.pop();
if (right.getNodeType() == NodeType.TYPE)
{
// Convert TYPE into "instanceof"
Node primNode = right.getFirstChild();
Node expr = new Node(NodeType.OPERATOR, "instanceof");
expr.appendChildNode(primNode);
expr.appendChildNode(left);
stack.push(expr);
}
else if (left.getNodeType() == NodeType.TYPE)
{
// Convert TYPE into "instanceof"
Node primNode = left.getFirstChild();
Node expr = new Node(NodeType.OPERATOR, "instanceof");
expr.appendChildNode(primNode);
expr.appendChildNode(right);
stack.push(expr);
}
else
{
Node expr = new Node(NodeType.OPERATOR, "==");
expr.insertChildNode(right);
expr.insertChildNode(left);
stack.push(expr);
}
}
else if (p.parseString("<>"))
{
processAdditiveExpression();
Node right = stack.pop();
Node left = stack.pop();
if (right.getNodeType() == NodeType.TYPE)
{
// Convert TYPE into "instanceof"
Node primNode = right.getFirstChild();
Node expr = new Node(NodeType.OPERATOR, "instanceof");
expr.appendChildNode(primNode);
expr.appendChildNode(left);
Node notNode = new Node(NodeType.OPERATOR, "!");
notNode.appendChildNode(expr);
stack.push(notNode);
}
else if (left.getNodeType() == NodeType.TYPE)
{
// Convert TYPE into "instanceof"
Node primNode = left.getFirstChild();
Node expr = new Node(NodeType.OPERATOR, "instanceof");
expr.appendChildNode(primNode);
expr.appendChildNode(right);
Node notNode = new Node(NodeType.OPERATOR, "!");
notNode.appendChildNode(expr);
stack.push(notNode);
}
else
{
Node expr = new Node(NodeType.OPERATOR, "!=");
expr.insertChildNode(right);
expr.insertChildNode(left);
stack.push(expr);
}
}
else if (p.parseStringIgnoreCase("NOT "))
{
if (p.parseStringIgnoreCase("BETWEEN "))
{
// {expression} NOT BETWEEN {lower} AND {upper}
Node inputNode = stack.pop();
processAdditiveExpression();
Node lowerNode = stack.pop();
if (p.parseStringIgnoreCase("AND "))
{
processAdditiveExpression();
Node upperNode = stack.pop();
Node leftNode = new Node(NodeType.OPERATOR, "<");
leftNode.appendChildNode(inputNode);
leftNode.appendChildNode(lowerNode);
Node rightNode = new Node(NodeType.OPERATOR, ">");
rightNode.appendChildNode(inputNode);
rightNode.appendChildNode(upperNode);
Node betweenNode = new Node(NodeType.OPERATOR, "||");
betweenNode.appendChildNode(leftNode);
betweenNode.appendChildNode(rightNode);
stack.push(betweenNode);
}
else
{
throw new NucleusUserException("Query has BETWEEN keyword with no AND clause");
}
}
else if (p.parseStringIgnoreCase("LIKE "))
{
processLikeExpression();
Node notNode = new Node(NodeType.OPERATOR, "!");
notNode.insertChildNode(stack.pop());
stack.push(notNode);
}
else if (p.parseStringIgnoreCase("IN"))
{
// {expression} NOT IN (expr1 [,expr2[,expr3]])
processInExpression(true);
}
else if (p.parseStringIgnoreCase("MEMBER "))
{
processMemberExpression(true);
}
else
{
throw new NucleusException("Unsupported query syntax NOT followed by unsupported keyword");
}
}
else if (p.parseStringIgnoreCase("BETWEEN "))
{
// {expression} BETWEEN {lower} AND {upper}
Node inputNode = stack.pop();
processAdditiveExpression();
Node lowerNode = stack.pop();
if (p.parseStringIgnoreCase("AND "))
{
processAdditiveExpression();
Node upperNode = stack.pop();
Node leftNode = new Node(NodeType.OPERATOR, ">=");
leftNode.appendChildNode(inputNode);
leftNode.appendChildNode(lowerNode);
Node rightNode = new Node(NodeType.OPERATOR, "<=");
rightNode.appendChildNode(inputNode);
rightNode.appendChildNode(upperNode);
Node betweenNode = new Node(NodeType.OPERATOR, "&&");
betweenNode.appendChildNode(rightNode);
betweenNode.appendChildNode(leftNode);
stack.push(betweenNode);
}
else
{
throw new NucleusUserException("Query has BETWEEN keyword with no AND clause");
}
}
else if (p.parseStringIgnoreCase("LIKE "))
{
// {expression} LIKE {pattern_value} [ESCAPE {escape_char}]
processLikeExpression();
}
else if (p.parseStringIgnoreCase("IN"))
{
// {expression} IN (expr1 [,expr2[,expr3]])
processInExpression(false);
}
else if (p.parseStringIgnoreCase("MEMBER "))
{
processMemberExpression(false);
}
else if (p.parseStringIgnoreCase("IS "))
{
// {expression} IS [NOT] [NULL | EMPTY]
Node inputNode = stack.pop();
Node inputRootNode = inputNode;
if (inputNode.getNodeType() == NodeType.IDENTIFIER)
{
// Find the end of the identifier chain
while (inputNode.getFirstChild() != null)
{
inputNode = inputNode.getFirstChild();
}
}
boolean not = false;
if (p.parseStringIgnoreCase("NOT "))
{
not = true;
}
if (p.parseStringIgnoreCase("NULL"))
{
Node isNode = new Node(NodeType.OPERATOR, (not ? "!=" : "=="));
Node compareNode = new Node(NodeType.LITERAL, null);
isNode.insertChildNode(compareNode);
isNode.insertChildNode(inputRootNode);
stack.push(isNode);
}
else if (p.parseStringIgnoreCase("EMPTY"))
{
// Convert IS EMPTY to a method call of "size()==0" on collection/map
Node sizeNode = new Node(NodeType.INVOKE, "size");
inputNode.insertChildNode(sizeNode);
Node isEmptyNode = new Node(NodeType.OPERATOR, not ? "!=" : "==");
isEmptyNode.appendChildNode(inputNode);
Node zeroNode = new Node(NodeType.LITERAL, 0);
isEmptyNode.appendChildNode(zeroNode);
stack.push(isEmptyNode);
}
else
{
throw new NucleusException("Encountered IS " + (not ? "NOT " : " ") +
" that should be followed by NULL | EMPTY but isnt");
}
}
else if (p.parseString("<="))
{
processAdditiveExpression();
Node expr = new Node(NodeType.OPERATOR, "<=");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else if (p.parseString(">="))
{
processAdditiveExpression();
Node expr = new Node(NodeType.OPERATOR, ">=");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else if (p.parseChar('<'))
{
processAdditiveExpression();
Node expr = new Node(NodeType.OPERATOR, "<");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else if (p.parseChar('>'))
{
processAdditiveExpression();
Node expr = new Node(NodeType.OPERATOR, ">");
expr.insertChildNode(stack.pop());
expr.insertChildNode(stack.pop());
stack.push(expr);
}
else
{
break;