Search in sources :

Example 11 with TreeReference

use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.

the class FormInstanceParser method buildRepeatTree.

/**
 * Builds a pseudo-data model tree that describes the repeat structure of the instance. The
 * result is a FormInstance collapsed where all indexes are 0, and repeatable nodes are flagged as such.
 * Ignores (invalid) repeats that bind outside the top-level instance data node. Returns null if no repeats.
 */
private static FormInstance buildRepeatTree(List<TreeReference> repeatRefs, String topLevelName) {
    TreeElement root = new TreeElement(null, 0);
    for (TreeReference repeatRef : repeatRefs) {
        // check and see if this references a repeat from a non-main instance, if so, skip it
        if (repeatRef.getInstanceName() != null) {
            continue;
        }
        if (repeatRef.size() <= 1) {
            // invalid repeat: binds too high. ignore for now and error will be raised in verifyBindings
            continue;
        }
        TreeElement cur = root;
        for (int j = 0; j < repeatRef.size(); j++) {
            String name = repeatRef.getName(j);
            TreeElement child = cur.getChild(name, 0);
            if (child == null) {
                child = new TreeElement(name, 0);
                cur.addChild(child);
            }
            cur = child;
        }
        cur.setRepeatable(true);
    }
    return (root.getNumChildren() == 0) ? null : new FormInstance(root.getChild(topLevelName, TreeReference.DEFAULT_MULTIPLICITY));
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) FormInstance(org.javarosa.core.model.instance.FormInstance) Constraint(org.javarosa.core.model.condition.Constraint) TreeElement(org.javarosa.core.model.instance.TreeElement)

Example 12 with TreeReference

use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.

the class FormEntryModel method isIndexRelevant.

/**
 * Determine if the current FormIndex is relevant. Only relevant indexes
 * should be returned when filling out a form.
 *
 * @param index
 * @return true if current element at FormIndex is relevant
 */
public boolean isIndexRelevant(FormIndex index) {
    TreeReference ref = form.getChildInstanceRef(index);
    boolean isAskNewRepeat = (getEvent(index) == FormEntryController.EVENT_PROMPT_NEW_REPEAT);
    boolean isRepeatJuncture = (getEvent(index) == FormEntryController.EVENT_REPEAT_JUNCTURE);
    boolean relevant;
    if (isAskNewRepeat) {
        relevant = form.isRepeatRelevant(ref) && form.canCreateRepeat(ref, index);
    // repeat junctures are still relevant if no new repeat can be created; that option
    // is simply missing from the menu
    } else if (isRepeatJuncture) {
        relevant = form.isRepeatRelevant(ref);
    } else {
        TreeElement node = form.getMainInstance().resolveReference(ref);
        // check instance flag first
        relevant = node != null && node.isRelevant();
    }
    if (relevant) {
        // if instance flag/condition says relevant, we still
        // have to check the <group>/<repeat> hierarchy
        FormIndex ancestorIndex = index;
        while (!ancestorIndex.isTerminal()) {
            // This should be safe now that the TreeReference is contained
            // in the ancestor index itself
            TreeElement ancestorNode = form.getMainInstance().resolveReference(ancestorIndex.getLocalReference());
            if (!ancestorNode.isRelevant()) {
                relevant = false;
                break;
            }
            ancestorIndex = ancestorIndex.getNextLevel();
        }
    }
    return relevant;
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) FormIndex(org.javarosa.core.model.FormIndex) TreeElement(org.javarosa.core.model.instance.TreeElement)

Example 13 with TreeReference

use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.

the class FormEntryModel method isIndexReadonly.

/**
 * @param index
 * @return true if the element at the specified index is read only
 */
public boolean isIndexReadonly(FormIndex index) {
    if (index.isBeginningOfFormIndex() || index.isEndOfFormIndex())
        return true;
    TreeReference ref = form.getChildInstanceRef(index);
    boolean isAskNewRepeat = (getEvent(index) == FormEntryController.EVENT_PROMPT_NEW_REPEAT || getEvent(index) == FormEntryController.EVENT_REPEAT_JUNCTURE);
    if (isAskNewRepeat) {
        return false;
    } else {
        TreeElement node = form.getMainInstance().resolveReference(ref);
        return !node.isEnabled();
    }
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) TreeElement(org.javarosa.core.model.instance.TreeElement)

