示例#1
0
            protected XmlSchemaComplexType FindOrCreateComplexType(Type t)
            {
                XmlSchemaComplexType ct;
                string typeId = GenerateIDFromType(t);

                ct = FindComplexTypeByID(typeId);
                if (ct != null)
                {
                    return(ct);
                }

                ct      = new XmlSchemaComplexType();
                ct.Name = typeId;

                // Force mixed attribute for tasks names in the mixedTaskNames array.  Fixes Bug#: 3058913
                if (Array.IndexOf(mixedTaskNames, ct.Name) != -1)
                {
                    ct.IsMixed = true;
                }

                // add complex type to collection immediately to avoid stack
                // overflows, when we allow a type to be nested
                _nantComplexTypes.Add(typeId, ct);

#if NOT_IMPLEMENTED
                //
                // TODO - add task/type documentation in the future
                //

                ct.Annotation = new XmlSchemaAnnotation();
                XmlSchemaDocumentation doc = new XmlSchemaDocumentation();
                ct.Annotation.Items.Add(doc);
                doc.Markup = ...;
#endif

                XmlSchemaSequence         group1 = null;
                XmlSchemaObjectCollection attributesCollection = ct.Attributes;

                foreach (MemberInfo memInfo in t.GetMembers(BindingFlags.Instance | BindingFlags.Public))
                {
                    if (memInfo.DeclaringType.Equals(typeof(object)))
                    {
                        continue;
                    }

                    //Check for any return type that is derived from Element

                    // add Attributes
                    TaskAttributeAttribute taskAttrAttr = (TaskAttributeAttribute)
                                                          Attribute.GetCustomAttribute(memInfo, typeof(TaskAttributeAttribute),
                                                                                       false);
                    BuildElementAttribute buildElemAttr = (BuildElementAttribute)
                                                          Attribute.GetCustomAttribute(memInfo, typeof(BuildElementAttribute),
                                                                                       false);

                    if (taskAttrAttr != null)
                    {
                        XmlSchemaAttribute newAttr = CreateXsdAttribute(taskAttrAttr.Name, taskAttrAttr.Required);
                        attributesCollection.Add(newAttr);
                    }
                    else if (buildElemAttr != null)
                    {
                        // Create individial choice for any individual child Element
                        Decimal min = 0;

                        if (buildElemAttr.Required)
                        {
                            min = 1;
                        }

                        XmlSchemaElement childElement = new XmlSchemaElement();
                        childElement.MinOccurs = min;
                        childElement.MaxOccurs = 1;
                        childElement.Name      = buildElemAttr.Name;

                        //XmlSchemaGroupBase elementGroup = CreateXsdSequence(min, Decimal.MaxValue);

                        Type childType;

                        // We will only process child elements if they are defined for Properties or Fields, this should be enforced by the AttributeUsage on the Attribute class
                        if (memInfo is PropertyInfo)
                        {
                            childType = ((PropertyInfo)memInfo).PropertyType;
                        }
                        else if (memInfo is FieldInfo)
                        {
                            childType = ((FieldInfo)memInfo).FieldType;
                        }
                        else if (memInfo is MethodInfo)
                        {
                            MethodInfo method = (MethodInfo)memInfo;
                            if (method.GetParameters().Length == 1)
                            {
                                childType = method.GetParameters()[0].ParameterType;
                            }
                            else
                            {
                                throw new ApplicationException("Method should have one parameter.");
                            }
                        }
                        else
                        {
                            throw new ApplicationException("Member Type != Field/Property/Method");
                        }

                        BuildElementArrayAttribute buildElementArrayAttribute = (BuildElementArrayAttribute)
                                                                                Attribute.GetCustomAttribute(memInfo, typeof(BuildElementArrayAttribute), false);

                        // determine type of child elements

                        if (buildElementArrayAttribute != null)
                        {
                            if (buildElementArrayAttribute.ElementType == null)
                            {
                                if (childType.IsArray)
                                {
                                    childType = childType.GetElementType();
                                }
                                else
                                {
                                    Type elementType = null;

                                    // locate Add method with 1 parameter, type of that parameter is parameter type
                                    foreach (MethodInfo method in childType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
                                    {
                                        if (method.Name == "Add" && method.GetParameters().Length == 1)
                                        {
                                            ParameterInfo parameter = method.GetParameters()[0];
                                            elementType = parameter.ParameterType;
                                            break;
                                        }
                                    }

                                    childType = elementType;
                                }
                            }
                            else
                            {
                                childType = buildElementArrayAttribute.ElementType;
                            }

                            if (childType == null || !typeof(Element).IsAssignableFrom(childType))
                            {
                                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                                       ResourceUtils.GetString("NA1140"), memInfo.DeclaringType.FullName, memInfo.Name));
                            }
                        }

                        BuildElementCollectionAttribute buildElementCollectionAttribute = (BuildElementCollectionAttribute)Attribute.GetCustomAttribute(memInfo, typeof(BuildElementCollectionAttribute), false);
                        if (buildElementCollectionAttribute != null)
                        {
                            XmlSchemaComplexType collectionType = new XmlSchemaComplexType();
                            XmlSchemaSequence    sequence       = new XmlSchemaSequence();
                            collectionType.Particle = sequence;

                            sequence.MinOccurs       = 0;
                            sequence.MaxOccursString = "unbounded";

                            XmlSchemaElement itemType = new XmlSchemaElement();
                            itemType.Name           = buildElementCollectionAttribute.ChildElementName;
                            itemType.SchemaTypeName = FindOrCreateComplexType(childType).QualifiedName;

                            sequence.Items.Add(itemType);

                            childElement.SchemaType = collectionType;
                        }
                        else
                        {
                            childElement.SchemaTypeName = FindOrCreateComplexType(childType).QualifiedName;
                        }

                        // lazy init of sequence
                        if (group1 == null)
                        {
                            group1      = CreateXsdSequence(0, Decimal.MaxValue);
                            ct.Particle = group1;
                        }

                        group1.Items.Add(childElement);
                    }
                }

                // allow attributes from other namespace
                ct.AnyAttribute                 = new XmlSchemaAnyAttribute();
                ct.AnyAttribute.Namespace       = "##other";
                ct.AnyAttribute.ProcessContents = XmlSchemaContentProcessing.Skip;

                Schema.Items.Add(ct);
                Compile();

                return(ct);
            }
