예제 #1
0
        public void TestValidate()
        {
            DomNodeType childType = new DomNodeType("child");
            DomNodeType parentType = new DomNodeType("parent");
            ChildInfo childInfo = new ChildInfo("child", childType, true);
            parentType.Define(childInfo);
            DomNode parent = new DomNode(parentType);
            IList<DomNode> childList = parent.GetChildList(childInfo);
            DomNode child1 = new DomNode(childType);
            DomNode child2 = new DomNode(childType);
            DomNode child3 = new DomNode(childType);

            ChildCountRule test = new ChildCountRule(1, 2);
            
            // 0 children. Not valid.
            Assert.False(test.Validate(parent, null, childInfo));

            // 1 child. Valid.
            childList.Add(child1);
            Assert.True(test.Validate(parent, null, childInfo));
            
            // 2 children. Valid.
            childList.Add(child2);
            Assert.True(test.Validate(parent, null, childInfo));

            // 3 children. Not valid.
            childList.Add(child3);
            Assert.False(test.Validate(parent, null, childInfo));

            // 0 children. Not valid.
            childList.Clear();
            Assert.False(test.Validate(parent, null, childInfo));
        }
예제 #2
0
파일: TestChildInfo.cs 프로젝트: Joxx0r/ATF
 public void TestListConstructor()
 {
     DomNodeType type = new DomNodeType("child");
     ChildInfo test = new ChildInfo("test", type, true);
     Assert.AreEqual(test.Name, "test");
     Assert.AreEqual(test.Type, type);
     Assert.True(test.IsList);
 }
예제 #3
0
 public void TestConstructor()
 {
     DomNodeType type = new DomNodeType("child");
     ChildInfo info = new ChildInfo("test", type);
     DomNode test = new DomNode(type, info);
     Assert.AreSame(test.Type, type);
     Assert.AreSame(test.ChildInfo, info);
 }
예제 #4
0
        public Slot(DomNode owner, ChildInfo childInfo)
        {
            if (owner == null || childInfo == null)
                throw new ArgumentNullException();

            m_owner = owner;
            m_childInfo = childInfo;
        }
        /// <summary>
        /// Constructor</summary>
        /// <param name="name">Property's display name</param>
        /// <param name="childInfo">ChildInfo identifying child</param>
        /// <param name="category">Category of property</param>
        /// <param name="description">Description of property</param>
        /// <param name="isReadOnly">Whether or not property is read-only</param>
        public ChildPropertyDescriptor(
            string name,
            ChildInfo childInfo,
            string category,
            string description,
            bool isReadOnly)

            : this(name, childInfo, category, description, isReadOnly, null, null)
        {
        }
        public void TestEquality()
        {
            var attrType1 = new AttributeType("xkcd", typeof(string));
            var attrInfo1 = new AttributeInfo("xkcd", attrType1);
            var domNodeType = new DomNodeType("WebComic", DomNodeType.BaseOfAllTypes);
            var childInfo1 = new ChildInfo("xkcd", domNodeType);
            attrInfo1.DefaultValue = "Firefly";
            var desc1 = new ChildAttributePropertyDescriptor(
                "xkcd", attrInfo1, childInfo1, "Category 1", "A commonly used word or phrase in the xkcd comic", true);
            int originalHashCode = desc1.GetHashCode();

            // test if two identically created property descriptors compare as being equal
            var desc2 = new ChildAttributePropertyDescriptor(
                "xkcd", attrInfo1, childInfo1, "Category 1", "A commonly used word or phrase in the xkcd comic", true);
            Assert.AreEqual(desc1, desc2);
            Assert.AreEqual(desc1.GetHashCode(), desc2.GetHashCode());

            // test category being different; oddly, although I think they should not be considered equal,
            //  the .Net PropertyDescriptor ignores the difference in category name. So, I'm guessing that
            //  the AttributePropertyDescriptor should behave the same as PropertyDescriptor.
            var desc3 = new ChildAttributePropertyDescriptor(
                "xkcd", attrInfo1, childInfo1, "Category 2", "A commonly used word or phrase in the xkcd comic", true);
            Assert.AreEqual(desc1, desc3);
            Assert.AreEqual(desc1.GetHashCode(), desc3.GetHashCode());

            // test description being different; similarly here, the .Net PropertyDescriptor doesn't care.
            var desc4 = new ChildAttributePropertyDescriptor(
                "xkcd", attrInfo1, childInfo1, "Category 1", "slightly different description", true);
            Assert.AreEqual(desc1, desc4);
            Assert.AreEqual(desc1.GetHashCode(), desc4.GetHashCode());

            // test readOnly being different; ditto for read-only flag!
            var desc5 = new ChildAttributePropertyDescriptor(
                "xkcd", attrInfo1, childInfo1, "Category 1", "A commonly used word or phrase in the xkcd comic", false);
            Assert.AreEqual(desc1, desc5);
            Assert.AreEqual(desc1.GetHashCode(), desc5.GetHashCode());

            // test that the hash code hasn't changed after using the AttributeInfo
            var attrInfo2 = new AttributeInfo("xkcd", attrType1);
            domNodeType.Define(attrInfo2);
            Assert.AreEqual(desc1.GetHashCode(), originalHashCode);

            // test that the hash code hasn't changed after creating a derived DomNodeType
            var derivedDomNodeType = new DomNodeType("ScientificWebComic", domNodeType);
            var derivedAttrInfo = new AttributeInfo("xkcd", attrType1);
            var derivedChildInfo = new ChildInfo("xkcd", derivedDomNodeType);
            derivedDomNodeType.Define(derivedAttrInfo);
            Assert.AreEqual(desc1.GetHashCode(), originalHashCode);

            // test that an AttributeInfo used in a derived DomNodeType doesn't change equality or hash code
            var desc6 = new ChildAttributePropertyDescriptor(
                "xkcd", derivedAttrInfo, derivedChildInfo, "Category 1", "A commonly used word or phrase in the xkcd comic", true);
            Assert.AreEqual(desc1, desc6);
            Assert.AreEqual(desc1.GetHashCode(), desc6.GetHashCode());
        }
        /// <summary>
        /// Constructor</summary>
        /// <param name="name">Value's display name</param>
        /// <param name="attributeInfos">An array of meta attributes in the collection</param>
        /// <param name="childInfo">Meta element identifying child that owns the attributes</param>
        /// <param name="category">Category of property</param>
        /// <param name="description">Description of property</param>
        /// <param name="isReadOnly">Whether or not property is read-only</param>
        public ChildAttributeCollectionPropertyDescriptor(
            string name,
            AttributeInfo[] attributeInfos,
            ChildInfo childInfo,
            string category,
            string description,
            bool isReadOnly)

            : this(name, attributeInfos, childInfo, category, description, isReadOnly, null, null)
        {
        }
