示例#1
0
        private void BeginProperty(XmlReader reader)
        {
            StackFrame topFrame = stack.Peek();

            EntityPropertyInfo entityPropertyInfo = topFrame.entity.Properties[reader.LocalName];

            if (!topFrame.dynamic)
            {
                // Assumptions:
                // - expecting property to match exactly XML element name
                // - only public members looked for
                // Improvement:
                // - Process this validation when the metadata has been processed.
                PropertyInfo property = topFrame.instanceType.GetProperty(reader.LocalName);
                if (property == null)
                {
                    throw new InvalidOperationException(string.Format("Property {0} does not exist on typeName {1}", reader.LocalName, topFrame.instanceType.Name));
                }

                // Assumptions:
                // - No type conversion is performed to assign the variable
                // Improvements:
                // - Process this validation when the metadata has been processed.
                if (!property.PropertyType.IsAssignableFrom(entityPropertyInfo.Type))
                {
                    throw new InvalidOperationException(string.Format("Property {0} cannot be assigned from type {1}", reader.LocalName, entityInfo.Properties[reader.LocalName].TypeName));
                }

                StackFrame frame = topFrame.Clone();
                frame.elementName        = XmlConvert.DecodeName(reader.LocalName);
                frame.property           = property;
                frame.entityPropertyInfo = entityPropertyInfo;
                frame.state = state;

                stack.Push(frame);
            }
            else
            {
                StackFrame frame = topFrame.Clone();
                frame.elementName        = XmlConvert.DecodeName(reader.LocalName);
                frame.entityPropertyInfo = entityPropertyInfo;
                frame.state = state;

                if (hasAddMethod)
                {
                    frame.iAddInstance = (IEntityPropertySetter)frame.instance;
                }
                else
                {
                    MethodInfo addMethod = topFrame.instanceType.GetMethod("Add");
                    frame.addMethod = addMethod;
                }

                stack.Push(frame);
            }

            if (entityPropertyInfo.IsArray)
            {
                state = ParserState.ArrayProperty;
                if (reader.IsEmptyElement)
                {
                    EndArrayProperty(reader);
                }
            }
            else
            {
                state = ParserState.Property;
                if (reader.IsEmptyElement)
                {
                    ProcessPropertyValue(reader);
                    EndProperty(reader);
                }
            }
        }
