use of org.apache.commons.jexl2.parser.ASTNullLiteral in project datawave by NationalSecurityAgency.
the class IsNotNullIntentVisitor method visit.
@Override
public Object visit(ASTERNode node, Object data) {
// If the ER node is meant to match any string, it can be replaced with FIELD != null.
Object value = JexlASTHelper.getLiteralValue(node);
if (".*?".equals(value)) {
ASTNENode neNode = new ASTNENode(ParserTreeConstants.JJTNENODE);
neNode.jjtAddChild(node.jjtGetChild(0), 0);
neNode.jjtAddChild(new ASTNullLiteral(ParserTreeConstants.JJTNULLLITERAL), 1);
return super.visit(neNode, data);
}
return super.visit(node, data);
}
use of org.apache.commons.jexl2.parser.ASTNullLiteral in project datawave by NationalSecurityAgency.
the class QueryModelVisitor method expandBinaryNodeFromModel.
/**
* Applies the forward mapping from the QueryModel to a node, expanding the node into an Or if needed.
*
* @param node
* @param data
* @return
*/
protected JexlNode expandBinaryNodeFromModel(JexlNode node, Object data) {
String field = JexlASTHelper.getIdentifier(node);
if (isFieldExcluded(field)) {
return node;
}
// Count the immediate children:
int childCount = node.jjtGetNumChildren();
if (childCount != 2) {
QueryException qe = new QueryException(DatawaveErrorCode.BINARY_NODE_TOO_MANY_CHILDREN, MessageFormat.format("Node: {0}", PrintingVisitor.formattedQueryString(node)));
throw new DatawaveFatalQueryException(qe);
}
// Find identifiers
List<ASTIdentifier> allidentifiers = JexlASTHelper.getIdentifiers(node);
// If we don't have any identifiers, we have nothing to expand
if (allidentifiers.isEmpty()) {
return node;
}
JexlNode leftNode = node.jjtGetChild(0);
JexlNode rightNode = node.jjtGetChild(1);
if (log.isTraceEnabled()) {
log.trace("leftNode:" + PrintingVisitor.formattedQueryString(leftNode));
log.trace("leftNodeQuery:" + JexlStringBuildingVisitor.buildQuery(leftNode));
log.trace("rightNode:" + PrintingVisitor.formattedQueryString(rightNode));
log.trace("rightNodeQuery:" + JexlStringBuildingVisitor.buildQuery(rightNode));
}
// this will expand identifiers that have a method connected to them
boolean leftState = JexlASTHelper.HasMethodVisitor.hasMethod(leftNode);
if (leftState) {
// there is a method under leftNode
leftNode = (JexlNode) leftNode.jjtAccept(this.simpleQueryModelVisitor, null);
}
boolean rightState = JexlASTHelper.HasMethodVisitor.hasMethod(rightNode);
if (rightState) {
// there is a method under rightNode
rightNode = (JexlNode) rightNode.jjtAccept(this.simpleQueryModelVisitor, null);
}
// expand any identifiers inside of methods/functions in the left and right nodes
leftNode = (JexlNode) leftNode.jjtAccept(this, null);
rightNode = (JexlNode) rightNode.jjtAccept(this, null);
if (log.isTraceEnabled()) {
log.trace("after expansion, leftNode:" + PrintingVisitor.formattedQueryString(leftNode));
log.trace("after expansion, leftNodeQuery:" + JexlStringBuildingVisitor.buildQuery(leftNode));
log.trace("after expansion, rightNode:" + PrintingVisitor.formattedQueryString(rightNode));
log.trace("after expansion, rightNodeQuery:" + JexlStringBuildingVisitor.buildQuery(rightNode));
}
// if state == true on either side, then there is a method on one side and we are done applying the model
if (leftState || rightState) {
JexlNode toReturn = JexlNodeFactory.buildUntypedBinaryNode(node, leftNode, rightNode);
if (log.isTraceEnabled()) {
log.trace("done early. returning:" + JexlStringBuildingVisitor.buildQuery(toReturn));
}
return toReturn;
}
JexlNode leftSeed, rightSeed;
Set<JexlNode> left = Sets.newHashSet(), right = Sets.newHashSet();
boolean isNullEquality = false;
if (node instanceof ASTEQNode && (leftNode instanceof ASTNullLiteral || rightNode instanceof ASTNullLiteral)) {
isNullEquality = true;
}
// the query has been previously groomed so that identifiers are on the left and literals are on the right
// an identifier with a method attached will have already been substituted above (and will return null for the IdentifierOpLiteral)
// The normal case of `IDENTIFIER op 'literal'`
JexlASTHelper.IdentifierOpLiteral op = JexlASTHelper.getIdentifierOpLiteral(node);
if (op != null) {
// One identifier
leftSeed = op.getIdentifier();
rightSeed = op.getLiteral();
if (rightSeed instanceof ASTNullLiteral && node instanceof ASTEQNode) {
isNullEquality = true;
}
} else {
// We know from above that childCount == 2. We may have a reference on both sides of the expression
leftSeed = node.jjtGetChild(0);
rightSeed = node.jjtGetChild(1);
}
if (leftSeed instanceof ASTReference) {
// String fieldName = JexlASTHelper.getIdentifier((JexlNode)leftSeed);
List<ASTIdentifier> identifiers = JexlASTHelper.getIdentifiers(leftSeed);
if (identifiers.size() > 1) {
log.warn("I did not expect to see more than one Identifier here for " + JexlStringBuildingVisitor.buildQuery(leftSeed) + " from " + JexlStringBuildingVisitor.buildQuery(leftNode));
}
for (ASTIdentifier identifier : identifiers) {
for (String fieldName : getAliasesForField(JexlASTHelper.deconstructIdentifier(identifier))) {
left.add(JexlNodeFactory.buildIdentifier(fieldName));
}
}
} else if (leftSeed instanceof ASTIdentifier) {
for (String fieldName : getAliasesForField(JexlASTHelper.deconstructIdentifier((ASTIdentifier) leftSeed))) {
left.add(JexlNodeFactory.buildIdentifier(fieldName));
}
} else {
// Not an identifier, therefore it's probably a literal
left.add(leftSeed);
}
if (rightSeed instanceof ASTReference) {
List<ASTIdentifier> identifiers = JexlASTHelper.getIdentifiers(rightSeed);
if (identifiers.size() > 1) {
log.warn("I did not expect to see more than one Identifier here for " + JexlStringBuildingVisitor.buildQuery(rightSeed) + " from " + JexlStringBuildingVisitor.buildQuery(rightNode));
}
for (ASTIdentifier identifier : identifiers) {
for (String fieldName : getAliasesForField(JexlASTHelper.deconstructIdentifier(identifier))) {
right.add(JexlNodeFactory.buildIdentifier(fieldName));
}
}
} else if (rightSeed instanceof ASTIdentifier) {
for (String fieldName : getAliasesForField(JexlASTHelper.deconstructIdentifier((ASTIdentifier) rightSeed))) {
right.add(JexlNodeFactory.buildIdentifier(fieldName));
}
} else {
// Not an identifier, therefore it's probably a literal
right.add(rightSeed);
}
boolean requiresAnd = isNullEquality || node instanceof ASTNENode;
@SuppressWarnings("unchecked") Set<List<JexlNode>> // retrieve the cartesian product
product = Sets.cartesianProduct(left, right);
/**
* use the product transformer to shallow copy the jexl nodes. We've created new nodes that will be embedded within an ast reference. As a result, we
* need to ensure that if we create a logical structure ( such as an or ) -- each literal references a unique identifier from the right. Otherwise,
* subsequent visitors will reference incorrection sub trees, and potentially negate the activity of the query model visitor
*/
Set<List<JexlNode>> newSet = product.stream().map(list -> list.stream().map(RebuildingVisitor::copy).collect(Collectors.toList())).collect(Collectors.toSet());
if (product.size() > 1) {
JexlNode expanded;
if (requiresAnd) {
expanded = JexlNodeFactory.createNodeTreeFromPairs(ContainerType.AND_NODE, node, newSet);
} else {
expanded = JexlNodeFactory.createNodeTreeFromPairs(ContainerType.OR_NODE, node, newSet);
}
if (log.isTraceEnabled())
log.trace("expanded:" + PrintingVisitor.formattedQueryString(expanded));
return expanded;
} else if (1 == product.size()) {
List<JexlNode> pair = product.iterator().next();
JexlNode expanded = JexlNodeFactory.buildUntypedBinaryNode(node, pair.get(0), pair.get(1));
if (log.isTraceEnabled())
log.trace("expanded:" + PrintingVisitor.formattedQueryString(expanded));
return expanded;
}
// If we couldn't map anything, return a copy
if (log.isTraceEnabled())
log.trace("just returning the original:" + PrintingVisitor.formattedQueryString(node));
return node;
}
use of org.apache.commons.jexl2.parser.ASTNullLiteral in project datawave by NationalSecurityAgency.
the class RegexFunctionVisitor method visit.
@Override
public Object visit(ASTFunctionNode node, Object data) {
JexlNode returnNode = copy(node);
FunctionJexlNodeVisitor functionMetadata = new FunctionJexlNodeVisitor();
node.jjtAccept(functionMetadata, null);
if (functionMetadata.name().equals("includeRegex") || functionMetadata.name().equals("excludeRegex")) {
List<JexlNode> arguments = functionMetadata.args();
JexlNode node0 = arguments.get(0);
if (node0 instanceof ASTIdentifier) {
JexlNode regexNode = buildRegexNode((ASTIdentifier) node0, functionMetadata.name(), arguments.get(1).image);
if (regexNode != null) {
returnNode = regexNode;
}
} else {
JexlNode newParent;
if (functionMetadata.name().equals("excludeRegex")) {
newParent = new ASTAndNode(ParserTreeConstants.JJTANDNODE);
} else {
// it is likely an 'or' node...
newParent = JexlNodeFactory.shallowCopy(node0);
}
for (int i = 0; i < node0.jjtGetNumChildren(); i++) {
JexlNode child = node0.jjtGetChild(i);
if (child instanceof ASTIdentifier) {
this.adopt(newParent, buildRegexNode((ASTIdentifier) child, functionMetadata.name(), arguments.get(1).image));
} else {
// probably a Reference
for (int j = 0; j < child.jjtGetNumChildren(); j++) {
JexlNode maybeIdentifier = child.jjtGetChild(j);
if (maybeIdentifier instanceof ASTIdentifier) {
this.adopt(newParent, buildRegexNode((ASTIdentifier) maybeIdentifier, functionMetadata.name(), arguments.get(1).image));
}
}
}
}
if (newParent.jjtGetNumChildren() == node0.jjtGetNumChildren() && newParent.jjtGetNumChildren() != 0) {
returnNode = newParent;
}
}
} else if (functionMetadata.name().equals("isNull")) {
List<JexlNode> arguments = functionMetadata.args();
JexlNode node0 = arguments.get(0);
if (node0 instanceof ASTIdentifier) {
returnNode = JexlNodeFactory.buildNode(new ASTEQNode(ParserTreeConstants.JJTEQNODE), node0.image, new ASTNullLiteral(ParserTreeConstants.JJTNULLLITERAL));
}
} else if (functionMetadata.name().equals("isNotNull")) {
List<JexlNode> arguments = functionMetadata.args();
JexlNode node0 = arguments.get(0);
if (node0 instanceof ASTIdentifier) {
returnNode = JexlNodeFactory.buildNode(new ASTNENode(ParserTreeConstants.JJTNENODE), node0.image, new ASTNullLiteral(ParserTreeConstants.JJTNULLLITERAL));
}
}
return returnNode;
}
use of org.apache.commons.jexl2.parser.ASTNullLiteral in project datawave by NationalSecurityAgency.
the class JexlASTHelper method getLiteralValue.
/**
* Fetch the literal off of the grandchild. Throws an exception if there is no literal
*
* @param node
* @return
* @throws NoSuchElementException
*/
@SuppressWarnings("rawtypes")
public static Object getLiteralValue(JexlNode node) throws NoSuchElementException {
Object literal = getLiteral(node);
// If the grandchild and its image is non-null and equal to the any-field identifier
if (literal instanceof JexlNode.Literal) {
return ((JexlNode.Literal) literal).getLiteral();
} else if (literal instanceof ASTTrueNode) {
return true;
} else if (literal instanceof ASTFalseNode) {
return false;
} else if (literal instanceof ASTNullLiteral) {
return null;
}
NotFoundQueryException qe = new NotFoundQueryException(DatawaveErrorCode.LITERAL_MISSING);
throw (NoSuchElementException) (new NoSuchElementException().initCause(qe));
}
use of org.apache.commons.jexl2.parser.ASTNullLiteral 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;
}
Aggregations