예제 #8
0
        public void TestChildParent()
        {
            DomNodeType type = new DomNodeType("type");
            ChildInfo childInfo = new ChildInfo("child", type, true);
            type.Define(childInfo);

            DomNode child = new DomNode(type);
            DomNode parent = new DomNode(type);
            parent.GetChildList(childInfo).Add(child);
            Assert.AreSame(child.Parent, parent);
        }
예제 #9
0
 /// <summary>
 /// Constructor</summary>
 /// <param name="parent">Node's parent</param>
 /// <param name="childInfo">Metadata for child</param>
 /// <param name="child">Child node</param>
 /// <param name="index">Node's index in parent</param>
 public ChildEventArgs(
     DomNode parent,
     ChildInfo childInfo,
     DomNode child,
     int index)
 {
     Parent = parent;
     ChildInfo = childInfo;
     Child = child;
     Index = index;
 }
 /// <summary>
 /// Constructor</summary>
 /// <param name="name">Value's display name</param>
 /// <param name="attributeInfos">An array of meta attributes in the collection</param>
 /// <param name="childInfo">Meta element identifying child that owns the attributes</param>
 /// <param name="category">Category of property</param>
 /// <param name="description">Description of property</param>
 /// <param name="isReadOnly">Whether or not property is read-only</param>
 /// <param name="editor">The editor used to edit the property</param>
 /// <param name="typeConverter">The type converter used for this property</param>
 public ChildAttributeCollectionPropertyDescriptor(
     string name,
     AttributeInfo[] attributeInfos,
     ChildInfo childInfo,
     string category,
     string description,
     bool isReadOnly,
     object editor,
     TypeConverter typeConverter)
     : this(name, attributeInfos, childInfo, category, description, isReadOnly, editor, typeConverter, null)
 {
 }
        /// <summary>
        /// Constructor</summary>
        /// <param name="name">Value's display name</param>
        /// <param name="attributeInfo">Attribute metadata</param>
        /// <param name="childInfo">ChildInfo identifying child</param>
        /// <param name="category">Category of property</param>
        /// <param name="description">Description of property</param>
        /// <param name="isReadOnly">Whether or not property is read-only</param>
        /// <param name="editor">The editor used to edit the property</param>
        public ChildAttributePropertyDescriptor(
            string name,
            AttributeInfo attributeInfo,
            ChildInfo childInfo,
            string category,
            string description,
            bool isReadOnly,
            object editor)

            : this(name, attributeInfo, childInfo, category, description, isReadOnly, editor, null)
        {
        }
예제 #12
0
        /// <summary>
        /// Adds OSC addresses (one for the x-coordinate and one for the y-coordinate) for a list
        /// of DOM children that have attributes that are arrays of floats. Each array of floats
        /// represents a 2D point where the first float is the x coordinate and the second float
        /// is the y coordinate.</summary>
        /// <param name="childInfo">The child info which defines the list of children of a selected DomNode</param>
        /// <param name="childAttributeDesc">The attribute on each child that defines the array of floats</param>
        /// <param name="oscAddress">The base OSC address to use. "/x" and "/y" will be appended for
        /// the x-coordinate array and the y-coordinate array, which is how Lemur sends and receives
        /// 2-D point arrays.</param>
        /// <returns>The base OSC address, with possible changes to make it legal.</returns>
        public string Add2DPointProperty(ChildInfo childInfo, AttributePropertyDescriptor childAttributeDesc, string oscAddress)
        {
            oscAddress = OscServices.FixPropertyAddress(oscAddress);

            var xCoordDesc = new ChildListFloatingPointArrayDesc(childInfo, childAttributeDesc, 0);
            AddPropertyAddress(xCoordDesc, oscAddress + "/x");

            var yCoordDesc = new ChildListFloatingPointArrayDesc(childInfo, childAttributeDesc, 1);
            AddPropertyAddress(yCoordDesc, oscAddress + "/y");

            return oscAddress;
        }
예제 #13
0
 /// <summary>
 /// Checks that the parent DomNode has the correct # of children of the given type</summary>
 /// <param name="parent">Parent DOM node</param>
 /// <param name="child">Child DOM node; ignored</param>
 /// <param name="childInfo">Child relationship info</param>
 /// <returns>True, iff 'parent' has a valid number of children of the type associated
 /// with 'childInfo'</returns>
 public override bool Validate(DomNode parent, DomNode child, ChildInfo childInfo)
 {
     if (childInfo.IsList)
     {
         IList<DomNode> childList = parent.GetChildList(childInfo);
         int count = childList.Count;
         return
             count >= m_min &&
             count <= m_max;
     }
     // singleton child references can always be set
     return true;
 }
        /// <summary>
        /// Constructor</summary>
        /// <param name="name">Value's display name</param>
        /// <param name="childInfo">ChildInfo identifying child</param>
        /// <param name="category">Category of property</param>
        /// <param name="description">Description of property</param>
        /// <param name="isReadOnly">Whether or not property is read-only</param>
        /// <param name="editor">The editor used to edit the property</param>
        /// <param name="typeConverter">The type converter used for this property</param>
        public ChildPropertyDescriptor(
            string name,
            ChildInfo childInfo,
            string category,
            string description,
            bool isReadOnly,
            object editor,
            TypeConverter typeConverter)

            : base(name, typeof(DomNode), category, description, isReadOnly, editor, typeConverter)
        {
            m_childInfo = childInfo;
        }
