Example #1
0
 private void AddTargets(string file, LinkType2 type)
 {
     try {
         XPathDocument document = new XPathDocument(file);
         XmlTargetCollectionUtilities.AddTargets(targets, document.CreateNavigator(), type);
     } catch (XmlSchemaException e) {
         WriteMessage(MessageLevel.Error, String.Format("The reference targets file '{0}' is not valid. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
     } catch (XmlException e) {
         WriteMessage(MessageLevel.Error, String.Format("The reference targets file '{0}' is not well-formed XML. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
     } catch (IOException e) {
         WriteMessage(MessageLevel.Error, String.Format("An access error occured while opening the reference targets file '{0}'. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
     }
 }
Example #2
0
 private void AddTargets(string directory, string filePattern, bool recurse, LinkType2 type)
 {
     string[] files = Directory.GetFiles(directory, filePattern);
     foreach (string file in files)
     {
         AddTargets(file, type);
     }
     if (recurse)
     {
         string[] subdirectories = Directory.GetDirectories(directory);
         foreach (string subdirectory in subdirectories)
         {
             AddTargets(subdirectory, filePattern, recurse, type);
         }
     }
 }
Example #3
0
        private string ResolveExternalUrl(string targetId, LinkType2 type)
        {
            IExternalReferenceResolver resolver = (type == LinkType2.Msdn) ? this.msdn : this.ExternalResover;

            if ((resolver == null) || (resolver.IsDisabled))
            {
                // no resolver
                WriteMessage(MessageLevel.Warn, String.Format("No resolver for link type {0} is defined or enabled.", type));
                return(null);
            }

            String externalUrl = resolver.GetExternalUrl(targetId);

            if (String.IsNullOrEmpty(externalUrl))
            {
                WriteMessage(MessageLevel.Warn, String.Format("{0} not found for target '{1}'.", resolver.ResolverName, targetId));
            }
            return(externalUrl);
        }
        private static EnumerationTarget CreateEnumerationTarget (XPathNavigator api, LinkType2 linkType) {

            EnumerationTarget enumeration = new EnumerationTarget();

            string typeId = (string) api.Evaluate(topicIdExpression);
            string file = (string) api.Evaluate(topicFileExpression);

            // Create tar
            List<MemberTarget> members = new List<MemberTarget>();
            XPathNodeIterator elementNodes = api.Select("elements/element");
            foreach (XPathNavigator elementNode in elementNodes) {
                string memberId = elementNode.GetAttribute("api", String.Empty);

                // try to get name from attribute on element node
                string memberName = elementNode.GetAttribute("name", String.Empty);
                if (String.IsNullOrEmpty(memberName)) {
                    // if we can't do that, try to get the name by searching the file for the <api> element of that member
                    XPathNavigator memberApi = api.SelectSingleNode(String.Format("following-sibling::api[@id='{0}']", memberId));
                    if (memberApi != null) {
                        memberName = (string) memberApi.Evaluate(apiNameExpression);
                    } else {
                        // if all else fails, get the name by parsing the identifier
                        string arguments;
                        string type;
                        TextReferenceUtilities.DecomposeMemberIdentifier(memberId, out type, out memberName, out arguments);
                    }
                }

                MemberTarget member = new MemberTarget();
                member.id = memberId; // get Id from element
                member.file = file; // get file from type file
                member.type = linkType;
                member.name = memberName; // get name from element
                member.containingType = new SimpleTypeReference(typeId); // get containing type from this type
                members.Add(member);
            }

            enumeration.elements = members.ToArray();

            return (enumeration);
        }
        private static TypeTarget CreateTypeTarget (XPathNavigator api, LinkType2 linkType) {
            string subgroup = (string)api.Evaluate(apiSubgroupExpression);

            TypeTarget target;
            if (subgroup == "enumeration") {
                target = CreateEnumerationTarget(api, linkType);
            } else {
                target = new TypeTarget();
            }

            target.name = (string) api.Evaluate(apiNameExpression);

            // containing namespace
            XPathNavigator namespaceNode = api.SelectSingleNode(apiContainingNamespaceExpression);
            target.containingNamespace = CreateNamespaceReference(namespaceNode);

            // containing type, if any
            XPathNavigator typeNode = api.SelectSingleNode(apiContainingTypeExpression);
            if (typeNode == null) {
                target.containingType = null;
            } else {
                target.containingType = CreateSimpleTypeReference(typeNode);
            }

            // templates
            target.templates = GetTemplateNames(api);

            return(target);
        }
        private static Target CreateApiTarget (XPathNavigator api, LinkType2 linkType) {
            string subGroup = (string) api.Evaluate(apiGroupExpression);
            if (subGroup == "namespace") {
                return( CreateNamespaceTarget(api) );
            } else if (subGroup == "type") {
                return (CreateTypeTarget(api, linkType));
            } else if (subGroup == "member") {
                return (CreateMemberTarget(api));
            } else {
                return (null);
            }

        }
        // Target factory methods

        public static Target CreateTarget (XPathNavigator topic, LinkType2 type) {
            if (topic == null) throw new ArgumentNullException("topic");

            bool isApiTarget = (bool)topic.Evaluate("boolean(apidata)");

            Target target;
            if (isApiTarget) {
                target = CreateApiTarget(topic, type);
            } else {
                target = new Target();
            }

            if (target == null) throw new XmlSchemaValidationException(String.Format("The target file '{0}' is not valid.", topic.BaseURI));

            target.id = (string)topic.Evaluate(topicIdExpression);
            if (String.IsNullOrEmpty(target.id)) throw new XmlSchemaValidationException(String.Format("The target file '{0}' is not valid.", topic.BaseURI));

            target.container = (string)topic.Evaluate(topicContainerExpression);

            target.file = (string)topic.Evaluate(topicFileExpression);
            if (String.IsNullOrEmpty(target.file)) throw new XmlSchemaValidationException(String.Format("The target file '{0}' is not valid.", topic.BaseURI));

            target.type = type;

            return(target);
        }
        // super factory method

        public static void AddTargets (TargetCollection targets, XPathNavigator topicsNode, LinkType2 type) {
            XPathNodeIterator topicNodes = topicsNode.Select("/*/apis/api[not(topicdata/@notopic)]");
            foreach (XPathNavigator topicNode in topicNodes) {
                Target target = CreateTarget(topicNode, type);
                if (target != null) target.Add(targets);
            }
        }
Example #9
0
        private void ProcessTargetsNode(XPathNavigator targets_node)
        {
            // get target type
            string typeValue = targets_node.GetAttribute("type", String.Empty);

            if (String.IsNullOrEmpty(typeValue))
            {
                WriteMessage(MessageLevel.Error, "Each targets element must have a type attribute that specifies which type of links to create.");
            }

            LinkType2 type = LinkType2.None;

            try
            {
                type = (LinkType2)Enum.Parse(typeof(LinkType2), typeValue, true);
                if ((type == LinkType2.Msdn) && (msdn == null))
                {
                    WriteMessage(MessageLevel.Info, "Creating MSDN URL resolver.");
                    msdn = new MsdnResolver();
                }
            }
            catch (ArgumentException)
            {
                WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a supported reference link type.", typeValue));
            }

            if (type == LinkType2.External)
            {
                ProcessExternalTargetNode(targets_node);
                return;
            }

            // get base directory
            string baseValue = targets_node.GetAttribute("base", String.Empty);

            // get file pattern
            string filesValue = targets_node.GetAttribute("files", String.Empty);

            if (String.IsNullOrEmpty(filesValue))
            {
                WriteMessage(MessageLevel.Error, "Each targets element must have a files attribute specifying which target files to load.");
            }

            // determine whether to search recursively
            bool   recurse      = false;
            string recurseValue = targets_node.GetAttribute("recurse", String.Empty);

            if (!String.IsNullOrEmpty(recurseValue))
            {
                if (String.Compare(recurseValue, Boolean.TrueString, true) == 0)
                {
                    recurse = true;
                }
                else if (String.Compare(recurseValue, Boolean.FalseString, true) == 0)
                {
                    recurse = false;
                }
                else
                {
                    WriteMessage(MessageLevel.Error, String.Format("On the targets element, recurse='{0}' is not an allowed value.", recurseValue));
                }
            }

            // turn baseValue and filesValue into directoryPath and filePattern
            string fullPath;

            if (String.IsNullOrEmpty(baseValue))
            {
                fullPath = filesValue;
            }
            else
            {
                fullPath = Path.Combine(baseValue, filesValue);
            }
            fullPath = Environment.ExpandEnvironmentVariables(fullPath);
            string directoryPath = Path.GetDirectoryName(fullPath);

            if (String.IsNullOrEmpty(directoryPath))
            {
                directoryPath = Environment.CurrentDirectory;
            }
            string filePattern = Path.GetFileName(fullPath);

            // verify that directory exists
            if (!Directory.Exists(directoryPath))
            {
                WriteMessage(MessageLevel.Error, String.Format("The targets directory '{0}' does not exist.", directoryPath));
            }

            // add the specified targets from the directory
            WriteMessage(MessageLevel.Info, String.Format("Searching directory '{0}' for targets files of the form '{1}'.", directoryPath, filePattern));
            AddTargets(directoryPath, filePattern, recurse, type);
        }
Example #10
0
        // component logic

        public override void Apply(XmlDocument document, string key)
        {
            // XmlNodeList link_nodes = document.SelectNodes("//referenceLink");
            XPathNodeIterator linkIterator = document.CreateNavigator().Select(referenceLinkExpression);

            XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator);

            foreach (XPathNavigator linkNode in linkNodes)
            {
                // extract link information
                ReferenceLinkInfo2 link = ReferenceLinkInfo2.Create(linkNode);

                if (link == null)
                {
                    WriteMessage(MessageLevel.Warn, "Invalid referenceLink element.");
                }
                else
                {
                    // determine target, link type, and display options
                    string         targetId = link.Target;
                    DisplayOptions options  = link.DisplayOptions;
                    LinkType2      type     = LinkType2.None;

                    Target target = GetTarget(targetId);
                    if (target == null)
                    {
                        // no such target known; set link type to none and warn
                        type = LinkType2.None;
                        WriteMessage(MessageLevel.Warn, String.Format("Unknown reference link target '{0}'.", targetId));
                    }
                    else
                    {
                        // if overload is prefered and found, change targetId and make link options hide parameters
                        if (link.PreferOverload)
                        {
                            bool isConversionOperator = false;

                            MethodTarget method = target as MethodTarget;
                            if (method != null)
                            {
                                isConversionOperator = method.conversionOperator;
                            }

                            MemberTarget member = target as MemberTarget;

                            // if conversion operator is found, always link to individual topic.
                            if ((member != null) && (!String.IsNullOrEmpty(member.OverloadId)) && !isConversionOperator)
                            {
                                Target overloadTarget = targets[member.OverloadId];
                                if (overloadTarget != null)
                                {
                                    target   = overloadTarget;
                                    targetId = overloadTarget.Id;
                                }
                            }

                            // if individual conversion operator is found, always display parameters.
                            if (isConversionOperator && member != null && (!string.IsNullOrEmpty(member.OverloadId)))
                            {
                                options = options | DisplayOptions.ShowParameters;
                            }
                            else
                            {
                                options = options & ~DisplayOptions.ShowParameters;
                            }
                        }

                        // get stored link type
                        type = target.DefaultLinkType;

                        // if link type is local or index, determine which
                        if (type == LinkType2.LocalOrIndex)
                        {
                            if ((key != null) && targets.Contains(key) && (target.Container == targets[key].Container))
                            {
                                type = LinkType2.Local;
                            }
                            else
                            {
                                type = LinkType2.Index;
                            }
                        }
                    }

                    // links to this page are not live
                    if (targetId == key)
                    {
                        type = LinkType2.Self;
                    }
                    else if ((target != null) && (key != null) && targets.Contains(key) && (target.File == targets[key].File))
                    {
                        type = LinkType2.Self;
                    }

                    // get msdn or external endpoint, if needed
                    string externalUrl = null;
                    if (type == LinkType2.Msdn || type == LinkType2.External)
                    {
                        externalUrl = ResolveExternalUrl(targetId, type);
                        if (String.IsNullOrEmpty(externalUrl))
                        {
                            type = LinkType2.None;
                        }
                    }

                    // write opening link tag and target info
                    XmlWriter writer = linkNode.InsertAfter();
                    switch (type)
                    {
                    case LinkType2.None:
                        writer.WriteStartElement("span");
                        writer.WriteAttributeString("class", "nolink");
                        break;

                    case LinkType2.Self:
                        writer.WriteStartElement("span");
                        writer.WriteAttributeString("class", "selflink");
                        break;

                    case LinkType2.Local:
                        // format link with prefix and/or postfix
                        string href = String.Format(hrefFormat, target.File);

                        // make link relative, if we have a baseUrl
                        if (baseUrl != null)
                        {
                            href = BuildComponentUtilities.GetRelativePath(href, BuildComponentUtilities.EvalXPathExpr(document, baseUrl, "key", key));
                        }

                        writer.WriteStartElement("a");
                        writer.WriteAttributeString("href", href);
                        break;

                    case LinkType2.Index:
                        writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp");
                        writer.WriteAttributeString("keywords", targetId);
                        writer.WriteAttributeString("tabindex", "0");
                        break;

                    case LinkType2.Msdn:
                    case LinkType2.External:
                        writer.WriteStartElement("a");
                        writer.WriteAttributeString("href", externalUrl);
                        writer.WriteAttributeString("target", linkTarget);
                        break;
                    }

                    // write the link text
                    if (String.IsNullOrEmpty(link.DisplayTarget))
                    {
                        if (link.Contents == null)
                        {
                            if (target != null)
                            {
                                resolver.WriteTarget(target, options, writer);
                            }
                            else
                            {
                                //Console.WriteLine("Attemting to create reference");
                                Reference reference = TextReferenceUtilities.CreateReference(targetId);
                                //Console.WriteLine("Returned");
                                if (reference is InvalidReference)
                                {
                                    WriteMessage(MessageLevel.Warn, String.Format("Invalid reference link target '{0}'.", targetId));
                                }
                                resolver.WriteReference(reference, options, writer);
                            }
                        }
                        else
                        {
                            // write contents to writer
                            link.Contents.WriteSubtree(writer);
                        }
                    }
                    else
                    {
                        //Console.WriteLine("Display target = {0}", link.DisplayTarget);
                        if ((String.Compare(link.DisplayTarget, "content", true) == 0) && (link.Contents != null))
                        {
                            // Use the contents as an XML representation of the display target

                            //Console.WriteLine(link.Contents.NodeType);
                            Reference reference = XmlTargetCollectionUtilities.CreateReference(link.Contents);
                            //Console.WriteLine(reference.GetType().FullName);
                            resolver.WriteReference(reference, options, writer);
                        }
                        if ((String.Compare(link.DisplayTarget, "format", true) == 0) && (link.Contents != null))
                        {
                            // Use the contents as a format string for the display target

                            string format = link.Contents.OuterXml;
                            //Console.WriteLine("format = {0}", format);

                            string       input     = null;
                            StringWriter textStore = new StringWriter();
                            try {
                                XmlWriterSettings settings = new XmlWriterSettings();
                                settings.ConformanceLevel = ConformanceLevel.Fragment;

                                XmlWriter xmlStore = XmlWriter.Create(textStore, settings);
                                try {
                                    if (target != null)
                                    {
                                        resolver.WriteTarget(target, options, xmlStore);
                                    }
                                    else
                                    {
                                        Reference reference = TextReferenceUtilities.CreateReference(targetId);
                                        resolver.WriteReference(reference, options, xmlStore);
                                    }
                                } finally {
                                    xmlStore.Close();
                                }
                                input = textStore.ToString();
                            } finally {
                                textStore.Close();
                            }
                            //Console.WriteLine("input = {0}", input);

                            string output = String.Format(format, input);
                            //Console.WriteLine("output = {0}", output);

                            XmlDocumentFragment fragment = document.CreateDocumentFragment();
                            fragment.InnerXml = output;
                            fragment.WriteTo(writer);

                            //writer.WriteRaw(output);
                        }
                        else if ((String.Compare(link.DisplayTarget, "extension", true) == 0) && (link.Contents != null))
                        {
                            Reference extMethodReference = XmlTargetCollectionUtilities.CreateExtensionMethodReference(link.Contents);
                            resolver.WriteReference(extMethodReference, options, writer);
                        }
                        else
                        {
                            // Use the display target value as a CER for the display target

                            TextReferenceUtilities.SetGenericContext(key);
                            Reference reference = TextReferenceUtilities.CreateReference(link.DisplayTarget);
                            //Console.WriteLine("Reference is {0}", reference.GetType().FullName);
                            resolver.WriteReference(reference, options, writer);
                        }
                    }

                    // write the closing link tag
                    writer.WriteEndElement();
                    writer.Close();
                }

                // delete the original tag
                linkNode.DeleteSelf();
            }
        }
        // instantiation logic

        public ResolveReferenceLinksComponent2(BuildAssembler assembler, XPathNavigator configuration)
            : base(assembler, configuration)
        {
            // base-url is an xpath expression applied against the current document to pick up the save location of the
            // document. If specified, local links will be made relative to the base-url.
            string baseUrlValue = configuration.GetAttribute("base-url", String.Empty);

            if (!String.IsNullOrEmpty(baseUrlValue))
            {
                baseUrl = XPathExpression.Compile(baseUrlValue);
            }

            // url-format is a string format that is used to format the value of local href attributes. The default is
            // "{0}.htm" for backwards compatibility.
            string hrefFormatValue = configuration.GetAttribute("href-format", String.Empty);

            if (!String.IsNullOrEmpty(hrefFormatValue))
            {
                hrefFormat = hrefFormatValue;
            }

            // the container XPath can be replaced; this is useful
            string containerValue = configuration.GetAttribute("container", String.Empty);

            if (!String.IsNullOrEmpty(containerValue))
            {
                XmlTargetCollectionUtilities.ContainerExpression = containerValue;
            }

            targets  = new TargetCollection();
            resolver = new LinkTextResolver(targets);

            XPathNodeIterator targets_nodes = configuration.Select("targets");

            foreach (XPathNavigator targets_node in targets_nodes)
            {
                // get target type
                string typeValue = targets_node.GetAttribute("type", String.Empty);
                if (String.IsNullOrEmpty(typeValue))
                {
                    WriteMessage(MessageLevel.Error, "Each targets element must have a type attribute that specifies which type of links to create.");
                }

                LinkType2 type = LinkType2.None;
                try {
                    type = (LinkType2)Enum.Parse(typeof(LinkType2), typeValue, true);
                    if ((type == LinkType2.Msdn) && (msdn == null))
                    {
                        WriteMessage(MessageLevel.Info, "Creating MSDN URL resolver.");
                        msdn = new MsdnResolver();
                    }
                } catch (ArgumentException) {
                    WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a supported reference link type.", typeValue));
                }

                // get base directory
                string baseValue = targets_node.GetAttribute("base", String.Empty);

                // get file pattern
                string filesValue = targets_node.GetAttribute("files", String.Empty);
                if (String.IsNullOrEmpty(filesValue))
                {
                    WriteMessage(MessageLevel.Error, "Each targets element must have a files attribute specifying which target files to load.");
                }

                // determine whether to search recursively
                bool   recurse      = false;
                string recurseValue = targets_node.GetAttribute("recurse", String.Empty);
                if (!String.IsNullOrEmpty(recurseValue))
                {
                    if (String.Compare(recurseValue, Boolean.TrueString, true) == 0)
                    {
                        recurse = true;
                    }
                    else if (String.Compare(recurseValue, Boolean.FalseString, true) == 0)
                    {
                        recurse = false;
                    }
                    else
                    {
                        WriteMessage(MessageLevel.Error, String.Format("On the targets element, recurse='{0}' is not an allowed value.", recurseValue));
                    }
                }

                // turn baseValue and filesValue into directoryPath and filePattern
                string fullPath;
                if (String.IsNullOrEmpty(baseValue))
                {
                    fullPath = filesValue;
                }
                else
                {
                    fullPath = Path.Combine(baseValue, filesValue);
                }
                fullPath = Environment.ExpandEnvironmentVariables(fullPath);
                string directoryPath = Path.GetDirectoryName(fullPath);
                if (String.IsNullOrEmpty(directoryPath))
                {
                    directoryPath = Environment.CurrentDirectory;
                }
                string filePattern = Path.GetFileName(fullPath);

                // verify that directory exists
                if (!Directory.Exists(directoryPath))
                {
                    WriteMessage(MessageLevel.Error, String.Format("The targets directory '{0}' does not exist.", directoryPath));
                }

                // add the specified targets from the directory
                WriteMessage(MessageLevel.Info, String.Format("Searching directory '{0}' for targets files of the form '{1}'.", directoryPath, filePattern));
                AddTargets(directoryPath, filePattern, recurse, type);
            }

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

            string locale_value = configuration.GetAttribute("locale", String.Empty);

            if (!String.IsNullOrEmpty(locale_value) && msdn != null)
            {
                msdn.Locale = locale_value;
            }

            string target_value = configuration.GetAttribute("linkTarget", String.Empty);

            if (!String.IsNullOrEmpty(target_value))
            {
                linkTarget = target_value;
            }
        }
 private void AddTargets (string file, LinkType2 type) {
     try {
         XPathDocument document = new XPathDocument(file);
         XmlTargetCollectionUtilities.AddTargets(targets, document.CreateNavigator(), type);
     } catch (XmlSchemaException e) {
         WriteMessage(MessageLevel.Error, String.Format("The reference targets file '{0}' is not valid. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
     } catch (XmlException e) {
         WriteMessage(MessageLevel.Error, String.Format("The reference targets file '{0}' is not well-formed XML. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
     } catch (IOException e) {
         WriteMessage(MessageLevel.Error, String.Format("An access error occured while opening the reference targets file '{0}'. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
     }
 }
 private void AddTargets (string directory, string filePattern, bool recurse, LinkType2 type) {
     string[] files = Directory.GetFiles(directory, filePattern);
     foreach (string file in files) {
         AddTargets(file, type);
     }
     if (recurse) {
         string[] subdirectories = Directory.GetDirectories(directory);
         foreach (string subdirectory in subdirectories) {
             AddTargets(subdirectory, filePattern, recurse, type);
         }
     }
 }