private static void ParseDictionaryItem(IDictionary result, XmlElement childElement,
                                                XmlProcessingContext xmlProcessingContext)
        {
            if (childElement.GetElementsByTagName("Key").Count != 1)
            {
                xmlProcessingContext.ReportError(
                    "Each 'Item' in a 'Dictionary' should contain exactly one 'Key' element as a nested tag.");
                return;
            }

            if (childElement.GetElementsByTagName("Value").Count != 1)
            {
                xmlProcessingContext.ReportError(
                    "Each 'Item' in a 'Dictionary' should contain exactly one 'Value' element as a nested tag.");
                return;
            }

            xmlProcessingContext.EnterRunningLocation("Key");
            var keyValue =
                XmlValueParser.ParseValue((XmlElement)childElement.GetElementsByTagName("Key")[0], xmlProcessingContext, null);

            xmlProcessingContext.LeaveRunningLocation();

            xmlProcessingContext.EnterRunningLocation("Value");
            var valueValue =
                XmlValueParser.ParseValue((XmlElement)childElement.GetElementsByTagName("Value")[0], xmlProcessingContext, null);

            xmlProcessingContext.LeaveRunningLocation();

            result.Add(keyValue, valueValue);
        }
        private static void ParseObjectProperty(object result, XmlElement childElement,
                                                XmlProcessingContext xmlProcessingContext)
        {
            if (childElement.Attributes["name"] == null)
            {
                xmlProcessingContext.ReportError("'Property' element in the composition XML should have a 'name' attribute.");
                return;
            }

            var propertyName = childElement.Attributes["name"].Value;

            xmlProcessingContext.EnterRunningLocation(string.Format("Property({0})", propertyName));

            var propertyInfo = result.GetType().GetProperty(propertyName);

            if (propertyInfo == null)
            {
                xmlProcessingContext.ReportError(
                    string.Format("Object type '{0}' does not contain a property definition named '{1}", result.GetType().FullName,
                                  propertyName));
                xmlProcessingContext.LeaveRunningLocation();
                return;
            }

            var propertyValue =
                XmlValueParser.ParseValue(childElement, xmlProcessingContext, ObjectPropertyExcludedAttributes);

            propertyInfo.SetValue(result, propertyValue, null);

            xmlProcessingContext.LeaveRunningLocation();
        }
