use of org.apache.commons.jexl2.parser.ASTMethodNode in project datawave by NationalSecurityAgency.
the class JexlNodeFactory method shallowCopy.
/**
* A shallow copy of the given JexlNode, creates a new node of the same type with the same parent and image. Children are not copied
*
* @param original
* @return
*/
public static JexlNode shallowCopy(JexlNode original) {
if (null == original) {
throw new IllegalArgumentException();
}
JexlNode copy;
Class<?> clz = original.getClass();
if (ASTAndNode.class.isAssignableFrom(clz)) {
copy = new ASTAndNode(ParserTreeConstants.JJTANDNODE);
} else if (ASTBitwiseAndNode.class.isAssignableFrom(clz)) {
copy = new ASTBitwiseAndNode(ParserTreeConstants.JJTBITWISEANDNODE);
} else if (ASTBitwiseComplNode.class.isAssignableFrom(clz)) {
copy = new ASTBitwiseComplNode(ParserTreeConstants.JJTBITWISECOMPLNODE);
} else if (ASTBitwiseOrNode.class.isAssignableFrom(clz)) {
copy = new ASTBitwiseOrNode(ParserTreeConstants.JJTBITWISEORNODE);
} else if (ASTBitwiseXorNode.class.isAssignableFrom(clz)) {
copy = new ASTBitwiseXorNode(ParserTreeConstants.JJTBITWISEXORNODE);
} else if (ASTEmptyFunction.class.isAssignableFrom(clz)) {
copy = new ASTEmptyFunction(ParserTreeConstants.JJTEMPTYFUNCTION);
} else if (ASTEQNode.class.isAssignableFrom(clz)) {
copy = new ASTEQNode(ParserTreeConstants.JJTEQNODE);
} else if (ASTERNode.class.isAssignableFrom(clz)) {
copy = new ASTERNode(ParserTreeConstants.JJTERNODE);
} else if (ASTFalseNode.class.isAssignableFrom(clz)) {
copy = new ASTFalseNode(ParserTreeConstants.JJTFALSENODE);
} else if (ASTGENode.class.isAssignableFrom(clz)) {
copy = new ASTGENode(ParserTreeConstants.JJTGENODE);
} else if (ASTGTNode.class.isAssignableFrom(clz)) {
copy = new ASTGTNode(ParserTreeConstants.JJTGTNODE);
} else if (ASTIdentifier.class.isAssignableFrom(clz)) {
copy = new ASTIdentifier(ParserTreeConstants.JJTIDENTIFIER);
} else if (ASTLENode.class.isAssignableFrom(clz)) {
copy = new ASTLENode(ParserTreeConstants.JJTLENODE);
} else if (ASTLTNode.class.isAssignableFrom(clz)) {
copy = new ASTLTNode(ParserTreeConstants.JJTLTNODE);
} else if (ASTNENode.class.isAssignableFrom(clz)) {
copy = new ASTNENode(ParserTreeConstants.JJTNENODE);
} else if (ASTNRNode.class.isAssignableFrom(clz)) {
copy = new ASTNRNode(ParserTreeConstants.JJTNRNODE);
} else if (ASTNotNode.class.isAssignableFrom(clz)) {
copy = new ASTNotNode(ParserTreeConstants.JJTNOTNODE);
} else if (ASTNullLiteral.class.isAssignableFrom(clz)) {
copy = new ASTNullLiteral(ParserTreeConstants.JJTNULLLITERAL);
} else if (ASTNumberLiteral.class.isAssignableFrom(clz)) {
copy = new ASTNumberLiteral(ParserTreeConstants.JJTNUMBERLITERAL);
JexlNodes.setLiteral((ASTNumberLiteral) copy, ((ASTNumberLiteral) original).getLiteral());
} else if (ASTOrNode.class.isAssignableFrom(clz)) {
copy = new ASTOrNode(ParserTreeConstants.JJTORNODE);
} else if (ASTStringLiteral.class.isAssignableFrom(clz)) {
copy = new ASTStringLiteral(ParserTreeConstants.JJTSTRINGLITERAL);
JexlNodes.setLiteral((ASTStringLiteral) copy, ((ASTStringLiteral) original).getLiteral());
} else if (ASTTrueNode.class.isAssignableFrom(clz)) {
copy = new ASTTrueNode(ParserTreeConstants.JJTTRUENODE);
} else if (ASTReferenceExpression.class.isAssignableFrom(clz)) {
copy = new ASTReferenceExpression(ParserTreeConstants.JJTREFERENCEEXPRESSION);
} else if (ASTReference.class.isAssignableFrom(clz)) {
copy = new ASTReference(ParserTreeConstants.JJTREFERENCE);
} else if (ASTAdditiveNode.class.isAssignableFrom(clz)) {
copy = new ASTAdditiveNode(ParserTreeConstants.JJTADDITIVENODE);
} else if (ASTMethodNode.class.isAssignableFrom(clz)) {
copy = new ASTMethodNode(ParserTreeConstants.JJTMETHODNODE);
} else if (ASTFunctionNode.class.isAssignableFrom(clz)) {
copy = new ASTFunctionNode(ParserTreeConstants.JJTFUNCTIONNODE);
} else if (ASTMulNode.class.isAssignableFrom(clz)) {
copy = new ASTMulNode(ParserTreeConstants.JJTMULNODE);
} else if (ASTAssignment.class.isAssignableFrom(clz)) {
copy = new ASTAssignment(ParserTreeConstants.JJTASSIGNMENT);
} else {
throw new UnsupportedOperationException();
}
copy.jjtSetParent(original.jjtGetParent());
copy.image = original.image;
return copy;
}
use of org.apache.commons.jexl2.parser.ASTMethodNode in project commons-jexl by apache.
the class Interpreter method visit.
@Override
protected Object visit(final ASTReference node, final Object data) {
cancelCheck(node);
final int numChildren = node.jjtGetNumChildren();
final JexlNode parent = node.jjtGetParent();
// pass first piece of data in and loop through children
Object object = null;
JexlNode objectNode = null;
JexlNode ptyNode = null;
StringBuilder ant = null;
boolean antish = !(parent instanceof ASTReference);
int v = 1;
main: for (int c = 0; c < numChildren; c++) {
objectNode = node.jjtGetChild(c);
if (objectNode instanceof ASTMethodNode) {
antish = false;
if (object == null) {
// we may be performing a method call on an antish var
if (ant != null) {
final JexlNode child = objectNode.jjtGetChild(0);
if (child instanceof ASTIdentifierAccess) {
final int alen = ant.length();
ant.append('.');
ant.append(((ASTIdentifierAccess) child).getName());
object = context.get(ant.toString());
if (object != null) {
object = visit((ASTMethodNode) objectNode, object, context);
continue;
}
// remove method name from antish
ant.delete(alen, ant.length());
ptyNode = objectNode;
}
}
break;
}
} else if (objectNode instanceof ASTArrayAccess) {
antish = false;
if (object == null) {
ptyNode = objectNode;
break;
}
}
// attempt to evaluate the property within the object (visit(ASTIdentifierAccess node))
object = objectNode.jjtAccept(this, object);
cancelCheck(node);
if (object != null) {
// disallow mixing antish variable & bean with same root; avoid ambiguity
antish = false;
} else if (antish) {
// create first from first node
if (ant == null) {
// if we still have a null object, check for an antish variable
final JexlNode first = node.jjtGetChild(0);
if (!(first instanceof ASTIdentifier)) {
// not an identifier, not antish
ptyNode = objectNode;
break main;
}
final ASTIdentifier afirst = (ASTIdentifier) first;
ant = new StringBuilder(afirst.getName());
// *... and continue
if (!options.isAntish()) {
antish = false;
continue;
}
// skip the first node case since it was trialed in jjtAccept above and returned null
if (c == 0) {
continue;
}
}
// catch up to current node
for (; v <= c; ++v) {
final JexlNode child = node.jjtGetChild(v);
if (!(child instanceof ASTIdentifierAccess)) {
// not an identifier, not antish
ptyNode = objectNode;
break main;
}
final ASTIdentifierAccess achild = (ASTIdentifierAccess) child;
if (achild.isSafe() || achild.isExpression()) {
break main;
}
ant.append('.');
ant.append(achild.getName());
}
// solve antish
object = context.get(ant.toString());
} else if (c != numChildren - 1) {
// only the last one may be null
ptyNode = objectNode;
//
break;
}
}
// dealing with null
if (object == null) {
if (ptyNode != null) {
if (ptyNode.isSafeLhs(isSafe())) {
return null;
}
if (ant != null) {
final String aname = ant.toString();
final boolean defined = isVariableDefined(frame, block, aname);
return unsolvableVariable(node, aname, !defined);
}
return unsolvableProperty(node, stringifyProperty(ptyNode), ptyNode == objectNode, null);
}
if (antish) {
if (node.isSafeLhs(isSafe())) {
return null;
}
final String aname = ant != null ? ant.toString() : "?";
final boolean defined = isVariableDefined(frame, block, aname);
// defined but null; arg of a strict operator?
if (defined && !isStrictOperand(node)) {
return null;
}
return unsolvableVariable(node, aname, !defined);
}
}
return object;
}
use of org.apache.commons.jexl2.parser.ASTMethodNode in project commons-jexl by apache.
the class Engine method getVariables.
/**
* Fills up the list of variables accessed by a node.
* @param script the owning script
* @param node the node
* @param collector the variable collector
*/
protected void getVariables(final ASTJexlScript script, final JexlNode node, final VarCollector collector) {
if (node instanceof ASTIdentifier) {
final JexlNode parent = node.jjtGetParent();
if (parent instanceof ASTMethodNode || parent instanceof ASTFunctionNode) {
// skip identifiers for methods and functions
collector.collect(null);
return;
}
final ASTIdentifier identifier = (ASTIdentifier) node;
final int symbol = identifier.getSymbol();
// symbols that are captured are considered "global" variables
if (symbol >= 0 && script != null && !script.isCapturedSymbol(symbol)) {
collector.collect(null);
} else {
// start collecting from identifier
collector.collect(identifier);
collector.add(identifier.getName());
}
} else if (node instanceof ASTIdentifierAccess) {
final JexlNode parent = node.jjtGetParent();
if (parent instanceof ASTMethodNode || parent instanceof ASTFunctionNode) {
// skip identifiers for methods and functions
collector.collect(null);
return;
}
// belt and suspender since an identifier should have been seen first
if (collector.isCollecting()) {
collector.add(((ASTIdentifierAccess) node).getName());
}
} else if (node instanceof ASTArrayAccess && collector.mode > 0) {
final int num = node.jjtGetNumChildren();
// collect only if array access is const and follows an identifier
boolean collecting = collector.isCollecting();
for (int i = 0; i < num; ++i) {
final JexlNode child = node.jjtGetChild(i);
if (collecting && child.isConstant()) {
// collect all constants or only string and number literals
final boolean collect = collector.mode > 1 || (child instanceof ASTStringLiteral || child instanceof ASTNumberLiteral);
if (collect) {
final String image = child.toString();
collector.add(image);
}
} else {
collecting = false;
collector.collect(null);
getVariables(script, child, collector);
collector.collect(null);
}
}
} else {
final int num = node.jjtGetNumChildren();
for (int i = 0; i < num; ++i) {
getVariables(script, node.jjtGetChild(i), collector);
}
collector.collect(null);
}
}
use of org.apache.commons.jexl2.parser.ASTMethodNode in project datawave by NationalSecurityAgency.
the class JexlStringBuildingVisitor method visit.
@Override
public Object visit(ASTMethodNode node, Object data) {
StringBuilder sb = (StringBuilder) data;
StringBuilder methodStringBuilder = new StringBuilder();
StringBuilder argumentStringBuilder = new StringBuilder();
int kidCount = node.jjtGetNumChildren();
for (int i = 0; i < kidCount; i++) {
if (i == 0) {
JexlNode methodNode = node.jjtGetChild(i);
methodStringBuilder.append(".");
if (allowedMethods.contains(methodNode.image) == false) {
QueryException qe = new QueryException(DatawaveErrorCode.METHOD_COMPOSITION_ERROR, MessageFormat.format("{0}", methodNode.image));
throw new DatawaveFatalQueryException(qe);
}
methodStringBuilder.append(methodNode.image);
// parens are open. don't forget to close
methodStringBuilder.append("(");
} else {
// adding any method arguments
JexlNode argumentNode = node.jjtGetChild(i);
if (argumentNode instanceof ASTReference) {
// a method may have an argument that is another method. In this case, descend the visit tree for it
if (JexlASTHelper.HasMethodVisitor.hasMethod(argumentNode)) {
this.visit((ASTReference) argumentNode, argumentStringBuilder);
} else {
for (int j = 0; j < argumentNode.jjtGetNumChildren(); j++) {
JexlNode argKid = argumentNode.jjtGetChild(j);
if (argKid instanceof ASTFunctionNode) {
this.visit((ASTFunctionNode) argKid, argumentStringBuilder);
} else {
if (argumentStringBuilder.length() > 0) {
argumentStringBuilder.append(",");
}
if (argKid instanceof ASTStringLiteral) {
argumentStringBuilder.append("'");
}
argumentStringBuilder.append(argKid.image);
if (argKid instanceof ASTStringLiteral) {
argumentStringBuilder.append("'");
}
}
}
}
} else if (argumentNode instanceof ASTNumberLiteral) {
if (argumentStringBuilder.length() > 0) {
argumentStringBuilder.append(",");
}
argumentStringBuilder.append(argumentNode.image);
}
}
}
methodStringBuilder.append(argumentStringBuilder);
// close parens in method
methodStringBuilder.append(")");
sb.append(methodStringBuilder);
return sb;
}
use of org.apache.commons.jexl2.parser.ASTMethodNode in project datawave by NationalSecurityAgency.
the class DatawaveInterpreter method hasSiblings.
/**
* a function node that has siblings has a method paired with it, like the size method in includeRegex(foo,bar).size() It must return its collection of
* results for the other method to use, instead of a boolean indicating that there were results
*
* @param node
* @return
*/
private boolean hasSiblings(ASTFunctionNode node) {
JexlNode parent = node.jjtGetParent();
if (parent.jjtGetNumChildren() > 1) {
return true;
}
JexlNode grandparent = parent.jjtGetParent();
if (grandparent instanceof ASTMethodNode) {
return true;
}
return false;
}
Aggregations