예제 #15
0
        public void TestDescendantGetRoot()
        {
            DomNodeType type = new DomNodeType("type");
            ChildInfo childInfo = new ChildInfo("child", type, true);
            type.Define(childInfo);

            DomNode child = new DomNode(type);
            DomNode parent = new DomNode(type);
            DomNode grandparent = new DomNode(type);
            parent.GetChildList(childInfo).Add(child);
            grandparent.GetChildList(childInfo).Add(parent);
            Assert.AreSame(child.GetRoot(), grandparent);
        }
        /// <summary>
        /// Constructor</summary>
        /// <param name="name">Value's display name</param>
        /// <param name="attributeInfo">Attribute metadata</param>
        /// <param name="childInfo">ChildInfo identifying child</param>
        /// <param name="category">Category of property</param>
        /// <param name="description">Description of property</param>
        /// <param name="isReadOnly">Whether or not property is read-only</param>
        /// <param name="editor">The editor used to edit the property</param>
        /// <param name="typeConverter">The type converter used for this property</param>
        public ChildAttributePropertyDescriptor(
            string name,
            AttributeInfo attributeInfo,
            ChildInfo childInfo,
            string category,
            string description,
            bool isReadOnly,
            object editor,
            TypeConverter typeConverter)

            : base(name, attributeInfo, category, description, isReadOnly, editor, typeConverter)
        {
            m_childPath = new[] { childInfo };
        }
예제 #17
0
파일: TestChildInfo.cs 프로젝트: Joxx0r/ATF
        public void TestValidation()
        {
            DomNodeType type = new DomNodeType("child");
            ChildInfo test = new ChildInfo("test", type);
            CollectionAssert.IsEmpty(test.Rules);

            var rule = new SimpleChildRule();
            test.AddRule(rule);

            Utilities.TestSequenceEqual(test.Rules, rule);

            Assert.True(test.Validate(null, null));
            Assert.True(rule.Validated);
        }
예제 #18
0
        public void TestGetPath()
        {
            DomNodeType type = new DomNodeType("type");
            ChildInfo childInfo = new ChildInfo("child", type, true);
            type.Define(childInfo);

            DomNode child = new DomNode(type);
            DomNode parent = new DomNode(type);
            DomNode grandparent = new DomNode(type);
            parent.GetChildList(childInfo).Add(child);
            grandparent.GetChildList(childInfo).Add(parent);

            Utilities.TestSequenceEqual(child.GetPath(), grandparent, parent, child);
            Utilities.TestSequenceEqual(parent.GetPath(), grandparent, parent);
            Utilities.TestSequenceEqual(grandparent.GetPath(), grandparent);
        }
예제 #19
0
        public TestValidator()
        {
            // define a tree of validation contexts
            m_childType = new DomNodeType("test");
            m_stringAttrInfo = GetStringAttribute("string");
            m_childType.Define(m_stringAttrInfo);
            m_refAttrInfo = GetRefAttribute("ref");
            m_childType.Define(m_refAttrInfo);
            m_childInfo = new ChildInfo("child", m_childType);
            m_childType.Define(m_childInfo);
            m_childType.Define(new ExtensionInfo<ValidationContext>());

            // define a distinct root type with the validator
            m_rootType = new DomNodeType("root");
            m_rootType.BaseType = m_childType;
            m_rootType.Define(new ExtensionInfo<Validator>());

            IEnumerable<AttributeInfo> attributes = m_rootType.Attributes; // freezes the types
        }
예제 #20
0
        public void Remove(DomNode parent, DomNode child, ChildInfo chInfo)
        {
            NativeObjectAdapter childObject = child.As<NativeObjectAdapter>();
            NativeObjectAdapter parentObject = parent.As<NativeObjectAdapter>();

            object listIdObj = chInfo.GetTag(NativeAnnotations.NativeElement);

            if (childObject == null || parentObject == null || listIdObj == null)
                return;

            uint listId = (uint)listIdObj;
            uint typeId = (uint)chInfo.DefiningType.GetTag(NativeAnnotations.NativeType);
            ulong parentId = parentObject.InstanceId;
            ulong childId = childObject.InstanceId;
            GameEngine.ObjectRemoveChild(typeId, listId, parentId, childId);
            if (ManageNativeObjectLifeTime)
            {                
                GameEngine.DestroyObject(childObject);
            }
        }
예제 #21
0
파일: TestValidator.cs 프로젝트: Joxx0r/ATF
        protected DomNodeType RootType;//derives from ChildType

        public TestValidator()
        {
            // define a tree of validation contexts
            ChildType = new DomNodeType("test");
            StringAttrInfo = GetStringAttribute("string");
            ChildType.Define(StringAttrInfo);
            RefAttrInfo = GetRefAttribute("ref");
            ChildType.Define(RefAttrInfo);
            ChildInfo = new ChildInfo("child", ChildType);
            ChildType.Define(ChildInfo);
            ChildType.Define(new ExtensionInfo<ValidationContext>());

            // define a distinct root type with the validator
            RootType = new DomNodeType("root");
            RootType.BaseType = ChildType;
            RootType.Define(new ExtensionInfo<Validator>());
            AttributeInfo overriddenInfo = GetStringAttribute("string");
            RootType.Define(overriddenInfo);

            IEnumerable<AttributeInfo> attributes = RootType.Attributes; // freezes the types
        }
예제 #22
0
        public void Insert(DomNode parent, DomNode child, ChildInfo chInfo, int index)
        {
            NativeObjectAdapter childObject = child.As<NativeObjectAdapter>();
            NativeObjectAdapter parentObject = parent.As<NativeObjectAdapter>();

            object listIdObj = chInfo.GetTag(NativeAnnotations.NativeElement);

            if (childObject == null || parentObject == null || listIdObj == null)
                return;

            if (chInfo.IsList && index >= (parent.GetChildList(chInfo).Count - 1))
                index = -1;

            if (ManageNativeObjectLifeTime)
            {
                GameEngine.CreateObject(childObject);
                childObject.UpdateNativeOjbect();
            }
            System.Diagnostics.Debug.Assert(childObject.InstanceId != 0);

            uint listId = (uint)listIdObj;
            uint typeId = (uint)chInfo.DefiningType.GetTag(NativeAnnotations.NativeType);
            ulong parentId = parentObject.InstanceId;
            ulong childId = childObject.InstanceId;

            if (index >= 0)
            {
                GameEngine.ObjectInsertChild(typeId, listId, parentId, childId, index);
            }
            else
            {
                GameEngine.ObjectAddChild(typeId, listId, parentId, childId);
            }

            foreach (var node in child.Children)
            {
                Insert(child, node, node.ChildInfo, -1); // use -1 for index to indicate an append operation.
            }
        }    
