use of datawave.query.collections.FunctionalSet in project datawave by NationalSecurityAgency.
the class DatawaveInterpreter method visit.
public Object visit(ASTAndNode node, Object data) {
// we could have arrived here after the node was dereferenced
if (QueryPropertyMarker.findInstance(node).isType(ExceededOrThresholdMarkerJexlNode.class)) {
return visitExceededOrThresholdMarker(node);
}
// check for the special case of a range (conjunction of a G/GE and a L/LE node) and reinterpret as a function
Object evaluation = evaluateRange(node);
if (evaluation != null) {
return evaluation;
}
FunctionalSet leftFunctionalSet = null;
FunctionalSet rightFunctionalSet = null;
Object left = node.jjtGetChild(0).jjtAccept(this, data);
if (left == null)
left = FunctionalSet.empty();
if (left instanceof Collection == false) {
try {
boolean leftValue = arithmetic.toBoolean(left);
if (!leftValue) {
return Boolean.FALSE;
}
} catch (RuntimeException xrt) {
throw new JexlException(node.jjtGetChild(0), "boolean coercion error", xrt);
}
} else {
if (leftFunctionalSet == null)
leftFunctionalSet = new FunctionalSet();
leftFunctionalSet.addAll((Collection) left);
}
Object right = node.jjtGetChild(1).jjtAccept(this, data);
if (right == null)
right = FunctionalSet.empty();
if (right instanceof Collection == false) {
try {
boolean rightValue = arithmetic.toBoolean(right);
if (!rightValue) {
return Boolean.FALSE;
}
} catch (ArithmeticException xrt) {
throw new JexlException(node.jjtGetChild(1), "boolean coercion error", xrt);
}
} else {
if (rightFunctionalSet == null)
rightFunctionalSet = new FunctionalSet();
rightFunctionalSet.addAll((Collection) right);
}
// return union of left and right iff they are both non-null & non-empty
if (leftFunctionalSet != null && rightFunctionalSet != null) {
if (!leftFunctionalSet.isEmpty() && !rightFunctionalSet.isEmpty()) {
FunctionalSet functionalSet = new FunctionalSet(leftFunctionalSet);
functionalSet.addAll(rightFunctionalSet);
return functionalSet;
} else {
return Boolean.FALSE;
}
} else {
return getBooleanAnd(left, right);
}
}
use of datawave.query.collections.FunctionalSet in project datawave by NationalSecurityAgency.
the class DatawaveInterpreter method interpretOr.
public Object interpretOr(Object left, Object right) {
FunctionalSet leftFunctionalSet = null;
FunctionalSet rightFunctionalSet = null;
if (left == null)
left = FunctionalSet.empty();
if (!(left instanceof Collection)) {
try {
boolean leftValue = arithmetic.toBoolean(left);
if (leftValue) {
return Boolean.TRUE;
}
} catch (ArithmeticException xrt) {
throw new RuntimeException(left.toString() + " boolean coercion error", xrt);
}
} else {
leftFunctionalSet = new FunctionalSet();
leftFunctionalSet.addAll((Collection) left);
}
if (right == null)
right = FunctionalSet.empty();
if (!(right instanceof Collection)) {
try {
boolean rightValue = arithmetic.toBoolean(right);
if (rightValue) {
return Boolean.TRUE;
}
} catch (ArithmeticException xrt) {
throw new RuntimeException(right.toString() + " boolean coercion error", xrt);
}
} else {
rightFunctionalSet = new FunctionalSet();
rightFunctionalSet.addAll((Collection) right);
}
// for both (all?) fields must be gathered into a single collection to be returned.
if (leftFunctionalSet != null && rightFunctionalSet != null) {
// add left and right
FunctionalSet functionalSet = new FunctionalSet(leftFunctionalSet);
functionalSet.addAll(rightFunctionalSet);
return functionalSet;
} else if (leftFunctionalSet != null) {
return leftFunctionalSet;
} else if (rightFunctionalSet != null) {
return rightFunctionalSet;
} else {
return getBooleanOr(left, right);
}
}
use of datawave.query.collections.FunctionalSet in project datawave by NationalSecurityAgency.
the class EvaluationPhaseFilterFunctions method includeRegex.
/**
* Returns a set that contains the hit term for the first field value where the regex matches against the value of the field value. If the regex string
* contains case-insensitive flags, e.g. {@code (?i).*(?-i)}, a search for a match will also be done against the normalized value of the field value.
* <p>
* Note: the regex will be compiled into a {@link Pattern} with case-insensitive and multiline matching. Additionally, a regex of {@code ".*"} still
* requires a value to be present. In other words, searching for {@code FIELD:'.*'} requires a value for {@code FIELD} to exist in the document to match.
*
* @param values
* the values to evaluate
* @param regex
* the regex
* @return a {@link FunctionalSet} with the matching hit term, or an empty set if no matches were found
*/
public static FunctionalSet<ValueTuple> includeRegex(Iterable<?> values, String regex) {
if (values != null) {
final Pattern pattern = JexlPatternCache.getPattern(regex);
final boolean caseInsensitive = regex.matches(CASE_INSENSITIVE);
// @formatter:off
return StreamSupport.stream(values.spliterator(), false).filter(Objects::nonNull).filter((value) -> isMatchForPattern(pattern, caseInsensitive, value)).findFirst().map(EvaluationPhaseFilterFunctions::getHitTerm).map(FunctionalSet::singleton).orElseGet(FunctionalSet::emptySet);
// @formatter:on
}
return FunctionalSet.emptySet();
}
use of datawave.query.collections.FunctionalSet in project datawave by NationalSecurityAgency.
the class DatawaveInterpreter method addHitsForFunction.
/**
* Add a fielded phrase to the HIT_TERM
*
* @param field
* the phrase function hit on this field
* @param node
* an ASTFunctionNode
* @param hitListArithmetic
* a JexlArithmetic that supports hit lists
*/
private void addHitsForFunction(String field, ASTFunctionNode node, HitListArithmetic hitListArithmetic) {
ColumnVisibility cv;
// aggregate individual hits for the content function
Collection<ColumnVisibility> cvs = new HashSet<>();
Attributes source = new Attributes(true);
ContentFunctionsDescriptor.ContentJexlArgumentDescriptor jexlArgDescriptor = new ContentFunctionsDescriptor().getArgumentDescriptor(node);
Set<String> values = jexlArgDescriptor.getHitTermValues();
FunctionalSet<?> set = (FunctionalSet<?>) this.context.get(field);
if (set != null) {
for (ValueTuple tuple : set) {
if (values.contains(tuple.getNormalizedValue())) {
Attribute<?> attr = tuple.getSource();
source.add(attr);
cvs.add(attr.getColumnVisibility());
}
}
}
try {
cv = MarkingFunctionsFactory.createMarkingFunctions().combine(cvs);
} catch (MarkingFunctions.Exception e) {
log.error("Failed to combine column visibilities while generating HIT_TERM for phrase function for field [" + field + "]");
log.error("msg: ", e);
return;
}
source.setColumnVisibility(cv);
// create an Attributes<?> backed ValueTuple
String phrase = jexlArgDescriptor.getHitTermValue();
ValueTuple vt = new ValueTuple(field, phrase, phrase, source);
hitListArithmetic.add(vt);
}
use of datawave.query.collections.FunctionalSet in project datawave by NationalSecurityAgency.
the class GeoWaveFunctions method getGeometryFromFieldValue.
private static Geometry getGeometryFromFieldValue(Object fieldValue) {
Geometry geometry = null;
if (fieldValue instanceof Geometry) {
geometry = (Geometry) fieldValue;
} else if (fieldValue instanceof GeoNormalizer.GeoPoint) {
geometry = geoPointToGeometry((GeoNormalizer.GeoPoint) fieldValue);
} else if (fieldValue instanceof String) {
geometry = parseGeometry((String) fieldValue);
} else if (fieldValue instanceof ValueTuple) {
ValueTuple t = (ValueTuple) fieldValue;
Object o = t.second();
if (o instanceof AbstractGeometryType) {
AbstractGeometryType<?> gt = (AbstractGeometryType<?>) o;
geometry = ((AbstractGeometry<?>) gt.getDelegate()).getJTSGeometry();
} else if (o instanceof GeoType) {
geometry = parseGeometryFromGeoType(ValueTuple.getNormalizedStringValue(fieldValue));
}
} else if (fieldValue instanceof FunctionalSet) {
FunctionalSet<?> funcSet = (FunctionalSet<?>) fieldValue;
Geometry[] geometries = funcSet.stream().map(GeoWaveFunctions::getGeometryFromFieldValue).toArray(Geometry[]::new);
geometry = new GeometryCollection(geometries, geometryFactory);
}
if (geometry == null) {
throw new IllegalArgumentException("Field Value:" + fieldValue + " cannot be recognized as a geometry");
}
return geometry;
}
Aggregations