예제 #1
0
        public IDataPointer[] retrieveExternalDataPointer(IAnswerData data)
        {
            IEnumerator en = additionalSerializers.GetEnumerator();

            while (en.MoveNext())
            {
                IAnswerDataSerializer serializer = (IAnswerDataSerializer)en.Current;
                Boolean contains = serializer.containsExternalData(data);
                if (contains != null)
                {
                    return(serializer.retrieveExternalDataPointer(data));
                }
            }
            if (data is PointerAnswerData)
            {
                IDataPointer[] pointer = new IDataPointer[1];
                pointer[0] = (IDataPointer)((PointerAnswerData)data).getValue();
                return(pointer);
            }
            else if (data is MultiPointerAnswerData)
            {
                return((IDataPointer[])((MultiPointerAnswerData)data).Value);
            }
            //This shouldn't have been called.
            return(null);
        }
예제 #2
0
        //this method is for copying in the answers to an itemset. the template node of the destination
        //is used for overall structure (including data types), and the itemset source node is used for
        //raw data. note that data may be coerced across types, which may result in type conversion error
        //very similar in structure to populate()
        public void populateTemplate(TreeElement incoming, FormDef f)
        {
            if (this.isLeaf())
            {
                IAnswerData value = incoming.value;
                if (value == null)
                {
                    this.setValue(null);
                }
                else
                {
                    Type classType = CompactInstanceWrapper.classForDataType(this.dataType);

                    if (classType == null)
                    {
                        throw new SystemException("data type [" + value.GetType().Name + "] not supported inside itemset");
                    }
                    else if (classType.IsAssignableFrom(value.GetType()) &&
                             !(value is SelectOneData || value is SelectMultiData))
                    {
                        this.setValue(value);
                    }
                    else
                    {
                        String      textVal  = RestoreUtils.xfFact.serializeData(value);
                        IAnswerData typedVal = RestoreUtils.xfFact.parseData(textVal, this.dataType, this.getRef(), f);
                        this.setValue(typedVal);
                    }
                }
            }
            else
            {
                for (int i = 0; i < this.getNumChildren(); i++)
                {
                    TreeElement        child       = this.getChildAt(i);
                    List <TreeElement> newChildren = incoming.getChildrenWithName(child.getName());

                    if (child.repeatable)
                    {
                        for (int k = 0; k < newChildren.Count; k++)
                        {
                            TreeElement template = f.Instance.getTemplate(child.getRef());
                            TreeElement newChild = template.deepCopy(false);
                            newChild.setMult(k);
                            this.children.Insert(i + k + 1, newChild);
                            newChild.populateTemplate((TreeElement)newChildren[k], f);
                        }
                        i += newChildren.Count;
                    }
                    else
                    {
                        child.populateTemplate((TreeElement)newChildren[0], f);
                    }
                }
            }
        }
예제 #3
0
        /**
         * saveAnswer attempts to save the current answer into the data model
         * without doing any constraint checking. Only use this if you know what
         * you're doing. For normal form filling you should always use
         * answerQuestion or answerCurrentQuestion.
         *
         * @param index
         * @param data
         * @return true if saved successfully, false otherwise.
         */
        public Boolean saveAnswer(FormIndex index, IAnswerData data)
        {
            if (model.getEvent(index) != FormEntryController.EVENT_QUESTION)
            {
                throw new SystemException("Non-Question object at the form index.");
            }
            TreeElement element = model.getTreeElement(index);

            return(commitAnswer(element, index, data));
        }
예제 #4
0
 public void setValue(IAnswerData value)
 {
     if (isLeaf())
     {
         this.value = value;
     }
     else
     {
         throw new SystemException("Can't set data value for node that has children!");
     }
 }
