/// <summary> /// Automatically exclude build elements that are defined on the task /// from things that get executed, as they are evaluated normally during /// XML task initialization. /// </summary> /// <param name="taskNode"><see cref="XmlNode" /> used to initialize the container.</param> protected override void InitializeTask(XmlNode taskNode) { base.InitializeTask(taskNode); // Exclude any BuildElements (like FileSets, etc.) from our execution elements. // These build elements will be handled during the xml init of the task container (Element xmlinit code) _subXMLElements = new StringCollection(); foreach (MemberInfo memInfo in this.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public)) { if (memInfo.DeclaringType.Equals(typeof(object))) { continue; } BuildElementAttribute buildElemAttr = (BuildElementAttribute)Attribute.GetCustomAttribute(memInfo, typeof(BuildElementAttribute), true); if (buildElemAttr != null) { _subXMLElements.Add(buildElemAttr.Name); } } }
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); }