/// <summary> /// Add a configuration value node. /// </summary> /// <param name="parent">Parent Configuration node</param> /// <param name="name">Value node name</param> /// <param name="value">Value</param> private void AddValueNode(AbstractConfigNode parent, string name, string value, bool encrypted) { ConfigValueNode vn = new ConfigValueNode(parent.Configuration, parent); vn.Encrypted = encrypted; vn.Name = name; vn.SetValue(value); if (parent.GetType() == typeof(ConfigParametersNode)) { ConfigParametersNode node = (ConfigParametersNode)parent; node.Add(vn); } else if (parent.GetType() == typeof(ConfigPropertiesNode)) { ConfigPropertiesNode node = (ConfigPropertiesNode)parent; node.Add(vn); } else if (parent.GetType() == typeof(ConfigListValueNode)) { ConfigListValueNode node = (ConfigListValueNode)parent; node.Add(vn); } else if (parent.GetType() == typeof(ConfigPathNode)) { ConfigPathNode node = (ConfigPathNode)parent; node.AddChildNode(vn); } else { throw new ConfigurationException(String.Format("Invalid Stack State: Cannot add value node to parent. [parent={0}]", parent.GetType().FullName)); } }
/// <summary> /// Load a defined process from the configuration node. /// </summary> /// <param name="pipeline">Parent pipeline</param> /// <param name="node">Configuration node</param> /// <param name="pname">Pipeline name</param> private void LoadProcessor(object pipeline, ConfigPathNode node, string pname) { LogUtils.Debug(String.Format("Loading processor from node. [pipeline={0}][node={1}]", pname, node.GetAbsolutePath())); if (node.Name != CONFIG_NODE_PROCESSOR) { LogUtils.Warn(String.Format("Invalid Processor Node: [path={0}]", node.GetSearchPath())); return; } ProcessConfig def = ConfigurationAnnotationProcessor.Process <ProcessConfig>(node); Conditions.NotNull(def); string typename = def.Type; Type type = null; if (!String.IsNullOrWhiteSpace(def.Assembly)) { string aname = Path.GetFileName(def.Assembly); Assembly asm = AssemblyUtils.GetOrLoadAssembly(aname, def.Assembly); Conditions.NotNull(asm); type = asm.GetType(typename, true); Conditions.NotNull(type); } else { type = Type.GetType(typename, true); Conditions.NotNull(type); } object obj = null; if (def.IsReference) { if (ReflectionUtils.ImplementsGenericInterface(type, typeof(Pipeline <>))) { if (pipelines.ContainsKey(def.Name)) { obj = pipelines[def.Name]; } else { throw new ProcessException(String.Format("Referenced Pipeline not found: [name={0}][type={1}]", def.Name, type.FullName)); } } } else { obj = ConfigurationAnnotationProcessor.CreateInstance(type, node); Conditions.NotNull(obj); if (!ReflectionUtils.IsSubclassOfRawGeneric(obj.GetType(), typeof(Processor <>))) { throw new ProcessException(String.Format("Invalid processor type. [type={0}]", type.FullName)); } PropertyInfo pi = TypeUtils.FindProperty(type, "Name"); Conditions.NotNull(pi); pi.SetValue(obj, def.Name); } AddProcessor(pipeline, obj, def.Condition, def.TypeName); }
/// <summary> /// Create a new Instance of the specified type. /// /// Type should have an empty constructor or a constructor with annotation. /// </summary> /// <param name="type">Type</param> /// <param name="node">Configuration node.</param> /// <returns>Created Instance</returns> public static object CreateInstance(Type type, ConfigPathNode node) { object target = null; ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance); if (constructors != null && constructors.Length > 0) { foreach (ConstructorInfo ci in constructors) { MethodInvoke mi = (MethodInvoke)Attribute.GetCustomAttribute(ci, typeof(MethodInvoke)); if (mi != null) { ParameterInfo[] parameters = ci.GetParameters(); ConfigPathNode nnode = node; if (parameters != null && parameters.Length > 0) { if (!String.IsNullOrWhiteSpace(mi.Path)) { AbstractConfigNode cnode = nnode.Find(mi.Path); if (cnode != null && cnode.GetType() == typeof(ConfigPathNode)) { nnode = (ConfigPathNode)cnode; } } if (nnode != null) { ConfigParametersNode pnode = nnode.GetParameters(); if (pnode != null) { List <object> values = FindParameters(pnode, ci.Name, parameters); if (values != null && values.Count > 0) { target = Activator.CreateInstance(type, values.ToArray()); } } } } else { target = Activator.CreateInstance(type); } } } } if (target == null) { target = Activator.CreateInstance(type); } if (target != null) { target = ReadValues((ConfigPathNode)node, target, null); CallMethodInvokes((ConfigPathNode)node, target); } return(target); }
/// <summary> /// Process the annotated field and set the values from the configuration attributes. /// </summary> /// <typeparam name="T">Target Instance type</typeparam> /// <param name="node">Configuration Node</param> /// <param name="target">Target Type instance.</param> /// <param name="field">Property to update</param> /// <param name="attr">Config attribute annotation</param> /// <returns>Updated Target Type instance.</returns> private static T ProcessField <T>(ConfigPathNode node, T target, FieldInfo field, ConfigAttribute attr, List <string> valuePaths) { string pname = attr.Name; if (String.IsNullOrWhiteSpace(pname)) { pname = field.Name; } string value = null; if (!String.IsNullOrWhiteSpace(attr.Path)) { AbstractConfigNode nnode = node.Find(attr.Path); if (nnode != null && nnode.GetType() == typeof(ConfigPathNode)) { node = (ConfigPathNode)nnode; } else { node = null; } } if (node != null) { ConfigAttributesNode pnode = node.GetAttributes(); if (pnode != null) { ConfigValueNode vn = pnode.GetValue(pname); if (vn != null) { value = vn.GetValue(); } if (valuePaths != null) { valuePaths.Add(pnode.GetSearchPath()); } } } if (!String.IsNullOrWhiteSpace(value)) { object v = GetValue <T>(pname, value, attr.Function, field.FieldType, target, attr.Required); if (v != null) { TypeUtils.CallSetter(field, target, v); } } else if (attr.Required) { throw AnnotationProcessorException.Throw(target.GetType(), pname); } return(target); }
/// <summary> /// Process the annotated property and set the values from the configuration parameters. /// </summary> /// <typeparam name="T">Target Instance type</typeparam> /// <param name="node">Configuration Node</param> /// <param name="target">Target Type instance.</param> /// <param name="property">Property to update</param> /// <param name="param">Config param annotation</param> /// <returns>Updated Target Type instance.</returns> private static T ProcessProperty <T>(ConfigPathNode node, T target, PropertyInfo property, ConfigParam param, List <string> valuePath) { string pname = param.Name; if (String.IsNullOrWhiteSpace(pname)) { pname = property.Name; } string value = null; if (!String.IsNullOrWhiteSpace(param.Path)) { AbstractConfigNode nnode = node.Find(param.Path); if (nnode != null && nnode.GetType() == typeof(ConfigPathNode)) { node = (ConfigPathNode)nnode; } else { node = null; } } if (node != null) { ConfigParametersNode pnode = node.GetParameters(); if (pnode != null) { ConfigValueNode vn = pnode.GetValue(pname); if (vn != null) { value = vn.GetValue(); } if (valuePath != null) { valuePath.Add(pnode.GetSearchPath()); } } } if (!String.IsNullOrWhiteSpace(value)) { object v = GetValue <T>(pname, value, param.Function, property.PropertyType, target, param.Required); if (v != null) { property.SetValue(target, v); } } else if (param.Required) { throw AnnotationProcessorException.Throw(target.GetType(), pname); } return(target); }
/// <summary> /// Check and Invoke annotated methods for this type. /// </summary> /// <typeparam name="T">Target Instance type</typeparam> /// <param name="node">Configuration node.</param> /// <param name="target">Target Type instance</param> private static void CallMethodInvokes <T>(ConfigPathNode node, T target) { Type type = target.GetType(); MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance); if (methods != null) { foreach (MethodInfo method in methods) { MethodInvoke mi = (MethodInvoke)Attribute.GetCustomAttribute(method, typeof(MethodInvoke)); if (mi != null) { bool invoked = false; ParameterInfo[] parameters = method.GetParameters(); ConfigPathNode nnode = node; if (parameters != null && parameters.Length > 0) { if (!String.IsNullOrWhiteSpace(mi.Path)) { AbstractConfigNode cnode = nnode.Find(mi.Path); if (cnode != null && cnode.GetType() == typeof(ConfigPathNode)) { nnode = (ConfigPathNode)cnode; } } if (nnode != null) { ConfigParametersNode pnode = nnode.GetParameters(); if (pnode != null) { List <object> values = FindParameters(pnode, method.Name, parameters); if (values != null && values.Count > 0) { method.Invoke(target, values.ToArray()); invoked = true; } } } } else { method.Invoke(target, null); invoked = true; } if (!invoked) { throw new AnnotationProcessorException(String.Format("Error Invoking Method : [mehtod={0}][node={1}]", method.Name, node.GetSearchPath())); } } } } }
/// <summary> /// Parse a included configuration reference. /// </summary> /// <param name="parent">Parent Config Node</param> /// <param name="elem">XML Element</param> private void AddIncludeNode(ConfigPathNode parent, XmlElement elem) { string configName = elem.GetAttribute(ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE_NAME); if (String.IsNullOrWhiteSpace(configName)) { throw ConfigurationException.PropertyMissingException(ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE_NAME); } string path = elem.GetAttribute(ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE_PATH); if (String.IsNullOrWhiteSpace(path)) { throw ConfigurationException.PropertyMissingException(ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE_PATH); } string st = elem.GetAttribute(ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE_TYPE); if (String.IsNullOrWhiteSpace(st)) { throw ConfigurationException.PropertyMissingException(ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE_TYPE); } EUriScheme type = EUriScheme.none.ParseScheme(st); if (type == EUriScheme.none) { throw ConfigurationException.PropertyMissingException(ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE_TYPE); } string vs = elem.GetAttribute(ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE_VERSION); if (String.IsNullOrWhiteSpace(vs)) { throw ConfigurationException.PropertyMissingException(ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE_VERSION); } Version version = Version.Parse(vs); ConfigIncludeNode node = new ConfigIncludeNode(configuration, parent); node.Name = elem.Name; node.ConfigName = configName; node.Path = ReaderTypeHelper.ParseUri(path); node.ReaderType = type; node.Version = version; using (AbstractReader reader = ReaderTypeHelper.GetReader(type, node.Path)) { reader.Open(); XmlConfigParser parser = new XmlConfigParser(); parser.Parse(node.ConfigName, reader, node.Version, settings); Configuration config = parser.GetConfiguration(); node.Reference = config; node.Node = config.RootConfigNode; node.UpdateConfiguration(configuration); } parent.AddChildNode(node); }
/// <summary> /// Read the configuration values from the passed node and /// update the target instance. /// </summary> /// <typeparam name="T">Target Instance type</typeparam> /// <param name="node">Configuration Node to read values from</param> /// <param name="target">Target Type instance</param> /// <returns>Updated Target Type instance</returns> private static T ReadValues <T>(ConfigPathNode node, T target, List <string> valuePaths) { Type type = target.GetType(); PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); if (properties != null) { foreach (PropertyInfo property in properties) { ConfigParam param = (ConfigParam)Attribute.GetCustomAttribute(property, typeof(ConfigParam)); if (param != null) { target = ProcessProperty(node, target, property, param, valuePaths); } ConfigAttribute attr = (ConfigAttribute)Attribute.GetCustomAttribute(property, typeof(ConfigAttribute)); if (attr != null) { target = ProcessProperty(node, target, property, attr, valuePaths); } ConfigValue value = (ConfigValue)Attribute.GetCustomAttribute(property, typeof(ConfigValue)); if (value != null) { target = ProcessProperty(node, target, property, value, valuePaths); } } } FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (fields != null) { foreach (FieldInfo field in fields) { ConfigParam param = (ConfigParam)Attribute.GetCustomAttribute(field, typeof(ConfigParam)); if (param != null) { target = ProcessField(node, target, field, param, valuePaths); } ConfigAttribute attr = (ConfigAttribute)Attribute.GetCustomAttribute(field, typeof(ConfigAttribute)); if (attr != null) { target = ProcessField(node, target, field, attr, valuePaths); } ConfigValue value = (ConfigValue)Attribute.GetCustomAttribute(field, typeof(ConfigValue)); if (value != null) { target = ProcessField(node, target, field, value, valuePaths); } } } return(target); }
/// <summary> /// Load a pipeline definition from the specified node. /// </summary> /// <param name="node">Configuration Node</param> private void LoadPipeline(ConfigPathNode node) { LogUtils.Debug(String.Format("Loading pipeline from node. [node={0}]", node.GetAbsolutePath())); if (node.Name != CONFIG_NODE_PIPELINE) { LogUtils.Warn(String.Format("Invalid Pipeline Node: [path={0}]", node.GetSearchPath())); return; } PipelineConfig def = ConfigurationAnnotationProcessor.Process <PipelineConfig>(node); Conditions.NotNull(def); Type type = null; string typename = def.Type; if (!String.IsNullOrWhiteSpace(def.Assembly)) { string aname = Path.GetFileName(def.Assembly); Assembly asm = AssemblyUtils.GetOrLoadAssembly(aname, def.Assembly); Conditions.NotNull(asm); type = asm.GetType(typename, true); Conditions.NotNull(type); } else { type = Type.GetType(typename, true); Conditions.NotNull(type); } object obj = ConfigurationAnnotationProcessor.CreateInstance(type, node); Conditions.NotNull(obj); if (!ReflectionUtils.ImplementsGenericInterface(obj.GetType(), typeof(Pipeline <>))) { throw new ProcessException(String.Format("Invalid pipeline type. [type={0}]", type.FullName)); } PropertyInfo pi = TypeUtils.FindProperty(type, PROPPERTY_NAME); Conditions.NotNull(pi); pi.SetValue(obj, def.Name); LoadProcessors(obj, node, def.Name); if (pipelines.ContainsKey(def.Name)) { throw new ProcessException(String.Format("Duplicate pipeline name: [name={0}][type={1}]", def.Name, type.FullName)); } pipelines[def.Name] = obj; }
/// <summary> /// Load the defined processes for the pipeline. /// </summary> /// <param name="pipeline">Parent pipeline</param> /// <param name="node">Configuration node.</param> /// <param name="name">Pipeline name</param> private void LoadProcessors(object pipeline, ConfigPathNode node, string name) { AbstractConfigNode pnode = node.Find(CONFIG_NODE_PROCESSORS); Conditions.NotNull(pnode); if (pnode.GetType() == typeof(ConfigPathNode)) { LoadProcessor(pipeline, (ConfigPathNode)pnode, name); } else if (pnode.GetType() == typeof(ConfigElementListNode)) { ConfigElementListNode nodes = (ConfigElementListNode)pnode; foreach (ConfigElementNode elem in nodes.GetValues()) { if (elem.GetType() == typeof(ConfigPathNode) && elem.Name == CONFIG_NODE_PROCESSOR) { LoadProcessor(pipeline, (ConfigPathNode)elem, name); } } } }
/// <summary> /// Process the annotated field and set the values from the configuration value. /// </summary> /// <typeparam name="T">Target Instance type</typeparam> /// <param name="node">Configuration Node</param> /// <param name="target">Target Type instance.</param> /// <param name="field">Property to update</param> /// <param name="configValue">Config value annotation</param> /// <returns>Updated Target Type instance.</returns> private static T ProcessField <T>(ConfigPathNode node, T target, FieldInfo field, ConfigValue configValue, List <string> valuePaths) { string pname = configValue.Name; if (String.IsNullOrWhiteSpace(pname)) { pname = field.Name; } string value = null; if (!String.IsNullOrWhiteSpace(configValue.Path)) { AbstractConfigNode nnode = node.Find(configValue.Path); if (nnode != null && nnode.GetType() == typeof(ConfigPathNode)) { node = (ConfigPathNode)nnode; } else { node = null; } } if (node != null) { AbstractConfigNode cnode = node.GetChildNode(pname); if (cnode != null) { if (valuePaths != null) { valuePaths.Add(cnode.GetSearchPath()); } if (cnode.GetType() == typeof(ConfigValueNode)) { ConfigValueNode vn = (ConfigValueNode)cnode; if (vn != null) { value = vn.GetValue(); } if (!String.IsNullOrWhiteSpace(value)) { object v = GetValue <T>(pname, value, configValue.Function, field.FieldType, target, configValue.Required); if (v != null) { TypeUtils.CallSetter(field, target, v); } } } else { if (ReflectionUtils.IsSubclassOfRawGeneric(field.FieldType, typeof(List <>))) { if (cnode.GetType() == typeof(ConfigListValueNode)) { ConfigListValueNode configList = (ConfigListValueNode)cnode; List <string> values = configList.GetValueList(); if (values != null) { Type inner = field.FieldType.GetGenericArguments()[0]; object v = ReflectionUtils.ConvertListFromStrings(inner, values); if (v != null) { TypeUtils.CallSetter(field, target, v); } } } } else if (ReflectionUtils.IsSubclassOfRawGeneric(field.FieldType, typeof(HashSet <>))) { if (cnode.GetType() == typeof(ConfigListValueNode)) { ConfigListValueNode configList = (ConfigListValueNode)cnode; List <string> values = configList.GetValueList(); if (values != null) { Type inner = field.FieldType.GetGenericArguments()[0]; object v = ReflectionUtils.ConvertSetFromStrings(inner, values); if (v != null) { TypeUtils.CallSetter(field, target, v); } } } } } } } object ov = TypeUtils.CallGetter(field, target); if (ov == null && configValue.Required) { throw AnnotationProcessorException.Throw(target.GetType(), pname); } return(target); }
/// <summary> /// Create a new Instance of the specified type. /// /// Type should have an empty constructor or a constructor with annotation. /// </summary> /// <typeparam name="T">Target Instance type</typeparam> /// <param name="type">Type</param> /// <param name="node">Configuration node.</param> /// <returns>Created Instance</returns> public static T CreateInstance <T>(Type type, ConfigPathNode node) { T target = default(T); ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance); if (constructors != null && constructors.Length > 0) { foreach (ConstructorInfo ci in constructors) { MethodInvoke mi = (MethodInvoke)Attribute.GetCustomAttribute(ci, typeof(MethodInvoke)); if (mi != null) { ParameterInfo[] parameters = ci.GetParameters(); ConfigPathNode nnode = node; if (parameters != null && parameters.Length > 0) { if (!String.IsNullOrWhiteSpace(mi.Path)) { AbstractConfigNode cnode = nnode.Find(mi.Path); if (cnode != null && cnode.GetType() == typeof(ConfigPathNode)) { nnode = (ConfigPathNode)cnode; } } if (nnode != null) { ConfigParametersNode pnode = nnode.GetParameters(); if (pnode != null) { List <object> values = FindParameters(pnode, ci.Name, parameters); if (values != null && values.Count > 0) { target = (T)Activator.CreateInstance(type, values.ToArray()); break; } } } } else { target = Activator.CreateInstance <T>(); break; } } } } if (ReflectionUtils.IsNull(target)) { target = Activator.CreateInstance <T>(); } if (!ReflectionUtils.IsNull(target)) { target = ReadValues((ConfigPathNode)node, target, null); CallMethodInvokes((ConfigPathNode)node, target); } else { throw new AnnotationProcessorException(String.Format("Error creating instance of Type: [path={0}][type={1}]", node.GetSearchPath(), type.FullName)); } return(target); }
/// <summary> /// Recursively replace defined variables with properties in the configuration nodes. /// /// </summary> /// <param name="node">Configuration Node.</param> /// <param name="inProps">Scoped properties map</param> /// <param name="replace">Replace variables?</param> private void NodePostLoad(AbstractConfigNode node, Dictionary <string, ConfigValueNode> inProps, bool replace) { Dictionary <string, ConfigValueNode> properties = General.Clone <string, ConfigValueNode>(inProps); if (node.GetType() == typeof(ConfigPathNode)) { ConfigPathNode pnode = (ConfigPathNode)node; ConfigPropertiesNode props = pnode.GetProperties(); if (props != null && !props.IsEmpty()) { Dictionary <string, ConfigValueNode> pd = props.GetValues(); foreach (string key in pd.Keys) { if (!properties.ContainsKey(key)) { properties.Add(key, pd[key]); } else { properties[key] = pd[key]; } } } if (!pnode.IsEmpty()) { foreach (string key in pnode.GetChildren().Keys) { NodePostLoad(pnode.GetChildren()[key], properties, replace); } } } else { if (node.GetType() == typeof(ConfigParametersNode)) { ConfigParametersNode pnode = (ConfigParametersNode)node; if (!pnode.IsEmpty() && replace) { foreach (string key in pnode.GetValues().Keys) { ConfigValueNode vn = pnode.GetValue(key); string value = vn.GetValue(); if (!String.IsNullOrWhiteSpace(value)) { string nv = ReplaceVariable(value, properties); vn.SetValue(nv); } } } } else if (node.GetType() == typeof(ConfigAttributesNode)) { ConfigAttributesNode pnode = (ConfigAttributesNode)node; if (!pnode.IsEmpty() && replace) { foreach (string key in pnode.GetValues().Keys) { ConfigValueNode vn = pnode.GetValue(key); string value = vn.GetValue(); if (!String.IsNullOrWhiteSpace(value)) { string nv = ReplaceVariable(value, properties); vn.SetValue(nv); } } } } else if (node.GetType() == typeof(ConfigListValueNode)) { ConfigListValueNode pnode = (ConfigListValueNode)node; if (!pnode.IsEmpty() && replace) { foreach (ConfigValueNode vn in pnode.GetValues()) { string value = vn.GetValue(); if (!String.IsNullOrWhiteSpace(value)) { string nv = ReplaceVariable(value, properties); vn.SetValue(nv); } } } } else if (node.GetType() == typeof(ConfigElementListNode)) { ConfigElementListNode pnode = (ConfigElementListNode)node; if (!pnode.IsEmpty()) { foreach (ConfigElementNode vn in pnode.GetValues()) { NodePostLoad(vn, properties, replace); } } } else if (node.GetType() == typeof(ConfigValueNode)) { if (replace) { ConfigValueNode vn = (ConfigValueNode)node; string value = vn.GetValue(); if (!String.IsNullOrWhiteSpace(value)) { string nv = ReplaceVariable(value, properties); vn.SetValue(nv); } } } } }
/// <summary> /// Create a Resource node instance. /// </summary> /// <param name="parent">Parent Config node</param> /// <param name="elem">XML Element</param> private void AddResourceNode(ConfigPathNode parent, XmlElement elem) { string resourceName = elem.GetAttribute(ConstXmlResourceNode.XML_CONFIG_ATTR_RESOURCE_NAME); if (String.IsNullOrWhiteSpace(resourceName)) { throw ConfigurationException.PropertyMissingException(ConstXmlResourceNode.XML_CONFIG_ATTR_RESOURCE_NAME); } string st = elem.GetAttribute(ConstXmlResourceNode.XML_CONFIG_ATTR_RESOURCE_TYPE); if (String.IsNullOrWhiteSpace(st)) { throw ConfigurationException.PropertyMissingException(ConstXmlResourceNode.XML_CONFIG_ATTR_RESOURCE_TYPE); } EResourceType type = Enum.Parse <EResourceType>(st); if (type == EResourceType.NONE) { throw ConfigurationException.PropertyMissingException(ConstXmlResourceNode.XML_CONFIG_ATTR_RESOURCE_TYPE); } Uri uri = null; if (elem.HasChildNodes) { foreach (XmlNode nn in elem.ChildNodes) { if (nn.NodeType == XmlNodeType.Element && nn.Name == ConstXmlResourceNode.XML_CONFIG_NODE_RESOURCE_URL) { string su = nn.InnerText; if (String.IsNullOrWhiteSpace(su)) { throw ConfigurationException.PropertyMissingException(ConstXmlResourceNode.XML_CONFIG_NODE_RESOURCE_URL); } uri = new Uri(su); break; } } } if (uri == null) { throw ConfigurationException.PropertyMissingException(ConstXmlResourceNode.XML_CONFIG_NODE_RESOURCE_URL); } ConfigResourceNode node = null; switch (type) { case EResourceType.FILE: node = new ConfigResourceFile(configuration, parent); break; case EResourceType.DIRECTORY: node = new ConfigDirectoryResource(configuration, parent); break; case EResourceType.ZIP: node = new ConfigResourceZip(configuration, parent); break; } node.Name = elem.Name; node.Type = type; node.Location = uri; node.ResourceName = resourceName; if (settings.DownloadOptions == EDownloadOptions.LoadRemoteResourcesOnStartup) { if (type == EResourceType.ZIP || type == EResourceType.FILE) { ConfigResourceFile fnode = (ConfigResourceFile)node; ConfigResourceHelper.DownloadResource(fnode); } } if (type == EResourceType.DIRECTORY) { ConfigDirectoryResource dnode = (ConfigDirectoryResource)node; if (!dnode.Location.IsFile) { throw new ConfigurationException(String.Format("Invalid URI: Must be a local/mounted directory. [uri={0}]", dnode.Location.ToString())); } string dir = dnode.Location.LocalPath; DirectoryInfo di = new DirectoryInfo(dir); if (di.Exists) { throw new ConfigurationException(String.Format("Invalid URI: Directory not found. [uri={0}]", dnode.Location.ToString())); } dnode.Downloaded = true; dnode.Directory = di; } parent.AddChildNode(node); }
/// <summary> /// Parse a configuration node. /// </summary> /// <param name="name">Config node name</param> /// <param name="elem">XML Element</param> /// <param name="nodeStack">Current Node Stack</param> private void ParseBodyNode(string name, XmlElement elem, Stack <AbstractConfigNode> nodeStack) { bool popStack = false; bool processed = false; AbstractConfigNode parent = nodeStack.Peek(); if (IsTextNode(elem)) { bool encrypted = false; if (elem.HasAttributes) { string attr = elem.Attributes[XML_VALUE_ENCRYPTED].Value; if (!String.IsNullOrWhiteSpace(attr)) { if (attr.CompareTo("true") == 0) { encrypted = true; } } } AddValueNode(parent, elem.Name, elem.FirstChild.Value, encrypted); } else { XmlNodeType nt = IsListNode(elem); if (nt == XmlNodeType.Element) { if (parent.GetType() != typeof(ConfigPathNode)) { throw new ConfigurationException(String.Format("Invalid Stack State: Cannot add List node to parent. [parent={0}]", parent.GetType().FullName)); } ConfigPathNode pnode = (ConfigPathNode)parent; ConfigElementListNode nodeList = new ConfigElementListNode(parent.Configuration, parent); nodeList.Name = name; pnode.AddChildNode(nodeList); nodeStack.Push(nodeList); popStack = true; } else if (nt == XmlNodeType.Text) { if (parent.GetType() != typeof(ConfigPathNode)) { throw new ConfigurationException(String.Format("Invalid Stack State: Cannot add List node to parent. [parent={0}]", parent.GetType().FullName)); } ConfigPathNode pnode = (ConfigPathNode)parent; ConfigListValueNode nodeList = new ConfigListValueNode(parent.Configuration, parent); nodeList.Name = name; pnode.AddChildNode(nodeList); nodeStack.Push(nodeList); popStack = true; } else { if (elem.Name == ConstXmlConfigIncludeNode.XML_CONFIG_INCLUDE) { if (parent.GetType() != typeof(ConfigPathNode)) { throw new ConfigurationException(String.Format("Invalid Stack State: Cannot add List node to parent. [parent={0}]", parent.GetType().FullName)); } ConfigPathNode pnode = (ConfigPathNode)parent; AddIncludeNode(pnode, elem); processed = true; } else if (elem.Name == ConstXmlResourceNode.XML_CONFIG_NODE_RESOURCE) { if (parent.GetType() != typeof(ConfigPathNode)) { throw new ConfigurationException(String.Format("Invalid Stack State: Cannot add List node to parent. [parent={0}]", parent.GetType().FullName)); } ConfigPathNode pnode = (ConfigPathNode)parent; AddResourceNode(pnode, elem); processed = true; } else if (elem.Name == settings.ParametersNodeName) { if (parent.GetType() != typeof(ConfigPathNode)) { throw new ConfigurationException(String.Format("Invalid Stack State: Cannot add List node to parent. [parent={0}]", parent.GetType().FullName)); } ConfigPathNode pnode = (ConfigPathNode)parent; ConfigParametersNode paramNode = new ConfigParametersNode(parent.Configuration, parent); paramNode.Name = name; pnode.AddChildNode(paramNode); nodeStack.Push(paramNode); popStack = true; } else if (elem.Name == settings.PropertiesNodeName) { if (parent.GetType() != typeof(ConfigPathNode)) { throw new ConfigurationException(String.Format("Invalid Stack State: Cannot add List node to parent. [parent={0}]", parent.GetType().FullName)); } ConfigPathNode pnode = (ConfigPathNode)parent; ConfigPropertiesNode propNode = new ConfigPropertiesNode(parent.Configuration, parent); propNode.Name = name; pnode.AddChildNode(propNode); nodeStack.Push(propNode); popStack = true; } else { ConfigPathNode cnode = new ConfigPathNode(parent.Configuration, parent); cnode.Name = name; if (parent.GetType() == typeof(ConfigPathNode)) { ConfigPathNode pnode = (ConfigPathNode)parent; pnode.AddChildNode(cnode); } else if (parent.GetType() == typeof(ConfigElementListNode)) { ConfigElementListNode nodeList = (ConfigElementListNode)parent; nodeList.Add(cnode); } else { throw new ConfigurationException(String.Format("Invalid Stack State: Cannot add path node to parent. [parent={0}]", parent.GetType().FullName)); } nodeStack.Push(cnode); popStack = true; } } if (!processed) { if (elem.HasAttributes) { AbstractConfigNode pp = nodeStack.Peek(); if (pp.GetType() == typeof(ConfigPathNode)) { ConfigPathNode cp = (ConfigPathNode)pp; ConfigAttributesNode attrs = new ConfigAttributesNode(cp.Configuration, cp); cp.AddChildNode(attrs); foreach (XmlAttribute attr in elem.Attributes) { ConfigValueNode vn = new ConfigValueNode(attrs.Configuration, attrs); vn.Name = attr.Name; vn.SetValue(attr.Value); attrs.Add(vn); } } } if (elem.HasChildNodes) { foreach (XmlNode cnode in elem.ChildNodes) { if (cnode.NodeType == XmlNodeType.Element) { ParseBodyNode(cnode.Name, (XmlElement)cnode, nodeStack); } } } } if (popStack) { nodeStack.Pop(); } } }
/// <summary> /// Write a configuration node. /// </summary> /// <param name="writer">XML Writer</param> /// <param name="node">Node To write</param> /// <param name="settings">Configuration Settings.</param> private void WriteNode(XmlWriter writer, AbstractConfigNode node, ConfigurationSettings settings) { if (node.GetType() == typeof(ConfigPathNode)) { ConfigPathNode pnode = (ConfigPathNode)node; writer.WriteStartElement(node.Name); { ConfigAttributesNode attrs = pnode.GetAttributes(); if (attrs != null) { Dictionary <string, ConfigValueNode> values = attrs.GetValues(); if (values != null && values.Count > 0) { foreach (string key in values.Keys) { ConfigValueNode vn = values[key]; if (vn != null) { writer.WriteAttributeString(vn.Name, vn.GetValue()); } } } } Dictionary <string, AbstractConfigNode> nodes = pnode.GetChildren(); foreach (string key in nodes.Keys) { AbstractConfigNode cnode = nodes[key]; if (cnode.Name == settings.AttributesNodeName) { continue; } WriteNode(writer, cnode, settings); } } writer.WriteEndElement(); } else if (node.GetType() == typeof(ConfigValueNode)) { ConfigValueNode vn = (ConfigValueNode)node; writer.WriteStartElement(vn.Name); writer.WriteString(vn.GetValue()); writer.WriteEndElement(); } else if (node.GetType() == typeof(ConfigParametersNode) || node.GetType() == typeof(ConfigPropertiesNode)) { string name = null; if (node.GetType() == typeof(ConfigParametersNode)) { name = settings.ParametersNodeName; } else { name = settings.PropertiesNodeName; } ConfigKeyValueNode kvnode = (ConfigKeyValueNode)node; WriteKeyValueNode(writer, kvnode, name); } else if (node.GetType() == typeof(ConfigListValueNode)) { WriteListValueNode(writer, (ConfigListValueNode)node); } else if (node.GetType() == typeof(ConfigElementListNode)) { WriteListElementNode(writer, (ConfigElementListNode)node, settings); } else if (node.GetType() == typeof(ConfigIncludeNode)) { ConfigIncludeNode inode = (ConfigIncludeNode)node; WriteNode(writer, inode.Node, settings); } else if (typeof(ConfigResourceNode).IsAssignableFrom(node.GetType())) { ConfigResourceNode rnode = (ConfigResourceNode)node; WriteResourceNode(writer, rnode); } }