Esempio n. 1
0
        /// <summary>
        /// Creates an instance of InheritDocumentationComponent class.
        /// </summary>
        /// <param name="configuration">Configuration section to be parsed.</param>
        /// <param name="data">A dictionary object with string as key and object as value.</param>
        public InheritDocumentationComponent(XPathNavigator configuration, Dictionary <string, object> data)
            : base(configuration, data)
        {
            // get the copy commands
            XPathNodeIterator copy_nodes = configuration.Select("copy");

            foreach (XPathNavigator copy_node in copy_nodes)
            {
                // get the comments info
                string source_name = copy_node.GetAttribute("name", string.Empty);
                if (String.IsNullOrEmpty(source_name))
                {
                    throw new ConfigurationErrorsException("Each copy command must specify an index to copy from.");
                }

                // get the reflection info
                string reflection_name = copy_node.GetAttribute("use", String.Empty);
                if (String.IsNullOrEmpty(reflection_name))
                {
                    throw new ConfigurationErrorsException("Each copy command must specify an index to get reflection information from.");
                }

                this.index           = (IndexedDocumentCache)data[source_name];
                this.reflectionIndex = (IndexedDocumentCache)data[reflection_name];
            }
        }
Esempio n. 2
0
        public IndexedDocument(IndexedDocumentCache cache, string file)
        {
            if (cache == null)
            {
                throw new ArgumentNullException("cache");
            }
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            // remember the file
            this.file = file;

            // load the document
            try {
                //XPathDocument document = new XPathDocument(file, XmlSpace.Preserve);
                XPathDocument document = new XPathDocument(file);

                // search for value nodes
                XPathNodeIterator valueNodes = document.CreateNavigator().Select(cache.ValueExpression);
                // Console.WriteLine("found {0} instances of '{1}' (key xpath is '{2}')", valueNodes.Count, valueExpression.Expression, keyExpression.Expression);

                // get the key string for each value node and record it in the index
                foreach (XPathNavigator valueNode in valueNodes)
                {
                    XPathNavigator keyNode = valueNode.SelectSingleNode(cache.KeyExpression);
                    if (keyNode == null)
                    {
                        // Console.WriteLine("null key");
                        continue;
                    }

                    string key = keyNode.Value;
                    index[key] = valueNode;
                    if (!index.ContainsKey(key))
                    {
                        //index.Add(key, valueNode);
                    }
                    else
                    {
                        // Console.WriteLine("Repeat key '{0}'", key);
                    }
                }
            } catch (IOException e) {
                cache.Component.WriteHelperMessage(MessageLevel.Error, String.Format("An access error occured while attempting to load the file '{0}'. The error message is: {1}", file, e.Message));
            } catch (XmlException e) {
                cache.Component.WriteHelperMessage(MessageLevel.Error, String.Format("The indexed document '{0}' is not a valid XML document. The error message is: {1}", file, e.Message));
            }
            // Console.WriteLine("indexed {0} keys", index.Count);
        }
        /// <summary>
        /// Creates an instance of InheritDocumentationComponent class.
        /// </summary>
        /// <param name="configuration">Configuration section to be parsed.</param>
        /// <param name="data">A dictionary object with string as key and object as value.</param>
        public InheritDocumentationComponent(XPathNavigator configuration, Dictionary <string, object> data)
            : base(configuration, data)
        {
            // get the copy commands
            XPathNodeIterator copy_nodes = configuration.Select("copy");

            foreach (XPathNavigator copy_node in copy_nodes)
            {
                // get the comments info
                string source_name = copy_node.GetAttribute("name", string.Empty);
                if (String.IsNullOrEmpty(source_name))
                {
                    throw new ConfigurationErrorsException("Each copy command must specify an index to copy from.");
                }

                // get the reflection info
                string reflection_name = copy_node.GetAttribute("use", String.Empty);
                if (String.IsNullOrEmpty(reflection_name))
                {
                    throw new ConfigurationErrorsException("Each copy command must specify an index to get reflection information from.");
                }

                this.index           = (IndexedDocumentCache)data[source_name];
                this.reflectionIndex = (IndexedDocumentCache)data[reflection_name];
            }

            // Retrieve a message writer...
            if (index != null && index.Component != null)
            {
                if (_messageWriter == null)
                {
                    BuildAssembler assembler = index.Component.BuildAssembler;
                    if (assembler != null)
                    {
                        _messageWriter = assembler.MessageWriter;
                    }
                }
            }
            if (_messageWriter == null &&
                (reflectionIndex != null && reflectionIndex.Component != null))
            {
                BuildAssembler assembler = reflectionIndex.Component.BuildAssembler;
                if (assembler != null)
                {
                    _messageWriter = assembler.MessageWriter;
                }
            }
        }
