public string ToPublicUrl(string internalMediaUrl, UrlSpace urlSpace)
        {
            int openBracketIndex = internalMediaUrl.IndexOf("(", StringComparison.Ordinal);
            if (openBracketIndex < 0)
            {
                return null;
            }

            int closingBracketOffset = internalMediaUrl.IndexOf(")", openBracketIndex + 1, StringComparison.Ordinal);
            if (closingBracketOffset < 0)
            {
                return null;
            }

            Guid mediaId;

            string mediaStore;
            string mediaIdStr = internalMediaUrl.Substring(openBracketIndex + 1, closingBracketOffset - openBracketIndex - 1);

            int semicolonOffset = mediaIdStr.IndexOf(":", StringComparison.Ordinal);
            if (semicolonOffset > 0)
            {
                mediaStore = mediaIdStr.Substring(0, semicolonOffset);
                mediaIdStr = mediaIdStr.Substring(semicolonOffset + 1);
            }
            else
            {
                mediaStore = DefaultMediaStore;
            }

            if (!Guid.TryParse(mediaIdStr, out mediaId))
            {
                return null;
            }

            UrlBuilder parsedOldUrl;

            try
            {
                parsedOldUrl = new UrlBuilder(internalMediaUrl);
            }
            catch
            {
                Log.LogWarning(LogTitle, "Failed to parse url '{0}'".FormatWith(internalMediaUrl));
                return null;
            }

            NameValueCollection queryParams = parsedOldUrl.GetQueryParameters();

            return MediaUrls.BuildUrl(
                new MediaUrlData
                {
                    MediaId = mediaId,
                    MediaStore = mediaStore,
                    QueryParameters = queryParams
                },
                UrlKind.Public);
        }
        public string ToPublicUrl(string internalDataUrl, UrlSpace urlSpace)
        {
            object keyValue = ExtractKeyValue(internalDataUrl);
            if(keyValue == null) return null;

            var data = DataFacade.TryGetDataByUniqueKey(_type, keyValue);
            if(data == null) return null;

            var pageUrlData = DataUrls.TryGetPageUrlData(data.ToDataReference());
            return pageUrlData != null ? PageUrls.BuildUrl(pageUrlData, UrlKind.Public, urlSpace) : null;
        }
示例#3
0
        /// <summary>
        /// Parses the URL.
        /// </summary>
        /// <param name="absoluteUrl">The absolute URL.</param>
        /// <param name="urlKind">Kind of the URL.</param>
        /// <returns></returns>
        public static PageUrlData ParseUrl(string absoluteUrl, out UrlKind urlKind)
        {
            if (absoluteUrl.StartsWith("http") && absoluteUrl.Contains("://"))
            {
                return(UrlProvider.ParseUrl(absoluteUrl, out urlKind));
            }

            var    context  = HttpContext.Current;
            string hostname = context != null ? context.Request.Url.Host : null;
            var    urlSpace = new UrlSpace(hostname, absoluteUrl);

            return(UrlProvider.ParseUrl(absoluteUrl, urlSpace, out urlKind));
        }
示例#4
0
        /// <summary>
        /// Parses the URL.
        /// </summary>
        /// <param name="absoluteUrl">The absolute URL.</param>
        /// <param name="urlKind">Kind of the URL.</param>
        /// <returns></returns>
        public static PageUrlData ParseUrl(string absoluteUrl, out UrlKind urlKind)
        {
            if (absoluteUrl.StartsWith("http") && absoluteUrl.Contains("://"))
            {
                return UrlProvider.ParseUrl(absoluteUrl, out urlKind);
            }

            var context = HttpContext.Current;
            string hostname = context != null ? context.Request.Url.Host : null;
            var urlSpace = new UrlSpace(hostname, absoluteUrl);

            return UrlProvider.ParseUrl(absoluteUrl, urlSpace, out urlKind);
        }
        private static string GetPagePreviewUrl(PageUrlData pageUrlData)
        {
            var httpContext = HttpContext.Current;

            var urlSpace = new UrlSpace();
            if (HostnameBindingsFacade.GetBindingForCurrentRequest() != null
                || HostnameBindingsFacade.GetAliasBinding(httpContext) != null)
            {
                urlSpace.ForceRelativeUrls = true;
            }

            return PageUrls.BuildUrl(pageUrlData, UrlKind.Public, urlSpace)
                      ?? PageUrls.BuildUrl(pageUrlData, UrlKind.Renderer, urlSpace);
        }
