/// <summary> /// Actually parses an array, and is used in both short-hand and separate /// element formats of array specification. /// </summary> public static Array ParseArray(string elementTypeName, XmlElement[] childElements, XmlProcessingContext context) { context.EnterRunningLocation(string.Format("Array({0})", elementTypeName ?? "object")); var elementType = typeof(object); if (elementTypeName != null) { elementType = SimpleTypeParserUtil.ParseType(elementTypeName, context); if (elementType == null) { context.ReportError(string.Format("Type '{0}' could not be loaded.", elementTypeName)); return(null); } } var arrayElements = GetCollectionElements(childElements, elementType, context); var result = Array.CreateInstance(elementType, arrayElements.Count); for (var i = 0; i < result.Length; i++) { result.SetValue(arrayElements[i], i); } context.LeaveRunningLocation(); return(result); }
/// <summary> /// Actually parses the contents of lists from composition XMLs, and is /// used in both short-hand form and complete form of list specification. /// </summary> public static IList ParseList(string elementTypeName, XmlElement[] childElements, XmlProcessingContext context) { context.EnterRunningLocation(string.Format("List({0})", elementTypeName ?? "object")); var elementType = typeof(object); if (elementTypeName != null) { elementType = SimpleTypeParserUtil.ParseType(elementTypeName, context); if (elementType == null) { context.ReportError(string.Format("Type '{0}' could not be loaded.", elementTypeName)); context.LeaveRunningLocation(); return(null); } } var listElements = GetCollectionElements(childElements, elementType, context); var listType = Type.GetType(string.Format("System.Collections.Generic.List`1[[{0}]]", elementType.AssemblyQualifiedName)); var result = (IList)Activator.CreateInstance(listType); foreach (var o in listElements) { result.Add(o); } context.LeaveRunningLocation(); return(result); }
/// <summary> /// Actually parses the object and returns the result. Used both in short-hand /// form and in direct Object element parsing. /// </summary> public static object ParseObject(string typeName, bool initializePlugs, XmlElement[] childElements, XmlProcessingContext context) { context.EnterRunningLocation(string.Format("Object({0})", typeName)); // Look for constructor arguments. // Set default to null, so that Activator calls default constructor // in case the the "ConstructorArgs" element is not specified. object[] constructorArguments = null; foreach (var childElement in childElements) { if (childElement.Name != "ConstructorArgs") { continue; } // Check if this is the second "ConstructorArgs" element. // If so, report an error and return. if (constructorArguments != null) { context.ReportError("The 'ConstructorArgs' element can be specified maximum once in an 'Object' element."); context.LeaveRunningLocation(); return(null); } constructorArguments = ParseConstructorArgs(childElement, context); context.ThrowIfErrors(); } // Resolve the "Type" for the object to be instantiated var objectType = SimpleTypeParserUtil.ParseType(typeName, context); if (objectType == null) { context.ReportError(string.Format("Type '{0}' could not be loaded.", typeName)); context.LeaveRunningLocation(); return(null); } // Use Activator class to instantiate the object var result = Activator.CreateInstance(objectType, constructorArguments); if (initializePlugs) { context.ComponentContext.InitializePlugs(result, objectType); } foreach (var childElement in childElements) { switch (childElement.Name) { case "ConstructorArgs": break; case "Property": ParseObjectProperty(result, childElement, context); break; case "Field": ParseObjectField(result, childElement, context); break; default: // Also: case "ConstructorArgs" context.ReportError( string.Format("Xml element '{0}' is not allowed in 'Object' element - type: {1}", childElement.Name, typeName)); context.LeaveRunningLocation(); return(null); } } context.LeaveRunningLocation(); return(result); }
/// <summary> /// Actually parses the contents of dictionaries in composition XMLs, and is /// used for both short-hand and seperate element formats of dictionary specification. /// </summary> public static IDictionary ParseDictionary(string keyTypeName, string valueTypeName, XmlElement[] xmlElements, XmlProcessingContext context) { context.EnterRunningLocation( string.Format("Parse Dictionary({0}, {1})", keyTypeName ?? "object", valueTypeName ?? "object")); var keyType = typeof(object); var valueType = typeof(object); if (keyTypeName != null) { keyType = SimpleTypeParserUtil.ParseType(keyTypeName, context); if (keyType == null) { context.ReportError(string.Format("Type '{0}' could not be loaded.", keyTypeName)); context.LeaveRunningLocation(); return(null); } } if (valueTypeName != null) { valueType = SimpleTypeParserUtil.ParseType(valueTypeName, context); if (valueType == null) { context.ReportError(string.Format("Type '{0}' could not be loaded.", valueTypeName)); context.LeaveRunningLocation(); return(null); } } var dictionaryType = Type.GetType(string.Format("System.Collections.Generic.Dictionary`2[[{0}],[{1}]]", keyType.AssemblyQualifiedName, valueType.AssemblyQualifiedName)); var result = (IDictionary)Activator.CreateInstance(dictionaryType); for (var i = 0; i < xmlElements.Length; i++) { var childElement = xmlElements[i]; if (childElement.Name == "Item") { context.EnterRunningLocation(string.Format("Item({0})", i)); ParseDictionaryItem(result, childElement, context); context.LeaveRunningLocation(); // For Item } else { context.ReportError( string.Format("Xml element '{0}' is not allowed in 'Dictionary' element - type: Dictionary<{1}, {2}>", childElement.Name, keyType.FullName, valueType.FullName)); context.LeaveRunningLocation(); return(null); } } context.LeaveRunningLocation(); return(result); }