Example #1
0
        /// <summary>
        /// Gets the content from the SIFElement for the specified version of SIF. Only
        /// elements that apply to the requested version of SIF will be returned.
        /// </summary>
        /// <param name="element">The element to retrieve content from</param>
        /// <param name="version"></param>
        /// <returns></returns>
        public virtual IList <Element> GetContent(SifElement element, SifVersion version)
        {
            List <Element>            returnValue = new List <Element>();
            ICollection <SimpleField> fields      = element.GetFields();

            foreach (SimpleField val in fields)
            {
                IElementDef def = val.ElementDef;
                if (def.IsSupported(version) &&
                    !def.IsAttribute(version) &&
                    def.Field)
                {
                    returnValue.Add(val);
                }
            }

            IList <SifElement> children = element.GetChildList();

            foreach (SifElement val in children)
            {
                IElementDef def = val.ElementDef;
                if (def.IsSupported(version))
                {
                    returnValue.Add(val);
                }
            }


            MergeSort.Sort <Element>(returnValue, ElementSorter <Element> .GetInstance(version));
            //returnValue.Sort( ElementSorter<Element>.GetInstance( version ) );
            return(returnValue);
        }
Example #2
0
        /// <summary>
        /// Gets the content from the SIFElement for the specified version of SIF. Only
        /// elements that apply to the requested version of SIF will be returned.
        /// </summary>
        /// <param name="element">The element to retrieve content from</param>
        /// <param name="version"></param>
        /// <returns></returns>
        public override IList <Element> GetContent(SifElement element, SifVersion version)
        {
            List <Element>            returnValue = new List <Element>();
            ICollection <SimpleField> fields      = element.GetFields();

            foreach (SimpleField val in fields)
            {
                IElementDef def = val.ElementDef;
                if (def.IsSupported(version) &&
                    !def.IsAttribute(version) &&
                    def.Field)
                {
                    returnValue.Add(val);
                }
            }

            IList <SifElement> children = element.GetChildList();

            foreach (SifElement val in children)
            {
                IElementDef def = val.ElementDef;
                if (def.IsSupported(version))
                {
                    if (def.IsCollapsed(version))
                    {
                        ICollection <Element> subElements = GetContent(val, version);
                        // FIXUP the ElementDef for this version of SIF.
                        // for example, StudentPersonal/EmailList/Email needs it's
                        // ElementDef set to "StudentPersonal_Email"
                        foreach (Element e in subElements)
                        {
                            IElementDef subElementDef = e.ElementDef;
                            if (version.CompareTo(subElementDef.EarliestVersion) >= 0)
                            {
                                String      tag         = subElementDef.Tag(Adk.SifVersion);
                                IElementDef restoredDef = Adk.Dtd.LookupElementDef(element.ElementDef, tag);
                                if (restoredDef != null)
                                {
                                    e.ElementDef = restoredDef;
                                }
                                returnValue.Add(e);
                            }
                        }
                    }
                    else
                    {
                        returnValue.Add(val);
                    }
                }
            }
            MergeSort.Sort <Element>(returnValue, ElementSorter <Element> .GetInstance(version));
            //returnValue.Sort(ElementSorter<Element>.GetInstance(version));
            return(returnValue);
        }
Example #3
0
 /// <summary>
 /// Parses the source of the XmlReader into a SifElement object.
 /// </summary>
 /// <param name="reader">The reader containing the Xml data to be parsed</param>
 /// <param name="zone">The Zone from which the message was received, or null if
 /// not applicable or not known</param>
 /// <param name="flags">The flags to use for parsing</param>
 /// <param name="version">The version of SIF that will be associated with the
 /// returned object.</param>
 /// <returns> A SifElement object encapsulating the message payload (e.g.
 /// a OpenADK.Library.us.Student.StudentPersonal object)</returns>
 /// <exception cref="OpenADK.Library.AdkParsingException">AdkParsingException is thrown if unable to
 /// parse the message</exception>
 /// <exception cref="System.IO.IOException"> IOException is thrown if an error is reported while reading
 /// the message content</exception>
 public SifElement Parse(XmlReader reader,
                         IZone zone,
                         SifParserFlags flags,
                         SifVersion version)
 {
     try
     {
         reader.MoveToContent();
         if (reader.LocalName == "SIF_Message")
         {
             SifElement element = ReadSIFMessageElement(reader, Adk.Dtd, zone, flags, version);
             return(element.GetChildList()[0]);
         }
         else
         {
             version = ParseVersion(reader, Adk.Dtd, zone, flags, version);
             return(ParseElementStream(reader, version, Adk.Dtd, zone, flags));
         }
     }
     catch (XmlException xmle)
     {
         throw new AdkParsingException(xmle.Message, zone, xmle);
     }
 }
