コード例 #1
0
 private void AddDatabaseTargets(string file, ReferenceLinkType type)
 {
     try
     {
         XPathDocument document = new XPathDocument(file);
         // This will only load into the memory...
         TargetCollectionXmlUtilities.AddTargets(_msdnStorage, 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 occurred while opening the reference targets file '{0}'. The error message is: {1}",
                          file, BuildComponentUtilities.GetExceptionMessage(e)));
     }
 }
コード例 #2
0
        private void AddTargets(string file, ReferenceLinkType type)
        {
            XPathDocument document = new XPathDocument(file);

            // This will only load into the memory...
            TargetCollectionXmlUtilities.AddTargets(_storage,
                                                    document.CreateNavigator(), type);
        }
コード例 #3
0
        public TargetCollections(MemoryTargetStorage local, DatabaseTargetStorage msdn,
                                 ReferenceLinkType localLink, ReferenceLinkType msdnLink)
        {
            _localLink = localLink;
            _msdnLink  = msdnLink;

            _localStorage = local;
            _msdnStorage  = msdn;
        }
コード例 #4
0
ファイル: Target.cs プロジェクト: paulushub/SandAssists
        protected virtual void OnReadXml(XmlReader reader)
        {
            // This reads only the target node...
            if (!String.Equals(reader.Name, "Target",
                               StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            id        = reader.GetAttribute("id");
            container = reader.GetAttribute("container");
            file      = reader.GetAttribute("file");

            string typeText = reader.GetAttribute("type");

            if (!String.IsNullOrEmpty(typeText))
            {
                switch (typeText.ToLower())
                {
                case "none":
                    type = ReferenceLinkType.None;
                    break;

                case "self":
                    type = ReferenceLinkType.Self;
                    break;

                case "local":
                    type = ReferenceLinkType.Local;
                    break;

                case "index":
                    type = ReferenceLinkType.Index;
                    break;

                case "localorindex":
                    type = ReferenceLinkType.LocalOrIndex;
                    break;

                case "msdn":
                    type = ReferenceLinkType.Msdn;
                    break;

                case "id":
                    type = ReferenceLinkType.Id;
                    break;
                }
            }
        }
コード例 #5
0
        private static EnumerationTarget CreateEnumerationTarget(XPathNavigator api, ReferenceLinkType 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;
                        ReferenceTextUtilities.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;

            return(enumeration);
        }
コード例 #6
0
 private void AddTargets(string directory, string filePattern, bool recurse, ReferenceLinkType 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);
         }
     }
 }
コード例 #7
0
ファイル: TargetTypeDictionary.cs プロジェクト: zyj0021/SHFB
        /// <summary>
        /// This attempts to retrieve the item with the specified key, returning it along with the reference
        /// link type with which it is associated.
        /// </summary>
        /// <param name="key">The item key to look up</param>
        /// <param name="value">On return, this will contain the item value if found</param>
        /// <param name="linkType">On return, this will contain the link type of the item if found</param>
        /// <returns>True if the item was found, false if not</returns>
        public bool TryGetValue(string key, out Target value, out ReferenceLinkType linkType)
        {
            value    = null;
            linkType = ReferenceLinkType.None;

            foreach (var kp in targetDictionaries)
            {
                if (kp.Value.TryGetValue(key, out value))
                {
                    linkType = kp.Key;
                    return(true);
                }
            }

            return(false);
        }
コード例 #8
0
        // Target factory methods

        private static Target CreateTarget(XPathNavigator topic, ReferenceLinkType 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);
        }
コード例 #9
0
        private static Target CreateApiTarget(XPathNavigator api, ReferenceLinkType 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);
            }
        }
コード例 #10
0
        private void AddTargets(string directory, string filePattern, bool recurse, ReferenceLinkType type)
        {
            // add the specified targets from the directory
            WriteMessage(MessageLevel.Info, String.Format(
                             "Searching directory '{0}' for targets files of the form '{1}'.",
                             directory, filePattern));


            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);
                }
            }
        }
コード例 #11
0
        private static TypeTarget CreateTypeTarget(XPathNavigator api, ReferenceLinkType 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);
        }
コード例 #12
0
 public TargetCollections()
 {
     _localLink = ReferenceLinkType.None;
     _msdnLink  = ReferenceLinkType.None;
 }
