/// <summary>
        /// Parses a ContentsOfVariable element in the composition XML.
        /// </summary>
        public static object ParseWindowsRegistry(XmlElement element, XmlProcessingContext context)
        {
            if (element.ChildNodes.Count > 0)
            {
                context.ReportError("'WindowsRegistry' elements should not contain any child elements.");
                return(null);
            }

            string keyPath   = null;
            string valueName = null;

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

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

            if (keyPath == null)
            {
                context.ReportError("'WindowsRegistry' elements require a 'keyPath' attribute.");
                return(null);
            }

            return(ParseWindowsRegistry(keyPath, valueName, context));
        }
        /// <summary>
        /// Used for parsing an Object element in the composition XML.
        /// </summary>
        public static object ParseObject(XmlElement element, XmlProcessingContext context)
        {
            string typeName        = null;
            var    initializePlugs = false;

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

            if (element.Attributes["initializePlugs"] != null)
            {
                initializePlugs = Boolean.Parse(element.Attributes["initializePlugs"].Value);
            }

            if (typeName == null)
            {
                context.ReportError("'Object' element in the composition XML should have a 'type' attribute.");
                return(null);
            }

            var childElements = new List <XmlElement>();

            foreach (XmlNode childNode in element.ChildNodes)
            {
                if (childNode is XmlElement)
                {
                    childElements.Add((XmlElement)childNode);
                }
            }

            return(ParseObject(typeName, initializePlugs, childElements.ToArray(), context));
        }
        /// <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);
        }
        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);
        }
        /// <summary>
        /// Used for parsing short-hand specification of dictionaries in
        /// the composition XML.
        /// </summary>
        public static IDictionary ParseDictionary(IEnumerable <XmlAttribute> attributes, XmlElement[] childElements,
                                                  XmlProcessingContext context)
        {
            string keyType   = null;
            string valueType = null;

            foreach (var attribute in attributes)
            {
                switch (attribute.Name)
                {
                case "dictionaryKeyType":
                    keyType = attribute.Value;
                    break;

                case "dictionaryValueType":
                    valueType = attribute.Value;
                    break;

                default:
                    context.ReportError(string.Format("Attribute name {0} is not supported for array value elements.", attribute.Name));
                    return(null);
                }
            }

            return(ParseDictionary(keyType, valueType, childElements, context));
        }
        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();
        }
        /// <summary>
        /// Parses a Ref specification in the short-hand form from a
        /// composition XML.
        /// </summary>
        public static object ParseRef(IEnumerable <XmlAttribute> attributes, XmlProcessingContext context)
        {
            string refType = null;
            string refName = null;

            foreach (var attribute in attributes)
            {
                switch (attribute.Name)
                {
                case "refType":
                    refType = attribute.Value;
                    break;

                case "refName":
                    refName = attribute.Value;
                    break;

                default:
                    context.ReportError(
                        string.Format("Attribute name {0} is not supported for ref value elements.", attribute.Name));
                    return(null);
                }
            }

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

            return(ParseRef(refType, refName, context));
        }
        /// <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);
        }
        /// <summary>
        /// Parses an enum value in its short-hand form in composition XML.
        /// </summary>
        public static object ParseEnum(IEnumerable <XmlAttribute> attributes, XmlProcessingContext context)
        {
            string enumType  = null;
            string enumValue = null;

            foreach (var attribute in attributes)
            {
                switch (attribute.Name)
                {
                case "enumType":
                    enumType = attribute.Value;
                    break;

                case "enumValue":
                    enumValue = attribute.Value;
                    break;

                default:
                    context.ReportError(
                        string.Format("Attribute name {0} is not supported for enum value elements.", attribute.Name));
                    return(null);
                }
            }

            if ((enumValue == null) || (enumType == null))
            {
                context.ReportError("Both 'enumType' and 'enumValue' attributes are required.");
                return(null);
            }

            return(ParseEnum(enumType, enumValue, context));
        }
        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>
        /// Parses a Dictionary element in the composition XML.
        /// </summary>
        public static IDictionary ParseDictionary(XmlElement element, XmlProcessingContext xmlProcessingContext)
        {
            string keyTypeName   = null;
            string valueTypeName = null;

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

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

            var childElements = new List <XmlElement>();

            foreach (XmlNode childNode in element.ChildNodes)
            {
                if (childNode is XmlElement xmlElement)
                {
                    childElements.Add(xmlElement);
                }
            }

            return(ParseDictionary(keyTypeName, valueTypeName, childElements.ToArray(), xmlProcessingContext));
        }
        internal static void ProcessCompositionXml(Stream configurationStream, XmlProcessingContext xmlProcessingContext)
        {
            if (configurationStream == null)
            {
                throw new ArgumentNullException(nameof(configurationStream));
            }

            var xsdStream =
                typeof(AssemblyPointer).Assembly.GetManifestResourceStream(
                    "ComposerCore.CompositionXml.Schema.compositionXml.1.0.xsd");

            if (xsdStream == null)
            {
                throw new NullReferenceException("Could not load XSD resource from DLL.");
            }

            var schema =
                XmlSchema.Read(
                    xsdStream,
                    (sender, e) => throw new CompositionXmlValidationException(
                        "Could not load XSD for Composition XML. Message: " + e.Message + "; Sender: " +
                        sender, e.Exception));

            var schemaSet = new XmlSchemaSet();

            schemaSet.Add(schema);

            var settings = new XmlReaderSettings {
                ValidationType = ValidationType.Schema, Schemas = schemaSet
            };

            settings.ValidationEventHandler += delegate(object sender, ValidationEventArgs e)
            {
                var errorMessage = "Composition XML Schema Validation error: ";

                if (e.Exception is XmlSchemaValidationException validationException)
                {
                    errorMessage += "Line: " + validationException.LineNumber + ", Position: " +
                                    validationException.LinePosition +
                                    "; " + validationException.Message;
                }
                else
                {
                    errorMessage += "Message: " + e.Message + "; Sender: " + sender +
                                    "; Inner exception: " + e.Exception.Message;
                }

                xmlProcessingContext.ReportError(errorMessage);
            };

            var serializer = new XmlSerializer(typeof(CompositionInfo));

            var reader = XmlReader.Create(configurationStream, settings);
            var info   = (CompositionInfo)serializer.Deserialize(reader);

            info.Validate();

            CompositionInfoApplicator.ApplyCompositionInfo(info, xmlProcessingContext);
        }
        /// <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 ParseWindowsRegistry(string keyPath, string valueName, XmlProcessingContext context)
        {
            if (keyPath == null)
            {
                throw new ArgumentNullException("keyPath");
            }

            return(Registry.GetValue(keyPath, valueName, null));
        }
        /// <summary>
        /// Parses a contentsOfVariableName specification in composition XML in its short-hand form.
        /// </summary>
        public static object ParseTimeSpan(IEnumerable <XmlAttribute> attributes, XmlProcessingContext context)
        {
            // Declare variables for possible input values
            string timeSpanString = null;
            int?   days           = null;
            int?   hours          = null;
            int?   minutes        = null;
            int?   seconds        = null;
            int?   milliseconds   = null;
            long?  ticks          = null;

            // Extract input values from the attributes (can be in any order)

            foreach (var attribute in attributes)
            {
                switch (attribute.Name)
                {
                case "timeSpan":
                    timeSpanString = attribute.Value;
                    break;

                case "timeSpanDays":
                    days = Int32.Parse(attribute.Value);
                    break;

                case "timeSpanHours":
                    hours = Int32.Parse(attribute.Value);
                    break;

                case "timeSpanMinutes":
                    minutes = Int32.Parse(attribute.Value);
                    break;

                case "timeSpanSeconds":
                    seconds = Int32.Parse(attribute.Value);
                    break;

                case "timeSpanMilliseconds":
                    milliseconds = Int32.Parse(attribute.Value);
                    break;

                case "timeSpanTicks":
                    ticks = Int64.Parse(attribute.Value);
                    break;

                default:
                    context.ReportError(
                        string.Format("Attribute name {0} is not supported for timeSpan value elements.", attribute.Name));
                    return(null);
                }
            }

            // Validate and parse the extracted values

            return(ParseTimeSpan(timeSpanString, days, hours, minutes, seconds, milliseconds, ticks, context));
        }
        /// <summary>
        /// Actually parses a Type string, looking up the type name. Used in
        /// both short-hand form and element form of type specification.
        /// </summary>
        public static Type ParseType(string typeName, XmlProcessingContext context)
        {
            if (typeName == null)
            {
                throw new ArgumentNullException("typeName");
            }

            var result = context.TypeCache.LookupType(typeName) ?? Type.GetType(typeName, false, false);

            return(result);
        }
        /// <summary>
        /// Actually parses an Assembly string, trying to load the assembly object. Used in
        /// both short-hand form and element form of assembly specification.
        /// </summary>
        public static Assembly ParseAssembly(string assemblyName, XmlProcessingContext context)
        {
            if (assemblyName == null)
            {
                throw new ArgumentNullException("assemblyName");
            }

            var result = Assembly.Load(assemblyName);

            return(result);
        }
