Search in sources :

Example 21 with TreeReference

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

the class FormDef method getChildInstanceRef.

public TreeReference getChildInstanceRef(List<IFormElement> elements, List<Integer> multiplicities) {
    if (elements.size() == 0)
        return null;
    IFormElement element = elements.get(elements.size() - 1);
    // get reference for target element
    TreeReference ref = FormInstance.unpackReference(element.getBind()).clone();
    for (int i = 0; i < ref.size(); i++) {
        // There has to be a better way to encapsulate this
        if (ref.getMultiplicity(i) != TreeReference.INDEX_ATTRIBUTE) {
            ref.setMultiplicity(i, 0);
        }
    }
    // fill in multiplicities for repeats along the way
    for (int i = 0; i < elements.size(); i++) {
        IFormElement temp = elements.get(i);
        if (temp instanceof GroupDef && ((GroupDef) temp).getRepeat()) {
            TreeReference repRef = FormInstance.unpackReference(temp.getBind());
            if (repRef.isParentOf(ref, false)) {
                int repMult = multiplicities.get(i);
                ref.setMultiplicity(repRef.size() - 1, repMult);
            } else {
                // question/repeat hierarchy is not consistent
                return null;
            // with instance instance and bindings
            }
        }
    }
    return ref;
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) Constraint(org.javarosa.core.model.condition.Constraint)

Example 22 with TreeReference

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

the class FormDef method createNewRepeat.

public void createNewRepeat(FormIndex index) throws InvalidReferenceException {
    TreeReference destRef = getChildInstanceRef(index);
    TreeElement template = mainInstance.getTemplate(destRef);
    mainInstance.copyNode(template, destRef);
    TreeElement newNode = mainInstance.resolveReference(destRef);
    preloadInstance(newNode);
    // 2013-05-14 - ctsims - Events should get fired _before_ calculate stuff
    // is fired, moved
    // this above triggering triggerables
    // Grab any actions listening to this event
    List<Action> listeners = getEventListeners(Action.EVENT_JR_INSERT);
    for (Action a : listeners) {
        a.processAction(this, destRef);
    }
    TreeReference parentRef = destRef.getParentRef();
    TreeElement parentElement = mainInstance.resolveReference(parentRef);
    dagImpl.createRepeatGroup(getMainInstance(), getEvaluationContext(), destRef, parentElement, newNode);
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) TreeElement(org.javarosa.core.model.instance.TreeElement)

Example 23 with TreeReference

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

the class FormDef method canCreateRepeat.

public boolean canCreateRepeat(TreeReference repeatRef, FormIndex repeatIndex) {
    GroupDef repeat = (GroupDef) this.getChild(repeatIndex);
    // Check to see if this repeat can have children added by the user
    if (repeat.noAddRemove) {
        // should have
        if (repeat.getCountReference() != null) {
            int currentMultiplicity = repeatIndex.getElementMultiplicity();
            // Lu Gram: the count XPath needs to be contextualized for nested
            // repeat groups...
            TreeReference countRef = FormInstance.unpackReference(repeat.getCountReference());
            TreeElement countNode = this.getMainInstance().resolveReference(countRef.contextualize(repeatRef));
            if (countNode == null) {
                throw new RuntimeException("Could not locate the repeat count value expected at " + repeat.getCountReference().getReference().toString());
            }
            // get the total multiplicity possible
            IAnswerData count = countNode.getValue();
            long fullcount = count == null ? 0 : (Integer) count.getValue();
            if (fullcount <= currentMultiplicity) {
                return false;
            }
        } else {
            // Otherwise the user can never add repeat instances
            return false;
        }
    }
    return true;
}
Also used : IAnswerData(org.javarosa.core.model.data.IAnswerData) TreeReference(org.javarosa.core.model.instance.TreeReference) Constraint(org.javarosa.core.model.condition.Constraint) TreeElement(org.javarosa.core.model.instance.TreeElement)

Example 24 with TreeReference

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

the class FormDef method getAbsRef.

// take a (possibly relative) reference, and make it absolute based on its parent
// moved from the parser to this class so it can be used more cleanly by ItemsetBinding
public static IDataReference getAbsRef(IDataReference ref, TreeReference parentRef) {
    TreeReference tref;
    if (!parentRef.isAbsolute()) {
        throw new RuntimeException("XFormParser.getAbsRef: parentRef must be absolute");
    }
    if (ref != null) {
        tref = (TreeReference) ref.getReference();
    } else {
        // only happens for <group>s with no binding
        tref = TreeReference.selfRef();
    }
    tref = tref.parent(parentRef);
    if (tref == null) {
        throw new XFormParseException("Binding path [" + tref + "] not allowed with parent binding of [" + parentRef + "]");
    }
    return new XPathReference(tref);
}
Also used : TreeReference(org.javarosa.core.model.instance.TreeReference) XFormParseException(org.javarosa.xform.parse.XFormParseException) XPathReference(org.javarosa.model.xform.XPathReference)

Example 25 with TreeReference

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

the class FormDef method initEvalContext.

/**
 * @param ec The new Evaluation Context
 */