コード例 #13
0
ファイル: TargetTypeDictionary.cs プロジェクト: zyj0021/SHFB
 /// <summary>
 /// Add a target type dictionary to the collection
 /// </summary>
 /// <param name="type">The reference link type to use for targets in the given dictionary</param>
 /// <param name="dictionary">The target dictionary to add</param>
 public void Add(ReferenceLinkType type, TargetDictionary dictionary)
 {
     // Dictionaries are stored in reverse order to allow entries from later dictionaries to override
     // one from earlier dictionaries
     targetDictionaries.Insert(0, new KeyValuePair <ReferenceLinkType, TargetDictionary>(type, dictionary));
 }
コード例 #14
0
        public TargetCollection GetCollection(XPathNavigator configuration,
                                              out ReferenceLinkType localLink, out ReferenceLinkType msdnLink)
        {
            localLink = ReferenceLinkType.None;
            msdnLink  = ReferenceLinkType.None;

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

            if (targetsNodes == null || targetsNodes.Count == 0)
            {
                return(new TargetCollections());
            }

            foreach (XPathNavigator targetsNode in targetsNodes)
            {
                // get target type
                string typeValue = targetsNode.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.");
                }

                ReferenceLinkType linkType = ReferenceLinkType.None;
                try
                {
                    linkType = (ReferenceLinkType)Enum.Parse(typeof(ReferenceLinkType), typeValue, true);
                }
                catch (ArgumentException)
                {
                    WriteMessage(MessageLevel.Error, String.Format(
                                     "'{0}' is not a supported reference link type.", typeValue));
                }

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

                // get file pattern
                string filesValue = targetsNode.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 = targetsNode.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);

                bool isSystem = false;

                // verify that directory exists
                if (!Directory.Exists(directoryPath))
                {
                    WriteMessage(MessageLevel.Error, String.Format(
                                     "The targets directory '{0}' does not exist.", directoryPath));
                }
                else
                {
                    if (directoryPath.EndsWith(@"Sandcastle\Data\Reflection",
                                               StringComparison.OrdinalIgnoreCase))
                    {
                        isSystem = true;
                        if (msdnLink == ReferenceLinkType.None)
                        {
                            msdnLink = linkType;
                        }
                    }
                    else
                    {
                        if (localLink == ReferenceLinkType.None)
                        {
                            localLink = linkType;
                        }
                    }
                }

                if (!_isDataLoaded)
                {
                    if (isSystem)
                    {
                        if (!_msdnStorage.Exists)
                        {
                            AddTargets(directoryPath, filePattern, recurse, linkType);
                        }
                    }
                    else
                    {
                        AddTargets(directoryPath, filePattern, recurse, linkType);
                    }
                }
            }

            if (!_isDataLoaded)
            {
                _isDataLoaded = true;
            }

            return(new TargetCollections(_localStorage, _msdnStorage, localLink, msdnLink));
        }
コード例 #15
0
 protected TargetStorage(ReferenceLinkType linkType)
 {
     _linkType = linkType;
 }