Пример #3
0
        private static void ParseObjectField(object result, XmlElement childElement, XmlProcessingContext xmlProcessingContext)
        {
            if (childElement.Attributes["name"] == null)
            {
                xmlProcessingContext.ReportError("'Field' element in the composition XML should have a 'name' attribute.");
                return;
            }

            var fieldName = childElement.Attributes["name"].Value;

            xmlProcessingContext.EnterRunningLocation(string.Format("Field({0})", fieldName));

            var fieldInfo = result.GetType().GetField(fieldName);

            if (fieldInfo == null)
            {
                xmlProcessingContext.ReportError(
                    string.Format("Object type '{0}' does not contain a field definition named '{1}", result.GetType().FullName,
                                  fieldName));
                xmlProcessingContext.LeaveRunningLocation();
                return;
            }

            var fieldValue = XmlValueParser.ParseValue(childElement, xmlProcessingContext, objectFieldExcludedAttributes);

            fieldInfo.SetValue(result, fieldValue);

            xmlProcessingContext.LeaveRunningLocation();
        }
        /// <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 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>
        /// Parses an Assembly element in the composition XML.
        /// </summary>
        public static Assembly ParseAssembly(XmlElement element, XmlProcessingContext context)
        {
            if (element.ChildNodes.Count > 0)
            {
                context.ReportError("Type elements should not contain any child elements.");
                return(null);
            }

            string assemblyName = null;

            if (element.Attributes["name"] != null)
            {
                assemblyName = element.Attributes["name"].Value;
            }

            var result = ParseAssembly(assemblyName, context);

            if (result == null)
            {
                context.EnterRunningLocation(string.Format("Assembly({0})", assemblyName));
                context.ReportError("Could not load assembly '" + assemblyName + "'.");
                context.LeaveRunningLocation();
                return(null);
            }

            return(result);
        }
        /// <summary>
        /// Actually parses an Enum specification in the composition XML, and
        /// is used in both element form, and short-hand forms.
        /// </summary>
        public static object ParseEnum(string enumTypeName, string enumValue, XmlProcessingContext context)
        {
            if (enumTypeName == null)
            {
                throw new ArgumentNullException("enumTypeName");
            }

            if (enumValue == null)
            {
                throw new ArgumentNullException("enumValue");
            }

            context.EnterRunningLocation(string.Format("enum({0}, {1})", enumTypeName, enumValue));

            var enumType = ParseType(enumTypeName, context);

            if (enumType == null)
            {
                context.ReportError(string.Format("Type '{0}' could not be loaded.", enumTypeName));
                return(null);
            }

            if (!enumType.IsValueType)
            {
                context.ReportError(
                    string.Format("Type '{0}' is not an enumeration type, and can not be used in <EnumValue> tag.", enumType));
                return(null);
            }

            var result = Enum.Parse(enumType, enumValue);

            context.LeaveRunningLocation();

            return(result);
        }
        private static List <object> GetCollectionElements(XmlElement[] xmlElements, Type elementType,
                                                           XmlProcessingContext xmlProcessingContext)
        {
            var arrayElements = new List <object>();

            for (var i = 0; i < xmlElements.Length; i++)
            {
                xmlProcessingContext.EnterRunningLocation(string.Format("Item({0})", i));

                var childElement = xmlElements[i];

                if (childElement.Name == "Item")
                {
                    var arrayElement = XmlValueParser.ParseValue(childElement, xmlProcessingContext, null);

                    if ((arrayElement != null) && (!elementType.IsInstanceOfType(arrayElement)))
                    {
                        xmlProcessingContext.ReportError(
                            string.Format("Array of the element type {0} can not contain items with type {1}.", elementType.FullName,
                                          arrayElement.GetType().FullName));
                        xmlProcessingContext.LeaveRunningLocation();
                        return(null);
                    }

                    arrayElements.Add(arrayElement);
                }
                else
                {
                    xmlProcessingContext.ReportError(
                        string.Format("Xml element '{0}' is not allowed in 'Array' element - type: {1}[]", childElement.Name,
                                      elementType.FullName));
                    xmlProcessingContext.LeaveRunningLocation();
                    return(null);
                }

                xmlProcessingContext.LeaveRunningLocation();
            }

            return(arrayElements);
        }
        /// <summary>
        /// Actually parses contentsOfVariable string, looking up the variable name. Used in
        /// both short-hand form and element form of contentsOfVariable specification.
        /// </summary>
        public static object ParseContentsOfVariable(string variableName, XmlProcessingContext context)
        {
            if (variableName == null)
            {
                throw new ArgumentNullException("variableName");
            }

            context.EnterRunningLocation(string.Format("Parsing ContentsOfVariable({0})", variableName));

            var result = context.ComponentContext.GetVariable(variableName);

            context.LeaveRunningLocation();

            return(result);
        }
        /// <summary>
        /// Parses a SerializeBinary element in the composition XML.
        /// </summary>
        public static object ParseSerializeBinary(XmlElement element, XmlProcessingContext context)
        {
            context.EnterRunningLocation("SerializeBinary");

            var serializableValue = XmlValueParser.ParseValue(element, context, null);

            var formatter = new BinaryFormatter();
            var stream    = new MemoryStream();

            formatter.Serialize(stream, serializableValue);

            var result = stream.ToArray();

            stream.Close();

            context.LeaveRunningLocation();

            return(result);
        }