예제 #23
0
        public TestDataValidator()
        {
            m_childType = new DomNodeType("child");
            m_parentType = new DomNodeType("parent");
            m_parentType.Define(new ExtensionInfo<ValidationContext>());
            m_parentType.Define(new ExtensionInfo<DataValidator>());

            m_childCountRule = new ChildCountRule(2, 3);
            m_childInfo = new ChildInfo("child", m_childType, true);
            m_parentType.Define(m_childInfo);
            m_childInfo.AddRule(m_childCountRule);

            m_parent = new DomNode(m_parentType);
            m_parent.InitializeExtensions();

            m_validationContext = m_parent.As<ValidationContext>();

            m_child1 = new DomNode(m_childType);
            m_child2 = new DomNode(m_childType);
            m_child3 = new DomNode(m_childType);
            m_child4 = new DomNode(m_childType);
        }
예제 #24
0
        /// <summary>
        /// Gets the descendant metadata corresponding to the given path</summary>
        /// <param name="path">Path to descendant, with ':' as separator</param>
        /// <returns>Descendant metadata corresponding to the given path</returns>
        public ChildInfo GetDescendantInfo(string path)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            ChildInfo   result = null;
            DomNodeType type   = this;

            string[] segments = path.Split(':');
            foreach (string segment in segments)
            {
                result = type.GetChildInfo(segment);
                if (result == null)
                {
                    break;
                }
                type = result.Type;
            }

            return(result);
        }
예제 #25
0
 /// <summary>
 /// Parses annotations in schema sets. Override this to handle custom annotations.</summary>
 /// <param name="schemaSet">XML schema sets being loaded</param>
 /// <param name="annotations">Dictionary of annotations in schema</param>
 protected virtual void ParseAnnotations(
     XmlSchemaSet schemaSet,
     IDictionary <NamedMetadata, IList <XmlNode> > annotations)
 {
     // Inspect root types for the legacy annotation specifying id attribute
     // Get types reachable from global elements
     foreach (XmlSchemaElement element in schemaSet.GlobalElements.Values)
     {
         ChildInfo       childInfo = GetRootElement(element.QualifiedName.ToString());
         IList <XmlNode> xmlNodes;
         if (annotations.TryGetValue(childInfo.Type, out xmlNodes))
         {
             string idAttribute = FindAttribute(xmlNodes, "idAttribute", "name");
             if (idAttribute != null)
             {
                 foreach (DomNodeType type in GetNodeTypes(element.QualifiedName.Namespace))
                 {
                     type.SetIdAttribute(idAttribute);
                 }
             }
         }
     }
 }
예제 #26
0
        /// <summary>
        /// Starts writing an element for the given DomNode</summary>
        /// <param name="node">DomNode to write</param>
        /// <param name="writer">The XML writer. See <see cref="T:System.Xml.XmlWriter"/></param>
        protected void WriteStartElement(DomNode node, XmlWriter writer)
        {
            // It's possible to create DomNodes with no ChildInfo, and if the DomNode is never
            //  parented, then its ChildInfo property will still be null. We could try to search
            //  for a compatible root element in the m_typeCollection, but that's more code.
            if (node.ChildInfo == null)
            {
                throw new InvalidOperationException(
                          "Please check your document's creation method to ensure that the root DomNode's" +
                          " constructor was given a ChildInfo.");
            }
            // writes the start of an element
            m_elementNS = m_typeCollection.TargetNamespace;
            int index = node.ChildInfo.Type.Name.LastIndexOf(':');

            if (index >= 0)
            {
                m_elementNS = node.ChildInfo.Type.Name.Substring(0, index);
            }

            m_elementPrefix = string.Empty;

            // is this the root DomNode (the one passed to Write)?
            if (IsRootNode(node))
            {
                m_elementPrefix = m_typeCollection.GetPrefix(m_elementNS);
                if (m_elementPrefix == null)
                {
                    m_elementPrefix = GeneratePrefix(m_elementNS);
                }

                writer.WriteStartElement(m_elementPrefix, node.ChildInfo.Name, m_elementNS);

                // define the xsi namespace
                writer.WriteAttributeString("xmlns", "xsi", null, XmlSchema.InstanceNamespace);

                // define schema namespaces
                foreach (XmlQualifiedName name in m_typeCollection.Namespaces)
                {
                    if (name.Name != m_elementPrefix) // don't redefine the element namespace
                    {
                        writer.WriteAttributeString("xmlns", name.Name, null, name.Namespace);
                    }
                }
            }
            else
            {
                // not the root, so all schema namespaces have been defined
                m_elementPrefix = writer.LookupPrefix(m_elementNS);

                ChildInfo actualChildInfo = node.ChildInfo;

                // Check for substitutions. They're not mandatory if the node type is an exact match to the child info type.
                // http://www.w3schools.com/schema/schema_complex_subst.asp
                if (node.Type != node.ChildInfo.Type)
                {
                    var substitutionGroupRule = node.ChildInfo.Rules.OfType <SubstitutionGroupChildRule>().FirstOrDefault();
                    if (substitutionGroupRule != null)
                    {
                        ChildInfo substituteChildInfo =
                            node.Type.Lineage.Join(substitutionGroupRule.Substitutions,
                                                   n => n.Name,
                                                   s => s.Type.Name,
                                                   (n, s) => s
                                                   ).FirstOrDefault();
                        if (substituteChildInfo == null)
                        {
                            throw new InvalidOperationException("No suitable Substitution Group found for node " + node);
                        }

                        actualChildInfo = substituteChildInfo;
                        m_elementNS     = m_typeCollection.TargetNamespace;

                        index = substituteChildInfo.Type.Name.LastIndexOf(':');
                        if (index >= 0)
                        {
                            m_elementNS = substituteChildInfo.Type.Name.Substring(0, index);
                        }

                        // It is possible that an element of this namespace has not
                        // yet been written.  If the lookup fails then get the prefix from
                        // the type collection.
                        m_elementPrefix = writer.LookupPrefix(m_elementNS);
                        if (m_elementPrefix == null)
                        {
                            m_elementPrefix = m_typeCollection.GetPrefix(m_elementNS);
                        }
                    }
                }

                if (m_elementPrefix == null)
                {
                    m_elementPrefix = GeneratePrefix(m_elementNS);
                }

                writer.WriteStartElement(m_elementPrefix, actualChildInfo.Name, m_elementNS);
            }
        }