コード例 #16
0
        public TargetCollection GetCollection(XPathNavigator configuration,
                                              out ReferenceLinkType localLink, out ReferenceLinkType msdnLink)
        {
            localLink = ReferenceLinkType.None;
            msdnLink  = ReferenceLinkType.None;

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

            if (targetsNodes == null || targetsNodes.Count == 0)
            {
                return(new TargetCollections());
            }

            foreach (XPathNavigator targetsNode in targetsNodes)
            {
                // get target type
                string typeValue = targetsNode.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.");
                }

                ReferenceLinkType linkType = ReferenceLinkType.None;
                try
                {
                    linkType = (ReferenceLinkType)Enum.Parse(typeof(ReferenceLinkType), typeValue, true);
                }
                catch (ArgumentException)
                {
                    WriteMessage(MessageLevel.Error, String.Format(
                                     "'{0}' is not a supported reference link type.", typeValue));
                }

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

                // get file pattern
                string filesValue = targetsNode.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 = targetsNode.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);

                bool       isSystem   = false;
                DataSource dataSource = null;

                // Verify that directory exists...
                if (!Directory.Exists(directoryPath))
                {
                    WriteMessage(MessageLevel.Error, String.Format(
                                     "The targets directory '{0}' does not exist.", directoryPath));
                }
                else
                {
                    bool   systemIsFound = false;
                    string systemValue   = targetsNode.GetAttribute("system", String.Empty);
                    if (!String.IsNullOrEmpty(systemValue))
                    {
                        if (String.Compare(systemValue, Boolean.TrueString, true) == 0)
                        {
                            isSystem      = true;
                            systemIsFound = true;

                            if (msdnLink == ReferenceLinkType.None)
                            {
                                msdnLink = linkType;
                            }
                        }
                        else if (String.Compare(systemValue, Boolean.FalseString, true) == 0)
                        {
                            isSystem      = false;
                            systemIsFound = true;

                            if (localLink == ReferenceLinkType.None &&
                                linkType != ReferenceLinkType.Msdn)
                            {
                                localLink = linkType;
                            }
                        }
                        else
                        {
                            WriteMessage(MessageLevel.Error, String.Format(
                                             "On the targets element, system='{0}' is not an allowed value.", systemValue));
                        }
                    }

                    // Retrieve the data source, if any...
                    XPathNavigator nodeDataSource =
                        targetsNode.SelectSingleNode("source");
                    if (nodeDataSource != null)
                    {
                        dataSource = new DataSource(false, nodeDataSource);
                        if (dataSource.IsValid)
                        {
                            // Currently, database is supported for systems only...
                            if (!dataSource.IsSystem && !dataSource.IsDatabase)
                            {
                                dataSource = null;
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(systemValue))
                                {
                                    isSystem      = dataSource.IsSystem;
                                    systemIsFound = true;
                                }
                            }
                        }
                        else
                        {
                            dataSource = null;
                        }
                    }

                    if (String.IsNullOrEmpty(systemValue) && !systemIsFound)
                    {
                        // Try doing it generally...
                        if (directoryPath.IndexOf(@"Sandcastle\Data\Reflection",
                                                  StringComparison.OrdinalIgnoreCase) >= 0)
                        {
                            isSystem = true;
                            if (msdnLink == ReferenceLinkType.None)
                            {
                                msdnLink = linkType;
                            }
                        }
                        else
                        {
                            if (localLink == ReferenceLinkType.None &&
                                linkType != ReferenceLinkType.Msdn)
                            {
                                localLink = linkType;
                            }
                        }
                    }
                }

                // If the database is not yet loaded, we load all...
                if (!_isDataLoaded)
                {
                    if (isSystem || (dataSource != null && dataSource.IsSystem))
                    {
                        if (dataSource != null && dataSource.Exists)
                        {
                            if (_msdnStorage.IsInitialize)
                            {
                                DatabaseTargetStorageEx databaseStorage =
                                    new DatabaseTargetStorageEx(true, false,
                                                                dataSource.OutputDir);

                                _msdnStorage.AddStorage(databaseStorage);
                            }
                            else
                            {
                                _msdnStorage.Initialize(dataSource.OutputDir, false);
                            }
                        }
                        else
                        {
                            if (!_msdnStorage.Exists)
                            {
                                if (!_msdnStorage.IsInitialize)
                                {
                                    if (Directory.Exists(directoryPath))
                                    {
                                        _msdnStorage.Initialize(directoryPath, false);
                                    }
                                }

                                this.AddDatabaseTargets(directoryPath, filePattern,
                                                        recurse, linkType);
                            }
                        }
                    }
                    else
                    {
                        if (linkType == ReferenceLinkType.Msdn)
                        {
                            if (!_msdnStorage.IsInitialize)
                            {
                                if (Directory.Exists(directoryPath))
                                {
                                    _msdnStorage.Initialize(directoryPath, false);
                                }
                            }

                            this.AddDatabaseTargets(directoryPath, filePattern,
                                                    recurse, linkType);
                        }
                        else
                        {
                            this.AddTargets(directoryPath, filePattern,
                                            recurse, linkType);
                        }
                    }
                }
            }

            if (!_isDataLoaded)
            {
                _isDataLoaded = true;
            }

            return(new TargetCollections(_localStorage, _msdnStorage,
                                         localLink, msdnLink));
        }
コード例 #17
0
        // super factory method

        public static void AddTargets(TargetStorage storage, XPathNavigator topicsNode, ReferenceLinkType 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(storage);
                }
            }
        }