Example #4
0
        /// <summary>
        /// Gets the content from the SIFElement for the specified version of SIF. Only
        /// elements that apply to the requested version of SIF will be returned.
        /// </summary>
        /// <param name="element">The element to retrieve content from</param>
        /// <param name="version"></param>
        /// <returns></returns>
        public virtual IList<Element> GetContent( SifElement element, SifVersion version )
        {
            List<Element> returnValue = new List<Element>();
            ICollection<SimpleField> fields = element.GetFields();
            foreach (SimpleField val in fields) {
                IElementDef def = val.ElementDef;
                if (def.IsSupported(version) &&
                    !def.IsAttribute(version) &&
                    def.Field)
                {
                    returnValue.Add(val);
                }
            }

               IList<SifElement> children = element.GetChildList();
            foreach(SifElement val in children ) {
                IElementDef def = val.ElementDef;
                if (def.IsSupported(version))
                {
                    returnValue.Add(val);
                }
            }

            MergeSort.Sort<Element>(returnValue, ElementSorter<Element>.GetInstance(version));
            //returnValue.Sort( ElementSorter<Element>.GetInstance( version ) );
            return returnValue;
        }
        /// <summary>
        /// Gets the content from the SIFElement for the specified version of SIF. Only
        /// elements that apply to the requested version of SIF will be returned.
        /// </summary>
        /// <param name="element">The element to retrieve content from</param>
        /// <param name="version"></param>
        /// <returns></returns>
        public override IList<Element> GetContent(SifElement element, SifVersion version)
        {
            List<Element> returnValue = new List<Element>();
            ICollection<SimpleField> fields = element.GetFields();
            foreach (SimpleField val in fields)
            {
                IElementDef def = val.ElementDef;
                if (def.IsSupported(version) &&
                     !def.IsAttribute(version) &&
                     def.Field )
                {
                    returnValue.Add(val);
                }
            }

            IList<SifElement> children = element.GetChildList();
            foreach (SifElement val in children)
            {
                IElementDef def = val.ElementDef;
                if (def.IsSupported(version))
                {
                    if (def.IsCollapsed(version))
                    {
                        ICollection<Element> subElements = GetContent(val, version);
                        // FIXUP the ElementDef for this version of SIF.
                        // for example, StudentPersonal/EmailList/Email needs it's
                        // ElementDef set to "StudentPersonal_Email"
                        foreach (Element e in subElements)
                        {
                            IElementDef subElementDef = e.ElementDef;
                            if (version.CompareTo(subElementDef.EarliestVersion) >= 0)
                            {
                                String tag = subElementDef.Tag(Adk.SifVersion);
                                IElementDef restoredDef = Adk.Dtd.LookupElementDef(element.ElementDef, tag);
                                if (restoredDef != null)
                                {
                                    e.ElementDef = restoredDef;
                                }
                                returnValue.Add(e);
                            }
                        }
                    }
                    else
                    {
                        returnValue.Add(val);
                    }
                }
            }
            MergeSort.Sort<Element>(returnValue, ElementSorter<Element>.GetInstance(version));
            //returnValue.Sort(ElementSorter<Element>.GetInstance(version));
            return returnValue;
        }