Example #17
0
        public static void ProcessCompositionXmlFromResource(this IComponentContext context, Assembly assembly, string configurationResourceName)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var xmlProcessingContext = new XmlProcessingContext(context);

            ProcessCompositionXmlFromResource(assembly, configurationResourceName, xmlProcessingContext);
            xmlProcessingContext.ThrowIfErrors();
        }
Example #18
0
        public static void ProcessCompositionXml(this IComponentContext context, string configurationPath)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var xmlProcessingContext = new XmlProcessingContext(context);

            ProcessCompositionXml(configurationPath, xmlProcessingContext);
            xmlProcessingContext.ThrowIfErrors();
        }
Example #19
0
        internal static void ProcessCompositionXmlFromResource(Assembly assembly, string configurationResourceName,
                                                               XmlProcessingContext xmlProcessingContext)
        {
            var stream = assembly.GetManifestResourceStream(configurationResourceName);

            if (stream == null)
            {
                xmlProcessingContext.ReportError($"Resource name '{configurationResourceName}' could not be loaded from assembly '{assembly.FullName}'.");
                return;
            }

            ProcessCompositionXml(stream, xmlProcessingContext);
        }
Example #20
0
        public static object ParseValue(XmlElement[] elements, XmlAttribute[] attributes,
                                        XmlProcessingContext xmlProcessingContext, List <string> excludedAttributes)
        {
            if ((excludedAttributes == null) || (excludedAttributes.Count == 0))
            {
                return(ParseValue(elements, attributes, xmlProcessingContext));
            }

            var filteredAttributes =
                Array.FindAll(attributes,
                              attribute => !(excludedAttributes.Contains(attribute.Name)));

            return(ParseValue(elements, filteredAttributes, xmlProcessingContext));
        }
        public static byte[] ParseByteArray(string value, XmlProcessingContext context)
        {
            var filteredString = "";

            // remove all none A-F, 0-9, characters
            for (var i = 0; i < value.Length; i++)
            {
                var c = value[i];

                if ((char.IsWhiteSpace(c)) ||
                    (c == '-') ||
                    (c == '_'))
                {
                    continue;
                }

                if (!char.IsLetterOrDigit(c))
                {
                    context.ReportError("Character is not allowed in a hex string: '" + c + "', ignoring.");
                    continue;
                }

                c = char.ToUpper(c);

                if ((char.IsLetter(c)) && ((c > 'F') || (c < 'A')))
                {
                    context.ReportError("Character is not allowed in a hex string: '" + c + "', ignoring.");
                    continue;
                }

                filteredString += c;
            }

            // if odd number of characters, add a zero to the beginning
            if (filteredString.Length % 2 != 0)
            {
                filteredString = "0" + filteredString;
            }

            var byteLength = filteredString.Length / 2;
            var result     = new byte[byteLength];

            for (var i = 0; i < result.Length; i++)
            {
                result[i] = byte.Parse(filteredString.Substring(i << 1, 2), NumberStyles.HexNumber);
            }

            return(result);
        }
        /// <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);
        }