Example 14 with TreeReference

use of org.javarosa.core.model.instance.TreeReference in project javarosa by opendatakit.

the class XFormsModule method registerModule.

public void registerModule() {
    String[] classes = { "org.javarosa.model.xform.XPathReference", "org.javarosa.xpath.XPathConditional" };
    PrototypeManager.registerPrototypes(classes);
    PrototypeManager.registerPrototypes(XPathParseTool.xpathClasses);
    RestoreUtils.xfFact = new IXFormyFactory() {

        public TreeReference ref(String refStr) {
            return FormInstance.unpackReference(new XPathReference(refStr));
        }

        public IDataPayload serializeInstance(FormInstance dm) {
            try {
                return (new XFormSerializingVisitor()).createSerializedPayload(dm);
            } catch (IOException e) {
                return null;
            }
        }

        public FormInstance parseRestore(byte[] data, Class restorableType) {
            return XFormParser.restoreDataModel(data, restorableType);
        }

        public IAnswerData parseData(String textVal, int dataType, TreeReference ref, FormDef f) {
            return XFormAnswerDataParser.getAnswerData(textVal, dataType, XFormParser.ghettoGetQuestionDef(dataType, f, ref));
        }

        public String serializeData(IAnswerData data) {
            return (String) (new XFormAnswerDataSerializer().serializeAnswerData(data));
        }

        public IConditionExpr refToPathExpr(TreeReference ref) {
            return new XPathConditional(XPathPathExpr.fromRef(ref));
        }
    };
}
Also used : IAnswerData(org.javarosa.core.model.data.IAnswerData) IConditionExpr(org.javarosa.core.model.condition.IConditionExpr) IXFormyFactory(org.javarosa.core.model.util.restorable.IXFormyFactory) IOException(java.io.IOException) XFormAnswerDataSerializer(org.javarosa.xform.util.XFormAnswerDataSerializer) TreeReference(org.javarosa.core.model.instance.TreeReference) FormDef(org.javarosa.core.model.FormDef) FormInstance(org.javarosa.core.model.instance.FormInstance) XPathConditional(org.javarosa.xpath.XPathConditional) IDataPayload(org.javarosa.core.services.transport.payload.IDataPayload)

Example 15 with TreeReference

use of org.javarosa.core.model.instance.TreeReference 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);
}
Also used : DataInstance(org.javarosa.core.model.instance.DataInstance) XPathException(org.javarosa.xpath.XPathException) TreeReference(org.javarosa.core.model.instance.TreeReference) XPathNodeset(org.javarosa.xpath.XPathNodeset) XPathMissingInstanceException(org.javarosa.xpath.XPathMissingInstanceException)

Aggregations

TreeReference (org.javarosa.core.model.instance.TreeReference)85 ArrayList (java.util.ArrayList)30 TreeElement (org.javarosa.core.model.instance.TreeElement)29 EvaluationContext (org.javarosa.core.model.condition.EvaluationContext)16 Constraint (org.javarosa.core.model.condition.Constraint)12 HashSet (java.util.HashSet)11 Test (org.junit.Test)9 FormInstance (org.javarosa.core.model.instance.FormInstance)8 AbstractTreeElement (org.javarosa.core.model.instance.AbstractTreeElement)7 IFormElement (org.javarosa.core.model.IFormElement)6 Condition (org.javarosa.core.model.condition.Condition)6 IAnswerData (org.javarosa.core.model.data.IAnswerData)6 InstanceInitializationFactory (org.javarosa.core.model.instance.InstanceInitializationFactory)6 GroupDef (org.javarosa.core.model.GroupDef)5 XPathReference (org.javarosa.model.xform.XPathReference)5 DataBinding (org.javarosa.core.model.DataBinding)4 IDataReference (org.javarosa.core.model.IDataReference)4 DataInstance (org.javarosa.core.model.instance.DataInstance)4 EvaluationResult (org.javarosa.debug.EvaluationResult)4 XPathException (org.javarosa.xpath.XPathException)4