private static PageTemplateConfiguration LoadPageTemplateConfiguration(string configurationPath) { PageTemplateConfiguration rtnConfig = null; XmlSerializer serializer = new XmlSerializer(typeof(PageTemplateConfiguration)); bool pageAssemblyInstructionXmlValid = true; pageAssemblyInstructionXmlValid = PageAssemblyInstructionFactory.ValidateXml(PageTemplateConfigurationPath, HttpContext.Current.Server.MapPath(ContentDeliveryEngineConfig.PageAssembly.PageAssemblyInfoTypes.XsdPath)); try { using (FileStream xmlFile = File.Open(configurationPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) { rtnConfig = (PageTemplateConfiguration)serializer.Deserialize(XmlReader.Create(xmlFile)); } } catch (Exception ex) { //TODO: Do something here } return(rtnConfig); }
/// <summary> /// Identifies the display type print or web.loads the appropriate xml file and loads the IPageAssemblyInstruction /// Loads the page template info and provides the complete intructions/assemblyinfo to assemble a page for the requested URL. /// </summary> /// <param name="context">httpcontext</param> /// <param name="url">Requested URL</param> void RewriteUrl(HttpContext context, string url) { DisplayVersions displayVersion = DisplayVersions.Web; if (url.EndsWith("/")) //The key will never be just / because of the statement above { //strip the trailing / url = url.Substring(0, url.LastIndexOf('/')); if (string.IsNullOrEmpty(url)) { url = ContentDeliveryEngineConfig.DefaultHomePage.Homepage; } } //Store the url so it can be rewritten for logging. context.Items[REQUEST_URL_KEY] = url; bool isPrint = false; if (url.EndsWith(PRINT_URL_ENDING)) { //Do not take a substring if someone is trying to print the homepage //of the site if (url != PRINT_URL_ENDING) { //Since the pretty url map knows nothing about urls //that end with print we need to remove /print from //the key url = url.Substring(0, url.Length - PRINT_URL_ENDING.Length); } else { //We know the key for the homepage //This code does not seem to actually work //At the very least it should rewrite the url to /?print=1 or whatever url = "/"; } //Set the URL to Default home page if the requested url is "/". if (url == "/") { url = ContentDeliveryEngineConfig.DefaultHomePage.Homepage; } isPrint = true; displayVersion = DisplayVersions.Print; } //Now check to see if it is the view all. (For MultiPageAssemblyInstructions) if (url.EndsWith(VIEWALL_URL_ENDING)) { //Do not take a substring if someone is trying to print the homepage //of the site if (url != VIEWALL_URL_ENDING) { //Since the pretty url map knows nothing about urls //that end with print we need to remove /print from //the key url = url.Substring(0, url.Length - VIEWALL_URL_ENDING.Length); } else { //We know the key for the homepage //This code does not seem to actually work //At the very least it should rewrite the url to /?print=1 or whatever url = "/"; } if (isPrint) { displayVersion = DisplayVersions.PrintAll; } else { displayVersion = DisplayVersions.ViewAll; } } //Handle for Dictionary Print pages AND foia summaries pages. if (context.Request.Url.Query.Contains("print") && context.Request.Url.Query.Contains("allpages")) { displayVersion = DisplayVersions.PrintAll; } else if (context.Request.Url.Query.Contains("print")) { displayVersion = DisplayVersions.Print; } // Set Display version before loading the assembly instructions so it can be accessed in the constructor PageAssemblyContext.CurrentDisplayVersion = displayVersion; //Now lookup the url.. IPageAssemblyInstruction assemblyInfo = null; try { //Try to get the assemblyinfo following these rules. // When depth == 1, and we get an assemblyInfo, then we are looking for // the full URL that was requested // When depth == 2, and we get an assemblyInfo, then we are looking for // either a MPAI, or a SPAI that implements PushState // When depth >= 3, and we get an assemblyInfo, then we are looking for // only a SPAI that implements PushState string currUrlPath = url; int depth = 1; while (assemblyInfo == null && currUrlPath != string.Empty) { //Load the assembly info from a path/file. assemblyInfo = PageAssemblyInstructionFactory.GetPageAssemblyInfo(currUrlPath); //Did not find anything, let's continue. if (assemblyInfo == null) { //Chop off the current path and try again. currUrlPath = currUrlPath.Substring(0, currUrlPath.LastIndexOf('/')); // Increment the depth one more time as we continue diving. depth++; continue; } // We have an MPAI & depth is greater than 2 (e.g. MPAI is /foo and URL is /foo/bar/bazz) if (assemblyInfo is IMultiPageAssemblyInstruction && depth != 2) { assemblyInfo = null; break; } // We have a Single page that is 2 or more levels deep, and does not implement pushstate // e.g. SPAI is /foo and URL is /foo/bar. if ( assemblyInfo is SinglePageAssemblyInstruction && depth > 1 && !assemblyInfo.ImplementsPushState ) { assemblyInfo = null; break; } // Good so far, so let's check if it is a MPAI and it has the requested page. if (assemblyInfo is MultiPageAssemblyInstruction) { int index = ((IMultiPageAssemblyInstruction)assemblyInfo).GetPageIndexOfUrl(url); if (index >= 0) { //This url is a page, so set the current index so we can get the page template later. ((IMultiPageAssemblyInstruction)assemblyInfo).SetCurrentPageIndex(index); assemblyInfo.Initialize(); } else { assemblyInfo = null; break; } } //By now we have sussed out if we have a PAI or not. //If we do, then we need to initialize it. if (assemblyInfo != null) { assemblyInfo.Initialize(); } //Break out of loop. break; } } catch (Exception ex) { string errMessage = "RewriteUrl(): Requested URL: " + context.Items[REQUEST_URL_KEY] + "\nFailed to Create IPageAssemblyInstruction with the XML file Provided."; log.Error(errMessage, ex); RaiseErrorPage(errMessage, ex); return; } //Exiting because there is no page assembly instruction for the requested URL. if (assemblyInfo == null) { return; } //Load the page template info for the current request PageTemplateInfo pageTemplateInfo = null; try { pageTemplateInfo = PageTemplateResolver.GetPageTemplateInfo(assemblyInfo.TemplateTheme, assemblyInfo.PageTemplateName, displayVersion); } catch (Exception ex) { string errMessage = "RewriteUrl(): Requested URL: " + context.Items[REQUEST_URL_KEY] + "\nCannot Load the pageTemplateInfo problem with the PageTemplateConfiguration XML file "; log.Error(errMessage, ex); RaiseErrorPage(errMessage, ex); return; } if (pageTemplateInfo == null) { string errMessage = "RewriteUrl(): Requested URL: " + context.Items[REQUEST_URL_KEY] + "\nPage Template Not Found"; log.Error(errMessage); RaiseErrorPage(errMessage, null); return; } //set the page assembly context with the assemblyInfo, dispayVersion and pageTemplateInfo PageAssemblyContext.Current.InitializePageAssemblyInfo(assemblyInfo, displayVersion, pageTemplateInfo, url); // Set culture for selected content. // The language and culture are formatted as xx-yy (eg. "en-us") when a locale is chosen in Percussion. // The hyphenated four-letter code is then trimmed to a 2-character neutral culture (eg. "en") by the Velocity // user macros file and is added to the XML file to be published in /PublishedContent/PageInstructions. The // assemblyInfo object uses the neutral culture (found in the <Language> tag in the XML file) for page assembly. // The only exception to this is the Chinese language, in which the culture MUST be specified as either // "zh-hans" (Simplified Chinese) or "zh-hant" (Traditional Chinese). There is no support for a 2-character "zh" // culture - see http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo(v=vs.90).aspx for // details. The logic below is a workaround to catch the "zh" and convert it to the full "zh-hans" culture. if (!string.IsNullOrEmpty(assemblyInfo.Language)) { if (assemblyInfo.Language == "zh") { System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-hans"); } else { System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(assemblyInfo.Language); } } string rewriteUrl = PageAssemblyContext.Current.PageTemplateInfo.PageTemplatePath; // Append original parameters in the request URL if (!String.IsNullOrEmpty(context.Request.Url.Query)) { //The query should contain a ? rewriteUrl += context.Request.Url.Query; } //If we are showing the print version then append the print query //variable if (isPrint) { if (rewriteUrl.Contains("?")) { rewriteUrl += "&print=1"; } else { rewriteUrl += "?print=1"; } } // Do not reset the client path because it'll break form action url's. try { context.RewritePath(rewriteUrl, false); } catch (HttpException ex) { string errMessage = "RewriteUrl(): Requested URL: " + context.Items[REQUEST_URL_KEY] + "\nFailed to rewrite URL."; log.Error(errMessage, ex); RaiseErrorPage(errMessage, ex); } }
/// <summary> /// Creates an IPageAssemblyInstruction derived instance from the XML at the specified path. /// /// /// </summary> public static IPageAssemblyInstruction GetPageAssemblyInfo(string requestedPath) { bool pageAssemblyInstructionXmlValid = true; string xmlFilePath = HttpContext.Current.Server.MapPath(String.Format(ContentDeliveryEngineConfig.PathInformation.PagePathFormat.Path, requestedPath)); // Input validation. if (xmlFilePath == null) { throw new ArgumentNullException("pathToXml", "The pathToXml parameter cannot be null."); } if (!File.Exists(xmlFilePath)) { return(null); } if (ContentDeliveryEngineConfig.PageAssembly.PageAssemblyInfoTypes.EnableValidation == true) { pageAssemblyInstructionXmlValid = PageAssemblyInstructionFactory.ValidateXml(xmlFilePath, HttpContext.Current.Server.MapPath(ContentDeliveryEngineConfig.PageAssembly.PageAssemblyInfoTypes.XsdPath)); } if (pageAssemblyInstructionXmlValid == false) { return(null); } // Load the XML file into an XmlReader and create a IPageAssemblyInstruction derived instance from the XML. IPageAssemblyInstruction pageAssemblyInfo = null; try { using (FileStream xmlFile = File.Open(xmlFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) { using (XmlReader xmlReader = XmlReader.Create(xmlFile)) { // Read just enough to get the page type of assembly info object we want to create // e.g. a SinglePageAssemblyInfo, BookletAssemblyInfo, etc. xmlReader.MoveToContent(); // Get the name of hte serializer type we need (the document element name is the // name of the type). string pageAssemblyInfoTypeName = xmlReader.LocalName; // Make sure the serializer we need is in the cache (if it isn't, we've got invalid XML). if (Instance._serializers.ContainsKey(pageAssemblyInfoTypeName) == false) { string message = String.Format("Unable to find XmlSerializer for type \"{0}.\" Either \"{0}\" is an unsupported type and the XML file at \"{1}\" is invalid or the page assembly configuration needs a new entry to support \"{0}\"", pageAssemblyInfoTypeName, xmlFilePath); throw new PageAssemblyException(message); } // Get the serializer from the cache. XmlSerializer serializer = Instance._serializers[pageAssemblyInfoTypeName]; // Deserialize the XML into an object. pageAssemblyInfo = (IPageAssemblyInstruction)serializer.Deserialize(xmlReader); } } } catch (Exception ex) { throw new PageAssemblyException(String.Format("Unable to create IPageAssemblyInfo for file \"{0}.\"", xmlFilePath), ex); } return(pageAssemblyInfo); }