private void initEvalContext(EvaluationContext ec) {
    if (!ec.getFunctionHandlers().containsKey("jr:itext")) {
        final FormDef f = this;
        ec.addFunctionHandler(new IFunctionHandler() {

            @Override
            public String getName() {
                return "jr:itext";
            }

            @Override
            public Object eval(Object[] args, EvaluationContext ec) {
                String textID = (String) args[0];
                try {
                    // SUUUUPER HACKY
                    String form = ec.getOutputTextForm();
                    if (form != null) {
                        textID = textID + ";" + form;
                        String result = f.getLocalizer().getRawText(f.getLocalizer().getLocale(), textID);
                        return result == null ? "" : result;
                    } else {
                        String text = f.getLocalizer().getText(textID);
                        return text == null ? "[itext:" + textID + "]" : text;
                    }
                } catch (NoSuchElementException nsee) {
                    return "[nolocale]";
                }
            }

            @Override
            public List<Class[]> getPrototypes() {
                Class[] proto = { String.class };
                List<Class[]> v = new ArrayList<Class[]>(1);
                v.add(proto);
                return v;
            }

            @Override
            public boolean rawArgs() {
                return false;
            }

            @Override
            public boolean realTime() {
                return false;
            }
        });
    }
    /*
       * function to reverse a select value into the display label for that
       * choice in the question it came from
       * 
       * arg 1: select value arg 2: string xpath referring to origin question;
       * must be absolute path
       * 
       * this won't work at all if the original label needed to be
       * processed/calculated in some way (<output>s, etc.) (is this even
       * allowed?) likely won't work with multi-media labels _might_ work for
       * itemsets, but probably not very well or at all; could potentially work
       * better if we had some context info DOES work with localization
       * 
       * it's mainly intended for the simple case of reversing a question with
       * compile-time-static fields, for use inside an <output>
       */
    if (!ec.getFunctionHandlers().containsKey("jr:choice-name")) {
        final FormDef f = this;
        ec.addFunctionHandler(new IFunctionHandler() {

            @Override
            public String getName() {
                return "jr:choice-name";
            }

            @Override
            public Object eval(Object[] args, EvaluationContext ec) {
                try {
                    String value = (String) args[0];
                    String questionXpath = (String) args[1];
                    TreeReference ref = RestoreUtils.xfFact.ref(questionXpath);
                    QuestionDef q = findQuestionByRef(ref, f);
                    if (q == null || (q.getControlType() != Constants.CONTROL_SELECT_ONE && q.getControlType() != Constants.CONTROL_SELECT_MULTI)) {
                        return "";
                    }
                    // NOTE: this is highly suspect. We have no context against
                    // which to evaluate
                    // a dynamic selection list. This will generally cause that
                    // evaluation to break
                    // if any filtering is done, or, worst case, give unexpected
                    // results.
                    // 
                    // We should hook into the existing code (FormEntryPrompt) for
                    // pulling
                    // display text for select choices. however, it's hard,
                    // because we don't really have
                    // any context to work with, and all the situations where that
                    // context would be used
                    // don't make sense for trying to reverse a select value back
                    // to a label in an unrelated
                    // expression
                    List<SelectChoice> choices;
                    ItemsetBinding itemset = q.getDynamicChoices();
                    if (itemset != null) {
                        if (itemset.getChoices() == null) {
                            if (ref.isAmbiguous()) {
                                // SurveyCTO: We need a absolute "ref" to populate the dynamic choices,
                                // like we do when we populate those at FormEntryPrompt (line 251).
                                // The "ref" here is ambiguous, so we need to make it concrete first.
                                ref = ref.contextualize(ec.getContextRef());
                            }
                            f.populateDynamicChoices(itemset, ref);
                        }
                        choices = itemset.getChoices();
                    } else {
                        // static choices
                        choices = q.getChoices();
                    }
                    if (choices != null) {
                        for (SelectChoice ch : choices) {
                            if (ch.getValue().equals(value)) {
                                // this is really not ideal. we should hook into the
                                // existing code (FormEntryPrompt) for pulling
                                // display text for select choices. however, it's
                                // hard, because we don't really have
                                // any context to work with, and all the situations
                                // where that context would be used
                                // don't make sense for trying to reverse a select
                                // value back to a label in an unrelated
                                // expression
                                String textID = ch.getTextID();
                                String templateStr;
                                if (textID != null) {
                                    templateStr = f.getLocalizer().getText(textID);
                                } else {
                                    templateStr = ch.getLabelInnerText();
                                }
                                return fillTemplateString(templateStr, ref);
                            }
                        }
                    }
                    return "";
                } catch (Exception e) {
                    throw new WrappedException("error in evaluation of xpath function [choice-name]", e);
                }
            }

            @Override
            public List<Class[]> getPrototypes() {
                Class[] proto = { String.class, String.class };
                List<Class[]> v = new ArrayList<Class[]>(1);
                v.add(proto);
                return v;
            }

            @Override
            public boolean rawArgs() {
                return false;
            }

            @Override
            public boolean realTime() {
                return false;
            }
        });
    }
}
Also used : WrappedException(org.javarosa.core.log.WrappedException) IFunctionHandler(org.javarosa.core.model.condition.IFunctionHandler) XPathException(org.javarosa.xpath.XPathException) InvalidReferenceException(org.javarosa.core.model.instance.InvalidReferenceException) DeserializationException(org.javarosa.core.util.externalizable.DeserializationException) NoSuchElementException(java.util.NoSuchElementException) WrappedException(org.javarosa.core.log.WrappedException) IOException(java.io.IOException) XFormParseException(org.javarosa.xform.parse.XFormParseException) TreeReference(org.javarosa.core.model.instance.TreeReference) List(java.util.List) ArrayList(java.util.ArrayList) ExtWrapList(org.javarosa.core.util.externalizable.ExtWrapList) EvaluationContext(org.javarosa.core.model.condition.EvaluationContext) NoSuchElementException(java.util.NoSuchElementException)

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