コード例 #18
0
        private void ProcessReferenceLink(XmlDocument document, string key)
        {
            XPathNodeIterator linkIterator = document.CreateNavigator().Select(
                referenceLinkExpression);

            if (linkIterator == null || linkIterator.Count == 0)
            {
                return;
            }

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

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

                if (link == null)
                {
                    this.WriteMessage(MessageLevel.Warn,
                                      "Invalid referenceLink element.");
#if DEBUG
                    this.WriteMessage(MessageLevel.Warn, linkNode.OuterXml);
#endif
                }
                else
                {
                    // determine target, link type, and display options
                    string targetId = link.Target;
                    ReferenceLinkDisplayOptions options = link.DisplayOptions;
                    ReferenceLinkType           type    = ReferenceLinkType.None;

                    Target target = _targets[targetId];
                    if (target == null)
                    {
                        if (_hasTopicLinks && _targetController[targetId] != null)
                        {
                            this.ProcessConceptualLink(linkNode, key);

                            // delete the original tag
                            linkNode.DeleteSelf();

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

                            TargetType targetType = target.TargetType;

                            MemberTarget member = null;
                            if (targetType == TargetType.Method)
                            {
                                MethodTarget method = (MethodTarget)target;
                                isConversionOperator = method.ConversionOperator;
                                member = method;  // a method is a member...
                            }
                            else if (targetType == TargetType.Member || targetType == TargetType.Constructor ||
                                     targetType == TargetType.Procedure || targetType == TargetType.Event ||
                                     targetType == TargetType.Property)
                            {
                                member = (MemberTarget)target;
                            }

                            // 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 | ReferenceLinkDisplayOptions.ShowParameters;
                            }
                            else
                            {
                                options = options & ~ReferenceLinkDisplayOptions.ShowParameters;
                            }
                        }

                        // get stored link type
                        type = _targets.RecentLinkTypeIsMsdn ?
                               _targets.RecentLinkType : target.LinkType;

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

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

                    // get msdn endpoint, if needed
                    string msdnUrl = null;
                    if (type == ReferenceLinkType.Msdn)
                    {
                        if ((_msdnResolver == null) || (_msdnResolver.IsDisabled))
                        {
                            // no msdn resolver
                        }
                        else
                        {
                            msdnUrl = _msdnResolver[targetId];
                            if (String.IsNullOrEmpty(msdnUrl))
                            {
                                WriteMessage(MessageLevel.Warn, String.Format(
                                                 "MSDN URL not found for target '{0}'.", targetId));
                            }
                        }

                        if (String.IsNullOrEmpty(msdnUrl))
                        {
                            type = ReferenceLinkType.None;
                        }
                    }

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

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

                    case ReferenceLinkType.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 ReferenceLinkType.Index:
                        writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp");
                        writer.WriteAttributeString("keywords", targetId);
                        writer.WriteAttributeString("tabindex", "0");
                        break;

                    case ReferenceLinkType.Msdn:
                        writer.WriteStartElement("a");
                        writer.WriteAttributeString("href", msdnUrl);
                        writer.WriteAttributeString("target", _linkTarget);
                        break;

                    case ReferenceLinkType.Id:
                        string xhelp = String.Format("ms-xhelp://?Id={0}", targetId);
                        xhelp = xhelp.Replace("#", "%23");
                        writer.WriteStartElement("a");
                        writer.WriteAttributeString("href", xhelp);
                        break;
                    }

                    // write the link text
                    if (String.IsNullOrEmpty(link.DisplayTarget))
                    {
                        if (link.Contents == null)
                        {
                            if (target != null)
                            {
                                _linkResolver.WriteTarget(target, options, writer);
                            }
                            else
                            {
                                Reference reference = ReferenceTextUtilities.CreateReference(targetId);

                                if (reference.ReferenceType == ReferenceType.Invalid)
                                {
                                    WriteMessage(MessageLevel.Warn, String.Format(
                                                     "Invalid reference link target '{0}'.", targetId));
                                }

                                _linkResolver.WriteReference(reference, options, writer);
                            }
                        }
                        else
                        {
                            // write contents to writer
                            link.Contents.WriteSubtree(writer);
                        }
                    }
                    else
                    {
                        if ((String.Compare(link.DisplayTarget, "content", true) == 0) && (link.Contents != null))
                        {
                            // Use the contents as an XML representation of the display target
                            Reference reference = TargetCollectionXmlUtilities.CreateReference(link.Contents);

                            _linkResolver.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;

                            string       input     = null;
                            StringWriter textStore = new StringWriter();
                            try
                            {
                                XmlWriter xmlStore = XmlWriter.Create(textStore, _writerSettings);
                                try
                                {
                                    if (target != null)
                                    {
                                        _linkResolver.WriteTarget(target, options, xmlStore);
                                    }
                                    else
                                    {
                                        Reference reference = ReferenceTextUtilities.CreateReference(targetId);
                                        _linkResolver.WriteReference(reference, options, xmlStore);
                                    }
                                }
                                finally
                                {
                                    xmlStore.Close();
                                }
                                input = textStore.ToString();
                            }
                            finally
                            {
                                textStore.Close();
                            }

                            string output = String.Format(format, input);

                            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 = TargetCollectionXmlUtilities.CreateExtensionMethodReference(link.Contents);
                            _linkResolver.WriteReference(extMethodReference, options, writer);
                        }
                        else
                        {
                            // Use the display target value as a CER for the display target

                            ReferenceTextUtilities.SetGenericContext(key);
                            Reference reference = ReferenceTextUtilities.CreateReference(link.DisplayTarget);

                            _linkResolver.WriteReference(reference, options, writer);
                        }
                    }

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

                // delete the original tag
                linkNode.DeleteSelf();
            }
        }
