예제 #1
0
        // try to obtain enumeration values from xml annotations
        // Legacy ATF 2.8 example:
        //  <xs:simpleType name="EmotionType">
        //    <xs:annotation>
        //        <xs:appinfo>
        //            <scea.dom.editors.enumeration name="Adequate" displayName="Adequate, good enough"/>
        //            <scea.dom.editors.enumeration name="Capable" displayName="Capable, you betcha!"/>
        //            <scea.dom.editors.enumeration name="Enthusiastic" />
        //        </xs:appinfo>
        //    </xs:annotation>
        //    <xs:restriction base="xs:string">
        //        <xs:enumeration value="Adequate"/>
        //        <xs:enumeration value="Capable"/>
        //        <xs:enumeration value="Enthusiastic"/>
        //     </xs:restriction>
        //  </xs:simpleType>
        private static string[] TryGetEnumeration(DomNodeType domNodeType, XmlNode annotation)
        {
            string[]     enumeration        = null;
            XmlAttribute targetDomAttribute = annotation.Attributes[AnnotationsNameAttribute];

            if (targetDomAttribute != null)
            {
                var domObjectAttribute = domNodeType.GetAttributeInfo(targetDomAttribute.Value);
                if (domObjectAttribute != null)
                {
                    var attributeType = domObjectAttribute.Type;
                    var xmlAnnotation = attributeType.GetTag <IEnumerable <XmlNode> >();
                    if (xmlAnnotation != null)
                    {
                        List <string> enumerationList = new List <string>();
                        foreach (XmlNode enumAnnotation in xmlAnnotation)
                        {
                            if (enumAnnotation.Name == AnnotationsLegacyEnumeration)
                            {
                                string  name        = enumAnnotation.Attributes[AnnotationsNameAttribute].Value;
                                XmlNode displayNode =
                                    enumAnnotation.Attributes.GetNamedItem(AnnotationsDisplayNameAttribute);
                                if (displayNode != null)
                                {
                                    enumerationList.Add(name + "==" + displayNode.Value);
                                }
                                else
                                {
                                    enumerationList.Add(name);
                                }
                            }
                            enumeration = enumerationList.ToArray();
                        }
                    }
                }
            }

            return(enumeration);
        }