예제 #5
0
        /* ==== SPECIAL SETTERS (SETTERS WITH SIDE-EFFECTS) ==== */

        public Boolean setAnswer(IAnswerData answer)
        {
            if (value != null || answer != null)
            {
                setValue(answer);
                alertStateObservers(FormElementStateListener_Fields.CHANGE_DATA);
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #6
0
 /**
  * commitAnswer actually saves the data into the datamodel.
  *
  * @param element
  * @param index
  * @param data
  * @return true if saved successfully, false otherwise
  */
 private Boolean commitAnswer(TreeElement element, FormIndex index, IAnswerData data)
 {
     if (data != null || element.getValue() != null)
     {
         // we should check if the data to be saved is already the same as
         // the data in the model, but we can't (no IAnswerData.equals())
         model.getForm().setValue(data, index.getReference(), element);
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #7
0
 public Boolean canSerialize(IAnswerData data)
 {
     if (data is StringData || data is DateData || data is TimeData ||
         data is SelectMultiData || data is SelectOneData ||
         data is IntegerData || data is DecimalData || data is PointerAnswerData ||
         data is MultiPointerAnswerData || data is GeoPointData || data is LongData || data is DateTimeData || data is UncastData)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #8
0
 public static Object unpackValue(IAnswerData val)
 {
     if (val == null)
     {
         return("");
     }
     else if (val is UncastData)
     {
         return(val.Value);
     }
     else if (val is IntegerData)
     {
         return(( Double)(((int)val.Value)));
     }
     else if (val is LongData)
     {
         return(( Double)(((long)val.Value)));
     }
     else if (val is DecimalData)
     {
         return(val.Value);
     }
     else if (val is StringData)
     {
         return(val.Value);
     }
     else if (val is SelectOneData)
     {
         return(((Selection)val.Value).Value);
     }
     else if (val is SelectMultiData)
     {
         return((new XFormAnswerDataSerializer()).serializeAnswerData(val));
     }
     else if (val is DateData)
     {
         return(val.Value);
     }
     else if (val is BooleanData)
     {
         return(val.Value);
     }
     else
     {
         Console.WriteLine("warning: unrecognized data type in xpath expr: " + val.GetType().Name);
         return(val.Value);        //is this a good idea?
     }
 }
예제 #9
0
        public String getAnswerText()
        {
            IAnswerData data = this.getAnswerValue();

            if (data == null)
            {
                return(null);
            }
            else
            {
                String text;

                //[email protected] - Aug 11, 2010 - Added special logic to
                //capture and display the appropriate value for selections
                //and multi-selects.
                if (data is SelectOneData)
                {
                    text = this.getSelectItemText((Selection)data);
                }
                else if (data is SelectMultiData)
                {
                    String           returnValue = "";
                    List <Selection> values      = (List <Selection>)data;
                    foreach (Selection value in values)
                    {
                        returnValue += this.getSelectItemText(value) + " ";
                    }
                    text = returnValue;
                }
                else
                {
                    text = data.DisplayText;
                }

                if (getControlType() == Constants.CONTROL_SECRET)
                {
                    String obfuscated = "";
                    for (int i = 0; i < text.Length; ++i)
                    {
                        obfuscated += "*";
                    }
                    text = obfuscated;
                }
                return(text);
            }
        }
예제 #10
0
        /**
         * Attempts to save the answer at the specified FormIndex into the
         * datamodel.
         *
         * @param index
         * @param data
         * @return OK if save was successful, error if a constraint was violated.
         */
        public int answerQuestion(FormIndex index, IAnswerData data)
        {
            QuestionDef q = model.getQuestionPrompt(index).getQuestion();

            if (model.getEvent(index) != FormEntryController.EVENT_QUESTION)
            {
                throw new SystemException("Non-Question object at the form index.");
            }
            TreeElement element         = model.getTreeElement(index);
            Boolean     complexQuestion = q.isComplex();

            Boolean hasConstraints = false;

            if (element.required && data == null)
            {
                return(ANSWER_REQUIRED_BUT_EMPTY);
            }
            else if (!complexQuestion && !model.getForm().evaluateConstraint(index.getReference(), data))
            {
                return(ANSWER_CONSTRAINT_VIOLATED);
            }
            else if (!complexQuestion)
            {
                commitAnswer(element, index, data);
                return(ANSWER_OK);
            }
            else if (complexQuestion && hasConstraints)
            {
                //TODO: itemsets: don't currently evaluate constraints for itemset/copy -- haven't figured out how handle it yet
                throw new SystemException("Itemsets do not currently evaluate constraints. Your constraint will not work, please remove it before proceeding.");
            }
            else
            {
                try
                {
                    model.getForm().copyItemsetAnswer(q, element, data);
                }
                catch (InvalidReferenceException ire)
                {
                    Console.WriteLine(ire.StackTrace);
                    throw new SystemException("Invalid reference while copying itemset answer: " + ire.Message);
                }
                return(ANSWER_OK);
            }
        }
예제 #11
0
        public Object serializeAnswerData(IAnswerData data, int dataType)
        {
            // First, we want to go through the additional serializers, as they should
            // take priority to the default serializations
            IEnumerator en = additionalSerializers.GetEnumerator();

            while (en.MoveNext())
            {
                IAnswerDataSerializer serializer = (IAnswerDataSerializer)en.Current;
                if (serializer.canSerialize(data))
                {
                    return(serializer.serializeAnswerData(data, dataType));
                }
            }
            //Defaults
            Object result = serializeAnswerData(data);

            return(result);
        }
예제 #12
0
        public TreeReference addNode(TreeReference ambigRef, IAnswerData data, int dataType)
        {
            TreeReference ref_ = ambigRef.clone();
            TreeElement   node = createNode(ref_);

            if (node != null)
            {
                if (dataType >= 0)
                {
                    node.dataType = dataType;
                }

                node.setValue(data);
                return(ref_);
            }
            else
            {
                return(null);
            }
        }
예제 #13
0
 public String getConstraintText(String textForm, IAnswerData attemptedValue)
 {
     if (mTreeElement.getConstraint() == null)
     {
         return(null);
     }
     else
     {
         EvaluationContext ec = new EvaluationContext(form.exprEvalContext, mTreeElement.getRef());
         if (textForm != null)
         {
             ec.OutputTextForm = textForm;
         }
         if (attemptedValue != null)
         {
             ec.isConstraint   = true;
             ec.candidateValue = attemptedValue;
         }
         return(mTreeElement.getConstraint().getConstraintMessage(ec, form.Instance));
     }
 }
예제 #14
0
        /*
         * (non-Javadoc)
         * @see org.javarosa.core.model.IAnswerDataSerializer#containsExternalData(org.javarosa.core.model.data.IAnswerData)
         */
        public Boolean containsExternalData(IAnswerData data)
        {
            //First check for registered serializers to identify whether
            //they override this one.
            IEnumerator en = additionalSerializers.GetEnumerator();

            while (en.MoveNext())
            {
                IAnswerDataSerializer serializer = (IAnswerDataSerializer)en.Current;
                Boolean contains = serializer.containsExternalData(data);
                if (contains != null)
                {
                    return(contains);
                }
            }
            if (data is PointerAnswerData ||
                data is MultiPointerAnswerData)
            {
                return(true);
            }
            return(false);
        }
예제 #15
0
 /**
  * For the current index: Checks whether the index represents a node which
  * should exist given a non-interactive repeat, along with a count for that
  * repeat which is beneath the dynamic level specified.
  *
  * If this index does represent such a node, the new model for the repeat is
  * created behind the scenes and the index for the initial question is
  * returned.
  *
  * Note: This method will not prevent the addition of new repeat elements in
  * the interface, it will merely use the xforms repeat hint to create new
  * nodes that are assumed to exist
  *
  * @param The index to be evaluated as to whether the underlying model is
  *        hinted to exist
  */
 private void createModelIfNecessary(FormIndex index)
 {
     if (index.isInForm())
     {
         IFormElement e = getForm().getChild(index);
         if (e is GroupDef)
         {
             GroupDef g = (GroupDef)e;
             if (g.Repeat && g.CountReference != null)
             {
                 IAnswerData count = getForm().Instance.getDataValue(g.CountReference);
                 if (count != null)
                 {
                     long          fullcount = ((int)count.Value);
                     TreeReference ref_      = getForm().getChildInstanceRef(index);
                     TreeElement   element   = getForm().Instance.resolveReference(ref_);
                     if (element == null)
                     {
                         if (index.getInstanceIndex() < fullcount)
                         {
                             try
                             {
                                 getForm().createNewRepeat(index);
                             }
                             catch (InvalidReferenceException ire)
                             {
                                 Console.WriteLine(ire.StackTrace);
                                 throw new SystemException("Invalid Reference while creting new repeat!" + ire.Message);
                             }
                         }
                     }
                 }
             }
         }
     }
 }
예제 #16
0
 public ExtWrapAnswerData(CompactInstanceWrapper instance, int dataType, IAnswerData val)
 {
     this.val      = val;
     this.dataType = dataType;
 }
예제 #17
0
 public String serializeData(IAnswerData data)
 {
     return((String)(new XFormAnswerDataSerializer().serializeAnswerData(data)));
 }
예제 #18
0
        //note: code overlap with FormDef.copyItemsetAnswer
        public IAnswerData getAnswerValue()
        {
            QuestionDef q = getQuestion();

            ItemsetBinding itemset = q.getDynamicChoices();

            if (itemset != null)
            {
                if (itemset.valueRef != null)
                {
                    List <SelectChoice> choices           = getSelectChoices();
                    List <String>       preselectedValues = new List <String>();

                    //determine which selections are already present in the answer
                    if (itemset.copyMode)
                    {
                        TreeReference        destRef  = itemset.getDestRef().contextualize(mTreeElement.getRef());
                        List <TreeReference> subNodes = form.Instance.expandReference(destRef);
                        for (int i = 0; i < subNodes.Count; i++)
                        {
                            TreeElement node  = form.Instance.resolveReference(subNodes[i]);
                            String      value = itemset.getRelativeValue().evalReadable(form.Instance, new EvaluationContext(form.exprEvalContext, node.getRef()));
                            preselectedValues.Add(value);
                        }
                    }
                    else
                    {
                        List <Selection> sels = new List <Selection>();
                        IAnswerData      data = mTreeElement.getValue();
                        if (data is SelectMultiData)
                        {
                            sels = (List <Selection>)data.Value;
                        }
                        else if (data is SelectOneData)
                        {
                            sels = new List <Selection>();
                            sels.Add((Selection)data.Value);
                        }
                        for (int i = 0; i < sels.Count; i++)
                        {
                            preselectedValues.Add(sels[i].xmlValue);
                        }
                    }

                    //populate 'selection' with the corresponding choices (matching 'value') from the dynamic choiceset
                    List <Selection> selection = new List <Selection>();
                    for (int i = 0; i < preselectedValues.Count; i++)
                    {
                        String       value  = preselectedValues[i];
                        SelectChoice choice = null;
                        for (int j = 0; j < choices.Count; j++)
                        {
                            SelectChoice ch = choices[j];
                            if (value.Equals(ch.Value))
                            {
                                choice = ch;
                                break;
                            }
                        }

                        selection.Add(choice.selection());
                    }

                    //convert to IAnswerData
                    if (selection.Count == 0)
                    {
                        return(null);
                    }
                    else if (q.ControlType == Constants.CONTROL_SELECT_MULTI)
                    {
                        return(new SelectMultiData(selection));
                    }
                    else if (q.ControlType == Constants.CONTROL_SELECT_ONE)
                    {
                        return(new SelectOneData(selection[0])); //do something if more than one selected?
                    }
                    else
                    {
                        throw new SystemException("can't happen");
                    }
                }
                else
                {
                    return(null); //cannot map up selections without <value>
                }
            }
            else
            { //static choices
                return(mTreeElement.getValue());
            }
        }
예제 #19
0
 public String getConstraintText(IAnswerData attemptedValue)
 {
     return(getConstraintText(null, attemptedValue));
 }
예제 #20
0
 /**
  * saveAnswer attempts to save the current answer into the data model
  * without doing any constraint checking. Only use this if you know what
  * you're doing. For normal form filling you should always use
  * answerQuestion().
  *
  * @param index
  * @param data
  * @return true if saved successfully, false otherwise.
  */
 public Boolean saveAnswer(IAnswerData data)
 {
     return(saveAnswer(model.getFormIndex(), data));
 }
예제 #21
0
        //rebuilding a node from an imported instance
        //  there's a lot of error checking we could do on the received instance, but it's
        //  easier to just ignore the parts that are incorrect
        public void populate(TreeElement incoming, FormDef f)
        {
            if (this.isLeaf())
            {
                // check that incoming doesn't have children?

                IAnswerData value = incoming.getValue();
                if (value == null)
                {
                    this.setValue(null);
                }
                else if (this.dataType == Constants.DATATYPE_TEXT ||
                         this.dataType == Constants.DATATYPE_NULL)
                {
                    this.setValue(value);             // value is a StringData
                }
                else
                {
                    String      textVal  = value.ToString();
                    IAnswerData typedVal = RestoreUtils.xfFact.parseData(textVal, this.dataType, this.getRef(), f);
                    this.setValue(typedVal);
                }
            }
            else
            {
                ArrayList names = new ArrayList();
                for (int i = 0; i < this.getNumChildren(); i++)
                {
                    TreeElement child = this.getChildAt(i);
                    if (!names.Contains(child.getName()))
                    {
                        names.Add(child.getName());
                    }
                }

                // remove all default repetitions from skeleton data model (_preserving_ templates, though)
                for (int i = 0; i < this.getNumChildren(); i++)
                {
                    TreeElement child = this.getChildAt(i);
                    if (child.repeatable && child.getMult() != TreeReference.INDEX_TEMPLATE)
                    {
                        this.removeChildAt(i);
                        i--;
                    }
                }

                // make sure ordering is preserved (needed for compliance with xsd schema)
                if (this.getNumChildren() != names.Count)
                {
                    throw new SystemException("sanity check failed");
                }

                for (int i = 0; i < this.getNumChildren(); i++)
                {
                    TreeElement child        = this.getChildAt(i);
                    String      expectedName = (String)names[i];

                    if (!child.getName().Equals(expectedName))
                    {
                        TreeElement child2 = null;
                        int         j;

                        for (j = i + 1; j < this.getNumChildren(); j++)
                        {
                            child2 = this.getChildAt(j);
                            if (child2.getName().Equals(expectedName))
                            {
                                break;
                            }
                        }
                        if (j == this.getNumChildren())
                        {
                            throw new SystemException("sanity check failed");
                        }

                        this.removeChildAt(j);
                        this.children.Insert(i, child2);
                    }
                }
                // java i hate you so much

                for (int i = 0; i < this.getNumChildren(); i++)
                {
                    TreeElement        child       = this.getChildAt(i);
                    List <TreeElement> newChildren = incoming.getChildrenWithName(child.getName());

                    if (child.repeatable)
                    {
                        for (int k = 0; k < newChildren.Count; k++)
                        {
                            TreeElement newChild = child.deepCopy(true);
                            newChild.setMult(k);
                            this.children.Insert(i + k + 1, newChild);
                            newChild.populate((TreeElement)newChildren[k], f);
                        }
                        i += newChildren.Count;
                    }
                    else
                    {
                        if (newChildren.Count == 0)
                        {
                            child.setRelevant(false);
                        }
                        else
                        {
                            child.populate((TreeElement)newChildren[0], f);
                        }
                    }
                }
            }
        }
예제 #22
0
        /* ==== SERIALIZATION ==== */

        /*
         * TODO:
         *
         * this new serialization scheme is kind of lame. ideally, we shouldn't have
         * to sub-class TreeElement at all; we should have an API that can
         * seamlessly represent complex data model objects (like weight history or
         * immunizations) as if they were explicity XML subtrees underneath the
         * parent TreeElement
         *
         * failing that, we should wrap this scheme in an ExternalizableWrapper
         */

        /*
         * (non-Javadoc)
         *
         * @see
         * org.javarosa.core.services.storage.utilities.Externalizable#readExternal
         * (java.io.DataInputStream)
         */
        public void readExternal(BinaryReader in_renamed, PrototypeFactory pf)
        {
            name         = ExtUtil.nullIfEmpty(ExtUtil.readString(in_renamed));
            multiplicity = ExtUtil.readInt(in_renamed);
            repeatable   = ExtUtil.readBool(in_renamed);
            value        = (IAnswerData)ExtUtil.read(in_renamed, new ExtWrapNullable(new ExtWrapTagged()), pf);

            // children = ExtUtil.nullIfEmpty((Vector)ExtUtil.read(in, new
            // ExtWrapList(TreeElement.class), pf));

            // Jan 22, 2009 - [email protected]
            // old line: children = ExtUtil.nullIfEmpty((Vector)ExtUtil.read(in, new
            // ExtWrapList(TreeElement.class), pf));
            // New Child deserialization
            // 1. read null status as boolean
            // 2. read number of children
            // 3. for i < number of children
            // 3.1 if read boolean true , then create TreeElement and deserialize
            // directly.
            // 3.2 if read boolean false then create tagged element and deserialize
            // child
            if (!ExtUtil.readBool(in_renamed))
            {
                // 1.
                children = null;
            }
            else
            {
                children = new ArrayList();
                // 2.
                int numChildren = (int)ExtUtil.readNumeric(in_renamed);
                // 3.
                for (int i = 0; i < numChildren; ++i)
                {
                    Boolean     normal = ExtUtil.readBool(in_renamed);
                    TreeElement child;

                    if (normal)
                    {
                        // 3.1
                        child = new TreeElement();
                        child.readExternal(in_renamed, pf);
                    }
                    else
                    {
                        // 3.2
                        child = (TreeElement)ExtUtil.read(in_renamed, new ExtWrapTagged(), pf);
                    }
                    child.setParent(this);
                    children.Add(child);
                }
            }

            // end Jan 22, 2009

            dataType          = ExtUtil.readInt(in_renamed);
            relevant          = ExtUtil.readBool(in_renamed);
            required          = ExtUtil.readBool(in_renamed);
            enabled           = ExtUtil.readBool(in_renamed);
            relevantInherited = ExtUtil.readBool(in_renamed);
            enabledInherited  = ExtUtil.readBool(in_renamed);
            constraint        = (Constraint)ExtUtil.read(in_renamed, new ExtWrapNullable(
                                                             typeof(Constraint)), pf);
            preloadHandler = ExtUtil.nullIfEmpty(ExtUtil.readString(in_renamed));
            preloadParams  = ExtUtil.nullIfEmpty(ExtUtil.readString(in_renamed));

            ArrayList attStrings = ExtUtil.nullIfEmpty((ArrayList)ExtUtil.read(in_renamed,
                                                                               new ExtWrapList(typeof(String)), pf));

            setAttributesFromSingleStringVector(attStrings);
        }
예제 #23
0
 /**
  * Attempts to save answer at the current FormIndex into the datamodel.
  *
  * @param data
  * @return
  */
 public int answerQuestion(IAnswerData data)
 {
     return(answerQuestion(model.getFormIndex(), data));
 }
예제 #24
0
        public Object serializeAnswerData(IAnswerData data)
        {
            if (data is StringData)
            {
                return(serializeAnswerData((StringData)data));
            }
            else if (data is SelectMultiData)
            {
                return(serializeAnswerData((SelectMultiData)data));
            }
            else if (data is SelectOneData)
            {
                return(serializeAnswerData((SelectOneData)data));
            }
            else if (data is IntegerData)
            {
                return(serializeAnswerData((IntegerData)data));
            }
            else if (data is LongData)
            {
                return(serializeAnswerData((LongData)data));
            }
            else if (data is DecimalData)
            {
                return(serializeAnswerData((DecimalData)data));
            }
            else if (data is DateData)
            {
                return(serializeAnswerData((DateData)data));
            }
            else if (data is TimeData)
            {
                return(serializeAnswerData((TimeData)data));
            }
            else if (data is PointerAnswerData)
            {
                return(serializeAnswerData((PointerAnswerData)data));
            }
            else if (data is MultiPointerAnswerData)
            {
                return(serializeAnswerData((MultiPointerAnswerData)data));
            }
            else if (data is GeoPointData)
            {
                return(serializeAnswerData((GeoPointData)data));
            }
            else if (data is DateTimeData)
            {
                return(serializeAnswerData((DateTimeData)data));
            }
            else if (data is BooleanData)
            {
                return(serializeAnswerData((BooleanData)data));
            }
            else if (data is UncastData)
            {
                return(serializeAnswerData((UncastData)data));
            }

            return(null);
        }