コード例 #19
0
        /// <inheritdoc />
        public override void Apply(XmlDocument document, string key)
        {
            Target target = null, keyTarget;
            string msdnUrl = null;

            foreach (XPathNavigator linkNode in document.CreateNavigator().Select(referenceLinkExpression).ToArray())
            {
                // Extract link information
                ReferenceLinkInfo link = new ReferenceLinkInfo(linkNode);

                // Determine target, link type, and display options
                string            targetId = link.Target;
                DisplayOptions    options  = link.DisplayOptions;
                ReferenceLinkType type     = ReferenceLinkType.None;

                if (String.IsNullOrWhiteSpace(targetId))
                {
                    this.WriteMessage(key, MessageLevel.Warn, "The target attribute is missing or has no " +
                                      "value.  You have most likely omitted a cref attribute or left it blank on an XML " +
                                      "comments element such as see, seealso, or exception.");
                    continue;
                }

                bool targetFound = targets.TryGetValue(targetId, out target, out type);

                // If it's an overload ID that wasn't found, it's possible that the overloads got excluded.
                // As such, see if we can find a match for a method using the same ID regardless of any
                // parameters.
                if (!targetFound && targetId.StartsWith("Overload:", StringComparison.Ordinal) ||
                    targetId.StartsWith("O:", StringComparison.Ordinal))
                {
                    string methodTargetId = "M:" + targetId.Substring(targetId.IndexOf(':') + 1);
                    methodTargetId = targets.Keys.FirstOrDefault(k => k.StartsWith(methodTargetId));

                    if (methodTargetId != null)
                    {
                        targetId    = methodTargetId;
                        targetFound = targets.TryGetValue(targetId, out target, out type);
                        options    |= DisplayOptions.ShowParameters;

                        // Don't use the content as it may not be appropriate for the method.  The default is
                        // "{0} Overload" which no longer applies.  Instead we'll show the method name and
                        // its parameters.
                        if (link.DisplayTarget.Equals("format", StringComparison.OrdinalIgnoreCase))
                        {
                            link.DisplayTarget = null;
                            link.Contents      = null;
                        }
                    }
                }

                // If not found and it starts with "System." or "Microsoft." we'll go with the assumption that
                // it's part of a Microsoft class library that is not part of the core framework but does have
                // documentation available on MSDN.  Worst case it doesn't and we get an unresolved link warning
                // instead of an unknown reference target warning.
                if (!targetFound && ((targetId.Length > 9 && targetId.Substring(2).StartsWith("System.",
                                                                                              StringComparison.Ordinal)) || (targetId.Length > 12 && targetId.Substring(2).StartsWith(
                                                                                                                                 "Microsoft.", StringComparison.Ordinal))))
                {
                    // Use the same link type as a core framework class
                    targetFound = targets.TryGetValue("T:System.Object", out target, out type);

                    // We don't have a target in this case so links to overloads pages won't work.  Also note
                    // that the link text will be generated from the ID which shouldn't make much of a difference
                    // in most cases.  If either case is an issue, the Additional Reference Links SHFB plug-in
                    // can be used to generate valid link target data.
                    target = null;
                }

                if (!targetFound)
                {
                    // If not being rendered as a link, don't report a warning
                    if (link.RenderAsLink && targetId != key)
                    {
                        this.WriteMessage(key, MessageLevel.Warn, "Unknown reference link target '{0}'.", targetId);
                    }

                    // !EFW - Turn off the Show Parameters option for unresolved elements except methods.  If
                    // not, it outputs an empty "()" after the member name which looks odd.
                    if (targetId[0] != 'M')
                    {
                        options &= ~DisplayOptions.ShowParameters;
                    }
                }
                else
                {
                    // If overload is preferred and found, change targetId and make link options hide parameters
                    if (link.PreferOverload && target != null)
                    {
                        bool isConversionOperator = false;

                        MethodTarget method = target as MethodTarget;

                        if (method != null)
                        {
                            isConversionOperator = method.IsConversionOperator;
                        }

                        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;
                        }
                    }
                }

                // Suppress the link if so requested.  Links to this page are not live.
                if (!link.RenderAsLink)
                {
                    type = ReferenceLinkType.None;
                }
                else
                if (targetId == key)
                {
                    type = ReferenceLinkType.Self;
                }
                else
                if (target != null && targets.TryGetValue(key, out keyTarget) && target.File == keyTarget.File)
                {
                    type = ReferenceLinkType.Self;
                }

                // !EFW - Redirect enumeration fields to the containing enumerated type so that we
                // get a valid link target.  Enum fields don't have a topic to themselves.
                if (type != ReferenceLinkType.None && type != ReferenceLinkType.Self && type != ReferenceLinkType.Local &&
                    targetId.StartsWith("F:", StringComparison.OrdinalIgnoreCase))
                {
                    MemberTarget member = target as MemberTarget;

                    if (member != null)
                    {
                        SimpleTypeReference typeRef = member.ContainingType as SimpleTypeReference;

                        if (typeRef != null && targets[typeRef.Id] is EnumerationTarget)
                        {
                            targetId = typeRef.Id;
                        }
                    }
                }

                // Get MSDN endpoint if needed
                if (type == ReferenceLinkType.Msdn)
                {
                    if (msdnResolver != null && !msdnResolver.IsDisabled)
                    {
                        msdnUrl = msdnResolver.GetMsdnUrl(targetId);

                        if (String.IsNullOrEmpty(msdnUrl))
                        {
                            // If the web service failed, report the reason
                            if (msdnResolver.IsDisabled)
                            {
                                this.WriteMessage(key, MessageLevel.Warn, "MSDN web service failed.  No " +
                                                  "further look ups will be performed for this build.\r\nReason: {0}",
                                                  msdnResolver.DisabledReason);
                            }
                            else
                            {
                                this.WriteMessage(key, MessageLevel.Warn, "MSDN URL not found for target '{0}'.",
                                                  targetId);
                            }

                            type = ReferenceLinkType.None;
                        }
                    }
                    else
                    {
                        type = ReferenceLinkType.None;
                    }
                }

                // Write opening link tag and target info
                XmlWriter writer = linkNode.InsertAfter();

                switch (type)
                {
                case ReferenceLinkType.None:
                    writer.WriteStartElement("span");

                    // If the link was intentionally suppressed, write it out as an identifier (i.e. links
                    // in the syntax section).
                    if (link.RenderAsLink)
                    {
                        writer.WriteAttributeString("class", "nolink");
                    }
                    else
                    {
                        writer.WriteAttributeString("class", "identifier");
                    }
                    break;

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

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

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

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

                case ReferenceLinkType.Msdn:
                    writer.WriteStartElement("a");
                    writer.WriteAttributeString("href", msdnUrl);
                    writer.WriteAttributeString("target", linkTarget);
                    break;

                case ReferenceLinkType.Id:
                    writer.WriteStartElement("a");
                    writer.WriteAttributeString("href", ("ms-xhelp:///?Id=" + targetId).Replace("#", "%23"));
                    break;
                }

                // Write the link text
                if (String.IsNullOrEmpty(link.DisplayTarget))
                {
                    if (link.Contents == null)
                    {
                        if (target != null)
                        {
                            resolver.WriteTarget(target, options, writer);
                        }
                        else
                        {
                            Reference reference = TextReferenceUtilities.CreateReference(targetId);

                            if (reference is InvalidReference)
                            {
                                this.WriteMessage(key, MessageLevel.Warn,
                                                  "Invalid reference link target '{0}'.", targetId);
                            }

                            resolver.WriteReference(reference, options, writer);
                        }
                    }
                    else
                    {
                        do
                        {
                            link.Contents.WriteSubtree(writer);
                        } while(link.Contents.MoveToNext());
                    }
                }
                else
                {
                    if (link.DisplayTarget.Equals("content", StringComparison.OrdinalIgnoreCase) &&
                        link.Contents != null)
                    {
                        // Use the contents as an XML representation of the display target
                        Reference reference = XmlTargetDictionaryUtilities.CreateReference(link.Contents);
                        resolver.WriteReference(reference, options, writer);
                    }

                    if (link.DisplayTarget.Equals("format", StringComparison.OrdinalIgnoreCase) &&
                        link.Contents != null)
                    {
                        // Use the contents as a format string for the display target
                        string format = link.Contents.OuterXml;
                        string input  = null;

                        using (StringWriter textStore = new StringWriter(CultureInfo.InvariantCulture))
                        {
                            XmlWriterSettings settings = new XmlWriterSettings();
                            settings.ConformanceLevel = ConformanceLevel.Fragment;

                            using (XmlWriter xmlStore = XmlWriter.Create(textStore, settings))
                            {
                                if (target != null)
                                {
                                    resolver.WriteTarget(target, options, xmlStore);
                                }
                                else
                                {
                                    Reference reference = TextReferenceUtilities.CreateReference(targetId);
                                    resolver.WriteReference(reference, options, xmlStore);
                                }
                            }

                            input = textStore.ToString();
                        }

                        string output = String.Format(CultureInfo.InvariantCulture, format, input);

                        XmlDocumentFragment fragment = document.CreateDocumentFragment();
                        fragment.InnerXml = output;
                        fragment.WriteTo(writer);
                    }
                    else if (link.DisplayTarget.Equals("extension", StringComparison.OrdinalIgnoreCase) &&
                             link.Contents != null)
                    {
                        Reference extMethodReference = XmlTargetDictionaryUtilities.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);
                        resolver.WriteReference(reference, options, writer);
                    }
                }

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

                // Delete the original tag
                linkNode.DeleteSelf();
            }
        }