예제 #27
0
        /// <summary>
        /// Gets the root element metadata for the reader's current XML node</summary>
        /// <param name="reader">XML reader</param>
        /// <param name="rootUri">URI of XML data</param>
        /// <returns>Root element metadata for the reader's current XML node</returns>
        protected virtual ChildInfo CreateRootElement(XmlReader reader, Uri rootUri)
        {
            ChildInfo rootElement = m_typeCollection.GetRootElement(reader.LocalName);

            return(rootElement);
        }
예제 #28
0
 public override bool Validate(DomNode parent, DomNode child, ChildInfo childInfo)
 {
     return(m_substitutions.Any(x => x.Type == child.Type));
 }
예제 #29
0
        public void TestGetDescendantInfo()
        {
            DomNodeType grandchildType = new DomNodeType("grandchild");
            ChildInfo grandChildInfo = new ChildInfo("grandChild", grandchildType);
            DomNodeType childType = new DomNodeType("child");
            childType.Define(grandChildInfo);

            Assert.Null(childType.GetDescendantInfo(string.Empty));
            Assert.Null(childType.GetDescendantInfo("foo"));
            Assert.AreSame(childType.GetDescendantInfo("grandChild"), grandChildInfo);

            ChildInfo childInfo = new ChildInfo("child", childType);
            DomNodeType parentType = new DomNodeType("parent");
            parentType.Define(childInfo);

            Assert.AreSame(parentType.GetDescendantInfo("child"), childInfo);
            Assert.AreSame(parentType.GetDescendantInfo("child:grandChild"), grandChildInfo);
        }
예제 #30
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);
        }
예제 #31
0
        public void TestInheritedChildInfo()
        {
            ChildInfo info = new ChildInfo("foo", new DomNodeType("foo"));
            DomNodeType test = new DomNodeType(
                "test",
                null,
                EmptyEnumerable<AttributeInfo>.Instance,
                new ChildInfo[] { info },
                EmptyEnumerable<ExtensionInfo>.Instance);

            DomNodeType child = new DomNodeType("child");
            child.BaseType = test;

            ChildInfo inherited = child.GetChildInfo("foo");
            Assert.AreEqual(inherited.OwningType, test);
            Assert.AreEqual(inherited.DefiningType, test);

            Assert.True(inherited.Equivalent(info));
            Assert.True(info.Equivalent(inherited));
        }
예제 #32
0
        public void TestOverriddenChildInfo()
        {
            DomNodeType childType = new DomNodeType("foo");
            ChildInfo info = new ChildInfo("foo", childType);
            DomNodeType test = new DomNodeType(
                "test",
                null,
                EmptyEnumerable<AttributeInfo>.Instance,
                new ChildInfo[] { info },
                EmptyEnumerable<ExtensionInfo>.Instance);

            ChildInfo overridden = new ChildInfo("foo", childType);
            DomNodeType child = new DomNodeType("child", test,
                EmptyEnumerable<AttributeInfo>.Instance,
                new ChildInfo[] { overridden },
                EmptyEnumerable<ExtensionInfo>.Instance);

            Assert.AreSame(child.GetChildInfo("foo"), overridden);
            Assert.AreEqual(overridden.OwningType, child);
            Assert.AreEqual(overridden.DefiningType, test);

            Assert.True(info.Equivalent(overridden));
            Assert.True(overridden.Equivalent(info));

            Assert.True(test.IsValid(overridden));
            Assert.True(child.IsValid(info));
        }
예제 #33
0
 public static Settings New(ChildInfo childInfo)
 {
     DomNode node = new DomNode(Schema.settingsType.Type, childInfo);
     return node.Cast<Settings>();
 }
예제 #34
0
        public void TestCustomChildInfo()
        {
            DomNodeType type = new DomNodeType("foo");
            ChildInfo info = new ChildInfo("foo", type);
            DomNodeType test = new DomNodeType(
                "test",
                null,
                EmptyEnumerable<AttributeInfo>.Instance,
                new ChildInfo[] { info },
                EmptyEnumerable<ExtensionInfo>.Instance);

            Utilities.TestSequenceEqual(test.Children, info);
            Assert.True(test.IsValid(info));
            Assert.AreSame(test.GetChildInfo("foo"), info);
            // check that type is now frozen
            Assert.Throws<InvalidOperationException>(delegate { test.Define(new ChildInfo("notFoo", type)); });

            Assert.AreEqual(info.OwningType, test);
            Assert.AreEqual(info.DefiningType, test);
            Assert.Null(test.GetChildInfo("bar"));
        }
