use of org.javarosa.xpath.expr.XPathExpression in project javarosa by opendatakit.
the class TreeReference method hashCode.
public int hashCode() {
int hash = (Integer.valueOf(refLevel)).hashCode();
for (int i = 0; i < size(); i++) {
// NOTE(ctsims): It looks like this is only using Integer to
// get the hashcode method, but that method
// is just returning the int value, I think, so
// this should potentially just be replaced by
// an int.
Integer mult = DataUtil.integer(getMultiplicity(i));
if (i == 0 && mult.intValue() == INDEX_UNBOUND)
mult = DataUtil.integer(0);
hash ^= getName(i).hashCode();
hash ^= mult.hashCode();
List<XPathExpression> predicates = this.getPredicate(i);
if (predicates == null) {
continue;
}
int val = 0;
for (XPathExpression xpe : predicates) {
hash ^= val;
hash ^= xpe.hashCode();
++val;
}
}
return hash;
}
use of org.javarosa.xpath.expr.XPathExpression in project javarosa by opendatakit.
the class XPathEvalTest method testEval.
private void testEval(String expr, FormInstance model, EvaluationContext ec, Object expected) {
XPathExpression xpe = null;
boolean exceptionExpected = (expected instanceof XPathException);
if (ec == null) {
ec = new EvaluationContext(model);
}
try {
xpe = XPathParseTool.parseXPath(expr);
} catch (XPathSyntaxException xpse) {
System.out.println("Parsing " + expr + " failed with " + xpse.toString());
}
if (xpe == null) {
fail("Null expression or syntax error");
}
try {
Object result = xpe.eval(model, ec);
if (exceptionExpected) {
fail("Expected exception, expression : " + expr);
} else if ((result instanceof Double && expected instanceof Double)) {
if (!expected.equals(result)) {
System.out.println(String.format("%s result %s differed from expected %s", expr, result, expected));
}
assertEquals((Double) expected, (Double) result, 1e-12);
} else if (result instanceof XPathNodeset && expected instanceof XPathNodeset) {
XPathNodeset expectedAsXPathNodeset = (XPathNodeset) expected;
XPathNodeset resultAsXPathNodeset = (XPathNodeset) result;
assertEquals(expectedAsXPathNodeset.size(), resultAsXPathNodeset.size());
assertEquals(expectedAsXPathNodeset.getRefAt(0), resultAsXPathNodeset.getRefAt(0));
assertEquals(expectedAsXPathNodeset.unpack(), resultAsXPathNodeset.unpack());
assertEquals(expectedAsXPathNodeset.toArgList().length, resultAsXPathNodeset.toArgList().length);
for (int i = 0; i < expectedAsXPathNodeset.toArgList().length; i++) {
assertEquals(expectedAsXPathNodeset.toArgList()[i], resultAsXPathNodeset.toArgList()[i]);
}
} else {
assertEquals(expected, result);
}
} catch (XPathException xpex) {
if (!exceptionExpected) {
fail("Unexpected exception: " + xpex);
} else if (xpex.getClass() != expected.getClass()) {
fail("Did not get expected exception type");
}
}
}
use of org.javarosa.xpath.expr.XPathExpression in project javarosa by opendatakit.
the class XPathConditional method getTriggers.
private static void getTriggers(XPathExpression x, Set<TreeReference> v, TreeReference contextRef) {
if (x instanceof XPathPathExpr) {
TreeReference ref = ((XPathPathExpr) x).getReference();
TreeReference contextualized = ref;
if (contextRef != null) {
contextualized = ref.contextualize(contextRef);
}
// TODO: It's possible we should just handle this the same way as "genericize". Not entirely clear.
if (contextualized.hasPredicates()) {
contextualized = contextualized.removePredicates();
}
v.add(contextualized);
for (int i = 0; i < ref.size(); i++) {
List<XPathExpression> predicates = ref.getPredicate(i);
if (predicates == null) {
continue;
}
// we can't generate this properly without an absolute reference
if (!ref.isAbsolute()) {
throw new IllegalArgumentException("can't get triggers for relative references");
}
TreeReference predicateContext = ref.getSubReference(i);
for (XPathExpression predicate : predicates) {
getTriggers(predicate, v, predicateContext);
}
}
} else if (x instanceof XPathBinaryOpExpr) {
getTriggers(((XPathBinaryOpExpr) x).a, v, contextRef);
getTriggers(((XPathBinaryOpExpr) x).b, v, contextRef);
} else if (x instanceof XPathUnaryOpExpr) {
getTriggers(((XPathUnaryOpExpr) x).a, v, contextRef);
} else if (x instanceof XPathFuncExpr) {
XPathFuncExpr fx = (XPathFuncExpr) x;
for (int i = 0; i < fx.args.length; i++) getTriggers(fx.args[i], v, contextRef);
}
}
use of org.javarosa.xpath.expr.XPathExpression in project javarosa by opendatakit.
the class EvaluationContext method expandReferenceAccumulator.
/**
* Recursively performs the search for all repeated nodes that match the pattern of the 'ref' argument.
*
* @param sourceRef original path we're matching against
* @param sourceInstance original node obtained from sourceRef
* @param workingRef explicit path that refers to the current node
* @param refs accumulator List to collect matching paths.
*/
private void expandReferenceAccumulator(TreeReference sourceRef, DataInstance sourceInstance, TreeReference workingRef, List<TreeReference> refs, boolean includeTemplates) {
final int depth = workingRef.size();
// check to see if we've matched fully
if (depth == sourceRef.size()) {
// TODO: Do we need to clone these references?
refs.add(workingRef);
return;
}
// Get the next set of matching references
final String name = sourceRef.getName(depth);
List<XPathExpression> predicates = sourceRef.getPredicate(depth);
// Copy predicates for batch fetch
if (predicates != null) {
List<XPathExpression> predCopy = new ArrayList<XPathExpression>(predicates.size());
for (XPathExpression xpe : predicates) {
predCopy.add(xpe);
}
predicates = predCopy;
}
// ETHERTON: Is this where we should test for predicates?
final int mult = sourceRef.getMultiplicity(depth);
final List<TreeReference> treeReferences = new ArrayList<>(1);
final AbstractTreeElement node = sourceInstance.resolveReference(workingRef);
if (node.getNumChildren() > 0) {
if (mult == TreeReference.INDEX_UNBOUND) {
final List<TreeElement> childrenWithName = node.getChildrenWithName(name);
final int count = childrenWithName.size();
for (int i = 0; i < count; i++) {
TreeElement child = childrenWithName.get(i);
if (child.getMultiplicity() != i) {
throw new IllegalStateException("Unexpected multiplicity mismatch");
}
treeReferences.add(child.getRef());
}
if (includeTemplates) {
AbstractTreeElement template = node.getChild(name, TreeReference.INDEX_TEMPLATE);
if (template != null) {
treeReferences.add(template.getRef());
}
}
} else if (mult != TreeReference.INDEX_ATTRIBUTE) {
// TODO: Make this test mult >= 0?
// If the multiplicity is a simple integer, just get
// the appropriate child
AbstractTreeElement child = node.getChild(name, mult);
if (child != null) {
treeReferences.add(child.getRef());
}
}
}
if (mult == TreeReference.INDEX_ATTRIBUTE) {
AbstractTreeElement attribute = node.getAttribute(null, name);
if (attribute != null) {
treeReferences.add(attribute.getRef());
}
}
if (predicates != null && predicateEvaluationProgress != null) {
predicateEvaluationProgress[1] += treeReferences.size();
}
if (predicates != null) {
boolean firstTime = true;
List<TreeReference> passed = new ArrayList<TreeReference>(treeReferences.size());
for (XPathExpression xpe : predicates) {
for (int i = 0; i < treeReferences.size(); ++i) {
// if there are predicates then we need to see if e.nextElement meets the standard of the predicate
TreeReference treeRef = treeReferences.get(i);
// test the predicate on the treeElement
EvaluationContext evalContext = rescope(treeRef, (firstTime ? treeRef.getMultLast() : i));
Object o = xpe.eval(sourceInstance, evalContext);
if (o instanceof Boolean) {
boolean testOutcome = (Boolean) o;
if (testOutcome) {
passed.add(treeRef);
}
}
}
firstTime = false;
treeReferences.clear();
treeReferences.addAll(passed);
passed.clear();
if (predicateEvaluationProgress != null) {
predicateEvaluationProgress[0]++;
}
}
}
for (TreeReference treeRef : treeReferences) {
expandReferenceAccumulator(sourceRef, sourceInstance, treeRef, refs, includeTemplates);
}
}
use of org.javarosa.xpath.expr.XPathExpression in project collect by opendatakit.
the class ExternalAppsUtils method populateParameters.
public static void populateParameters(Intent intent, Map<String, String> exParams, TreeReference reference) throws ExternalParamsException {
FormDef formDef = Collect.getInstance().getFormController().getFormDef();
FormInstance formInstance = formDef.getInstance();
EvaluationContext evaluationContext = new EvaluationContext(formDef.getEvaluationContext(), reference);
if (exParams != null) {
for (Map.Entry<String, String> paramEntry : exParams.entrySet()) {
String paramEntryValue = paramEntry.getValue();
try {
Object result;
if (paramEntryValue.startsWith("'")) {
// but not require an ending quote
if (paramEntryValue.endsWith("'")) {
result = paramEntryValue.substring(1, paramEntryValue.length() - 1);
} else {
result = paramEntryValue.substring(1, paramEntryValue.length());
}
} else if (paramEntryValue.startsWith("/")) {
// treat this is an xpath
XPathPathExpr pathExpr = XPathReference.getPathExpr(paramEntryValue);
XPathNodeset xpathNodeset = pathExpr.eval(formInstance, evaluationContext);
result = XPathFuncExpr.unpack(xpathNodeset);
} else if (paramEntryValue.equals("instanceProviderID()")) {
// instanceProviderID returns -1 if the current instance has not been
// saved to disk already
String path = Collect.getInstance().getFormController().getInstanceFile().getAbsolutePath();
String instanceProviderID = "-1";
Cursor c = new InstancesDao().getInstancesCursorForFilePath(path);
if (c != null && c.getCount() > 0) {
// should only ever be one
c.moveToFirst();
instanceProviderID = c.getString(c.getColumnIndex(InstanceColumns._ID));
}
if (c != null) {
c.close();
}
result = instanceProviderID;
} else {
// treat this is a function
XPathExpression xpathExpression = XPathParseTool.parseXPath(paramEntryValue);
result = xpathExpression.eval(formInstance, evaluationContext);
}
if (result != null && result instanceof Serializable) {
intent.putExtra(paramEntry.getKey(), (Serializable) result);
}
} catch (Exception e) {
throw new ExternalParamsException("Could not evaluate '" + paramEntryValue + "'", e);
}
}
}
}
Aggregations