Example #6
0
        /// <summary>  Recursively parse an XPath-like query.</summary>
        /// <param name="relativeTo">The SifElement this iteration is relative to. For the
        /// first call to this method, the <i>relativeTo</i> parameter is usually
        /// a SifDataObject such as StudentPersonal to which the XPath query
        /// string is relative. With each subsequent call it is the SifElement
        /// or SimpleField that was previously processed.</param>
        /// <param name="curSegment">The current segment of the path that is being processed.
        /// For the first call to this method, the <i>curSegment</i> should be
        /// the portion of the XPath query string up to the first forward slash,
        /// exclusive.</param>
        /// <param name="nextSegment">The remaining portion of the path to be processed.
        /// For the first call to this method, the <i>nextSegment</i> should be
        /// the portion of the XPath query string following the first forward
        /// slash.</param>
        /// <returns> The Element satisfying the query, or <c>null</c> if no
        /// match was found (unless the <i>create</i> parameter is true). If the
        /// query resolves to an attribute, a SimpleField object is returned. If
        /// it resolves to an element, a SifElement object is returned. In both
        /// cases the caller can obtain the text value of the attribute or
        /// element by calling its <c>getTextValue</c> method.
        /// </returns>
        private Element _xpath(SifElement relativeTo, string curSegment, string nextSegment)
        {
            SifElement nextEle = null;

            int attr = curSegment.IndexOf('@');
            int bracket = curSegment.IndexOf('[');
            if (bracket != -1)
            {
                if (attr == -1)
                {
                    throw new AdkSchemaException("Invalid query: \"" + curSegment +
                                                  "\" must be in the form [@Attribute='value']");
                }

                string subEleTag = curSegment.Substring(0, (bracket) - (0));
                SifElement subEle = relativeTo.GetChild(subEleTag);
                if (subEle == null)
                {
                    return null;
                }

                int endBracket = curSegment.IndexOf(']', bracket);
                if (bracket == -1)
                {
                    throw new AdkSchemaException("Invalid query: \"" + curSegment +
                                                  "\" must be in the form [@Attribute='value']");
                }

                List<SearchCond> condsList = new List<SearchCond>(10);
                string conds = curSegment.Substring(bracket + 1, (endBracket) - (bracket + 1));
                string[] tokens = conds.Split(',');
                foreach (string thisTok in tokens)
                {
                    if (thisTok[0] != '@')
                    {
                        throw new AdkSchemaException("Attribute names must be preceded with the @ character: " +
                                                      thisTok);
                    }

                    int eq = thisTok.IndexOf('=');
                    if (eq == -1)
                    {
                        throw new AdkSchemaException("Attribute value must be in the form [@Attribute='value']: " +
                                                      thisTok);
                    }

                    //  Lookup the referenced attribute
                    SimpleField attrEle = subEle.GetField(thisTok.Substring(1, (eq) - (1)));
                    if (attrEle == null)
                    {
                        return null;
                    }

                    //  Add the attribute/value to the list
                    string aval = _attrValue(thisTok.Substring(eq + 1));
                    SearchCond sc = new SearchCond(attrEle.ElementDef, aval);
                    condsList.Add(sc);
                }

                //  Search the parent's subEleTag children for matching attributes.
                //  All attributes in the condsList must match.
                SifElementList ch = relativeTo.GetChildList(subEleTag);
                int chLen = ch.Count;
                for (int i = 0; i < chLen && nextEle == null; i++)
                {
                    SifElement cmpEle;
                    cmpEle = ch[i];

                    int matched = 0;

                    //  Compare the attributes
                    for (int x = 0; x < condsList.Count; x++)
                    {
                        SearchCond sc = condsList[x];
                        SimpleField atr = cmpEle.GetField(sc.fAttr);
                        if (atr == null)
                        {
                            break;
                        }
                        if (atr.TextValue.Equals(sc.fValue))
                        {
                            matched++;
                        }
                    }

                    //  If all attributes matched, this is a match
                    if (matched == condsList.Count)
                    {
                        nextEle = cmpEle;

                        //  Continue the search if nextSegment has a value
                        if (nextSegment != null && nextSegment.Length > 0)
                        {
                            int ii = nextSegment.IndexOf('/');

                            Element ee =
                                _xpath(nextEle, ii == -1 ? nextSegment : nextSegment.Substring(0, (ii) - (0)),
                                        ii == -1 ? null : nextSegment.Substring(ii + 1));
                            if (ee != null)
                            {
                                return ee;
                            }
                            else
                            {
                                nextEle = null;
                            }
                        }
                    }
                }

                if (nextEle == null)
                {
                    return null;
                }
            }
            else
            {
                //  Search for the named attribute/element
                if (attr != -1)
                {
                    return relativeTo.GetField(curSegment.Substring(1));
                }
                else
                {
                    nextEle = relativeTo.GetChild(curSegment);
                    if (nextEle == null)
                    {
                        if (nextSegment == null || (nextSegment.Length > 0 && nextSegment[0] == '@'))
                        {
                            return relativeTo.GetField(curSegment);
                        }

                        return null;
                    }
                }
            }

            //  Continue the search if nextSegment has a value
            if ((nextSegment != null && nextSegment.Length > 0))
            {
                int i = nextSegment.IndexOf('/');

                return
                    _xpath(nextEle, i == -1 ? nextSegment : nextSegment.Substring(0, (i) - (0)),
                            i == -1 ? null : nextSegment.Substring(i + 1));
            }

            return nextEle;
        }