예제 #35
0
        private void WalkParticle(XmlSchemaParticle particle, DomNodeType nodeType)
        {
            XmlSchemaElement element = particle as XmlSchemaElement;

            if (element != null)
            {
                XmlSchemaSimpleType simpleType = element.ElementSchemaType as XmlSchemaSimpleType;
                if (simpleType != null &&
                    element.MaxOccurs == 1)
                {
                    XmlAttributeType attributeType = GetAttributeType(simpleType);
                    string           fieldName     = GetFieldName(element.QualifiedName);
                    XmlAttributeInfo attributeInfo = new XmlAttributeInfo(fieldName, attributeType);

                    nodeType.Define(attributeInfo);
                    m_annotations.Add(attributeInfo, GetAnnotation(element));

                    attributeInfo.IsElement = true;

                    if (element.DefaultValue != null)
                    {
                        if (element.FixedValue != null)
                        {
                            throw new InvalidOperationException(string.Format("Schema element {0} cannot have both a default value and a fixed value", element.QualifiedName));
                        }
                        attributeInfo.DefaultValue = attributeType.Convert(element.DefaultValue);
                    }
                    else if (element.FixedValue != null)
                    {
                        attributeInfo.DefaultValue = attributeType.Convert(element.FixedValue);
                    }
                }
                else
                {
                    DomNodeType childNodeType = null;
                    if (simpleType != null)
                    {
                        childNodeType = WrapSimpleType(simpleType);

                        // Add the value attribute
                        XmlAttributeType valueAttributeType = GetAttributeType(simpleType);
                        var valueAttributeInfo = new XmlAttributeInfo(string.Empty, valueAttributeType);
                        childNodeType.Define(valueAttributeInfo);
                    }
                    else
                    {
                        XmlSchemaComplexType complexType = element.ElementSchemaType as XmlSchemaComplexType;
                        if (complexType != null)
                        {
                            childNodeType = GetNodeType(complexType, element);
                        }
                    }

                    if (childNodeType != null)
                    {
                        int minOccurs = (int)Math.Min(element.MinOccurs, Int32.MaxValue);
                        int maxOccurs = (int)Math.Min(element.MaxOccurs, Int32.MaxValue);

                        // If <xs:choice> is within a <xs:sequence>, choose the most relaxed constraints.
                        if (particle.Parent is XmlSchemaChoice &&
                            particle.Parent.Parent is XmlSchemaSequence)
                        {
                            XmlSchemaChoice parent          = (XmlSchemaChoice)particle.Parent;
                            int             parentMinOccurs = (int)Math.Min(parent.MinOccurs, Int32.MaxValue);
                            int             parentMaxOccurs = (int)Math.Min(parent.MaxOccurs, Int32.MaxValue);
                            minOccurs = Math.Min(parentMinOccurs, minOccurs);
                            maxOccurs = Math.Max(parentMaxOccurs, maxOccurs);
                        }

                        ChildInfo childInfo = new ChildInfo(GetFieldName(element.QualifiedName), childNodeType, maxOccurs > 1);

                        if (minOccurs > 0 || maxOccurs < Int32.MaxValue)
                        {
                            childInfo.AddRule(new ChildCountRule(minOccurs, maxOccurs));
                        }

                        // Check for substitution groups
                        if (!element.RefName.IsEmpty)
                        {
                            m_refElements.Add(childInfo, element.RefName);
                        }

                        nodeType.Define(childInfo);
                        m_annotations.Add(childInfo, GetAnnotation(element));
                    }
                }
            }
            else
            {
                // if sequence, continue collecting elements
                XmlSchemaSequence sequence = particle as XmlSchemaSequence;
                if (sequence != null)
                {
                    foreach (XmlSchemaParticle subParticle in sequence.Items)
                    {
                        WalkParticle(subParticle, nodeType);
                    }
                }
                else
                {
                    XmlSchemaChoice choice = particle as XmlSchemaChoice;
                    if (choice != null)
                    {
                        // for now, treat choice as if it were a sequence
                        foreach (XmlSchemaParticle subParticle in choice.Items)
                        {
                            WalkParticle(subParticle, nodeType);
                        }
                    }
                }
            }
        }
예제 #36
0
        /// <summary>
        /// Sets the child of our adapted DomNode to a new DomNode</summary>
        /// <param name="childInfo">Metadata to indicate the child</param>
        /// <param name="value">Any IAdaptable, such as DomNodeAdapter, DomNode, or IAdapter</param>
        protected void SetChild(ChildInfo childInfo, IAdaptable value)
        {
            DomNode child = value.As <DomNode>();

            DomNode.SetChild(childInfo, child);
        }
