use of org.javarosa.xpath.expr.XPathFuncExpr in project collect by opendatakit.
the class ExternalDataUtil method getSearchXPathExpression.
public static XPathFuncExpr getSearchXPathExpression(String appearance) {
if (appearance == null) {
appearance = "";
}
appearance = appearance.trim();
Matcher matcher = SEARCH_FUNCTION_REGEX.matcher(appearance);
if (matcher.find()) {
String function = matcher.group(0);
try {
XPathExpression xpathExpression = XPathParseTool.parseXPath(function);
if (XPathFuncExpr.class.isAssignableFrom(xpathExpression.getClass())) {
XPathFuncExpr xpathFuncExpr = (XPathFuncExpr) xpathExpression;
if (xpathFuncExpr.id.name.equalsIgnoreCase(ExternalDataHandlerSearch.HANDLER_NAME)) {
// also check that the args are either 1, 4 or 6.
if (xpathFuncExpr.args.length == 1 || xpathFuncExpr.args.length == 4 || xpathFuncExpr.args.length == 6) {
return xpathFuncExpr;
} else {
Toast.makeText(Collect.getInstance(), Collect.getInstance().getString(R.string.ext_search_wrong_arguments_error), Toast.LENGTH_SHORT).show();
Timber.i(Collect.getInstance().getString(R.string.ext_search_wrong_arguments_error));
return null;
}
} else {
// this might mean a problem in the regex above. Unit tests required.
Toast.makeText(Collect.getInstance(), Collect.getInstance().getString(R.string.ext_search_wrong_function_error, xpathFuncExpr.id.name), Toast.LENGTH_SHORT).show();
Timber.i(Collect.getInstance().getString(R.string.ext_search_wrong_function_error, xpathFuncExpr.id.name));
return null;
}
} else {
// this might mean a problem in the regex above. Unit tests required.
Toast.makeText(Collect.getInstance(), Collect.getInstance().getString(R.string.ext_search_bad_function_error, function), Toast.LENGTH_SHORT).show();
Timber.i(Collect.getInstance().getString(R.string.ext_search_bad_function_error, function));
return null;
}
} catch (XPathSyntaxException e) {
Toast.makeText(Collect.getInstance(), Collect.getInstance().getString(R.string.ext_search_generic_error, appearance), Toast.LENGTH_SHORT).show();
Timber.i(Collect.getInstance().getString(R.string.ext_search_generic_error, appearance));
return null;
}
} else {
return null;
}
}
use of org.javarosa.xpath.expr.XPathFuncExpr 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.XPathFuncExpr in project collect by opendatakit.
the class ExternalAnswerResolver method resolveAnswer.
@Override
public IAnswerData resolveAnswer(String textVal, TreeElement treeElement, FormDef formDef) {
QuestionDef questionDef = XFormParser.ghettoGetQuestionDef(treeElement.getDataType(), formDef, treeElement.getRef());
if (questionDef != null && (questionDef.getControlType() == Constants.CONTROL_SELECT_ONE || questionDef.getControlType() == Constants.CONTROL_SELECT_MULTI)) {
boolean containsSearchExpression = false;
XPathFuncExpr xpathExpression = null;
try {
xpathExpression = ExternalDataUtil.getSearchXPathExpression(questionDef.getAppearanceAttr());
} catch (Exception e) {
Timber.e(e);
// there is a search expression, but has syntax errors
containsSearchExpression = true;
}
if (xpathExpression != null || containsSearchExpression) {
// that means that we have dynamic selects
// read the static choices from the options sheet
List<SelectChoice> staticChoices = questionDef.getChoices();
for (int index = 0; index < staticChoices.size(); index++) {
SelectChoice selectChoice = staticChoices.get(index);
String selectChoiceValue = selectChoice.getValue();
if (ExternalDataUtil.isAnInteger(selectChoiceValue)) {
Selection selection = selectChoice.selection();
switch(questionDef.getControlType()) {
case Constants.CONTROL_SELECT_ONE:
{
if (selectChoiceValue.equals(textVal)) {
// we just need to make sure, so we will override that.
if (questionDef.getControlType() == Constants.CONTROL_SELECT_ONE) {
// we don't need another, just return the static choice.
return new SelectOneData(selection);
}
}
break;
}
case Constants.CONTROL_SELECT_MULTI:
{
// we should search in a potential comma-separated string of
// values for a match
// copied from org.javarosa.xform.util.XFormAnswerDataParser
// .getSelections()
List<String> textValues = DateUtils.split(textVal, XFormAnswerDataSerializer.DELIMITER, true);
if (textValues.contains(textVal)) {
// choice.
if (selectChoiceValue.equals(textVal)) {
// this means that the user selected ONLY the static
// answer, so just return that
List<Selection> customSelections = new ArrayList<Selection>();
customSelections.add(selection);
return new SelectMultiData(customSelections);
} else {
// we will ignore it for now since we will return that
// selection together with the dynamic ones.
}
}
break;
}
default:
{
// There is a bug if we get here, so let's throw an Exception
throw createBugRuntimeException(treeElement, textVal);
}
}
} else {
switch(questionDef.getControlType()) {
case Constants.CONTROL_SELECT_ONE:
{
// the default implementation will search for the "textVal"
// (saved answer) inside the static choices.
// Since we know that there isn't such, we just wrap the textVal
// in a virtual choice in order to
// create a SelectOneData object to be used as the IAnswer to the
// TreeElement.
// (the caller of this function is searching for such an answer
// to populate the in-memory model.)
SelectChoice customSelectChoice = new SelectChoice(textVal, textVal, false);
customSelectChoice.setIndex(index);
return new SelectOneData(customSelectChoice.selection());
}
case Constants.CONTROL_SELECT_MULTI:
{
// we should create multiple selections and add them to the pile
List<SelectChoice> customSelectChoices = createCustomSelectChoices(textVal);
List<Selection> customSelections = new ArrayList<Selection>();
for (SelectChoice customSelectChoice : customSelectChoices) {
customSelections.add(customSelectChoice.selection());
}
return new SelectMultiData(customSelections);
}
default:
{
// There is a bug if we get here, so let's throw an Exception
throw createBugRuntimeException(treeElement, textVal);
}
}
}
}
// if we get there then that means that we have a bug
throw createBugRuntimeException(treeElement, textVal);
}
}
// default behavior matches original behavior (for static selects, etc.)
return super.resolveAnswer(textVal, treeElement, formDef);
}
Aggregations