示例#6
0
        public PageUrlBuilder(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace)
        {
            _publicationScope = publicationScope;
            _localizationScope = localizationScope;

            var localeMappedName = DataLocalizationFacade.GetUrlMappingName(localizationScope) ?? string.Empty;
            _forceRelativeUrls = urlSpace != null && urlSpace.ForceRelativeUrls;

            if (!_forceRelativeUrls
                && urlSpace != null
                && urlSpace.Hostname != null)
            {
                List<IHostnameBinding> hostnameBindings = DataFacade.GetData<IHostnameBinding>().ToList();

                _hostnameBinding = hostnameBindings.FirstOrDefault(b => b.Hostname == urlSpace.Hostname);

                bool knownHostname = _hostnameBinding != null;

                if(knownHostname)
                {
                    _hostnameBindings = hostnameBindings;

                    _urlSpace = urlSpace;
                }
            }

            if(_hostnameBinding != null
                && !_hostnameBinding.IncludeCultureInUrl
                && _hostnameBinding.Culture == localizationScope.Name)
            {
                _friendlyUrlPrefix = UrlUtils.PublicRootPath;

                if (!localeMappedName.IsNullOrEmpty())
                {
                    _friendlyUrlPrefixWithLanguageCode = UrlUtils.PublicRootPath + "/" + localeMappedName;
                }
            }
            else
            {
                _friendlyUrlPrefix = UrlUtils.PublicRootPath + (localeMappedName.IsNullOrEmpty() ? string.Empty : "/" + localeMappedName);
            }

            UrlSuffix = DataFacade.GetData<IUrlConfiguration>().Select(c => c.PageUrlSuffix).FirstOrDefault() ?? string.Empty;
        }