예제 #37
0
        /// <summary>
        /// Converts schemas to NodeTypes, AttributeTypes, and root elements</summary>
        /// <param name="schemaSet">Schemas to register</param>
        public void Load(XmlSchemaSet schemaSet)
        {
            if (!schemaSet.IsCompiled)
            {
                schemaSet.Compile();
            }

            System.Collections.ICollection schemas = schemaSet.Schemas();
            foreach (XmlSchema schema in schemas)
            {
                string targetNamespace = schema.TargetNamespace;
                if (string.IsNullOrEmpty(targetNamespace))
                {
                    throw new InvalidOperationException("Schema has no target namespace");
                }

                // only register the schema once; targetNamespaces must be globally unique
                if (!m_typeCollections.ContainsKey(targetNamespace))
                {
                    XmlQualifiedName[]      nameSpaces     = schema.Namespaces.ToArray();
                    XmlSchemaTypeCollection typeCollection = new XmlSchemaTypeCollection(nameSpaces, targetNamespace, this);
                    m_typeCollections.Add(targetNamespace, typeCollection);
                }
            }

            try
            {
                m_annotations     = new Dictionary <NamedMetadata, IList <XmlNode> >();
                m_typeNameSet     = new HashSet <string>();
                m_localElementSet = new Dictionary <XmlSchemaElement, XmlQualifiedName>();
                // collect global element & type names so we do not generate local type names that collides with those
                foreach (XmlSchemaElement element in schemaSet.GlobalElements.Values)
                {
                    m_typeNameSet.Add(element.QualifiedName.Name);
                }

                foreach (XmlSchemaType type in schemaSet.GlobalTypes.Values)
                {
                    if (type is XmlSchemaComplexType)
                    {
                        m_typeNameSet.Add(type.Name);
                    }
                }

                var substitutionGroups = new Multimap <XmlQualifiedName, ChildInfo>();

                // Get types reachable from global elements
                foreach (XmlSchemaElement element in schemaSet.GlobalElements.Values)
                {
                    XmlSchemaType type      = element.ElementSchemaType;
                    DomNodeType   nodeType  = GetNodeType(type, element);
                    ChildInfo     childInfo = new ChildInfo(GetFieldName(element.QualifiedName), nodeType);
                    m_annotations.Add(childInfo, GetAnnotation(element));

                    // Keep list of substitution groups
                    if (!element.SubstitutionGroup.IsEmpty)
                    {
                        substitutionGroups.Add(element.SubstitutionGroup, childInfo);
                    }

                    // only add root elements once; root element names must be globally unique
                    string name = element.QualifiedName.ToString();
                    if (!m_rootElements.ContainsKey(name))
                    {
                        m_rootElements[name] = childInfo;
                    }
                }

                // Get global complex type definitions
                foreach (XmlSchemaType type in schemaSet.GlobalTypes.Values)
                {
                    if (type is XmlSchemaComplexType)
                    {
                        GetNodeType(type, null);
                    }
                }

                // Parse substitution groups
                foreach (var kvp in m_refElements)
                {
                    XmlQualifiedName refName   = kvp.Value;
                    ChildInfo        childInfo = kvp.Key;

                    var substitutions = CreateSubstitutions(substitutionGroups, refName).ToArray();
                    if (substitutions.Length > 0)
                    {
                        childInfo.AddRule(new SubstitutionGroupChildRule(substitutions));
                    }
                }

                // Preserve annotation from any types that were redefined
                foreach (XmlSchema schema in schemas)
                {
                    foreach (XmlSchemaObject schemaInclude in schema.Includes)
                    {
                        XmlSchemaRedefine schemaRedefine = schemaInclude as XmlSchemaRedefine;
                        if (schemaRedefine != null)
                        {
                            MergeRedefinedTypeAnnotations(schemaRedefine);
                        }
                    }
                }

                // Sort DomNodeTypes, so that base types are always before derived types
                // Bucket sort by depth in the inheritance tree
                // Time: O(n * d) with n = number of DomNodeTypes, d = depth of inheritance tree
                var sortedTypes = new List <List <DomNodeType> >();
                foreach (DomNodeType type in GetNodeTypes())
                {
                    // Get inheritance depth of current type
                    int         depth   = 0;
                    DomNodeType curType = type;
                    while (curType != null && curType != DomNodeType.BaseOfAllTypes)
                    {
                        depth++;
                        curType = curType.BaseType;
                    }

                    // We don't need to merge annotations for BaseAllTypes (level 0)
                    // and its immediate child types (level 1)
                    int idx = depth - 2;
                    if (idx >= 0)
                    {
                        while (sortedTypes.Count <= idx)
                        {
                            sortedTypes.Add(new List <DomNodeType>());
                        }
                        sortedTypes[idx].Add(type);
                    }
                }

                // Merge type annotations with base type annotations
                foreach (var list in sortedTypes)
                {
                    foreach (DomNodeType type in list)
                    {
                        if (type.BaseType != null && type.BaseType != DomNodeType.BaseOfAllTypes)
                        {
                            IList <XmlNode> baseAnnotations;
                            IList <XmlNode> annotations;
                            if (m_annotations.TryGetValue(type.BaseType, out baseAnnotations) &&
                                m_annotations.TryGetValue(type, out annotations))
                            {
                                // Call protected virtual merge method - allowing clients to define if & how annotations are being merged
                                IEnumerable <XmlNode> mergedAnnotations = MergeInheritedTypeAnnotations(baseAnnotations, annotations);
                                m_annotations[type] = mergedAnnotations as IList <XmlNode> ?? mergedAnnotations.ToList();
                            }
                        }
                    }
                }

                // Call before the DomNodeTypes are frozen. Note that iterating through Attributes or
                //  calling 'SetIdAttribute' freezes the attributes on DomNodeType.
                OnSchemaSetLoaded(schemaSet);

                // Set up ID attributes where xs:ID has been specified
                foreach (DomNodeType nodeType in GetNodeTypes())
                {
                    foreach (var attribute in nodeType.Attributes.OfType <XmlAttributeInfo>())
                    {
                        if (((XmlAttributeType)attribute.Type).XmlTypeCode == XmlTypeCode.Id)
                        {
                            nodeType.SetIdAttribute(attribute.Name);
                        }
                    }
                }

                // Attach annotation as metadata to the associated type so that other classes can find it
                foreach (var keyValuePair in m_annotations)
                {
                    if (keyValuePair.Value.Count > 0)
                    {
                        keyValuePair.Key.SetTag <IEnumerable <XmlNode> >(keyValuePair.Value);
                    }
                }
                ParseAnnotations(schemaSet, m_annotations);

                // Call this after the ID attributes have been set and after the DomNodeTypes are frozen.
                OnDomNodeTypesFrozen(schemaSet);
            }
            finally
            {
                m_annotations     = null;
                m_typeNameSet     = null;
                m_localElementSet = null;
            }
        }
예제 #38
0
        public void TestCopy_MultipleNodes()
        {
            DomNodeType type = new DomNodeType("type");
            ChildInfo info = new ChildInfo("child", type);
            ChildInfo infoList = new ChildInfo("childList", type, true);
            type.Define(info);
            type.Define(infoList);
            ChildInfo rootInfo = new ChildInfo("root", type, true);
            DomNode test = new DomNode(type, rootInfo);
            DomNode child1 = new DomNode(type);
            test.SetChild(info, child1);
            DomNode child2 = new DomNode(type);
            DomNode child3 = new DomNode(type);
            IList<DomNode> list = test.GetChildList(infoList);
            list.Add(child2);
            list.Add(child3);

            DomNode[] result = DomNode.Copy(new DomNode[] { test });
            Assert.AreEqual(result.Length, 1);
            Assert.True(Equals(result[0], test));

            DomNode singleResult = DomNode.Copy(test);
            Assert.True(Equals(singleResult, test));
        }
예제 #39
0
 public DomXmlReader(ChildInfo rootNodeInfo, DomNodeTypeCollection typeCollection)
 {
     m_typeCollection = typeCollection;
     m_rootNodeInfo   = rootNodeInfo;
 }
 /// <summary>
 /// Constructor</summary>
 /// <param name="node">DomNode whose children are adapted by this</param>
 /// <param name="childInfo">Metadata indicating which child list to wrap</param>
 public DomNodeListAdapter(DomNode node, ChildInfo childInfo)
 {
     m_nodes = node.GetChildList(childInfo);
 }
예제 #41
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);
        }