コード例 #20
0
        private void ParseReferenceConfiguration(XPathNavigator configuration)
        {
            TargetController controller = TargetController.Controller;

            Debug.Assert(controller != null);
            controller.Initialize(this);

            ReferenceLinkType localLink = ReferenceLinkType.None;
            ReferenceLinkType msdnLink  = ReferenceLinkType.None;

            _targets = controller.GetCollection(configuration, out localLink, out msdnLink);
            Debug.Assert(_targets != null);
            _linkResolver = new ReferenceLinkTextResolver(_targets);

            if (msdnLink == ReferenceLinkType.Msdn && _msdnResolver == null)
            {
                XPathNavigator linkResolverNode =
                    configuration.SelectSingleNode("linkResolver");

                if (linkResolverNode != null)
                {
                    WriteMessage(MessageLevel.Info, "Creating cached MSDN URL resolver.");

                    _msdnResolver = TargetMsdnController.GetController(linkResolverNode);
                }
                else
                {
                    WriteMessage(MessageLevel.Info, "Creating MSDN URL resolver.");

                    _msdnResolver = TargetMsdnController.GetController();
                }
            }

            XPathNavigator optionsNode =
                configuration.SelectSingleNode("options");

            if (optionsNode == null)
            {
                optionsNode = 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 = optionsNode.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 = optionsNode.GetAttribute("href-format", String.Empty);

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

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

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

            string localeValue = optionsNode.GetAttribute("locale", String.Empty);

            if (!String.IsNullOrEmpty(localeValue) && _msdnResolver != null)
            {
                _msdnResolver.Locale = localeValue;
            }

            string versionValue = optionsNode.GetAttribute("version", String.Empty);

            if (!String.IsNullOrEmpty(versionValue) && _msdnResolver != null)
            {
                _msdnResolver.Version = versionValue;
            }

            string mvcVersionValue = optionsNode.GetAttribute("mvcVersion", String.Empty);

            if (!String.IsNullOrEmpty(mvcVersionValue) && _msdnResolver != null)
            {
                _msdnResolver.MvcVersion = mvcVersionValue;
            }

            string targetValue = optionsNode.GetAttribute("linkTarget", String.Empty);

            if (!String.IsNullOrEmpty(targetValue))
            {
                _linkTarget = targetValue;
            }

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

            _writerSettings = new XmlWriterSettings();
            _writerSettings.ConformanceLevel = ConformanceLevel.Fragment;

            _hasMsdnStorage = controller.HasMsdnStorage;
        }