예제 #2
0
        /// <summary>
        /// Reads the node specified by the child metadata</summary>
        /// <param name="nodeInfo">Child metadata for node</param>
        /// <param name="reader">XML reader</param>
        /// <returns>DomNode specified by the child metadata</returns>
        protected virtual DomNode ReadElement(ChildInfo nodeInfo, XmlReader reader)
        {
            // handle polymorphism, if necessary
            DomNodeType type   = GetChildType(nodeInfo.Type, reader);
            int         index  = type.Name.LastIndexOf(':');
            string      typeNS = type.Name.Substring(0, index);

            DomNode node = new DomNode(type, nodeInfo);

            // read attributes
            while (reader.MoveToNextAttribute())
            {
                if (reader.Prefix == string.Empty ||
                    reader.LookupNamespace(reader.Prefix) == typeNS)
                {
                    AttributeInfo attributeInfo = type.GetAttributeInfo(reader.LocalName);
                    if (attributeInfo != null)
                    {
                        string valueString = reader.Value;
                        if (attributeInfo.Type.Type == AttributeTypes.Reference)
                        {
                            // save reference so it can be resolved after all nodes have been read
                            m_nodeReferences.Add(new XmlNodeReference(node, attributeInfo, valueString));
                        }
                        else
                        {
                            object value = attributeInfo.Type.Convert(valueString);
                            node.SetAttribute(attributeInfo, value);
                        }
                    }
                }
            }

            // add node to map if it has an id
            if (node.Type.IdAttribute != null)
            {
                string id = node.GetId();
                if (!string.IsNullOrEmpty(id))
                {
                    m_nodeDictionary[id] = node; // don't Add, in case there are multiple DomNodes with the same id
                }
            }

            reader.MoveToElement();

            if (!reader.IsEmptyElement)
            {
                // read child elements
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        // look up metadata for this element
                        ChildInfo childInfo = type.GetChildInfo(reader.LocalName);
                        if (childInfo != null)
                        {
                            DomNode childObject = ReadElement(childInfo, reader);
                            // at this point, child is a fully populated sub-tree

                            if (childInfo.IsList)
                            {
                                node.GetChildList(childInfo).Add(childObject);
                            }
                            else
                            {
                                node.SetChild(childInfo, childObject);
                            }
                        }
                        else
                        {
                            // try reading as an attribute
                            AttributeInfo attributeInfo = type.GetAttributeInfo(reader.LocalName);
                            if (attributeInfo != null)
                            {
                                reader.MoveToElement();

                                if (!reader.IsEmptyElement)
                                {
                                    // read element text
                                    while (reader.Read())
                                    {
                                        if (reader.NodeType == XmlNodeType.Text)
                                        {
                                            object value = attributeInfo.Type.Convert(reader.Value);
                                            node.SetAttribute(attributeInfo, value);
                                            // skip child elements, as this is an attribute value
                                            reader.Skip();
                                            break;
                                        }
                                        if (reader.NodeType == XmlNodeType.EndElement)
                                        {
                                            break;
                                        }
                                    }

                                    reader.MoveToContent();
                                }
                            }
                            else
                            {
                                // skip unrecognized element
                                reader.Skip();
                                // if that takes us to the end of the enclosing element, break
                                if (reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    else if (reader.NodeType == XmlNodeType.Text)
                    {
                        AttributeInfo attributeInfo = type.GetAttributeInfo(string.Empty);
                        if (attributeInfo != null)
                        {
                            object value = attributeInfo.Type.Convert(reader.Value);
                            node.SetAttribute(attributeInfo, value);
                        }
                    }
                    else if (reader.NodeType == XmlNodeType.EndElement)
                    {
                        break;
                    }
                }
            }

            reader.MoveToContent();

            return(node);
        }
예제 #3
0
        private static PropertyDescriptor GetDescriptor(
            DomNodeType type,
            XmlNode annotation,
            string name,
            string[] segments)
        {
            PropertyDescriptor desc = null;
            // Get mandatory display name
            XmlAttribute displayNameAttr = annotation.Attributes["displayName"];

            if (displayNameAttr != null)
            {
                if (string.IsNullOrEmpty(name))
                {
                    throw new AnnotationException(string.Format(
                                                      "Required name attribute is null or empty.\r\nType: {0}\r\nElement: {1}",
                                                      type.Name, annotation.Name));
                }

                string displayName = displayNameAttr.Value;
                if (string.IsNullOrEmpty(displayName))
                {
                    displayName = name;
                }

                // Get optional annotations
                string        category      = GetAnnotation(annotation, "category");
                string        description   = GetAnnotation(annotation, "description");
                bool          readOnly      = GetAnnotation(annotation, "readOnly") == "true";
                object        editor        = CreateObject <object>(type, annotation, "editor");
                TypeConverter typeConverter = CreateObject <TypeConverter>(type, annotation, "converter");

                if (annotation.Name == "scea.dom.editors.attribute")
                {
                    // Attribute annotation
                    if (segments == null)
                    {
                        throw new AnnotationException("Unnamed attribute");
                    }

                    if (segments.Length == 1) // local attribute
                    {
                        AttributeInfo metaAttr = type.GetAttributeInfo(name);
                        if (metaAttr == null)
                        {
                            throw new AnnotationException("Type doesn't have this attribute");
                        }

                        desc = new AttributePropertyDescriptor(
                            displayName, metaAttr,
                            category, description, readOnly, editor, typeConverter);
                    }
                    else // descendant attribute
                    {
                        ChildInfo[]   metaElements = GetPath(type, segments, segments.Length - 1);
                        DomNodeType   childType    = metaElements[segments.Length - 2].Type;
                        AttributeInfo metaAttr     = childType.GetAttributeInfo(segments[segments.Length - 1]);
                        if (metaAttr == null)
                        {
                            throw new AnnotationException("Descendant type doesn't have this attribute");
                        }

                        desc = new ChildAttributePropertyDescriptor(
                            displayName, metaAttr, metaElements,
                            category, description, readOnly, editor, typeConverter);
                    }
                }
                else if (annotation.Name == "scea.dom.editors.child")
                {
                    // Child value annotation
                    ChildInfo element = type.GetChildInfo(name);
                    if (element == null)
                    {
                        throw new AnnotationException("Type doesn't have this element");
                    }

                    desc = new ChildPropertyDescriptor(
                        displayName, element,
                        category, description, readOnly, editor, typeConverter);
                }
            }

            return(desc);
        }
예제 #4
0
        /// <summary>
        /// Reads the node specified by the child metadata</summary>
        /// <param name="nodeInfo">Child metadata for node</param>
        /// <param name="reader">XML reader</param>
        /// <returns>DomNode specified by the child metadata</returns>
        protected virtual DomNode ReadElement(ChildInfo nodeInfo, XmlReader reader)
        {
            // handle polymorphism, if necessary
            DomNodeType type = null;
            var         substitutionGroupRule = nodeInfo.Rules.OfType <SubstitutionGroupChildRule>().FirstOrDefault();

            if (substitutionGroupRule != null)
            {
                foreach (var sub in substitutionGroupRule.Substitutions)
                {
                    if (sub.Name == reader.LocalName)
                    {
                        type = sub.Type;
                        break;
                    }
                }

                if (type == null)
                {
                    throw new InvalidOperationException("Could not match substitution group for child " + nodeInfo.Name);
                }
            }
            else
            {
                type = GetChildType(nodeInfo.Type, reader);
            }

            int    index  = type.Name.LastIndexOf(':');
            string typeNS = type.Name.Substring(0, index);

            DomNode node = new DomNode(type, nodeInfo);

            // read attributes
            while (reader.MoveToNextAttribute())
            {
                if (reader.Prefix == string.Empty ||
                    reader.LookupNamespace(reader.Prefix) == typeNS)
                {
                    AttributeInfo attributeInfo = type.GetAttributeInfo(reader.LocalName);
                    if (attributeInfo != null)
                    {
                        ReadAttribute(node, attributeInfo, reader.Value);
                    }
                }
            }

            // add node to map if it has an id
            if (node.Type.IdAttribute != null)
            {
                string id = node.GetId();
                if (!string.IsNullOrEmpty(id))
                {
                    m_nodeDictionary[id] = node; // don't Add, in case there are multiple DomNodes with the same id
                }
            }

            reader.MoveToElement();

            if (!reader.IsEmptyElement)
            {
                // read child elements
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        // look up metadata for this element
                        ChildInfo childInfo = type.GetChildInfo(reader.LocalName);
                        if (childInfo == null)
                        {
                            // Try and get substitution group
                            childInfo = GetSubsitutionGroup(type, reader.LocalName);
                        }

                        if (childInfo != null)
                        {
                            DomNode childNode = ReadElement(childInfo, reader);
                            if (childNode != null)
                            {
                                // childNode is fully populated sub-tree
                                if (childInfo.IsList)
                                {
                                    node.GetChildList(childInfo).Add(childNode);
                                }
                                else
                                {
                                    node.SetChild(childInfo, childNode);
                                }
                            }
                        }
                        else
                        {
                            // try reading as an attribute
                            AttributeInfo attributeInfo = type.GetAttributeInfo(reader.LocalName);
                            if (attributeInfo != null)
                            {
                                reader.MoveToElement();

                                if (!reader.IsEmptyElement)
                                {
                                    // read element text
                                    while (reader.Read())
                                    {
                                        if (reader.NodeType == XmlNodeType.Text)
                                        {
                                            ReadAttribute(node, attributeInfo, reader.Value);
                                            // skip child elements, as this is an attribute value
                                            reader.Skip();
                                            break;
                                        }
                                        if (reader.NodeType == XmlNodeType.EndElement)
                                        {
                                            break;
                                        }
                                    }

                                    reader.MoveToContent();
                                }
                            }
                            else
                            {
                                // skip unrecognized element
                                reader.Skip();
                                // if that takes us to the end of the enclosing element, break
                                if (reader.NodeType == XmlNodeType.EndElement)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    else if (reader.NodeType == XmlNodeType.Text)
                    {
                        AttributeInfo attributeInfo = type.GetAttributeInfo(string.Empty);
                        if (attributeInfo != null)
                        {
                            ReadAttribute(node, attributeInfo, reader.Value);
                        }
                    }
                    else if (reader.NodeType == XmlNodeType.EndElement)
                    {
                        break;
                    }
                }
            }

            reader.MoveToContent();

            return(node);
        }