예제 #42
0
        private void WalkParticle(XmlSchemaParticle particle, DomNodeType nodeType)
        {
            XmlSchemaElement element = particle as XmlSchemaElement;

            if (element != null)
            {
                XmlSchemaSimpleType simpleType = element.ElementSchemaType as XmlSchemaSimpleType;
                if (simpleType != null &&
                    element.MaxOccurs == 1)
                {
                    XmlAttributeType attributeType = GetAttributeType(simpleType);
                    string           fieldName     = GetFieldName(element.QualifiedName);
                    XmlAttributeInfo attributeInfo = new XmlAttributeInfo(fieldName, attributeType);

                    nodeType.Define(attributeInfo);
                    m_annotations.Add(attributeInfo, GetAnnotation(element));

                    attributeInfo.IsElement = true;

                    if (element.DefaultValue != null)
                    {
                        if (element.FixedValue != null)
                        {
                            throw new InvalidOperationException(string.Format("Schema element {0} cannot have both a default value and a fixed value", element.QualifiedName));
                        }
                        attributeInfo.DefaultValue = attributeType.Convert(element.DefaultValue);
                    }
                    else if (element.FixedValue != null)
                    {
                        attributeInfo.DefaultValue = attributeType.Convert(element.FixedValue);
                    }
                }
                else
                {
                    DomNodeType childNodeType = null;
                    if (simpleType != null)
                    {
                        bool firstTime;
                        childNodeType = WrapSimpleType(simpleType, out firstTime);

                        // The collada.xsd's ListOfUInts element breaks the generated Schema.cs file otherwise.
                        if (firstTime)
                        {
                            // Add the value attribute
                            XmlAttributeType valueAttributeType = GetAttributeType(simpleType);
                            var valueAttributeInfo = new XmlAttributeInfo(string.Empty, valueAttributeType);
                            childNodeType.Define(valueAttributeInfo);
                        }
                    }
                    else
                    {
                        XmlSchemaComplexType complexType = element.ElementSchemaType as XmlSchemaComplexType;
                        if (complexType != null)
                        {
                            childNodeType = GetNodeType(complexType, element);
                        }
                    }

                    if (childNodeType != null)
                    {
                        int minOccurs = (int)Math.Min(element.MinOccurs, Int32.MaxValue);
                        int maxOccurs = (int)Math.Min(element.MaxOccurs, Int32.MaxValue);

                        if (particle.Parent is XmlSchemaChoice)
                        {
                            var parent = (XmlSchemaChoice)particle.Parent;
                            if (parent.MinOccurs != 1)
                            {
                                minOccurs = (int)Math.Min(Math.Max(element.MinOccurs, parent.MinOccurs), Int32.MaxValue);
                            }
                            if (parent.MaxOccurs != 1)
                            {
                                maxOccurs = (int)Math.Min(Math.Max(element.MaxOccurs, parent.MaxOccurs), Int32.MaxValue);
                            }
                        }
                        else if (particle.Parent is XmlSchemaSequence)
                        {
                            var parent = (XmlSchemaSequence)particle.Parent;
                            if (parent.MinOccurs != 1)
                            {
                                minOccurs = (int)Math.Min(Math.Max(element.MinOccurs, parent.MinOccurs), Int32.MaxValue);
                            }
                            if (parent.MaxOccurs != 1)
                            {
                                maxOccurs = (int)Math.Min(Math.Max(element.MaxOccurs, parent.MaxOccurs), Int32.MaxValue);
                            }
                        }

                        ChildInfo childInfo = new ChildInfo(GetFieldName(element.QualifiedName), childNodeType, maxOccurs > 1);

                        if ((minOccurs > 0 || maxOccurs < Int32.MaxValue) &&
                            minOccurs <= maxOccurs)
                        {
                            childInfo.AddRule(new ChildCountRule(minOccurs, maxOccurs));
                        }

                        // Check for substitution groups
                        if (!element.RefName.IsEmpty)
                        {
                            m_refElements.Add(childInfo, element.RefName);
                        }

                        nodeType.Define(childInfo);
                        m_annotations.Add(childInfo, GetAnnotation(element));
                    }
                }
            }
            else
            {
                XmlSchemaGroupBase grp = particle as XmlSchemaSequence;
                if (grp == null)
                {
                    grp = particle as XmlSchemaChoice;
                }
                if (grp == null)
                {
                    grp = particle as XmlSchemaAll;
                }

                if (grp != null)
                {
                    foreach (XmlSchemaParticle subParticle in grp.Items)
                    {
                        WalkParticle(subParticle, nodeType);
                    }
                }
            }
        }
예제 #43
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);
        }
예제 #44
0
        public void TestChildRemoveEvents()
        {
            DomNodeType type = new DomNodeType("type");
            ChildInfo info = new ChildInfo("child", type);
            ChildInfo infoList = new ChildInfo("childList", type, true);
            type.Define(info);
            type.Define(infoList);
            DomNode test = new DomNode(type);
            test.ChildRemoving += new EventHandler<ChildEventArgs>(test_ChildRemoving);
            test.ChildRemoved += new EventHandler<ChildEventArgs>(test_ChildRemoved);

            // test child
            DomNode child = new DomNode(type);
            test.SetChild(info, child);
            ChildRemovingArgs = null;
            ChildRemovedArgs = null;
            test.SetChild(info, null);
            ChildEventArgs expected = new ChildEventArgs(test, info, child, 0);
            Assert.True(Equals(ChildRemovingArgs, expected));
            Assert.True(Equals(ChildRemovedArgs, expected));

            // test inserting a child when there is one there already
            test.SetChild(info, child);
            DomNode newChild = new DomNode(type);
            ChildRemovingArgs = null;
            ChildRemovedArgs = null;
            test.SetChild(info, newChild);
            expected = new ChildEventArgs(test, info, child, 0);
            Assert.True(Equals(ChildRemovingArgs, expected));
            Assert.True(Equals(ChildRemovedArgs, expected));

            // test child list
            IList<DomNode> list = test.GetChildList(infoList);
            DomNode child2 = new DomNode(type);
            list.Add(child2);
            DomNode child3 = new DomNode(type);
            list.Add(child3);
            ChildRemovingArgs = null;
            ChildRemovedArgs = null;
            list.Remove(child3);
            expected = new ChildEventArgs(test, infoList, child3, 1);
            Assert.True(Equals(ChildRemovingArgs, expected));
            Assert.True(Equals(ChildRemovedArgs, expected));
            ChildRemovingArgs = null;
            ChildRemovedArgs = null;
            list.Remove(child2);
            expected = new ChildEventArgs(test, infoList, child2, 0);
            Assert.True(Equals(ChildRemovingArgs, expected));
            Assert.True(Equals(ChildRemovedArgs, expected));
        }
예제 #45
0
 /// <summary>
 /// Gets the children of our adapted DomNode</summary>
 /// <typeparam name="T">The type to adapt each child to</typeparam>
 /// <param name="childInfo">Metadata to indicate the child list</param>
 /// <returns>Wrapper that adapts a node child list to a list of T items</returns>
 protected IList <T> GetChildList <T>(ChildInfo childInfo)
     where T : class
 {
     return(new DomNodeListAdapter <T>(DomNode, childInfo));
 }