use of org.javarosa.core.model.condition.Condition 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.core.model.condition.Condition in project javarosa by opendatakit.
the class FormDef method writeExternal.
/**
* Writes the form definition object to the supplied stream.
*
* @param dos - the stream to write to.
* @throws IOException
*/
@Override
public void writeExternal(DataOutputStream dos) throws IOException {
ExtUtil.writeNumeric(dos, getID());
ExtUtil.writeString(dos, ExtUtil.emptyIfNull(getName()));
ExtUtil.write(dos, new ExtWrapNullable(getTitle()));
ExtUtil.write(dos, new ExtWrapListPoly(getChildren()));
ExtUtil.write(dos, getMainInstance());
ExtUtil.write(dos, new ExtWrapNullable(localizer));
List<Condition> conditions = dagImpl.getConditions();
List<Recalculate> recalcs = dagImpl.getRecalculates();
ExtUtil.write(dos, new ExtWrapList(conditions));
ExtUtil.write(dos, new ExtWrapList(recalcs));
ExtUtil.write(dos, new ExtWrapListPoly(outputFragments));
ExtUtil.write(dos, new ExtWrapMap(submissionProfiles));
// for support of multi-instance forms
ExtUtil.write(dos, new ExtWrapMap(formInstances, new ExtWrapTagged()));
ExtUtil.write(dos, new ExtWrapMap(eventListeners, new ExtWrapListPoly()));
ExtUtil.write(dos, new ExtWrapListPoly(extensions));
}
use of org.javarosa.core.model.condition.Condition in project javarosa by opendatakit.
the class IDag method getConditionExpressionForTrueAction.
/**
* Pull this in from FormOverview so that we can make fields private.
*
* @param instanceNode
* @param action
* @return
*/
public final IConditionExpr getConditionExpressionForTrueAction(FormInstance mainInstance, TreeElement instanceNode, int action) {
IConditionExpr expr = null;
for (int i = 0; i < triggerablesDAG.size() && expr == null; i++) {
// Clayton Sims - Jun 1, 2009 : Not sure how legitimate this
// cast is. It might work now, but break later.
// Clayton Sims - Jun 24, 2009 : Yeah, that change broke things.
// For now, we won't bother to print out anything that isn't
// a condition.
QuickTriggerable qt = triggerablesDAG.get(i);
if (qt.t instanceof Condition) {
Condition c = (Condition) qt.t;
if (c.trueAction == action) {
List<TreeReference> targets = c.getTargets();
for (int j = 0; j < targets.size() && expr == null; j++) {
TreeReference target = targets.get(j);
TreeReference tr = (TreeReference) (new XPathReference(target)).getReference();
TreeElement element = mainInstance.getTemplatePath(tr);
if (instanceNode == element) {
expr = c.getExpr();
}
}
}
}
}
return expr;
}
use of org.javarosa.core.model.condition.Condition in project javarosa by opendatakit.
the class LegacyDagImpl 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();
//
// DAGify the triggerables based on dependencies and sort them so that
// trigbles come only after the trigbles they depend on
//
ArrayList<QuickTriggerable[]> partialOrdering = new ArrayList<QuickTriggerable[]>();
for (int i = 0; i < unorderedTriggerables.size(); i++) {
QuickTriggerable qt = unorderedTriggerables.get(i);
Triggerable t = qt.t;
ArrayList<QuickTriggerable> deps = new ArrayList<QuickTriggerable>();
if (t.canCascade()) {
for (int j = 0; j < t.getTargets().size(); j++) {
TreeReference target = t.getTargets().get(j);
ArrayList<QuickTriggerable> triggered = triggerIndex.get(target);
if (triggered != null) {
for (int k = 0; k < triggered.size(); k++) {
QuickTriggerable qu = triggered.get(k);
if (!deps.contains(qu))
deps.add(qu);
}
}
}
}
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) {
throw new RuntimeException("Cannot create partial ordering of triggerables due to dependency cycle. Why wasn't this caught during parsing?");
}
// 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();
}
use of org.javarosa.core.model.condition.Condition in project javarosa by opendatakit.
the class Safe2014DagImpl 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> newDestinationSet = new HashSet<QuickTriggerable>();
for (QuickTriggerable qt : vertices) {
HashSet<QuickTriggerable> deps = new HashSet<QuickTriggerable>();
newDestinationSet.clear();
fillTriggeredElements(mainInstance, evalContext, qt, deps, newDestinationSet);
// 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 - so the order is fixed
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();
}
Aggregations