use of org.javarosa.xpath.XPathException 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.XPathException in project javarosa by opendatakit.
the class XPathPathExpr method eval.
public XPathNodeset eval(DataInstance m, EvaluationContext ec) {
TreeReference genericRef = getReference();
TreeReference ref;
if (genericRef.getContext() == TreeReference.CONTEXT_ORIGINAL) {
ref = genericRef.contextualize(ec.getOriginalContext());
} else {
ref = genericRef.contextualize(ec.getContextRef());
}
// check if this nodeset refers to a non-main instance
if (ref.getInstanceName() != null && ref.isAbsolute()) {
DataInstance nonMain = ec.getInstance(ref.getInstanceName());
if (nonMain != null) {
m = nonMain;
} else {
throw new XPathMissingInstanceException(ref.getInstanceName(), "Instance referenced by " + ref.toString(true) + " does not exist");
}
} else {
// TODO: We should really stop passing 'm' around and start just getting the right instance from ec
// at a more central level
m = ec.getMainInstance();
if (m == null) {
String refStr = ref == null ? "" : ref.toString(true);
throw new XPathException("Cannot evaluate the reference [" + refStr + "] in the current evaluation context. No default instance has been declared!");
}
}
// regardless of the above, we want to ensure there is a definition
if (m.getRoot() == null) {
// This instance is _declared_, but doesn't actually have any data in it.
throw new XPathMissingInstanceException(ref.getInstanceName(), "Instance referenced by " + ref.toString(true) + " has not been loaded");
}
// this makes no sense...
// if (ref.isAbsolute() && m.getTemplatePath(ref) == null) {
// List<TreeReference> nodesetRefs = new List<TreeReference>();
// return new XPathNodeset(nodesetRefs, m, ec);
// }
List<TreeReference> nodesetRefs = ec.expandReference(ref);
// to fix conditions based on non-relevant data, filter the nodeset by relevancy
for (int i = 0; i < nodesetRefs.size(); i++) {
if (!m.resolveReference(nodesetRefs.get(i)).isRelevant()) {
nodesetRefs.remove(i);
i--;
}
}
return new XPathNodeset(nodesetRefs, m, ec);
}
use of org.javarosa.xpath.XPathException in project javarosa by opendatakit.
the class StandardBindAttributesProcessor method createBinding.
DataBinding createBinding(IXFormParserFunctions parserFunctions, FormDef formDef, Collection<String> usedAttributes, Collection<String> passedThroughAttributes, Element element) {
final DataBinding binding = new DataBinding();
binding.setId(element.getAttributeValue("", ID_ATTR));
final String nodeset = element.getAttributeValue(null, NODESET_ATTR);
if (nodeset == null) {
throw new XFormParseException("XForm Parse: <bind> without nodeset", element);
}
IDataReference ref;
try {
ref = new XPathReference(nodeset);
} catch (XPathException xpe) {
throw new XFormParseException(xpe.getMessage());
}
ref = parserFunctions.getAbsRef(ref, formDef);
binding.setReference(ref);
binding.setDataType(getDataType(element.getAttributeValue(null, "type")));
String xpathRel = element.getAttributeValue(null, "relevant");
if (xpathRel != null) {
if ("true()".equals(xpathRel)) {
binding.relevantAbsolute = true;
} else if ("false()".equals(xpathRel)) {
binding.relevantAbsolute = false;
} else {
Condition c = buildCondition(xpathRel, "relevant", ref);
c = (Condition) formDef.addTriggerable(c);
binding.relevancyCondition = c;
}
}
String xpathReq = element.getAttributeValue(null, "required");
if (xpathReq != null) {
if ("true()".equals(xpathReq)) {
binding.requiredAbsolute = true;
} else if ("false()".equals(xpathReq)) {
binding.requiredAbsolute = false;
} else {
Condition c = buildCondition(xpathReq, "required", ref);
c = (Condition) formDef.addTriggerable(c);
binding.requiredCondition = c;
}
}
String xpathRO = element.getAttributeValue(null, "readonly");
if (xpathRO != null) {
if ("true()".equals(xpathRO)) {
binding.readonlyAbsolute = true;
} else if ("false()".equals(xpathRO)) {
binding.readonlyAbsolute = false;
} else {
Condition c = buildCondition(xpathRO, "readonly", ref);
c = (Condition) formDef.addTriggerable(c);
binding.readonlyCondition = c;
}
}
final String xpathConstr = element.getAttributeValue(null, "constraint");
if (xpathConstr != null) {
try {
binding.constraint = new XPathConditional(xpathConstr);
} catch (XPathSyntaxException xse) {
throw new XFormParseException("bind for " + nodeset + " contains invalid constraint expression [" + xpathConstr + "] " + xse.getMessage());
}
binding.constraintMessage = element.getAttributeValue(NAMESPACE_JAVAROSA, "constraintMsg");
}
final String xpathCalc = element.getAttributeValue(null, "calculate");
if (xpathCalc != null) {
Recalculate r;
try {
r = buildCalculate(xpathCalc, ref);
} catch (XPathSyntaxException xpse) {
throw new XFormParseException("Invalid calculate for the bind attached to \"" + nodeset + "\" : " + xpse.getMessage() + " in expression " + xpathCalc);
}
r = (Recalculate) formDef.addTriggerable(r);
binding.calculate = r;
}
binding.setPreload(element.getAttributeValue(NAMESPACE_JAVAROSA, "preload"));
binding.setPreloadParams(element.getAttributeValue(NAMESPACE_JAVAROSA, "preloadParams"));
saveUnusedAttributes(binding, element, usedAttributes, passedThroughAttributes);
return binding;
}
use of org.javarosa.xpath.XPathException in project javarosa by opendatakit.
the class XPathReference method getPathExpr.
public static XPathPathExpr getPathExpr(String nodeset) {
XPathExpression path;
boolean validNonPathExpr = false;
try {
path = XPathParseTool.parseXPath(nodeset);
if (!(path instanceof XPathPathExpr)) {
validNonPathExpr = true;
throw new XPathSyntaxException();
}
} catch (XPathSyntaxException xse) {
// make these checked exceptions?
if (validNonPathExpr) {
throw new XPathTypeMismatchException("Expected XPath path, got XPath expression: [" + nodeset + "]," + xse.getMessage());
} else {
Std.printStack(xse);
throw new XPathException("Parse error in XPath path: [" + nodeset + "]." + (xse.getMessage() == null ? "" : "\n" + xse.getMessage()));
}
}
return (XPathPathExpr) path;
}
use of org.javarosa.xpath.XPathException in project javarosa by opendatakit.
the class FormDef method populateDynamicChoices.
/**
* Identify the itemset in the backend model, and create a set of
* SelectChoice objects at the current question reference based on the data
* in the model.
* <p/>
* Will modify the itemset binding to contain the relevant choices
*
* @param itemset The binding for an itemset, where the choices will be populated
* @param curQRef A reference to the current question's element, which will be
* used to determine the values to be chosen from.
*/
public void populateDynamicChoices(ItemsetBinding itemset, TreeReference curQRef) {
getEventNotifier().publishEvent(new Event("Dynamic choices", new EvaluationResult(curQRef, null)));
List<SelectChoice> choices = new ArrayList<SelectChoice>();
List<TreeReference> matches = itemset.nodesetExpr.evalNodeset(this.getMainInstance(), new EvaluationContext(exprEvalContext, itemset.contextRef.contextualize(curQRef)));
DataInstance fi = null;
if (// We're not dealing
itemset.nodesetRef.getInstanceName() != null) // with the default
// instance
{
fi = getNonMainInstance(itemset.nodesetRef.getInstanceName());
if (fi == null) {
throw new XPathException("Instance " + itemset.nodesetRef.getInstanceName() + " not found");
}
} else {
fi = getMainInstance();
}
if (matches == null) {
throw new XPathException("Could not find references depended on by" + itemset.nodesetRef.getInstanceName());
}
for (int i = 0; i < matches.size(); i++) {
TreeReference item = matches.get(i);
// String label =
// itemset.labelExpr.evalReadable(this.getMainInstance(), new
// EvaluationContext(exprEvalContext, item));
String label = itemset.labelExpr.evalReadable(fi, new EvaluationContext(exprEvalContext, item));
String value = null;
TreeElement copyNode = null;
if (itemset.copyMode) {
copyNode = this.getMainInstance().resolveReference(itemset.copyRef.contextualize(item));
}
if (itemset.valueRef != null) {
// value = itemset.valueExpr.evalReadable(this.getMainInstance(),
// new EvaluationContext(exprEvalContext, item));
value = itemset.valueExpr.evalReadable(fi, new EvaluationContext(exprEvalContext, item));
}
// SelectChoice choice = new
// SelectChoice(labelID,labelInnerText,value,isLocalizable);
SelectChoice choice = new SelectChoice(label, value != null ? value : "dynamic:" + i, itemset.labelIsItext);
choice.setIndex(i);
if (itemset.copyMode)
choice.copyNode = copyNode;
choices.add(choice);
}
if (choices.size() == 0) {
// throw new
// RuntimeException("dynamic select question has no choices! [" +
// itemset.nodesetRef + "]");
// When you exit a survey mid way through and want to save it, it seems
// that Collect wants to
// go through all the questions. Well of course not all the questions
// are going to have answers
// to chose from if the user hasn't filled them out. So I'm just going
// to make a note of this
// and not throw an exception.
Std.out.println("Dynamic select question has no choices! [" + itemset.nodesetRef + "]. If this occurs while filling out a form (and not while saving an incomplete form), the filter condition may have eliminated all the choices. Is that what you intended?\n");
}
itemset.clearChoices();
itemset.setChoices(choices, this.getLocalizer());
}
Aggregations