Esempio n. 4
0
 public CopyCommand(IndexedDocumentCache source_index, string key_xpath, string source_xpath, string target_xpath, string attribute_value, string ignoreCase_value)
 {
     this.cache = source_index;
     if (String.IsNullOrEmpty(key_xpath))
     {
         // Console.WriteLine("null key xpath");
         key = XPathExpression.Compile("string($key)");
     }
     else
     {
         // Console.WriteLine("compiling key xpath '{0}'", key_xpath);
         key = XPathExpression.Compile(key_xpath);
     }
     source     = XPathExpression.Compile(source_xpath);
     target     = target_xpath;
     attribute  = attribute_value;
     ignoreCase = ignoreCase_value;
 }
 public CopyCommand(IndexedDocumentCache source_index, string key_xpath, string source_xpath, string target_xpath, string attribute_value, string ignoreCase_value) {
     this.cache = source_index;
     if (String.IsNullOrEmpty(key_xpath)) {
         // Console.WriteLine("null key xpath");
         key = XPathExpression.Compile("string($key)");
     } else {
         // Console.WriteLine("compiling key xpath '{0}'", key_xpath);
         key = XPathExpression.Compile(key_xpath);
     }
     source = XPathExpression.Compile(source_xpath);
     target = target_xpath;
     attribute = attribute_value;
     ignoreCase = ignoreCase_value;
 }
        public IndexedDocument(IndexedDocumentCache cache, string file) {

            if (cache == null) throw new ArgumentNullException("cache");
            if (file == null) throw new ArgumentNullException("file");

            // remember the file
            this.file = file;

            // load the document
            try {
                //XPathDocument document = new XPathDocument(file, XmlSpace.Preserve);
                XPathDocument document = new XPathDocument(file);

                // search for value nodes
                XPathNodeIterator valueNodes = document.CreateNavigator().Select(cache.ValueExpression);
                // Console.WriteLine("found {0} instances of '{1}' (key xpath is '{2}')", valueNodes.Count, valueExpression.Expression, keyExpression.Expression);

                // get the key string for each value node and record it in the index
                foreach (XPathNavigator valueNode in valueNodes) {

                    XPathNavigator keyNode = valueNode.SelectSingleNode(cache.KeyExpression);
                    if (keyNode == null) {
                        // Console.WriteLine("null key");
                        continue;
                    }

                    string key = keyNode.Value;
                    index[key] = valueNode;
                    if (!index.ContainsKey(key)) {
                        //index.Add(key, valueNode);
                    } else {
                        // Console.WriteLine("Repeat key '{0}'", key);
                    }
                }

            } catch (IOException e) {
                cache.Component.WriteHelperMessage(MessageLevel.Error, String.Format("An access error occured while attempting to load the file '{0}'. The error message is: {1}", file, e.Message));
            } catch (XmlException e) {
                cache.Component.WriteHelperMessage(MessageLevel.Error, String.Format("The indexed document '{0}' is not a valid XML document. The error message is: {1}", file, e.Message));
            }
            // Console.WriteLine("indexed {0} keys", index.Count);


        }
        public CopyFromIndexComponent(BuildAssembler assembler, XPathNavigator configuration)
            : base(assembler, configuration) {

            // set up the context
            XPathNodeIterator context_nodes = configuration.Select("context");
            foreach (XPathNavigator context_node in context_nodes) {
                string prefix = context_node.GetAttribute("prefix", String.Empty);
                string name = context_node.GetAttribute("name", String.Empty);
                context.AddNamespace(prefix, name);
            }

            // set up the indices
            XPathNodeIterator index_nodes = configuration.Select("index");
            foreach (XPathNavigator index_node in index_nodes) {

                // get the name of the index
                string name = index_node.GetAttribute("name", String.Empty);
                if (String.IsNullOrEmpty(name)) throw new ConfigurationErrorsException("Each index must have a unique name.");

                // get the xpath for value nodes
                string value_xpath = index_node.GetAttribute("value", String.Empty);
                if (String.IsNullOrEmpty(value_xpath)) WriteMessage(MessageLevel.Error, "Each index element must have a value attribute containing an XPath that describes index entries.");

                // get the xpath for keys (relative to value nodes)
                string key_xpath = index_node.GetAttribute("key", String.Empty);
                if (String.IsNullOrEmpty(key_xpath)) WriteMessage(MessageLevel.Error, "Each index element must have a key attribute containing an XPath (relative to the value XPath) that evaluates to the entry key.");

                // get the cache size
                int cache = 10;
                string cache_value = index_node.GetAttribute("cache", String.Empty);
                if (!String.IsNullOrEmpty(cache_value)) cache = Convert.ToInt32(cache_value);

                // create the index
                IndexedDocumentCache index = new IndexedDocumentCache(this, key_xpath, value_xpath, context, cache);

                // search the data directories for entries
                XPathNodeIterator data_nodes = index_node.Select("data");
                foreach (XPathNavigator data_node in data_nodes) {

                    string base_value = data_node.GetAttribute("base", String.Empty);
                    if (!String.IsNullOrEmpty(base_value)) base_value = Environment.ExpandEnvironmentVariables(base_value);

                    bool recurse = false;
                    string recurse_value = data_node.GetAttribute("recurse", String.Empty);
                    if (!String.IsNullOrEmpty(recurse_value)) recurse = (bool)Convert.ToBoolean(recurse_value);

                    // get the files				
                    string files = data_node.GetAttribute("files", String.Empty);
                    if (String.IsNullOrEmpty(files)) WriteMessage(MessageLevel.Error, "Each data element must have a files attribute specifying which files to index.");
                    // if ((files == null) || (files.Length == 0)) throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a directory path using the files attribute.");
                    files = Environment.ExpandEnvironmentVariables(files);

                    WriteMessage(MessageLevel.Info, String.Format("Searching for files that match '{0}'.", files));
                    index.AddDocuments(base_value, files, recurse);

                }
                WriteMessage(MessageLevel.Info, String.Format("Indexed {0} elements in {1} files.", index.Count, index.DocumentCount));

                Data.Add(name, index);

            }

            // get the copy commands
            XPathNodeIterator copy_nodes = configuration.Select("copy");
            foreach (XPathNavigator copy_node in copy_nodes) {

                string source_name = copy_node.GetAttribute("name", String.Empty);
                if (String.IsNullOrEmpty(source_name)) throw new ConfigurationErrorsException("Each copy command must specify an index to copy from.");

                string key_xpath = copy_node.GetAttribute("key", String.Empty);

                string source_xpath = copy_node.GetAttribute("source", String.Empty);
                if (String.IsNullOrEmpty(source_xpath)) throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a source xpath format using the source attribute.");

                string target_xpath = copy_node.GetAttribute("target", String.Empty);
                if (String.IsNullOrEmpty(target_xpath)) throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a target xpath format using the target attribute.");

                string attribute_value = copy_node.GetAttribute("attribute", String.Empty);

                string ignoreCase_value = copy_node.GetAttribute("ignoreCase", String.Empty);

                string missingEntryValue = copy_node.GetAttribute("missing-entry", String.Empty);
                string missingSourceValue = copy_node.GetAttribute("missing-source", String.Empty);
                string missingTargetValue = copy_node.GetAttribute("missing-target", String.Empty);

                IndexedDocumentCache index = (IndexedDocumentCache)Data[source_name];

                CopyCommand copyCommand = new CopyCommand(index, key_xpath, source_xpath, target_xpath, attribute_value, ignoreCase_value);
                if (!String.IsNullOrEmpty(missingEntryValue)) {
                    try {
                        copyCommand.MissingEntry = (MessageLevel)Enum.Parse(typeof(MessageLevel), missingEntryValue, true);
                    } catch (ArgumentException) {
                        WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a message level.", missingEntryValue));
                    }
                }
                if (!String.IsNullOrEmpty(missingSourceValue)) {
                    try {
                        copyCommand.MissingSource = (MessageLevel)Enum.Parse(typeof(MessageLevel), missingSourceValue, true);
                    } catch (ArgumentException) {
                        WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a message level.", missingSourceValue));
                    }
                }
                if (!String.IsNullOrEmpty(missingTargetValue)) {
                    try {
                        copyCommand.MissingTarget = (MessageLevel)Enum.Parse(typeof(MessageLevel), missingTargetValue, true);
                    } catch (ArgumentException) {
                        WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a message level.", missingTargetValue));
                    }
                }

                copy_commands.Add(copyCommand);

            }

            XPathNodeIterator component_nodes = configuration.Select("components/component");
            foreach (XPathNavigator component_node in component_nodes) {

                // get the data to load the component
                string assembly_path = component_node.GetAttribute("assembly", String.Empty);
                if (String.IsNullOrEmpty(assembly_path)) WriteMessage(MessageLevel.Error, "Each component element must have an assembly attribute.");
                string type_name = component_node.GetAttribute("type", String.Empty);
                if (String.IsNullOrEmpty(type_name)) WriteMessage(MessageLevel.Error, "Each component element must have a type attribute.");

                // expand environment variables in the path
                assembly_path = Environment.ExpandEnvironmentVariables(assembly_path);

                //Console.WriteLine("loading {0} from {1}", type_name, assembly_path);
                try 
                {
                    Assembly assembly = Assembly.LoadFrom(assembly_path);
                    CopyComponent component = (CopyComponent)assembly.CreateInstance(type_name, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[2] { component_node.Clone(), Data }, null, null);

                    if (component == null)
                    {
                        WriteMessage(MessageLevel.Error, String.Format("The type '{0}' does not exist in the assembly '{1}'.", type_name, assembly_path));
                    }
                    else
                    {
                        components.Add(component);
                    }

                }
                catch (IOException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("A file access error occured while attempting to load the build component '{0}'. The error message is: {1}", assembly_path, e.Message));
                }
                catch (BadImageFormatException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("A syntax generator assembly '{0}' is invalid. The error message is: {1}.", assembly_path, e.Message));
                }
                catch (TypeLoadException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("The type '{0}' does not exist in the assembly '{1}'. The error message is: {2}", type_name, assembly_path, e.Message));
                }
                catch (MissingMethodException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("The type '{0}' in the assembly '{1}' does not have an appropriate constructor. The error message is: {2}", type_name, assembly_path, e.Message));
                }
                catch (TargetInvocationException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("An error occured while attempting to instantiate the type '{0}' in the assembly '{1}'. The error message is: {2}", type_name, assembly_path, e.InnerException.Message));
                }
                catch (InvalidCastException)
                {
                    WriteMessage(MessageLevel.Error, String.Format("The type '{0}' in the assembly '{1}' is not a SyntaxGenerator.", type_name, assembly_path));
                }
            }

            WriteMessage(MessageLevel.Info, String.Format("Loaded {0} copy components.", components.Count));

        }
