use of org.javarosa.core.model.condition.Condition in project javarosa by opendatakit.
the class StandardBindAttributesProcessor method buildCondition.
private Condition buildCondition(String xpath, String type, IDataReference contextRef) {
final int trueAction;
final int falseAction;
final String prettyType;
switch(type) {
case "relevant":
prettyType = "display";
trueAction = Condition.ACTION_SHOW;
falseAction = Condition.ACTION_HIDE;
break;
case "required":
prettyType = "require";
trueAction = Condition.ACTION_REQUIRE;
falseAction = Condition.ACTION_DONT_REQUIRE;
break;
case "readonly":
prettyType = "readonly";
trueAction = Condition.ACTION_DISABLE;
falseAction = Condition.ACTION_ENABLE;
break;
default:
throw new XFormParseException("Unsupported type " + type + " passed to buildCondition");
}
final XPathConditional xPathConditional;
try {
xPathConditional = new XPathConditional(xpath);
} catch (XPathSyntaxException xse) {
String errorMessage = "Encountered a problem with " + prettyType + " condition for node [" + contextRef.getReference().toString() + "] at line: " + xpath + ", " + xse.getMessage();
reporter.error(errorMessage);
throw new XFormParseException(errorMessage);
}
return new Condition(xPathConditional, trueAction, falseAction, FormInstance.unpackReference(contextRef));
}
use of org.javarosa.core.model.condition.Condition in project javarosa by opendatakit.
the class Fast2014DagImpl method finalizeTriggerables.
/**
* Finalize the DAG associated with the form's triggered conditions. This
* will create the appropriate ordering and dependencies to ensure the
* conditions will be evaluated in the appropriate orders.
*
* @throws IllegalStateException
* - If the trigger ordering contains an illegal cycle and the
* triggers can't be laid out appropriately
*/
@Override
public void finalizeTriggerables(FormInstance mainInstance, EvaluationContext evalContext) throws IllegalStateException {
//
// DAGify the triggerables based on dependencies and sort them so that
// triggerables come only after the triggerables they depend on
//
ArrayList<QuickTriggerable> vertices = new ArrayList<QuickTriggerable>(unorderedTriggerables);
triggerablesDAG.clear();
ArrayList<QuickTriggerable[]> partialOrdering = new ArrayList<QuickTriggerable[]>();
HashSet<QuickTriggerable> deps = new HashSet<QuickTriggerable>();
HashSet<QuickTriggerable> newDestinationSet = new HashSet<QuickTriggerable>();
for (QuickTriggerable qt : vertices) {
deps.clear();
newDestinationSet.clear();
fillTriggeredElements(mainInstance, evalContext, qt, deps, newDestinationSet, true);
// remove any self-reference if we have one...
deps.remove(qt);
for (QuickTriggerable qu : deps) {
QuickTriggerable[] edge = { qt, qu };
partialOrdering.add(edge);
}
// save for aggressive 2014 behavior
qt.t.setImmediateCascades(deps);
}
ArrayList<QuickTriggerable> orderedRoots = new ArrayList<QuickTriggerable>();
HashSet<QuickTriggerable> roots = new HashSet<QuickTriggerable>(vertices.size());
int waveCount = -1;
while (vertices.size() > 0) {
++waveCount;
// determine root nodes
roots.clear();
roots.addAll(vertices);
for (int i = 0; i < partialOrdering.size(); i++) {
QuickTriggerable[] edge = partialOrdering.get(i);
roots.remove(edge[1]);
}
// if no root nodes while graph still has nodes, graph has cycles
if (roots.size() == 0) {
String hints = "";
for (QuickTriggerable qt : vertices) {
for (TreeReference r : qt.t.getTargets()) {
hints += "\n" + r.toString(true);
}
}
String message = "Cycle detected in form's relevant and calculation logic!";
if (!hints.equals("")) {
message += "\nThe following nodes are likely involved in the loop:" + hints;
}
throw new IllegalStateException(message);
}
// order the root nodes - mainly for clean textual diffs when
// printing
// When this code is rewritten to use HashSet, this will become
// important.
orderedRoots.clear();
orderedRoots.addAll(roots);
Collections.sort(orderedRoots, QuickTriggerable.quickTriggerablesRootOrdering);
// add them to the triggerablesDAG.
for (int i = 0; i < orderedRoots.size(); i++) {
QuickTriggerable root = orderedRoots.get(i);
root.t.setWaveCount(waveCount);
triggerablesDAG.add(root);
vertices.remove(root);
}
for (int i = partialOrdering.size() - 1; i >= 0; i--) {
QuickTriggerable[] edge = partialOrdering.get(i);
if (roots.contains(edge[0]))
partialOrdering.remove(i);
}
}
//
// build the condition index for repeatable nodes
//
conditionRepeatTargetIndex.clear();
for (QuickTriggerable qt : triggerablesDAG) {
if (qt.t instanceof Condition) {
List<TreeReference> targets = qt.t.getTargets();
for (TreeReference target : targets) {
if (mainInstance.getTemplate(target) != null) {
conditionRepeatTargetIndex.put(target, qt);
}
}
}
}
// printTriggerables();
}
use of org.javarosa.core.model.condition.Condition in project javarosa by opendatakit.
the class FormDef method readExternal.
/**
* Reads the form definition object from the supplied stream.
* <p/>
* Requires that the instance has been set to a prototype of the instance
* that should be used for deserialization.
*
* @param dis - the stream to read from.
* @throws IOException
* @throws InstantiationException
* @throws IllegalAccessException
*/
@Override
public void readExternal(DataInputStream dis, PrototypeFactory pf) throws IOException, DeserializationException {
setID(ExtUtil.readInt(dis));
setName(ExtUtil.nullIfEmpty(ExtUtil.readString(dis)));
setTitle((String) ExtUtil.read(dis, new ExtWrapNullable(String.class), pf));
setChildren((List<IFormElement>) ExtUtil.read(dis, new ExtWrapListPoly(), pf));
setInstance((FormInstance) ExtUtil.read(dis, FormInstance.class, pf));
setLocalizer((Localizer) ExtUtil.read(dis, new ExtWrapNullable(Localizer.class), pf));
List<Condition> vcond = (List<Condition>) ExtUtil.read(dis, new ExtWrapList(Condition.class), pf);
for (Condition condition : vcond) {
addTriggerable(condition);
}
List<Recalculate> vcalc = (List<Recalculate>) ExtUtil.read(dis, new ExtWrapList(Recalculate.class), pf);
for (Recalculate recalculate : vcalc) {
addTriggerable(recalculate);
}
finalizeTriggerables();
outputFragments = (List<IConditionExpr>) ExtUtil.read(dis, new ExtWrapListPoly(), pf);
submissionProfiles = (HashMap<String, SubmissionProfile>) ExtUtil.read(dis, new ExtWrapMap(String.class, SubmissionProfile.class));
formInstances = (HashMap<String, DataInstance>) ExtUtil.read(dis, new ExtWrapMap(String.class, new ExtWrapTagged()), pf);
eventListeners = (HashMap<String, List<Action>>) ExtUtil.read(dis, new ExtWrapMap(String.class, new ExtWrapListPoly()), pf);
extensions = (List<XFormExtension>) ExtUtil.read(dis, new ExtWrapListPoly(), pf);
resetEvaluationContext();
}
use of org.javarosa.core.model.condition.Condition in project javarosa by opendatakit.
the class FormDef method isRepeatRelevant.
public boolean isRepeatRelevant(TreeReference repeatRef) {
boolean relev = true;
QuickTriggerable qc = dagImpl.getTriggerableForRepeatGroup(repeatRef.genericize());
if (qc != null) {
Condition c = (Condition) qc.t;
relev = c.evalBool(mainInstance, new EvaluationContext(exprEvalContext, repeatRef));
}
// check the relevancy of the immediate parent
if (relev) {
TreeElement templNode = mainInstance.getTemplate(repeatRef);
TreeReference parentPath = templNode.getParent().getRef().genericize();
TreeElement parentNode = mainInstance.resolveReference(parentPath.contextualize(repeatRef));
relev = parentNode.isRelevant();
}
return relev;
}
use of org.javarosa.core.model.condition.Condition in project javarosa by opendatakit.
the class April2014DagImpl method finalizeTriggerables.
/**
* Finalize the DAG associated with the form's triggered conditions. This
* will create the appropriate ordering and dependencies to ensure the
* conditions will be evaluated in the appropriate orders.
*
* @throws IllegalStateException
* - If the trigger ordering contains an illegal cycle and the
* triggers can't be laid out appropriately
*/
@Override
public void finalizeTriggerables(FormInstance mainInstance, EvaluationContext evalContext) throws IllegalStateException {
//
// DAGify the triggerables based on dependencies and sort them so that
// triggerables come only after the triggerables they depend on
//
triggerablesDAG.clear();
ArrayList<QuickTriggerable[]> partialOrdering = new ArrayList<QuickTriggerable[]>();
for (int i = 0; i < unorderedTriggerables.size(); i++) {
QuickTriggerable qt = unorderedTriggerables.get(i);
ArrayList<QuickTriggerable> deps = new ArrayList<QuickTriggerable>();
fillTriggeredElements(evalContext, qt, deps);
for (int j = 0; j < deps.size(); j++) {
QuickTriggerable qu = deps.get(j);
QuickTriggerable[] edge = { qt, qu };
partialOrdering.add(edge);
}
}
ArrayList<QuickTriggerable> vertices = new ArrayList<QuickTriggerable>(unorderedTriggerables);
ArrayList<QuickTriggerable> roots = new ArrayList<QuickTriggerable>(unorderedTriggerables.size());
while (vertices.size() > 0) {
// determine root nodes
roots.clear();
roots.addAll(vertices);
for (int i = 0; i < partialOrdering.size(); i++) {
QuickTriggerable[] edge = partialOrdering.get(i);
roots.remove(edge[1]);
}
// if no root nodes while graph still has nodes, graph has cycles
if (roots.size() == 0) {
String hints = "";
for (QuickTriggerable qt : vertices) {
for (TreeReference r : qt.t.getTargets()) {
hints += "\n" + r.toString(true);
}
}
String message = "Cycle detected in form's relevant and calculation logic!";
if (!hints.equals("")) {
message += "\nThe following nodes are likely involved in the loop:" + hints;
}
throw new IllegalStateException(message);
}
// remove root nodes and edges originating from them
for (int i = 0; i < roots.size(); i++) {
QuickTriggerable root = roots.get(i);
triggerablesDAG.add(root);
vertices.remove(root);
}
for (int i = partialOrdering.size() - 1; i >= 0; i--) {
QuickTriggerable[] edge = partialOrdering.get(i);
if (roots.contains(edge[0]))
partialOrdering.remove(i);
}
}
//
// build the condition index for repeatable nodes
//
conditionRepeatTargetIndex.clear();
for (QuickTriggerable qt : triggerablesDAG) {
if (qt.t instanceof Condition) {
List<TreeReference> targets = qt.t.getTargets();
for (TreeReference target : targets) {
if (mainInstance.getTemplate(target) != null) {
conditionRepeatTargetIndex.put(target, qt);
}
}
}
}
// printTriggerables();
}
Aggregations