/// <summary> /// <c>ICloneable</c> implementation. Returns a shallow copy of the object. /// </summary> public object Clone() { ExtenderSection ext = new ExtenderSection(); ext._retrievers = Retrievers.Clone() as ArrayList; ext._traverser = Traverser; ext._visitors = Visitors.Clone() as SortedList; return(ext); }
/// <summary> /// Creates and initializes the configuration options. /// </summary> /// <param name="parent">Parent configuration node, the root configuration.</param> /// <param name="configContext">Not used.</param> /// <param name="configNode">The configuration node.</param> /// <returns>An <c>ExtenderSection</c> object.</returns> public object Create(object parent, object configContext, XmlNode configNode) { if (configNode == null) { return(null); } ExtenderSection extender = new ExtenderSection(); AddConfigurations(configNode, extender); return(extender); }
/// <summary> /// Merges an existing ExtenderSection object with the new data. /// </summary> public object Merge(object currentConfig, object parent, object configContext, XmlNode configNode) { ExtenderSection extender; if (currentConfig != null) { extender = ((ExtenderSection)currentConfig).Clone() as ExtenderSection; } else { extender = new ExtenderSection(); } AddConfigurations(configNode, extender); return(extender); }
/// <summary> /// Processes the configuration node and adds the objects to the ExtenderSection. /// </summary> /// <param name="configNode">The node with the configuration data.</param> /// <param name="extender">The extender object to configure.</param> private void AddConfigurations(XmlNode configNode, ExtenderSection extender) { if (configNode == null) { return; } XmlNodeList nodes; try { #region Traversers nodes = configNode.SelectNodes("//traverser[@enabled=\"true\"]"); if (nodes.Count > 1) { throw new ConfigurationException("Only one Traverser can be enabled at a time."); } if (nodes.Count != 0) { object traverser = Reflection.GetObject(nodes[0].Attributes["type"].Value); if (traverser == null) { throw new ConfigurationException("Couldn't load Traverser: " + nodes[0].Attributes["type"].Value + "."); } // Traversers must implement ITraverser. Reflection.EnsureInterface(traverser.GetType(), typeof(ITraverser)); extender.Traverser = traverser as ITraverser; } #endregion #region Visitors // Retrieve all to remove disabled visitors. nodes = configNode.SelectNodes("//visitor"); foreach (XmlNode node in nodes) { if (node.Attributes["enabled"] == null || node.Attributes["enabled"].Value == "true") { object visitor = Reflection.GetObject(node.Attributes["type"].Value); if (visitor == null) { throw new ConfigurationException("Specified visitor type couldn't be loaded: " + node.Attributes["type"].Value); } // Visitors must implement IVisitor. Type vtype = visitor.GetType(); Reflection.EnsureInterface(vtype, typeof(IVisitor)); bool add = true; foreach (DictionaryEntry v in extender.Visitors) { if (v.Value.GetType() == vtype) { add = false; break; } } if (add) { XmlAttribute attr = node.Attributes["runOrder"]; int order = -1; if (attr != null) { order = int.Parse(attr.Value); } if (order == -1) { order = int.MaxValue; } extender.Visitors.Add(new SortedDuplicateKey(order), visitor); } } else { object[] visitors = new object[extender.Visitors.Count]; extender.Visitors.CopyTo(visitors, 0); Type visitor = Reflection.LoadType(node.Attributes["type"].Value); // Start from the last element to safely remove at an specific ordinal position. for (int i = visitors.Length - 1; i >= 0; i--) { if (((DictionaryEntry)visitors[i]).Value.GetType() == visitor) { extender.Visitors.RemoveAt(i); } } } } #endregion #region Retrievers nodes = configNode.SelectNodes("//retriever"); foreach (XmlNode node in nodes) { if (node.Attributes["enabled"].Value == "false") { object[] retrievers = new object[extender.Retrievers.Count]; extender.Retrievers.CopyTo(retrievers, 0); // Start from the last element to safely remove at an specific ordinal position. for (int i = retrievers.Length; i > 0; i--) { // We use StartsWith because the AssemblyQualifiedName contains version, token and language info. if (((DictionaryEntry)retrievers[i]).Value.GetType().AssemblyQualifiedName.StartsWith(node.Attributes["type"].Value)) { extender.Retrievers.RemoveAt(i); } } } else { object retriever = Reflection.GetObject(node.Attributes["type"].Value); if (retriever == null) { throw new ConfigurationException("Invalid Retriever type."); } // Retrievers must implement ICustomizationRetriever. Reflection.EnsureInterface(retriever.GetType(), typeof(ICustomizationRetriever)); extender.Retrievers.Add(retriever); } } #endregion } catch (Exception ex) { throw new ConfigurationException("Invalid values found in Extenders configuration.", ex); } }