示例#2
0
            protected override bool InitializeBuildElementCollection(System.Reflection.PropertyInfo propertyInfo)
            {
                Type elementType = typeof(Filter);

                BuildElementArrayAttribute buildElementArrayAttribute = (BuildElementArrayAttribute)
                                                                        Attribute.GetCustomAttribute(propertyInfo, typeof(BuildElementArrayAttribute));

                if (buildElementArrayAttribute == null || propertyInfo.PropertyType != typeof(FilterCollection))
                {
                    return(base.InitializeBuildElementCollection(propertyInfo));
                }

                XmlNodeList collectionNodes = ElementXml.ChildNodes;

                // create new array of the required size - even if size is 0
                ArrayList list = new ArrayList(collectionNodes.Count);

                foreach (XmlNode childNode in collectionNodes)
                {
                    // skip non-nant namespace elements and special elements like comments, pis, text, etc.
                    if (!(childNode.NodeType == XmlNodeType.Element) || !childNode.NamespaceURI.Equals(NamespaceManager.LookupNamespace("nant")))
                    {
                        continue;
                    }

                    // remove element from list of remaining items
                    UnprocessedChildNodes.Remove(childNode.Name);

                    // initialize child element (from XML or data type reference)
                    Filter filter = TypeFactory.CreateFilter(childNode,
                                                             Element);

                    list.Add(filter);
                }

                MethodInfo addMethod = null;

                // get array of public instance methods
                MethodInfo[] addMethods = propertyInfo.PropertyType.GetMethods(BindingFlags.Public | BindingFlags.Instance);

                // search for a method called 'Add' which accepts a parameter
                // to which the element type is assignable
                foreach (MethodInfo method in addMethods)
                {
                    if (method.Name == "Add" && method.GetParameters().Length == 1)
                    {
                        ParameterInfo parameter = method.GetParameters()[0];
                        if (parameter.ParameterType.IsAssignableFrom(elementType))
                        {
                            addMethod = method;
                            break;
                        }
                    }
                }

                if (addMethod == null)
                {
                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                           ResourceUtils.GetString("NA1020"), elementType.FullName,
                                                           propertyInfo.PropertyType.FullName, propertyInfo.Name, Name),
                                             Location);
                }

                // if value of property is null, create new instance of collection
                object collection = propertyInfo.GetValue(Element, BindingFlags.Default, null, null, CultureInfo.InvariantCulture);

                if (collection == null)
                {
                    if (!propertyInfo.CanWrite)
                    {
                        throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                               ResourceUtils.GetString("NA1093"),
                                                               buildElementArrayAttribute.Name, Name),
                                                 Location);
                    }
                    object instance = Activator.CreateInstance(
                        propertyInfo.PropertyType, BindingFlags.Public | BindingFlags.Instance,
                        null, null, CultureInfo.InvariantCulture);
                    propertyInfo.SetValue(Element, instance,
                                          BindingFlags.Default, null, null, CultureInfo.InvariantCulture);
                }

                // add each element of the arraylist to collection instance
                foreach (object childElement in list)
                {
                    addMethod.Invoke(collection, BindingFlags.Default, null, new object[] { childElement }, CultureInfo.InvariantCulture);
                }

                return(true);
            }