Пример #11
0
        private static object[] ParseConstructorArgs(XmlElement element,
                                                     XmlProcessingContext xmlProcessingContext)
        {
            if (element.Name != "ConstructorArgs")
            {
                throw new ArgumentException("Calling this method is only valid for 'ConstructorArgs' element.");
            }

            if (element.HasAttributes)
            {
                xmlProcessingContext.ReportError("'ConstructorArgs' element should not have any attributes.");
            }

            xmlProcessingContext.EnterRunningLocation("ConstructorArgs");

            var result = new List <object>();

            foreach (XmlNode childNode in element.ChildNodes)
            {
                var childElement = childNode as XmlElement;
                if (childElement == null)
                {
                    continue;
                }

                if (childElement.Name == "Arg")
                {
                    result.Add(XmlValueParser.ParseValue(childElement, xmlProcessingContext, null));
                }
                else
                {
                    xmlProcessingContext.ReportError(
                        string.Format("Element '{0}' is not allowed in the 'ConstructorArgs' element.", childElement.Name));
                }
            }

            xmlProcessingContext.LeaveRunningLocation();
            return(result.ToArray());
        }
        /// <summary>
        /// Actually parses the contents on Ref specification in composition XML.
        /// Looks up the referenced component in the component context, and returns the result.
        /// Is used both in short-hand form and element form on Ref specification.
        /// </summary>
        public static object ParseRef(string refTypeName, string refName, XmlProcessingContext context)
        {
            if (refTypeName == null)
            {
                throw new ArgumentNullException("refTypeName");
            }

            context.EnterRunningLocation(string.Format("Ref({0})", refTypeName));

            var refType = ParseType(refTypeName, context);

            if (refType == null)
            {
                context.ReportError(string.Format("Type '{0}' could not be loaded.", refTypeName));
                return(null);
            }

            var result = context.ComponentContext.GetComponent(refType, refName);

            context.LeaveRunningLocation();

            return(result);
        }
        /// <summary>
        /// Parses an assembly specification in composition XML in its short-hand form.
        /// </summary>
        public static Assembly ParseAssembly(IEnumerable <XmlAttribute> attributes, XmlProcessingContext context)
        {
            string assemblyName = null;

            foreach (var attribute in attributes)
            {
                if (attribute.Name == "assemblyName")
                {
                    assemblyName = attribute.Value;
                }
                else
                {
                    context.ReportError(
                        string.Format("Attribute name {0} is not supported for assembly value elements.", attribute.Name));
                    return(null);
                }
            }

            if (assemblyName == null)
            {
                context.ReportError("Attribute 'assemblyName' is required.");
                return(null);
            }

            var result = ParseAssembly(assemblyName, context);

            if (result == null)
            {
                context.EnterRunningLocation(string.Format("Assembly({0})", assemblyName));
                context.ReportError("Could not load assembly '" + assemblyName + "'.");
                context.LeaveRunningLocation();
                return(null);
            }


            return(result);
        }
        /// <summary>
        /// Parses a type specification in composition XML in its short-hand form.
        /// </summary>
        public static Type ParseType(IEnumerable <XmlAttribute> attributes, XmlProcessingContext context)
        {
            string typeName = null;

            foreach (var attribute in attributes)
            {
                if (attribute.Name == "typeName")
                {
                    typeName = attribute.Value;
                }
                else
                {
                    context.ReportError(string.Format("Attribute name {0} is not supported for type value elements.", attribute.Name));
                    return(null);
                }
            }

            if (typeName == null)
            {
                context.ReportError("Attribute 'typeName' is required.");
                return(null);
            }

            var result = ParseType(typeName, context);

            if (result == null)
            {
                context.EnterRunningLocation(string.Format("Type({0})", typeName));
                context.ReportError("Could not load type '" + typeName + "'.");
                context.LeaveRunningLocation();
                return(null);
            }


            return(result);
        }
        /// <summary>
        /// Validates the raw values extracted from a TimeSpan element or TimeSpan related
        /// attributes, and then extracts and returns the actual value.
        /// </summary>
        public static object ParseTimeSpan(string timeSpanString, int?days, int?hours, int?minutes, int?seconds,
                                           int?milliseconds, long?ticks, XmlProcessingContext context)
        {
            object result;

            context.EnterRunningLocation("TimeSpan");

            // Validate the entered values:
            // Should not specify "ticks" with anything else,
            // Should not specify "timeSpanString" with anything else,
            // Should have at least one value specified.

            if (timeSpanString != null)
            {
                if ((ticks.HasValue) ||
                    (days.HasValue) ||
                    (hours.HasValue) ||
                    (minutes.HasValue) ||
                    (seconds.HasValue) ||
                    (milliseconds.HasValue))
                {
                    context.ReportError("Cannot specify any other attribute for TimeSpan when the 'string' to be parsed is specified.");
                    context.LeaveRunningLocation();
                    return(null);
                }
            }

            if (ticks.HasValue)
            {
                if ((days.HasValue) ||
                    (hours.HasValue) ||
                    (minutes.HasValue) ||
                    (seconds.HasValue) ||
                    (milliseconds.HasValue))
                {
                    context.ReportError("Cannot specify any other attribute for TimeSpan when the ticks is specified.");
                    context.LeaveRunningLocation();
                    return(null);
                }
            }

            if ((timeSpanString == null) &&
                (!ticks.HasValue) &&
                (!days.HasValue) &&
                (!hours.HasValue) &&
                (!minutes.HasValue) &&
                (!seconds.HasValue) &&
                (!milliseconds.HasValue))
            {
                context.ReportError("Should specify at least one of the attributes for the TimeSpan value node.");
                context.LeaveRunningLocation();
                return(null);
            }

            // If string is specified, use it to parse the TimeSpan and return.

            if (timeSpanString != null)
            {
                result = ParseTimeSpan(timeSpanString);
                context.LeaveRunningLocation();
                return(result);
            }

            // If ticks is specified, use it to parse the TimeSpan and return.

            if (ticks.HasValue)
            {
                result = ParseTimeSpan(ticks.Value);
                context.LeaveRunningLocation();
                return(result);
            }

            // Use days/hours/minutes/seconds/milliseconds to create the TimeSpan, and
            // Set every un-specified values to zero, in order to prevent NullReferenceException.

            if (!days.HasValue)
            {
                days = 0;
            }

            if (!hours.HasValue)
            {
                hours = 0;
            }

            if (!minutes.HasValue)
            {
                minutes = 0;
            }

            if (!seconds.HasValue)
            {
                seconds = 0;
            }

            if (!milliseconds.HasValue)
            {
                milliseconds = 0;
            }

            result = ParseTimeSpan(days.Value, hours.Value, minutes.Value, seconds.Value, milliseconds.Value);
            context.LeaveRunningLocation();
            return(result);
        }
Пример #16
0
        /// <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);
        }