Example #23
0
        internal static void ProcessCompositionXml(string configurationPath, XmlProcessingContext xmlProcessingContext)
        {
            if (configurationPath == null)
            {
                throw new ArgumentNullException(nameof(configurationPath));
            }

            if (!File.Exists(configurationPath))
            {
                xmlProcessingContext.ReportError($"Specified configuration file '{configurationPath}' does not exist.");
                return;
            }

            using (Stream configurationStream = File.Open(configurationPath, FileMode.Open, FileAccess.Read))
            {
                ProcessCompositionXml(configurationStream, xmlProcessingContext);
            }
        }
        /// <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);
        }
        /// <summary>
        /// Used when parsing an Array element in composition XML.
        /// </summary>
        public static Array ParseArray(XmlElement element, XmlProcessingContext xmlProcessingContext)
        {
            string elementTypeName = null;

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

            var childElements = new List <XmlElement>();

            foreach (XmlNode childNode in element.ChildNodes)
            {
                if (childNode is XmlElement xmlElement)
                {
                    childElements.Add(xmlElement);
                }
            }

            return(ParseArray(elementTypeName, childElements.ToArray(), xmlProcessingContext));
        }
        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);
        }
        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>
        /// Parses a ContentsOfVariable element in the composition XML.
        /// </summary>
        public static object ParseContentsOfVariable(XmlElement element, XmlProcessingContext context)
        {
            if (element.ChildNodes.Count > 0)
            {
                context.ReportError("'ContentsOfVariable' elements should not contain any child elements.");
                return(null);
            }

            string variableName = null;

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

            if (variableName == null)
            {
                context.ReportError("'ContentsOfVariable' elements require a 'name' attribute.");
                return(null);
            }

            return(ParseContentsOfVariable(variableName, context));
        }
        /// <summary>
        /// Parses a Ref element in the composition XML.
        /// </summary>
        public static object ParseRef(XmlElement element, XmlProcessingContext context)
        {
            if (element.ChildNodes.Count > 0)
            {
                context.ReportError("Ref elements should not contain any child elements.");
                return(null);
            }

            string refType = null;
            string refName = null;

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

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

            return(ParseRef(refType, refName, context));
        }
        /// <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);
        }