/// <summary>Calculates an item url by walking it's parent path.</summary> /// <param name="item">The item whose url to compute.</param> /// <returns>A friendly url to the supplied item.</returns> public Url BuildUrl(ContentItem item) { if (item.ID == 0) { return(inner.BuildUrl(item)); } var cacheKey = "N2.UrlCache" + webContext.Url.Authority.ToLower(); // e.g. localhost var itemToUrlCache = cache.Get <Dictionary <int, string> >(cacheKey); if (itemToUrlCache == null) { lock (urlLock) { itemToUrlCache = cache.Get <Dictionary <int, string> >(cacheKey); if (itemToUrlCache == null) { itemToUrlCache = new Dictionary <int, string>(); cache.Add(cacheKey, itemToUrlCache, new CacheOptions { SlidingExpiration = SlidingExpiration }); if (!allCacheKeys.Contains(cacheKey)) { allCacheKeys.Add(cacheKey); // remember all keys used for flushing } } } } bool exists; string url; lock (urlLock) { exists = itemToUrlCache.TryGetValue(item.ID, out url); } if (!exists) { url = inner.BuildUrl(item); lock (urlLock) { itemToUrlCache[item.ID] = url; } } return(url); }
public PathData ResolvePath(Url url, ContentItem startNode = null, string remainingPath = null) { if (url == null) { return(PathData.Empty); } url = url.GetNormalizedContentUrl(); var urlKey = GetUrlLowerInvariantString(url); // Make sure the cached path data is initialized thread safely Dictionary <string, PathData> cachedPathData; if ((cachedPathData = cache.Get <Dictionary <string, PathData> >("N2.PathDataCache")) == null) { lock (classLock) { if ((cachedPathData = cache.Get <Dictionary <string, PathData> >("N2.PathDataCache")) == null) { cachedPathData = new Dictionary <string, PathData>(); cache.Add("N2.PathDataCache", cachedPathData, new CacheOptions { SlidingExpiration = SlidingExpiration }); } } } PathData data; if (cachedPathData.TryGetValue(urlKey, out data)) { data = data.Attach(persister); if (data == null || data.ID == 0) { // Cached path has to CMS content return(data); } logger.Debug("Retrieving " + url + " from cache"); if (!string.IsNullOrEmpty(url.Query)) { data.UpdateParameters(Url.Parse(url).GetQueries()); } } else { // The requested url doesn't exist in the cached path data lock (classLock) { if (!cachedPathData.TryGetValue(urlKey, out data)) { remainingPath = remainingPath ?? Url.ToRelative(url.Path).TrimStart('~'); string path = remainingPath; var pathData = GetStartNode(url, cachedPathData, ref path, 0); data = pathData.ID == 0 ? inner.ResolvePath(url) : inner.ResolvePath(url, persister.Get(pathData.ID), remainingPath.Substring(path.Length, remainingPath.Length - path.Length)); if (data.IsCacheable) { logger.Debug("Adding " + urlKey + " to cache"); cachedPathData.Add(urlKey, data.Detach()); } } } } return(data); }