Esempio n. 8
0
        public CopyFromIndexComponent(BuildAssembler assembler, XPathNavigator configuration)
            : base(assembler, configuration)
        {
            // set up the context
            XPathNodeIterator context_nodes = configuration.Select("context");

            foreach (XPathNavigator context_node in context_nodes)
            {
                string prefix = context_node.GetAttribute("prefix", String.Empty);
                string name   = context_node.GetAttribute("name", String.Empty);
                context.AddNamespace(prefix, name);
            }

            // set up the indices
            XPathNodeIterator index_nodes = configuration.Select("index");

            foreach (XPathNavigator index_node in index_nodes)
            {
                // get the name of the index
                string name = index_node.GetAttribute("name", String.Empty);
                if (String.IsNullOrEmpty(name))
                {
                    throw new ConfigurationErrorsException("Each index must have a unique name.");
                }

                // get the xpath for value nodes
                string value_xpath = index_node.GetAttribute("value", String.Empty);
                if (String.IsNullOrEmpty(value_xpath))
                {
                    WriteMessage(MessageLevel.Error, "Each index element must have a value attribute containing an XPath that describes index entries.");
                }

                // get the xpath for keys (relative to value nodes)
                string key_xpath = index_node.GetAttribute("key", String.Empty);
                if (String.IsNullOrEmpty(key_xpath))
                {
                    WriteMessage(MessageLevel.Error, "Each index element must have a key attribute containing an XPath (relative to the value XPath) that evaluates to the entry key.");
                }

                // get the cache size
                int    cache       = 10;
                string cache_value = index_node.GetAttribute("cache", String.Empty);
                if (!String.IsNullOrEmpty(cache_value))
                {
                    cache = Convert.ToInt32(cache_value);
                }

                // create the index
                IndexedDocumentCache index = new IndexedDocumentCache(this, key_xpath, value_xpath, context, cache);

                // search the data directories for entries
                XPathNodeIterator data_nodes = index_node.Select("data");
                foreach (XPathNavigator data_node in data_nodes)
                {
                    string base_value = data_node.GetAttribute("base", String.Empty);
                    if (!String.IsNullOrEmpty(base_value))
                    {
                        base_value = Environment.ExpandEnvironmentVariables(base_value);
                    }

                    bool   recurse       = false;
                    string recurse_value = data_node.GetAttribute("recurse", String.Empty);
                    if (!String.IsNullOrEmpty(recurse_value))
                    {
                        recurse = (bool)Convert.ToBoolean(recurse_value);
                    }

                    // get the files
                    string files = data_node.GetAttribute("files", String.Empty);
                    if (String.IsNullOrEmpty(files))
                    {
                        WriteMessage(MessageLevel.Error, "Each data element must have a files attribute specifying which files to index.");
                    }
                    // if ((files == null) || (files.Length == 0)) throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a directory path using the files attribute.");
                    files = Environment.ExpandEnvironmentVariables(files);

                    WriteMessage(MessageLevel.Info, String.Format("Searching for files that match '{0}'.", files));
                    index.AddDocuments(base_value, files, recurse);
                }
                WriteMessage(MessageLevel.Info, String.Format("Indexed {0} elements in {1} files.", index.Count, index.DocumentCount));

                Data.Add(name, index);
            }

            // get the copy commands
            XPathNodeIterator copy_nodes = configuration.Select("copy");

            foreach (XPathNavigator copy_node in copy_nodes)
            {
                string source_name = copy_node.GetAttribute("name", String.Empty);
                if (String.IsNullOrEmpty(source_name))
                {
                    throw new ConfigurationErrorsException("Each copy command must specify an index to copy from.");
                }

                string key_xpath = copy_node.GetAttribute("key", String.Empty);

                string source_xpath = copy_node.GetAttribute("source", String.Empty);
                if (String.IsNullOrEmpty(source_xpath))
                {
                    throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a source xpath format using the source attribute.");
                }

                string target_xpath = copy_node.GetAttribute("target", String.Empty);
                if (String.IsNullOrEmpty(target_xpath))
                {
                    throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a target xpath format using the target attribute.");
                }

                string attribute_value = copy_node.GetAttribute("attribute", String.Empty);

                string ignoreCase_value = copy_node.GetAttribute("ignoreCase", String.Empty);

                string missingEntryValue  = copy_node.GetAttribute("missing-entry", String.Empty);
                string missingSourceValue = copy_node.GetAttribute("missing-source", String.Empty);
                string missingTargetValue = copy_node.GetAttribute("missing-target", String.Empty);

                IndexedDocumentCache index = (IndexedDocumentCache)Data[source_name];

                CopyCommand copyCommand = new CopyCommand(index, key_xpath, source_xpath, target_xpath, attribute_value, ignoreCase_value);
                if (!String.IsNullOrEmpty(missingEntryValue))
                {
                    try {
                        copyCommand.MissingEntry = (MessageLevel)Enum.Parse(typeof(MessageLevel), missingEntryValue, true);
                    } catch (ArgumentException) {
                        WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a message level.", missingEntryValue));
                    }
                }
                if (!String.IsNullOrEmpty(missingSourceValue))
                {
                    try {
                        copyCommand.MissingSource = (MessageLevel)Enum.Parse(typeof(MessageLevel), missingSourceValue, true);
                    } catch (ArgumentException) {
                        WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a message level.", missingSourceValue));
                    }
                }
                if (!String.IsNullOrEmpty(missingTargetValue))
                {
                    try {
                        copyCommand.MissingTarget = (MessageLevel)Enum.Parse(typeof(MessageLevel), missingTargetValue, true);
                    } catch (ArgumentException) {
                        WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a message level.", missingTargetValue));
                    }
                }

                copy_commands.Add(copyCommand);
            }

            XPathNodeIterator component_nodes = configuration.Select("components/component");

            foreach (XPathNavigator component_node in component_nodes)
            {
                // get the data to load the component
                string assembly_path = component_node.GetAttribute("assembly", String.Empty);
                if (String.IsNullOrEmpty(assembly_path))
                {
                    WriteMessage(MessageLevel.Error, "Each component element must have an assembly attribute.");
                }
                string type_name = component_node.GetAttribute("type", String.Empty);
                if (String.IsNullOrEmpty(type_name))
                {
                    WriteMessage(MessageLevel.Error, "Each component element must have a type attribute.");
                }

                // expand environment variables in the path
                assembly_path = Environment.ExpandEnvironmentVariables(assembly_path);

                //Console.WriteLine("loading {0} from {1}", type_name, assembly_path);
                try
                {
                    Assembly      assembly  = Assembly.LoadFrom(assembly_path);
                    CopyComponent component = (CopyComponent)assembly.CreateInstance(type_name, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[2] {
                        component_node.Clone(), Data
                    }, null, null);

                    if (component == null)
                    {
                        WriteMessage(MessageLevel.Error, String.Format("The type '{0}' does not exist in the assembly '{1}'.", type_name, assembly_path));
                    }
                    else
                    {
                        components.Add(component);
                    }
                }
                catch (IOException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("A file access error occured while attempting to load the build component '{0}'. The error message is: {1}", assembly_path, e.Message));
                }
                catch (BadImageFormatException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("A syntax generator assembly '{0}' is invalid. The error message is: {1}.", assembly_path, e.Message));
                }
                catch (TypeLoadException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("The type '{0}' does not exist in the assembly '{1}'. The error message is: {2}", type_name, assembly_path, e.Message));
                }
                catch (MissingMethodException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("The type '{0}' in the assembly '{1}' does not have an appropriate constructor. The error message is: {2}", type_name, assembly_path, e.Message));
                }
                catch (TargetInvocationException e)
                {
                    WriteMessage(MessageLevel.Error, String.Format("An error occured while attempting to instantiate the type '{0}' in the assembly '{1}'. The error message is: {2}", type_name, assembly_path, e.InnerException.Message));
                }
                catch (InvalidCastException)
                {
                    WriteMessage(MessageLevel.Error, String.Format("The type '{0}' in the assembly '{1}' is not a SyntaxGenerator.", type_name, assembly_path));
                }
            }

            WriteMessage(MessageLevel.Info, String.Format("Loaded {0} copy components.", components.Count));
        }
        /// <summary>
        /// Creates an instance of InheritDocumentationComponent class.
        /// </summary>
        /// <param name="configuration">Configuration section to be parsed.</param>
        /// <param name="data">A dictionary object with string as key and object as value.</param>
        public InheritDocumentationComponent(XPathNavigator configuration, Dictionary<string, object> data)
            : base(configuration, data)
        {
            // get the copy commands
            XPathNodeIterator copy_nodes = configuration.Select("copy");
            foreach (XPathNavigator copy_node in copy_nodes)
            {
                // get the comments info
                string source_name = copy_node.GetAttribute("name", string.Empty);
		        if (String.IsNullOrEmpty(source_name))
                {
                    throw new ConfigurationErrorsException("Each copy command must specify an index to copy from.");
                }

                // get the reflection info
                string reflection_name = copy_node.GetAttribute("use", String.Empty);
                if (String.IsNullOrEmpty(reflection_name))
                {
                    throw new ConfigurationErrorsException("Each copy command must specify an index to get reflection information from.");
                }
                               
                this.index = (IndexedDocumentCache)data[source_name];
                this.reflectionIndex = (IndexedDocumentCache)data[reflection_name];
             }
        }