示例#7
0
        /// <summary>
        /// Converts internal urls to public ones in a given html fragment
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        public static void ConvertInternalUrlsToPublic(XDocument document)
        {
            Verify.ArgumentNotNull(document, nameof(document));

            var convertersMap = GetConvertersMap(ResolvePrefix);

            if (!convertersMap.Any())
            {
                return;
            }

            var urlSpace = new UrlSpace();

            var convertionCache = new Dictionary <string, string>();

            foreach (var element in document.Descendants())
            {
                foreach (var attr in element.Attributes().Where(a => IsLinkAttribute(a.Name)))
                {
                    string link = attr.Value;
                    if (convertionCache.TryGetValue(link, out string cachedLink))
                    {
                        attr.Value = cachedLink;
                        continue;
                    }

                    foreach (var prefix in convertersMap.Keys)
                    {
                        if (link.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                        {
                            var converter = convertersMap[prefix];
                            var newLink   = converter.ToPublicUrl(link, urlSpace);
                            if (newLink != null && newLink != link)
                            {
                                convertionCache[link] = newLink;
                                attr.Value            = newLink;
                                break;
                            }
                        }
                    }
                }
            }
        }
        public string ToPublicUrl(string internalPageUrl, UrlSpace urlSpace)
        {
            PageUrlData pageUrlData;
            string anchor;

            try
            {
                anchor = new UrlBuilder(internalPageUrl).Anchor;
                pageUrlData = PageUrls.UrlProvider.ParseInternalUrl(internalPageUrl);
            }
            catch
            {
                Log.LogWarning(LogTitle, "Failed to parse url '{0}'", internalPageUrl);
                return null;
            }

            if (pageUrlData == null)
            {
                return null;
            }

            // While viewing pages in "unpublished" scope, all the links should also be in the same scope
            if (DataScopeManager.CurrentDataScope == DataScopeIdentifier.Administrated)
            {
                pageUrlData.PublicationScope = PublicationScope.Unpublished;
            }

            string publicPageUrl = PageUrls.BuildUrl(pageUrlData, UrlKind.Public, urlSpace);
            if (publicPageUrl == null)
            {
                // We have this situation if page does not exist
                return null;
            }

            if (!anchor.IsNullOrEmpty())
            {
                publicPageUrl += "#" + anchor;
            }

            return publicPageUrl;
        }
示例#9
0
        /// <summary>
        /// Tries to convert an internal url to a public one, returns the original value if failed.
        /// </summary>
        /// <param name="internalUrl">The internal url.</param>
        /// <param name="urlSpace">The url space.</param>
        /// <returns></returns>
        public static string TryConvertInternalUrlToPublic(string internalUrl, UrlSpace urlSpace = null)
        {
            if (!internalUrl.StartsWith("~/"))
            {
                return(internalUrl);
            }

            string urlWithoutTilde = internalUrl.Substring(2);

            foreach (var converter in _converters)
            {
                foreach (var prefix in converter.AcceptedUrlPrefixes.Reverse())
                {
                    if (urlWithoutTilde.StartsWith(prefix, StringComparison.Ordinal))
                    {
                        return(converter.ToPublicUrl(internalUrl, urlSpace ?? new UrlSpace()) ?? internalUrl);
                    }
                }
            }

            return(internalUrl);
        }
示例#10
0
        public string BuildUrl(PageUrlData pageUrlData, UrlKind urlKind, UrlSpace urlSpace)
        {
            Verify.ArgumentCondition(urlKind != UrlKind.Undefined, "urlKind", "Url kind is undefined");

            /*var page = pageUrlData.Data;
            Verify.ArgumentCondition(page != null, "urlData", "Failed to get page from UrlData<IPage>");*/

            if (urlKind == UrlKind.Public)
            {
                return BuildPublicUrl(pageUrlData, urlSpace);
            }

            if (urlKind == UrlKind.Renderer)
            {
                return BuildRenderUrl(pageUrlData);
            }

            if (urlKind == UrlKind.Internal)
            {
                return BuildInternalUrl(pageUrlData);
            }

            throw new NotImplementedException("Only 'Public' and 'Internal' url types are supported.");
        }
示例#11
0
        public PageUrlData ParseUrl(string relativeUrl, UrlSpace urlSpace, out UrlKind urlKind)
        {
            if (IsInternalUrl(relativeUrl))
            {
                return ParseInternalUrl(relativeUrl, out urlKind);
            }

            var urlBuilder = new UrlBuilder(relativeUrl);

            // Structure of a public url:
            // http://<hostname>[/ApplicationVirtualPath]{/languageCode}[/Path to a page][/c1mode(unpublished)][/c1mode(relative)][UrlSuffix]{/PathInfo}
           

            string filePathAndPathInfo = HttpUtility.UrlDecode(urlBuilder.FullPath);
            filePathAndPathInfo = RemoveUrlMarkers(filePathAndPathInfo, urlSpace);

            string pathWithoutLanguageCode;

            IHostnameBinding hostnameBinding = urlSpace.ForceRelativeUrls ? null : GetHostnameBindings().FirstOrDefault(b => b.Hostname == urlSpace.Hostname);

            CultureInfo locale = GetCultureInfo(filePathAndPathInfo, hostnameBinding, out pathWithoutLanguageCode);
            if (locale == null)
            {
                urlKind = UrlKind.Undefined;
                return null;
            }

            var publicationScope = PublicationScope.Published;

            if (filePathAndPathInfo.Contains(UrlMarker_Unpublished))
            {
                publicationScope = PublicationScope.Unpublished;

                pathWithoutLanguageCode = pathWithoutLanguageCode.Replace(UrlMarker_Unpublished, string.Empty);
                if (pathWithoutLanguageCode == string.Empty)
                {
                    pathWithoutLanguageCode = "/";
                }
            }

            using (new DataScope(publicationScope, locale))
            {
                bool isObsolete = false;
                string pathToResolve = pathWithoutLanguageCode;

                // Supporting obsolete "*.aspx" urls
                if (!string.Equals(UrlSuffix, ".aspx", StringComparison.OrdinalIgnoreCase) 
                    && (pathToResolve.Contains(".aspx/") || pathToResolve.EndsWith(".aspx")))
                {
                    pathToResolve = pathToResolve.Replace(".aspx", UrlSuffix);
                    isObsolete = true;
                }

                PageUrlData data = ParsePagePath(pathToResolve, publicationScope, locale, hostnameBinding);
                if (data != null)
                {
                    urlKind = !isObsolete ? UrlKind.Public : UrlKind.Redirect;
                    data.QueryParameters = urlBuilder.GetQueryParameters();
                    return data;
                }

                Guid friendlyUrlPageId = ParseFriendlyUrlPath(pathWithoutLanguageCode);
                if (friendlyUrlPageId != Guid.Empty)
                {
                    urlKind = UrlKind.Friendly;
                    return new PageUrlData(friendlyUrlPageId, publicationScope, locale) {QueryParameters = urlBuilder.GetQueryParameters()};
                }
            }

            urlKind = UrlKind.Undefined;
            return null;
        }
示例#12
0
        public PageUrlData ParseUrl(string absoluteUrl, out UrlKind urlKind)
        {
            Verify.ArgumentNotNullOrEmpty(absoluteUrl, "absoluteUrl");

            // Converting links 
            // "http://localhost" to "http://localhost/"
            // "http://localhost?..." to "http://localhost/?..."
            if((absoluteUrl.Count(c => c == '/') == 2) && absoluteUrl.Contains("//"))
            {
                int questionMarkIndex = absoluteUrl.IndexOf('?');
                if(questionMarkIndex > 0)
                {
                    absoluteUrl = absoluteUrl.Insert(questionMarkIndex, "/");
                }
                else
                {
                    absoluteUrl += "/";
                }
            }

            Uri uri = new Uri(absoluteUrl);

            string hostname = uri.DnsSafeHost;
            if(!IsKnownHostname(hostname))
            {
                urlKind = UrlKind.Undefined;
                return null;
            }

            string serverUrl = new UrlBuilder(absoluteUrl).ServerUrl;
            string relativeUrl = absoluteUrl.Substring(serverUrl.Length - 1);

            var urlSpace = new UrlSpace(hostname, relativeUrl);

            return ParseUrl(relativeUrl, urlSpace, out urlKind);
        }
示例#13
0
        /// <summary>
        /// Builds the URL.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="urlKind">Kind of the URL.</param>
        /// <param name="urlSpace">The URL space.</param>
        /// <returns></returns>
        public static string BuildUrl(IPage page, UrlKind urlKind = UrlKind.Public, UrlSpace urlSpace = null)
        {
            Verify.ArgumentNotNull(page, "page");

            return(BuildUrl(new PageUrlData(page), urlKind, urlSpace ?? new UrlSpace()));
        }
示例#14
0
        /// <summary>
        /// Builds the URL.
        /// </summary>
        /// <param name="pageUrlData">The page URL data.</param>
        /// <param name="urlKind">Kind of the URL.</param>
        /// <param name="urlSpace">The URL space.</param>
        /// <returns></returns>
        public static string BuildUrl(PageUrlData pageUrlData, UrlKind urlKind = UrlKind.Public, UrlSpace urlSpace = null)
        {
            Verify.ArgumentNotNull(pageUrlData, "pageUrlData");

            return(UrlProvider.BuildUrl(pageUrlData, urlKind, urlSpace ?? new UrlSpace()));
        }
示例#15
0
        private static void RenderPage(IPage page)
        {
            var context = HttpContext.Current;
            if (context == null)
            {
                return;
            }

            var urlSpace = new UrlSpace(context) { ForceRelativeUrls = true };
            var url = PageUrls.BuildUrl(page, UrlKind.Public, urlSpace)
                ?? PageUrls.BuildUrl(page, UrlKind.Renderer, urlSpace);

            if (string.IsNullOrEmpty(url))
            {
                return;
            }

            var requestUrl = context.Request.Url;
            string hostName = requestUrl.Host;

            if (!url.StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
            {
                string serverUrl = new UrlBuilder(requestUrl.ToString()).ServerUrl;

                url = UrlUtils.Combine(serverUrl, url);
            }

            string cookies = context.Request.Headers["Cookie"];

            string responseBody, errorMessage;
            var result = RenderPage(hostName, url, cookies, out responseBody, out errorMessage);

            // TODO: log errors if any
        }
示例#16
0
        /// <summary>
        /// Converts internal urls to public ones in a given html fragment
        /// </summary>
        /// <param name="html"></param>
        /// <param name="converters"></param>
        /// <returns></returns>
        internal static string ConvertInternalUrlsToPublic(string html, IEnumerable <IInternalUrlConverter> converters)
        {
            var convertersMap = GetConvertersMap(_ => _);

            if (!convertersMap.Any())
            {
                return(html);
            }

            // Urls, generated in UserControl-s may still have "~/" as a prefix
            foreach (var urlPrefix in convertersMap.Keys)
            {
                string rawUrlPrefix      = "~/" + urlPrefix;
                string resolvedUrlPrefix = ResolvePrefix(urlPrefix);

                html = UrlUtils.ReplaceUrlPrefix(html, rawUrlPrefix, resolvedUrlPrefix);
            }

            StringBuilder result = null;

            var urlsToConvert = new List <UrlToConvert> ();

            foreach (var pair in convertersMap)
            {
                string internalPrefix = ResolvePrefix(pair.Key);
                var    converter      = pair.Value;

                // Bracket encoding fix
                string prefixToSearch = internalPrefix;
                if (prefixToSearch.EndsWith("(", StringComparison.Ordinal))
                {
                    prefixToSearch = prefixToSearch.Substring(0, internalPrefix.Length - 1);
                }

                urlsToConvert.AddRange(UrlUtils.FindUrlsInHtml(html, prefixToSearch).Select(match =>
                                                                                            new UrlToConvert(match, internalPrefix, converter)));
            }

            // Sorting the offsets by descending, so we can replace urls in that order by not affecting offsets of not yet processed urls
            urlsToConvert.Sort((a, b) => - a.Match.Index.CompareTo(b.Match.Index));

            int lastReplacementIndex = int.MaxValue;

            var urlSpace = new UrlSpace();

            var measurements = new Dictionary <string, Measurement>();

            var convertionCache = new Dictionary <string, string>();

            foreach (var urlToConvert in urlsToConvert)
            {
                UrlUtils.UrlMatch urlMatch = urlToConvert.Match;
                if (urlMatch.Index == lastReplacementIndex)
                {
                    continue;
                }

                string internalUrlPrefix = urlToConvert.UrlPrefix;

                string internalUrl = urlMatch.Value;
                string publicUrl;

                if (!convertionCache.TryGetValue(internalUrl, out publicUrl))
                {
                    string decodedInternalUrl = internalUrl.Replace("%28", "(").Replace("%29", ")").Replace("&amp;", "&");

                    if (!decodedInternalUrl.StartsWith(internalUrlPrefix))
                    {
                        continue;
                    }

                    var converter = urlToConvert.Converter;
                    MeasureConvertionPerformance(measurements, converter, () =>
                    {
                        publicUrl = urlToConvert.Converter.ToPublicUrl(decodedInternalUrl, urlSpace);
                    });

                    if (publicUrl == null)
                    {
                        convertionCache.Add(internalUrl, null);
                        continue;
                    }

                    // Encoding xml attribute value
                    publicUrl = publicUrl.Replace("&", "&amp;");

                    convertionCache.Add(internalUrl, publicUrl);
                }
                else
                {
                    if (internalUrl == null)
                    {
                        continue;
                    }
                }

                if (result == null)
                {
                    result = new StringBuilder(html);
                }

                result.Remove(urlMatch.Index, urlMatch.Value.Length);
                result.Insert(urlMatch.Index, publicUrl);

                lastReplacementIndex = urlMatch.Index;
            }

            foreach (var measurement in measurements.Values)
            {
                Profiler.AddSubMeasurement(measurement);
            }

            return(result != null?result.ToString() : html);
        }
示例#17
0
        private string BuildPublicUrl(PageUrlData pageUrlData, UrlSpace urlSpace)
        {
            var cultureInfo = pageUrlData.LocalizationScope;
            var publicationScope = pageUrlData.PublicationScope;

            var pageUrlPath = new StringBuilder();

            using (new DataScope(publicationScope, cultureInfo))
            {
                if (!BuildPageUrlPath(pageUrlData.PageId, cultureInfo, urlSpace, pageUrlPath))
                {
                    return null;
                }
            }

            if (publicationScope == PublicationScope.Unpublished)
            {
                AppendUrlPart(pageUrlPath, UrlMarker_Unpublished);
            }

            if (urlSpace.ForceRelativeUrls)
            {
                AppendUrlPart(pageUrlPath, UrlMarker_RelativeUrl);
            }

            if (!string.IsNullOrEmpty(UrlSuffix) 
                && pageUrlPath[pageUrlPath.Length - 1] != '/')
            {
                pageUrlPath.Append(UrlSuffix);
            }

            if (!string.IsNullOrEmpty(pageUrlData.PathInfo))
            {
                AppendPathInfo(pageUrlPath, pageUrlData.PathInfo);
            }


            string url = pageUrlPath.ToString();

            if (pageUrlData.QueryParameters != null)
            {
                var urlWithQuery = new UrlBuilder(url);
                urlWithQuery.AddQueryParameters(pageUrlData.QueryParameters);

                return urlWithQuery;
            }

            return url;
        }
示例#18
0
 public static IPageUrlBuilder GetPageUrlBuilder(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace)
 {
     return GetMap(publicationScope, localizationScope, urlSpace).PageUrlBuilder;
 }
示例#19
0
        private static Map BuildMap(UrlSpace urlSpace)
        {
            using (DebugLoggingScope.MethodInfoScope)
            {
                var publicationScope = DataScopeManager.CurrentDataScope.ToPublicationScope();
                var localizationScope = LocalizationScopeManager.CurrentLocalizationScope;

                Log.LogVerbose(LogTitle, string.Format("Building page structure in the publication scope '{0}' with the localization scope '{1}'", publicationScope, localizationScope));

                var urlToIdLookup = new Dictionary<string, Guid>();
                var idToUrlLookup = new Dictionary<Guid, string>();

                var pagesData = new SitemapBuildingData();

                var pageToToChildElementsTable = new Hashtable<Guid, List<PageTreeInfo>>();
                foreach (IPage page in pagesData.Pages)
                {
                    IPageStructure pageStructure = pagesData.StructureById[page.Id];

                    if (pageStructure == null)
                    {
                        Log.LogWarning(LogTitle, "Failed to find PageStructure data. Page ID is '{0}'".FormatWith(page.Id));
                        continue;
                    }

                    int localOrdering = pageStructure.LocalOrdering;

                    var pageElement = new XElement(ElementNames.Page,
                         new XAttribute(AttributeNames.Id, page.Id),
                         new XAttribute(AttributeNames.Title, page.Title),
                         (string.IsNullOrEmpty(page.MenuTitle) ? null : new XAttribute(AttributeNames.MenuTitle, page.MenuTitle)),
                         new XAttribute(AttributeNames.UrlTitle, page.UrlTitle),
                         new XAttribute(AttributeNames.Description, page.Description ?? string.Empty),
                         new XAttribute(AttributeNames.ChangedDate, page.ChangeDate),
                         new XAttribute(AttributeNames.ChangedBy, page.ChangedBy ?? string.Empty));

                    var list = pageToToChildElementsTable[pageStructure.ParentId];

                    if (list == null)
                    {
                        list = new List<PageTreeInfo>();
                        pageToToChildElementsTable[pageStructure.ParentId] = list;
                    }

                    list.Add(new PageTreeInfo
                    {
                        ID = page.Id,
                        LocalOrdering = localOrdering,
                        Element = pageElement
                    });
                }

                var root = new XElement("root");

                BuildXmlStructure(root, Guid.Empty, pageToToChildElementsTable, 100);

#pragma warning disable 612
                var pageUrlBuilder = PageUrls.UrlProvider.CreateUrlBuilder(publicationScope, localizationScope, urlSpace);
                BuildFolderPaths(pagesData, root.Elements(), pageUrlBuilder, urlToIdLookup);
#pragma warning restore 612

                foreach (var urlLookupEntry in urlToIdLookup)
                {
                    idToUrlLookup.Add(urlLookupEntry.Value, urlLookupEntry.Key);
                }

                var lowerCaseUrlToIdLookup = new Dictionary<string, Guid>();

                foreach (KeyValuePair<string, Guid> keyValuePair in urlToIdLookup)
                {
                    string loweredUrl = keyValuePair.Key.ToLowerInvariant();

                    if (lowerCaseUrlToIdLookup.ContainsKey(loweredUrl))
                    {
                        if (!_knownNotUniqueUrls.Contains(loweredUrl))
                        {
                            lock (_knownNotUniqueUrls)
                            {
                                _knownNotUniqueUrls.Add(loweredUrl);
                            }
                            Log.LogError(LogTitle, "Multiple pages share the same path '{0}'. Page ID: '{1}'. Duplicates are ignored.".FormatWith(loweredUrl, keyValuePair.Value));
                        }
                        
                        continue;
                    }

                    lowerCaseUrlToIdLookup.Add(loweredUrl, keyValuePair.Value);
                }

                return new Map
                           {
                               IdToUrlLookup = idToUrlLookup,
                               UrlToIdLookup = urlToIdLookup,
                               LowerCaseUrlToIdLookup = lowerCaseUrlToIdLookup,
                               RootPagesLookup = root.Elements(),
                               PageUrlBuilder = pageUrlBuilder
                           };
            }
        }
示例#20
0
        private static Tuple<PublicationScope, string, string> GetScopeKey(PublicationScope publicationScope, CultureInfo cultureInfo, UrlSpace urlSpace)
        {
            string hostnameScopeKey = urlSpace.ForceRelativeUrls ? "relative urls" : urlSpace.Hostname;

            return new Tuple<PublicationScope, string, string>(publicationScope, cultureInfo.Name, hostnameScopeKey);
        }
示例#21
0
        private static Map GetMap(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace)
        {
            Verify.ArgumentNotNull(localizationScope, "localizationScope");
            Verify.ArgumentNotNull(urlSpace, "urlSpace");

            if (System.Transactions.Transaction.Current != null)
            {
                var exceptionToLog = new Exception("It is not safe to use PageStructureInfo/SiteMap functionality in transactional context. Method Composite.Data.PageManager can be used instead.");
                Log.LogWarning(typeof(PageStructureInfo).Name, exceptionToLog);
            }

            var scopeKey = GetScopeKey(publicationScope, localizationScope, urlSpace);
            Map map = _generatedMaps[scopeKey];

            if (map != null)
            {
                return map;
            }

            // Using different sync roots for different datascopes
            //object buildingLock = _buildingLock[scopeKey.First == DataScopeIdentifier.Public.Name ? 0 : 1];

            // NOTE: Do not using a lock because it could because GetAssociatedPageIds is used inside transactions on some sites and it causes deadlocks 

            // lock (buildingLock)
            {
                map = _generatedMaps[scopeKey];
                if (map != null)
                {
                    return map;
                }


                Version version = _versions[scopeKey];
                if (version == null)
                {
                    lock (_updatingLock)
                    {
                        version = _versions[scopeKey];
                        if (version == null)
                        {
                            _versions.Add(scopeKey, version = new Version());
                        }
                    }
                }

                Thread.MemoryBarrier();
                int currentVersion = version.VersionNumber;
                Thread.MemoryBarrier();

                using(new DataScope(publicationScope, localizationScope))
                {
                    map = BuildMap(urlSpace);
                }

                lock (_updatingLock)
                {
                    if (_versions[scopeKey].VersionNumber == currentVersion)
                    {
                        _generatedMaps.Remove(scopeKey);
                        _generatedMaps.Add(scopeKey, map);
                    }
                }

                return map;
            }
        }
示例#22
0
        /// <summary>
        /// Builds the URL.
        /// </summary>
        /// <param name="pageUrlData">The page URL data.</param>
        /// <param name="urlKind">Kind of the URL.</param>
        /// <param name="urlSpace">The URL space.</param>
        /// <returns></returns>
        public static string BuildUrl(PageUrlData pageUrlData, UrlKind urlKind = UrlKind.Public, UrlSpace urlSpace = null) 
        {
            Verify.ArgumentNotNull(pageUrlData, "pageUrlData");

            return UrlProvider.BuildUrl(pageUrlData, urlKind, urlSpace ?? new UrlSpace());
        }
示例#23
0
        private static string RemoveUrlMarkers(string filePath, UrlSpace urlSpace)
        {
            if (urlSpace.ForceRelativeUrls && filePath.Contains(UrlMarker_RelativeUrl))
            {
                filePath = filePath.Replace(UrlMarker_RelativeUrl, string.Empty);
            }

            if (filePath == string.Empty)
            {
                filePath = "/";
            }

            return filePath;
        }
示例#24
0
        private bool BuildRootPageUrl(IPage rootPage, CultureInfo cultureInfo, UrlSpace urlSpace, StringBuilder result)
        {
            var bindings = GetHostnameBindings();

            bool knownHostname = urlSpace.Hostname != null
                                 && bindings.Any(b => b.Hostname == urlSpace.Hostname);

            IHostnameBinding hostnameBinding = null;

            // Searching for a hostname binding matching either the root page, or current hostname/UrlSpace
            if (!urlSpace.ForceRelativeUrls && knownHostname)
            {
                Guid pageId = rootPage.Id;
                string host = urlSpace.Hostname;
                string cultureName = cultureInfo.Name;

                hostnameBinding =
                    bindings.FirstOrDefault(b => b.HomePageId == pageId && b.Hostname == host && b.Culture == cultureName)
                    ?? bindings.FirstOrDefault(b => b.HomePageId == pageId && b.Culture == cultureName)
                    ?? bindings.FirstOrDefault(b => b.HomePageId == pageId && b.Hostname == host)
                    ?? bindings.FirstOrDefault(b => b.HomePageId == pageId);

                if (hostnameBinding != null)
                {
                    if (hostnameBinding.Hostname != urlSpace.Hostname)
                    {
                        result.Append("http://").Append(hostnameBinding.Hostname);
                    }
                }
                else
                {
                    hostnameBinding = bindings.FirstOrDefault(b => b.Hostname == urlSpace.Hostname);
                }
            }

            result.Append(UrlUtils.PublicRootPath);

            string cultureUrlMapping = DataLocalizationFacade.GetUrlMappingName(cultureInfo);

            if (cultureUrlMapping != string.Empty
                && (hostnameBinding == null 
                    || hostnameBinding.IncludeCultureInUrl 
                    || hostnameBinding.Culture != cultureInfo.Name))
            {
                result.Append("/").Append(cultureUrlMapping);
            }


            AppendSlash(result);

            if (rootPage.UrlTitle != string.Empty 
                && (hostnameBinding == null || hostnameBinding.IncludeHomePageInUrl || hostnameBinding.HomePageId != rootPage.Id))
            {
                result.Append(rootPage.UrlTitle);
            }

            return true;
        }
示例#25
0
 public IPageUrlBuilder CreateUrlBuilder(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace)
 {
     return new PageUrlBuilder(publicationScope, localizationScope, urlSpace);
 }
示例#26
0
            private static string GetCacheKey(string host, CultureInfo culture, Guid rootPageId)
            {
                var urlSpace = new UrlSpace();

                string hostnameKey = urlSpace.ForceRelativeUrls ? string.Empty : host;

                return CachePrefix + hostnameKey + rootPageId + culture.Name + PublicationScope;
            }
示例#27
0
        private bool BuildPageUrlPath(Guid pageId, CultureInfo culture, UrlSpace urlSpace, StringBuilder result)
        {
            IPage page = PageManager.GetPageById(pageId);
            if (page == null)
            {
                return false;
            }

            Guid parentPageId = PageManager.GetParentId(pageId);
            if (parentPageId == Guid.Empty)
            {
                return BuildRootPageUrl(page, culture, urlSpace, result);
            }

            if (!BuildPageUrlPath(parentPageId, culture, urlSpace, result))
            {
                return false;
            }

            Verify.That(result.Length >= 1, "Parent page urls is empty");

            AppendSlash(result);
            result.Append(page.UrlTitle);

            return true;
        }
        private static string GetPagePreviewUrl(PageUrlData pageUrlData)
        {
            var urlSpace = new UrlSpace {ForceRelativeUrls = true};

            return PageUrls.BuildUrl(pageUrlData, UrlKind.Public, urlSpace)
                      ?? PageUrls.BuildUrl(pageUrlData, UrlKind.Renderer, urlSpace);
        }
		public static Dictionary<string, Guid> GetMappingsFromSiteMap()
		{
			var result = new Dictionary<string, Guid>();

		    var urlSpace = new UrlSpace();

            // TODO: support for multiple languages as well
            var hostnameBindings = DataFacade.GetData<IHostnameBinding>().ToList();

		    var rootToHostnameMap = hostnameBindings.ToDictionary(h => h.HomePageId, h => h.Hostname);

			foreach (var cultureInfo in DataLocalizationFacade.ActiveLocalizationCultures.ToArray())
			{
                using (new DataScope(DataScopeIdentifier.Public, cultureInfo))
                {
                    var pages = DataFacade.GetData<IPage>().ToList();

					foreach (var page in pages)
					{
                        var url = PageUrls.BuildUrl(new PageUrlData(page), UrlKind.Public, urlSpace);
						if (url != null && !result.ContainsKey(url))
						{
							result.Add(url, page.Id);
						}

					    var rootPageId = GetRootPageId(page.Id);

					    string hostname;
                        if (rootToHostnameMap.TryGetValue(rootPageId, out hostname))
					    {
					        if (urlSpace.Hostname != hostname)
					        {
                                var hostnameBasedUrlSpace = new UrlSpace { ForceRelativeUrls = false, Hostname = hostname };
                                url = PageUrls.BuildUrl(new PageUrlData(page), UrlKind.Public, hostnameBasedUrlSpace);
                            }

					        if (url != null)
					        {
					            if (url.StartsWith("/"))
					            {
					                url = "http://{0}{1}".FormatWith(hostname, url);
					            }

					            if (!result.ContainsKey(url))
					            {
					                result.Add(url, page.Id);
					            }
					        }
					    }
					}
				}
			}
			
			return result;
		}
示例#30
0
        /// <summary>
        /// Parses the URL.
        /// </summary>
        /// <param name="relativeUrl">The relative URL.</param>
        /// <param name="urlSpace">The URL space.</param>
        /// <param name="urlKind">Kind of the URL.</param>
        /// <returns></returns>
        public static PageUrlData ParseUrl(string relativeUrl, UrlSpace urlSpace, out UrlKind urlKind) 
        {
            Verify.ArgumentNotNull(relativeUrl, "relativeUrl");

            return UrlProvider.ParseUrl(relativeUrl, urlSpace, out urlKind);
        }
示例#31
0
        /// <summary>
        /// Parses the URL.
        /// </summary>
        /// <param name="relativeUrl">The relative URL.</param>
        /// <param name="urlSpace">The URL space.</param>
        /// <param name="urlKind">Kind of the URL.</param>
        /// <returns></returns>
        public static PageUrlData ParseUrl(string relativeUrl, UrlSpace urlSpace, out UrlKind urlKind)
        {
            Verify.ArgumentNotNull(relativeUrl, "relativeUrl");

            return(UrlProvider.ParseUrl(relativeUrl, urlSpace, out urlKind));
        }
示例#32
0
        /// <summary>
        /// Builds the URL.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="urlKind">Kind of the URL.</param>
        /// <param name="urlSpace">The URL space.</param>
        /// <returns></returns>
        public static string BuildUrl(IPage page, UrlKind urlKind = UrlKind.Public, UrlSpace urlSpace = null)
        {
            Verify.ArgumentNotNull(page, "page");

            return BuildUrl(new PageUrlData(page), urlKind, urlSpace ?? new UrlSpace());
        }