Example #7
0
        /// <summary>  Recursively builds elements and attributes relative to a SifElement.</summary>
        /// <param name="relativeTo">The SifElement this iteration is relative to. For the
        /// first call to this method, the <i>relativeTo</i> parameter is usually
        /// a SifDataObject such as StudentPersonal to which the XPath query
        /// string is relative. With each subsequent call it is the SifElement
        /// or SimpleField that was previously processed.</param>
        /// <param name="path">A running path of the segments processed thus far; an empty
        /// StringBuffer should be passed to this parameter the first time the
        /// method is called </param>
        /// <param name="curSegment">The current segment of the path that is being processed.
        /// For the first call to this method, the <i>curSegment</i> should be
        /// the portion of the XPath query string up to the first forward slash,
        /// exclusive.</param>
        /// <param name="nextSegment">The remaining portion of the path to be processed.
        /// For the first call to this method, the <i>nextSegment</i> should be
        /// the portion of the XPath query string following the first forward
        /// slash.</param>
        /// <param name="prevAttributes">An optional array of attribute values that were
        /// used to construct an Element in the processing of the last segment.
        /// The array is comprised of attribute name and value pairs such that
        /// element N is an attribute name and N+1 is its value. For the first
        /// call to this method, the array should be null. For subsequent calls,
        /// it should be null unless an Element was constructed from attribute
        /// values.</param>
        /// <param name="version">The version of SIF for which this mapping operation is being evaluated</param>
        /// <param name="textFormatter">The SIFFormatter instance used to parse strings into strongly-typed data values.
        /// For many uses of this API, this formatter is equivalent to ADK.TextFormatter</param>
        /// <param name="pathFormatter">The SIFFormatter instance used for setting child SIFElements on their parents.
        /// This formatter may be different than the text formatter. The text formatter is, for
        /// compatibility's sake defaulted to SIF 1.x. However, the path formatter must be 
        /// correct for the mappings path being evaluated.</param>
        /// <param name="valueBuilder"></param>
        /// <returns> The Element satisfying the query, or <c>null</c> if no
        /// match was found (unless the <i>create</i> parameter is true). If the
        /// query resolves to an attribute, a SimpleField object is returned. If
        /// it resolves to an element, a SifElement object is returned. In both
        /// cases the caller can obtain the text value of the attribute or
        /// element by calling its <c>TextValue</c> Property.
        /// </returns>
        private Element _xpathBuild(
            SifElement relativeTo,
            StringBuilder path,
            string curSegment,
            string nextSegment,
            string[] prevAttributes,
            IValueBuilder valueBuilder,
            SifVersion version,
            SifFormatter textFormatter,
            SifFormatter pathFormatter)
        {
            string[] _prevAttributes = null;
            SifElement nextEle = null;

            int asgnEq = curSegment.LastIndexOf('=');
            int attr = curSegment.LastIndexOf('@', asgnEq == -1 ? curSegment.Length - 1 : asgnEq - 1);
            int bracket = curSegment.IndexOf('[');
            if (bracket != -1)
            {
                if (attr == -1)
                {
                    throw new AdkSchemaException("Invalid query: \"" + curSegment +
                                                  "\" must be in the form [@Attr='value1','value2',...]");
                }

                string subEleTag = curSegment.Substring(0, (bracket) - (0));

                int lastBracket = curSegment.LastIndexOf(']');
                string[] attrList = curSegment.Substring(bracket + 1, (lastBracket) - (bracket + 1)).Split(',');
                _prevAttributes = new string[attrList.Length * 2];
                int _prevI = 0;

                for (int a = 0; a < attrList.Length; a++)
                {
                    string _curSegment = attrList[a];

                    //  Determine the value of the attribute
                    int eq = _curSegment.IndexOf("=");
                    string val = _curSegment.Substring(eq + 1);
                    string v = null;
                    if (val[0] == '\'')
                    {
                        int end = val.IndexOf('\'', 1);
                        if (end != -1)
                        {
                            v = valueBuilder == null
                                    ? val.Substring(1, (end) - (1))
                                    : valueBuilder.Evaluate(val.Substring(1, (end) - (1)));
                        }
                    }

                    if (v == null)
                    {
                        throw new AdkSchemaException("Attribute value (" + val +
                                                      ") must be in the form @Attribute='value'");
                    }

                    string attrName = _curSegment.Substring(1, (eq) - (1));

                    _prevAttributes[_prevI++] = attrName;
                    _prevAttributes[_prevI++] = v;

                    if (nextEle == null)
                    {
                        //
                        //  Look at all of the peer elements to determine if any have the
                        //  attribute value set. If so, return it; otherwise create a new
                        //  instance of the element with the attribute set. For example, if
                        //  curSegment is "Address[@Type='M']", we must look at all of the
                        //  Address children of relativeTo in order to determine if any
                        //  currently exist with a Type field set to a value of 'M'. If one
                        //  does, then it already exists and there is nothing to do; if
                        //  not found, however, a new Address child must be added with a
                        //  Type field of 'M'.
                        //

                        //  Lookup the IElementDef of relativeTo
                        IElementDef subEleDef = Adk.Dtd.LookupElementDef(relativeTo.ElementDef, subEleTag);
                        if (subEleDef == null)
                        {
                            subEleDef = Adk.Dtd.LookupElementDef(subEleTag);
                            if (subEleDef == null)
                            {
                                throw new AdkSchemaException(subEleTag + " is not a recognized attribute of " +
                                                              relativeTo.Tag);
                            }
                        }

                        bool repeatable = subEleDef.IsRepeatable(relativeTo.SifVersion);

                        SifElementList peers = relativeTo.GetChildList(subEleDef);

                        if (curSegment.IndexOf("+]") == -1)
                        {
                            //
                            //  Determine if relatSifElementListiveTo has any children that already
                            //  define this attribute/value; if not, create a new instance.
                            //  If subEleDef is not repeatable, however, we cannot add
                            //  another instance of it regardless.
                            //
                            for (int i = 0; i < peers.Count && nextEle == null; i++)
                            {
                                SimpleField ftest = peers[i].GetField(attrName);
                                if (ftest != null && ftest.TextValue.Equals(v))
                                {
                                    nextEle = peers[i];
                                }
                            }
                        }

                        if (nextEle == null)
                        {
                            if (!(peers.Count > 0 && !repeatable))
                            {
                                nextEle =
                                    _createChild(relativeTo, subEleTag, valueBuilder, version, textFormatter,
                                                  pathFormatter);
                            }
                            else
                            {
                                //
                                //  subEleDef is not repeatable, so we need to back up
                                //  and add this attribute/value to a fresh instance of
                                //  relativeTo if possible. First use _xpath(path) to try
                                //  to select that instance in case it already exists (otherwise
                                //  we'd create a new instance each iteration, which is
                                //  not the desired result.)
                                //

                                string _tmp;
                                if (path.Length > 0)
                                {
                                    _tmp = path + "/" + curSegment;
                                }
                                else
                                {
                                    _tmp = curSegment;
                                }
                                if (XPATH_DEBUG)
                                {
                                    Console.Out.Write("Searching for path relative to " +
                                                       relativeTo.Root.ElementDef.Name + ": " + _tmp);
                                }

                                int _del = _tmp.IndexOf('/');
                                nextEle =
                                    (SifElement)
                                    _xpath((SifElement)relativeTo.Root,
                                            _tmp.Substring(0, (_del == -1 ? _tmp.Length : _del) - (0)),
                                            _del == -1 ? null : _tmp.Substring(_del + 1));

                                if (XPATH_DEBUG)
                                {
                                    if (nextEle == null)
                                    {
                                        Console.Out.WriteLine("; not found, a new instance will be created");
                                    }
                                    else
                                    {
                                        Console.Out.WriteLine("; found");
                                    }
                                }

                                if (nextEle == null)
                                {
                                    if (relativeTo.ElementDef.IsRepeatable(relativeTo.SifVersion))
                                    {
                                        //  Clone relativeTo
                                        SifElement grandParent = (SifElement)relativeTo.Parent;
                                        nextEle = SifElement.Create(grandParent, relativeTo.ElementDef);
                                        pathFormatter.AddChild(grandParent, nextEle, version);

                                        //  Clone subEleDef; this now becomes nextEle
                                        SifElement newEle = SifElement.Create(nextEle, subEleDef);
                                        pathFormatter.AddChild(nextEle, newEle, version);
                                        _copyAttributes(nextEle, prevAttributes);
                                        nextEle = newEle;
                                    }
                                    else
                                    {
                                        throw new AdkSchemaException(
                                            "It is not possible to create the element or attribute identified by this path: " +
                                            _tmp + (nextSegment == null ? "" : "/" + nextSegment) +
                                            ". The element or attribute is either undefined in this version of SIF, " +
                                            "or an attempt is being made to create another instance of an element that is not Repeatable.");
                                    }
                                }
                            }
                        }
                    }

                    if (nextEle != null)
                    {
                        _createField(nextEle, attrName, v);
                    }

                    if (a == attrList.Length && nextEle == null)
                    {
                        return null;
                    }
                }
            }
            else
            {
                //  Search for the named attribute/element
                if (attr != -1)
                {
                    SimpleField ff = relativeTo.GetField(curSegment.Substring(1));
                    if (ff == null)
                    {
                        ff = _createField(relativeTo, curSegment.Substring(1), null);
                    }

                    return ff;
                }
                else
                {
                    string _tag = curSegment;
                    int eq = curSegment.IndexOf('=');
                    if (eq != -1)
                    {
                        _tag = curSegment.Substring(0, (eq) - (0));
                    }

                    nextEle = relativeTo.GetChild(_tag);
                    if (nextEle == null)
                    {
                        //  The curSegment element does not exist as a child of the relativeTo
                        //  object, so create it.
                        nextEle =
                            _createChild(relativeTo, curSegment, valueBuilder, version, textFormatter, pathFormatter);
                        if (nextEle == null)
                        {
                            if (nextSegment == null)
                            {
                                return relativeTo.GetField(_tag);
                            }
                            return null;
                        }
                    }
                }
            }

            //  Continue the search if nextSegment has a value
            if (nextEle != null && (nextSegment != null && nextSegment.Length > 0))
            {
                int i = nextSegment.IndexOf('/');

                if (path.Length > 0)
                {
                    path.Append("/");
                }
                path.Append(curSegment);

                return _xpathBuild(
                    nextEle,
                    path, i == -1 ? nextSegment : nextSegment.Substring(0, (i)),
                    i == -1 ? null : nextSegment.Substring(i + 1),
                    _prevAttributes,
                    valueBuilder,
                    version,
                    textFormatter,
                    pathFormatter);
            }

            if (nextSegment == null && nextEle != null && (nextEle.TextValue == null || nextEle.TextValue.Length == 0))
            {
                int eq2 = curSegment.LastIndexOf('=');
                if (eq2 != -1)
                {
                    if (bracket == -1 || (curSegment.LastIndexOf(']') < eq2))
                    {
                        //
                        //  An equals sign in the final segment indicates there is
                        //  a value constant or expression following the XPath
                        //  (e.g. "OtherId[@Type='06']=@pad($(PERMNUM),0,5)" ). Use
                        //  the user-supplied ValueBuilder to evaluate it.
                        //
                        string str = curSegment.Substring(eq2 + 1);
                        nextEle.TextValue = valueBuilder == null ? str : valueBuilder.Evaluate(str);
                    }
                }
            }

            return nextEle;
        }