Beispiel #1
0
        protected LinkValidationResult VerifyLink(string docFilePath, string linkUrl, string docSetBasePath, out string relativeFileName)
        {
            relativeFileName = null;
            Uri parsedUri;
            var validUrl = Uri.TryCreate(linkUrl, UriKind.RelativeOrAbsolute, out parsedUri);

            FileInfo sourceFile = new FileInfo(docFilePath);

            if (validUrl)
            {
                if (parsedUri.IsAbsoluteUri && (parsedUri.Scheme == "http" || parsedUri.Scheme == "https"))
                {
                    // TODO: verify an external URL is valid by making a HEAD request
                    return(LinkValidationResult.ExternalSkipped);
                }
                else if (linkUrl.StartsWith("#"))
                {
                    string bookmarkName = linkUrl.Substring(1);
                    if (this.bookmarks.Contains(bookmarkName))
                    {
                        return(LinkValidationResult.Valid);
                    }
                    else
                    {
                        var suggestion = StringSuggestions.SuggestStringFromCollection(bookmarkName, this.bookmarks);
                        if (suggestion != null)
                        {
                            relativeFileName = "#" + suggestion;
                        }
                        return(LinkValidationResult.BookmarkMissing);
                    }
                }
                else
                {
                    return(this.VerifyRelativeLink(sourceFile, linkUrl, docSetBasePath, out relativeFileName));
                }
            }
            else
            {
                return(LinkValidationResult.UrlFormatInvalid);
            }
        }
Beispiel #2
0
        protected virtual LinkValidationResult VerifyRelativeLink(FileInfo sourceFile, string originalLinkUrl, string docSetBasePath, out string relativeFileName)
        {
            if (sourceFile == null)
            {
                throw new ArgumentNullException("sourceFile");
            }
            if (string.IsNullOrEmpty(originalLinkUrl))
            {
                throw new ArgumentNullException("linkUrl");
            }
            if (string.IsNullOrEmpty(docSetBasePath))
            {
                throw new ArgumentNullException("docSetBasePath");
            }


            if (originalLinkUrl.StartsWith("mailto:", StringComparison.OrdinalIgnoreCase))
            {
                // TODO: Verify that this is an actual email address
                relativeFileName = null;
                return(LinkValidationResult.Valid);
            }

            relativeFileName = null;
            var    rootPath       = sourceFile.DirectoryName;
            string bookmarkName   = null;
            var    workingLinkUrl = originalLinkUrl;

            if (workingLinkUrl.Contains("#"))
            {
                int indexOfHash = workingLinkUrl.IndexOf('#');
                bookmarkName   = workingLinkUrl.Substring(indexOfHash + 1);
                workingLinkUrl = workingLinkUrl.Substring(0, indexOfHash);
            }

            if (workingLinkUrl.StartsWith("/"))
            {
                // URL is relative to the base for the documentation
                rootPath       = docSetBasePath;
                workingLinkUrl = workingLinkUrl.Substring(1);
            }

            while (workingLinkUrl.StartsWith("../"))
            {
                var nextLevelParent = new DirectoryInfo(rootPath).Parent;
                if (null != nextLevelParent)
                {
                    rootPath       = nextLevelParent.FullName;
                    workingLinkUrl = workingLinkUrl.Substring(3);
                }
                else
                {
                    break;
                }
            }

            if (rootPath.Length < docSetBasePath.Length)
            {
                return(LinkValidationResult.ParentAboveDocSetPath);
            }

            try
            {
                workingLinkUrl = workingLinkUrl.Replace('/', Path.DirectorySeparatorChar);     // normalize the path syntax between local file system and web

                var      pathToFile = Path.Combine(rootPath, workingLinkUrl);
                FileInfo info       = new FileInfo(pathToFile);
                if (!info.Exists)
                {
                    if (info.Directory.Exists)
                    {
                        var candidateFiles = from f in info.Directory.GetFiles() select f.Name;
                        relativeFileName = StringSuggestions.SuggestStringFromCollection(info.Name, candidateFiles);
                    }
                    return(LinkValidationResult.FileNotFound);
                }

                relativeFileName = this.Parent.RelativePathToFile(info.FullName, urlStyle: true);

                if (bookmarkName != null)
                {
                    // See if that bookmark exists in the target document, assuming we know about it
                    var otherDocFile = this.Parent.LookupFileForPath(relativeFileName);
                    if (otherDocFile == null)
                    {
                        return(LinkValidationResult.BookmarkSkippedDocFileNotFound);
                    }
                    else if (!otherDocFile.bookmarks.Contains(bookmarkName))
                    {
                        var suggestion = StringSuggestions.SuggestStringFromCollection(bookmarkName, otherDocFile.bookmarks);
                        if (null != suggestion)
                        {
                            relativeFileName = "#" + suggestion;
                        }
                        return(LinkValidationResult.BookmarkMissing);
                    }
                }
                return(LinkValidationResult.Valid);
            }
            catch (Exception)
            {
                return(LinkValidationResult.UrlFormatInvalid);
            }
        }