示例#2
0
        public T ReadNextEntity(XmlReader reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                case XmlNodeType.Element:
                    switch (this.state)
                    {
                    case ParserState.Start:
                        // Assumption:
                        // - skip the soap response tags
                        if ((reader.LocalName == "QueryXmlResponse") ||
                            (reader.LocalName == "QueryXmlResult"))
                        {
                            continue;
                        }

                        if (string.CompareOrdinal(reader.LocalName, "queryResult") == 0)
                        {
                            this.state = ParserState.Root;
                        }
                        else
                        {
                            throw new InvalidOperationException("Expecting <queryResult> element but found " + reader.LocalName);
                        }
                        break;

                    case ParserState.Root:
                        if (string.CompareOrdinal(reader.LocalName, "template") == 0)
                        {
                            state = ParserState.Template;
                        }
                        else if (string.CompareOrdinal(reader.LocalName, "data") == 0)
                        {
                            if (entityInfo == null)
                            {
                                throw new InvalidOperationException("No root entity was defined in the template section");
                            }

                            state = ParserState.Data;
                        }
                        else
                        {
                            throw new InvalidOperationException("Unexepected element " + reader.LocalName);
                        }
                        break;

                    case ParserState.Template:
                        if (string.CompareOrdinal(reader.LocalName, "entity") == 0)
                        {
                            if (entityInfo != null)
                            {
                                throw new InvalidOperationException("Only one root entity is supported at this time");
                            }

                            StackFrame state = new StackFrame();
                            state.entity = new EntityInfo(reader["name"], reader["type"], bool.Parse(reader["dynamic"]));
                            stack.Push(state);

                            entityInfo = state.entity;

                            this.state = ParserState.EntityTemplate;
                        }

                        break;

                    case ParserState.EntityTemplate:
                        if (string.CompareOrdinal(reader.LocalName, "property") == 0)
                        {
                            var name   = reader["name"];
                            var entity = stack.Peek().entity;
                            entity.Properties.Add(XmlConvert.DecodeName(name), new EntityPropertyInfo(name, reader["type"]));

                            // Sometime empty elements come with an end element, adjust the statemachine state accordingly
                            if (!reader.IsEmptyElement)
                            {
                                state = ParserState.PropertyTemplate;
                            }
                        }
                        else if (string.CompareOrdinal(reader.LocalName, "entity") == 0)
                        {
                            StackFrame state = new StackFrame();
                            state.entity = new EntityInfo(reader["name"], reader["type"], bool.Parse(reader["dynamic"]));

                            stack.Peek().entitySet.Entities.Add(state.entity.EntityName, state.entity);

                            stack.Push(state);
                        }
                        else if (string.CompareOrdinal(reader.LocalName, "entitySet") == 0)
                        {
                            StackFrame state = new StackFrame();
                            state.entitySet = new EntitySetInfo(reader["name"]);

                            stack.Peek().entity.EntitySets.Add(state.entitySet.Name, state.entitySet);

                            stack.Push(state);
                        }
                        break;

                    case ParserState.Data:
                        BeginRootEntity(reader);
                        break;

                    case ParserState.Entity:
                        if (stack.Peek().entity.Properties.ContainsKey(XmlConvert.DecodeName(reader.LocalName)))
                        {
                            BeginProperty(reader);
                        }
                        else if (stack.Peek().entity.EntitySets.ContainsKey(XmlConvert.DecodeName(reader.LocalName)))
                        {
                            BeginEntitySet(reader);
                        }
                        else
                        {
                            throw new InvalidOperationException("Don't know how to handle element " + reader.LocalName);
                        }
                        break;

                    case ParserState.EntitySet:
                        if (stack.Peek().entitySet.Entities.ContainsKey(reader.LocalName))
                        {
                            BeginNestedEntity(reader);
                        }
                        else
                        {
                            throw new InvalidOperationException("Don't know how to handle element " + reader.LocalName);
                        }
                        break;

                    case ParserState.ArrayProperty:
                        if (string.CompareOrdinal(reader.LocalName, "item") == 0)
                        {
                            this.state = ParserState.ArrayItem;
                        }
                        else
                        {
                            throw new InvalidOperationException("Expecting <item> but encountered " + reader.LocalName);
                        }
                        break;

                    case ParserState.Errors:
                        if (string.CompareOrdinal(reader.LocalName, "errors") == 0)
                        {
                            state = ParserState.Error;
                            break;
                        }
                        return(default(T));

                    case ParserState.Error:
                        if (string.CompareOrdinal(reader.LocalName, "error") == 0)
                        {
                            ReadErrorMessages(reader);
                        }
                        break;

                    default:
                        break;
                    }
                    break;

                case XmlNodeType.EndElement:
                    switch (this.state)
                    {
                    case ParserState.Root:
                        ValidateEndElement(reader.LocalName, "queryResult", ParserState.Errors);
                        break;

                    case ParserState.Errors:
                        if (string.CompareOrdinal(reader.LocalName, "errors") == 0)
                        {
                            ValidateEndElement(reader.LocalName, "errors", ParserState.Root);
                        }
                        return(default(T));


                    case ParserState.Error:
                        if (string.CompareOrdinal(reader.LocalName, "error") == 0)
                        {
                            break;
                        }

                        ValidateEndElement(reader.LocalName, "errors", ParserState.Root);
                        return(default(T));

                    case ParserState.Data:
                        ValidateEndElement(reader.LocalName, "data", ParserState.Root);
                        break;

                    case ParserState.Template:
                        ValidateEndElement(reader.LocalName, "template", ParserState.Root);
                        break;

                    case ParserState.EntityTemplate:
                        if ((string.CompareOrdinal(reader.LocalName, "entity") != 0) &&
                            (string.CompareOrdinal(reader.LocalName, "entitySet") != 0))
                        {
                            throw new InvalidOperationException("Expecting </entity> or </entitySet> but encountered " + reader.LocalName);
                        }

                        stack.Pop();
                        if (stack.Count == 0)
                        {
                            this.state = ParserState.Template;
                        }
                        break;

                    case ParserState.PropertyTemplate:
                        ValidateEndElement(reader.LocalName, "property", ParserState.EntityTemplate);
                        break;

                    case ParserState.Property:
                        EndProperty(reader);
                        break;

                    case ParserState.ArrayProperty:
                        EndArrayProperty(reader);
                        break;

                    case ParserState.ArrayItem:
                        ValidateEndElement(reader.LocalName, "item", ParserState.ArrayProperty);
                        break;

                    case ParserState.Entity:
                        if (string.CompareOrdinal(reader.LocalName, stack.Peek().elementName) != 0)
                        {
                            throw new InvalidOperationException(string.Format("Expecting </{0}> but encountered {1}", stack.Peek().elementName, reader.LocalName));
                        }

                        if (stack.Count == 1)
                        {
                            return(EndRootEntity());
                        }
                        else
                        {
                            EndNestedEntity();
                        }
                        break;

                    case ParserState.EntitySet:
                        EndEntiySet(reader);
                        break;

                    default:
                        throw new InvalidOperationException(string.Format("Not expecting element {0} while in state {1}", reader.LocalName, this.state));
                    }
                    break;

                case XmlNodeType.Text:
                    switch (this.state)
                    {
                    case ParserState.Property:
                        ProcessPropertyValue(reader);
                        break;

                    case ParserState.ArrayItem:
                        ProcessArrayPropertyItem(reader);
                        break;
                    }
                    break;
                }
            }

            return(default(T));
        }