public virtual PathData ResolveUrl(Url url) { try { var path = parser.FindPath(url.RemoveDefaultDocument(Url.DefaultDocument).RemoveExtension(observedExtensions)); path.CurrentItem = path.CurrentPage; if (draftRepository.Versions.TryParseVersion(url[PathData.VersionQueryKey], url["versionKey"], path)) { return(path); } string viewPreferenceParameter = url.GetQuery(WebExtensions.ViewPreferenceQueryString); if (viewPreferenceParameter == WebExtensions.DraftQueryValue && draftRepository.HasDraft(path.CurrentItem)) { var draft = draftRepository.Versions.GetVersion(path.CurrentPage); path.TryApplyVersion(draft, url["versionKey"]); } return(path); } catch (Exception ex) { errorHandler.Notify(ex); } return(PathData.Empty); }
public virtual PathData ResolveUrl(Url url) { // simple cache to help with multiple requests for same URL - PoC if ((lastUrl != null) && (lastUrl.Item1 == url.ToString())) { var result = lastUrl.Item2; lastUrl = null; return(result); } try { var path = parser.FindPath(url.RemoveDefaultDocument(Url.DefaultDocument).RemoveExtension(observedExtensions)); path.CurrentItem = path.CurrentPage; if (draftRepository.Versions.TryParseVersion(url[PathData.VersionIndexQueryKey], url["versionKey"], path)) { lastUrl = new Tuple <string, PathData>(url, path); return(path); } string viewPreferenceParameter = url.GetQuery(WebExtensions.ViewPreferenceQueryString); if (viewPreferenceParameter == WebExtensions.DraftQueryValue && draftRepository.HasDraft(path.CurrentItem)) { var draft = draftRepository.Versions.GetVersion(path.CurrentPage); path.TryApplyVersion(draft, url["versionKey"]); } lastUrl = new Tuple <string, PathData>(url, path); return(path); } catch (Exception ex) { errorHandler.Notify(ex); } return(PathData.Empty); }
/// <summary>Finds the path associated with an url.</summary> /// <param name="url">The url to the template to locate.</param> /// <param name="startNode">The node to start finding path from if none supplied will start from StartNode</param> /// <param name="remainingPath">The remaining path to search</param> /// <returns>A PathData object. If no template was found the object will have empty properties.</returns> public PathData FindPath(Url url, ContentItem startNode = null, string remainingPath = null) { if (url == null) { return(PathData.Empty); } url = url.GetNormalizedContentUrl(); var urlKey = GetUrlLowerInvariantString(url); // Within the same request, we don't need to clone again! if (HttpContext.Current.Items[urlKey] != null) { return(((Tuple <PathData>)HttpContext.Current.Items[urlKey]).Item1); } // Make sure the cached path data is initialized thread safely Dictionary <string, PathData> cachedPathData = GetCachedPathData(); PathData data; bool pathDataFound; lock (pathLock) { pathDataFound = cachedPathData.TryGetValue(urlKey, out data); } if (pathDataFound) { logger.DebugFormat("Retrieving path {0} from cache for key {1} ({2})", data, urlKey, data.GetHashCode()); data = data.Attach(persister); if (data == null || data.ID == 0) { // Cached path has to CMS content HttpContext.Current.Items[urlKey] = Tuple.Create(data); return(data); } if (!string.IsNullOrEmpty(url.Query)) { data.UpdateParameters(Url.Parse(url).GetQueries()); } } else { // The requested url doesn't exist in the cached path data lock (pathLock) { if (cachedPathData.TryGetValue(urlKey, out data)) { logger.DebugFormat("Retrieving path {0} from cache (second chance) for key {1} ({2})", data, urlKey, data.GetHashCode()); data = data.Attach(persister); if (data == null || data.ID == 0) { // Cached path has to CMS content HttpContext.Current.Items[urlKey] = Tuple.Create(data); return(data); } if (!string.IsNullOrEmpty(url.Query)) { data.UpdateParameters(Url.Parse(url).GetQueries()); } } else { remainingPath = remainingPath ?? Url.ToRelative(url.Path).TrimStart('~'); string path = remainingPath; PathData partialPath = GetStartNode(url, cachedPathData, ref path, 0); if (partialPath.ID == 0) { data = inner.FindPath(url); logger.DebugFormat("Found path {0} for url {1}", data, url); } else { string subpath = remainingPath.Substring(path.Length, remainingPath.Length - path.Length); data = inner.FindPath(url, persister.Get(partialPath.ID), subpath); logger.DebugFormat("Found path {0} for subpath {1} below {2}", data, subpath, partialPath.ID); } if (data.IsCacheable) { var detached = data.Detach(); logger.DebugFormat("Adding {0} to cache for key {1} ({2})", detached, urlKey, detached.GetHashCode()); cachedPathData.Add(urlKey, detached); } } } } HttpContext.Current.Items[urlKey] = Tuple.Create(data); return(data); }
/// <summary>Finds the path associated with an url.</summary> /// <param name="url">The url to the template to locate.</param> /// <param name="startNode">The node to start finding path from if none supplied will start from StartNode</param> /// <param name="remainingPath">The remaining path to search</param> /// <returns>A PathData object. If no template was found the object will have empty properties.</returns> public PathData FindPath(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 (pathLock) { 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; bool pathDataFound; lock (pathLock) { pathDataFound = cachedPathData.TryGetValue(urlKey, out data); } if (pathDataFound) { logger.DebugFormat("Retrieving path {0} from cache for key {1} ({2})", data, urlKey, data.GetHashCode()); data = data.Attach(persister); if (data == null || data.ID == 0) { // Cached path has to CMS content return(data); } if (!string.IsNullOrEmpty(url.Query)) { data.UpdateParameters(Url.Parse(url).GetQueries()); } } else { // The requested url doesn't exist in the cached path data lock (pathLock) { if (cachedPathData.TryGetValue(urlKey, out data)) { logger.DebugFormat("Retrieving path {0} from cache (second chance) for key {1} ({2})", data, urlKey, data.GetHashCode()); data = data.Attach(persister); if (data == null || data.ID == 0) { // Cached path has to CMS content return(data); } if (!string.IsNullOrEmpty(url.Query)) { data.UpdateParameters(Url.Parse(url).GetQueries()); } } else { remainingPath = remainingPath ?? Url.ToRelative(url.Path).TrimStart('~'); string path = remainingPath; PathData partialPath = GetStartNode(url, cachedPathData, ref path, 0); if (partialPath.ID == 0) { data = inner.FindPath(url); logger.DebugFormat("Found path {0} for url {1}", data, url); } else { string subpath = remainingPath.Substring(path.Length, remainingPath.Length - path.Length); data = inner.FindPath(url, persister.Get(partialPath.ID), subpath); logger.DebugFormat("Found path {0} for subpath {1} below {2}", data, subpath, partialPath.ID); } if (data.IsCacheable) { var detached = data.Detach(); logger.DebugFormat("Adding {0} to cache for key {1} ({2})", detached, urlKey, detached.GetHashCode()); cachedPathData.Add(urlKey, detached); } } } } return(data); }