|
using System;
using Web = System.Web;
using WebUI = System.Web.UI;
using WebCtl = System.Web.UI.WebControls;
using HtmlCtl = System.Web.UI.HtmlControls;
using BasePageFramework.SmartState;
using BasePageFramework.Configuration;
namespace BasePageFramework
{
/// <summary>
/// Summary description for basePage.
/// </summary>
public class SuperBasePage : WebUI.Page
{
#region Constants
private const int LG_STR_BUFFER_SZ = 512; //large string builder initial buffer size
private const int MD_STR_BUFFER_SZ = 256; //medium string builder inital buffer size
private const int SM_STR_BUFFER_SZ = 128; //small (default) string builder buffer size
private const string OPEN_TITLE_TAG = "<TITLE>";
private const string CLOSE_TITLE_TAG = "</TITLE>";
private const string OPEN_HEAD_TAG = "<HEAD>";
private const string CLOSE_HEAD_TAG = "</HEAD>";
private const string OPEN_HTML_TAG = "<HTML>";
private const int DEFAULT_LINK_WIDTH = 20; //this is used to estimage the number of characters to reserve space for in our string builders in an attempt to maximize efficency
#endregion
#region SuperBasePage Members
private WebCtl.PlaceHolder _serverFormPlcHldr = new WebCtl.PlaceHolder(); //our form sits in this placeholder
private string _title = string.Empty; //the title of the page (displayed in the caption bar)
private BaseServerForm _baseForm = null; //new SuperBasePage("BASE_FORM"); //the form tag where we place all our webserver controls
private Configuration.BasePageConfiguration _config = null;
private string _basePageName = string.Empty;
private ISmartQueryString _smartQueryString = null;
private ISmartSession _smartSession = null;
private ISmartApplication _smartApp = null;
#endregion
#region Properties
public string Title
{
get{return this._title;}
set{this._title = value;}
}
public BaseServerForm BaseForm
{
get{return this._baseForm;}
}
public IBaseTemplate MainUITemplate
{
get
{
return this._baseForm.BaseTemplate;
}
}
public ISmartSession SmartSession
{
get
{
if(this._smartSession == null)
throw new InvalidOperationException("You must initialize the smart session state before you can reference it");
else
return this._smartSession;
}
}
public ISmartApplication SmartApplication
{
get
{
if(this._smartApp == null)
throw new InvalidOperationException("You must initialize the smart application state before you can reference it");
else
return this._smartApp;
}
}
public ISmartQueryString SmartQueryString
{
get
{
if(this._smartQueryString == null)
throw new InvalidOperationException("You must initialize the smart query string before you can reference it");
else
return this._smartQueryString;
}
}
#endregion
protected override void CreateChildControls()
{
InitSmartQueryString(ref this._smartQueryString);
if(this._smartQueryString != null)
this._smartQueryString.SetQueryStringInfo(this.Page);
InitSmartSession(ref this._smartSession);
if(this._smartSession != null)
this._smartSession.SetSessionState(this.Page.Session);
BasePreRender(this._baseForm); //allows us to set the base page state from the child page before any rendering of the base page occurs
LoadTemplatePanels(); //call the virutal method to allow the base page to set the appropriate usercontrols into the base template
}
protected override void OnInit(EventArgs e)
{
this.EnsureChildControls();
base.OnInit (e);
}
protected override void AddParsedSubObject(Object obj)
{
//put all the configuration extras into our html header here
//make sure you modify the body tag as well since it is also
//editable from our custom configuration section
if(obj is HtmlCtl.HtmlForm)
{
BasePageFramework.IBaseTemplate tmplt = null;
this.LoadBaseUITemplate(ref tmplt);
if(tmplt == null)
throw new InvalidOperationException("Unable to load the base UI Template");
this._baseForm = new BaseServerForm((HtmlCtl.HtmlForm)obj,tmplt);
obj = this._baseForm; //replace the object reference with our own "base server form"
}
if(obj is Web.UI.LiteralControl)
{
Web.UI.LiteralControl htmlHeader = (Web.UI.LiteralControl)obj;
//we only need to do this processing when we are in the header
if(htmlHeader.Text.ToUpper().IndexOf(OPEN_HTML_TAG)>=0)
{
//we are going to need the stuff from the configuration now so load it up...
ConfigLoadingArgs cfgParam = new ConfigLoadingArgs();
InitializeConfiguration(ref cfgParam);
this._config = (Configuration.BasePageConfiguration)Cache["BASE_CONFIGURATION_" + cfgParam.BasePageID];
if(this._config == null)
InitFromConfiguration(cfgParam.BasePageID);
if(this._config != null) //we will only do this after the configuration is initialized otherwise we can just use the default html header
{
System.Text.StringBuilder htmlBuilder = new System.Text.StringBuilder(htmlHeader.Text.Length*2);
htmlBuilder.Append(htmlHeader.Text);
//check to see if the current literal control being passed to us is actually
//the HTML header - if it is then we need to add any values from the custom web.config settings
//if the current page has any of the same values in the body tag or any inline scripts -
//then we need to allow the page to override the web.config settings - this is in following with the
//same pattern for everything in ASP.NET (machine.config-web.config-page...)
//see if the title is filled in if not insert the default title <title></title>
//if the title tag is missing then add one now
int openingTitleTagOffset = htmlHeader.Text.ToUpper().IndexOf(OPEN_TITLE_TAG,0,htmlHeader.Text.Length);
int endTitleTagOffset = htmlHeader.Text.ToUpper().IndexOf(CLOSE_TITLE_TAG,0,htmlHeader.Text.Length);
endTitleTagOffset -= CLOSE_TITLE_TAG.Length-1;
int titleLen = htmlHeader.Text.Substring(openingTitleTagOffset, endTitleTagOffset - openingTitleTagOffset).Length; //get the length of our title
if(openingTitleTagOffset >= 0)
{
//check the length of our title
//if the title is missing then add the default one
if(titleLen == 0)
htmlBuilder.Insert(openingTitleTagOffset+OPEN_TITLE_TAG.Length,this._config.DefaultTitle);
}
else
{
int openHeadTagOffset = htmlHeader.Text.ToUpper().IndexOf(OPEN_HEAD_TAG,0,htmlHeader.Text.Length);
//if the head tag is missing then add it otherwise just insert the default title if needed
//create another string Builder to handle our missing header/title tag
System.Text.StringBuilder subHtml =
new System.Text.StringBuilder(
(OPEN_HEAD_TAG.Length
+ CLOSE_HEAD_TAG.Length
+ OPEN_TITLE_TAG.Length
+ CLOSE_TITLE_TAG.Length)
+_config.DefaultTitle.Length);
if(openHeadTagOffset == -1)
{
subHtml.Append(OPEN_HEAD_TAG);
subHtml.Append(OPEN_TITLE_TAG);
subHtml.Append(_config.DefaultTitle);
subHtml.Append(CLOSE_TITLE_TAG);
subHtml.Append(CLOSE_HEAD_TAG);
//insert the output right after the opening HTML tag
htmlBuilder.Insert(OPEN_HTML_TAG.Length,subHtml.ToString());
}
else
{
subHtml.Append(OPEN_TITLE_TAG);
subHtml.Append(_config.DefaultTitle);
subHtml.Append(CLOSE_TITLE_TAG);
//insert the output right after the opening Head Tag
htmlBuilder.Insert(openHeadTagOffset,subHtml.ToString());
}
}
//insert our configuration metatags and scripts/links after the closing title tag...
//int closingTitleTagOffset = htmlBuilder.ToString().ToUpper().IndexOf(CLOSE_HEAD_TAG,0,htmlBuilder.ToString().Length);
htmlBuilder.Replace(CLOSE_HEAD_TAG,GetWebConfigLinks(htmlBuilder.ToString()));
RenderBodyTagLinks(htmlBuilder);
//replace the text in the literal control with our new header
htmlHeader.Text = htmlBuilder.ToString();
}
}
}
this.Controls.Add((System.Web.UI.Control)obj);
}
#region HTML Header Parsing Code
private void RenderBodyTagLinks(System.Text.StringBuilder htmlBuilder)
{
//rip out the body tag and replace it with our own
//that has the attributes from the web config file
//but allows the individual pages to override these settings at the page level
string bodyTag = htmlBuilder.ToString();
int bodyTagOffset = bodyTag.ToUpper().IndexOf("<BODY");
bodyTag = bodyTag.Substring(bodyTagOffset,bodyTag.Length - bodyTagOffset);
//create the attributes that will be dumped into the body tag
//make sure it is not already in the body before entering it
//if it is in the body then throw it out so the individual page
//can override the web.config's settings
System.Text.StringBuilder bodyTagBuilder = new System.Text.StringBuilder(SM_STR_BUFFER_SZ);
bodyTagBuilder.Append("<BODY ");
foreach(string attribute in _config.BodyAttributes.Keys)
if(bodyTag.IndexOf(attribute) == -1)
{
bodyTagBuilder.Append(" ");
bodyTagBuilder.Append(attribute);
bodyTagBuilder.Append("=\"");
bodyTagBuilder.Append(_config.BodyAttributes.Get(attribute));
bodyTagBuilder.Append("\" ");
}
//append the global body tag attributes to the end of the current attribute list in our body tag
string newAttribList = bodyTag.Substring(5,bodyTag.Length-6); //remove the opening body tag and closing bracket
//get the current attributes out of the old body tag and add them to our bodytagbuilder
bodyTagBuilder.Append(" ");
bodyTagBuilder.Append(newAttribList);
int bodytagoffset = htmlBuilder.ToString().IndexOf(bodyTag);
//remove the old body tag from our string builder
htmlBuilder.Remove(bodytagoffset,htmlBuilder.Length-bodytagoffset);
string output = htmlBuilder.ToString();
htmlBuilder.Append(bodyTagBuilder.ToString());
}
//takes the existing script links and returns a new string
//containing the existing links merged with the ones in the web.config
private string GetWebConfigLinks(string oldHtml)
{
System.Text.StringBuilder subHtml = new System.Text.StringBuilder((_config.Scripts.Count*DEFAULT_LINK_WIDTH)+CLOSE_HEAD_TAG.Length);
this.GetMetaTags(subHtml,oldHtml);
this.GetStyleSheetLinks(subHtml);
this.GetScriptLinks(subHtml);
subHtml.Append("\r\n\t");
subHtml.Append(CLOSE_HEAD_TAG);
return subHtml.ToString();
}
private void GetMetaTags(System.Text.StringBuilder htmlBuilder,string oldHtml)
{
foreach(string metaTag in _config.MetaTags.Keys)
{
if(oldHtml.IndexOf(metaTag) == -1)
{
htmlBuilder.Append("\r\n\t\t");
htmlBuilder.Append("<META ");
htmlBuilder.Append("NAME=\"");
htmlBuilder.Append(metaTag);
htmlBuilder.Append("\"");
htmlBuilder.Append(" CONTENT=\"");
htmlBuilder.Append(_config.MetaTags.Get(metaTag));
htmlBuilder.Append("\"/>");
}
}
}
private void GetStyleSheetLinks(System.Text.StringBuilder scriptLinks)
{
foreach(string key in this._config.StyleSheets.Keys)
{
scriptLinks.Append("\r\n\t\t<LINK ");
scriptLinks.Append("type=\"text/css\" ");
scriptLinks.Append("rel=\"stylesheet\" ");
scriptLinks.Append("href=\"");
scriptLinks.Append(ParseRootPath(this._config.StyleSheets.Get(key)));
scriptLinks.Append("/");
scriptLinks.Append(key);
scriptLinks.Append("\"");
scriptLinks.Append("/>");
scriptLinks.Append(Environment.NewLine);
}
}
private void GetScriptLinks(System.Text.StringBuilder scriptLinks)
{
foreach(string key in this._config.Scripts.Keys)
{
scriptLinks.Append("\r\n\t\t<SCRIPT lanugage=\"javascript\" src=\"");
scriptLinks.Append(ParseRootPath(this._config.Scripts.Get(key)));
scriptLinks.Append("/");
scriptLinks.Append(key);
scriptLinks.Append("\">");
scriptLinks.Append("</SCRIPT>");
}
}
#endregion
#region Utility Methods
private string ParseRootPath(string path)
{
if(path.IndexOf('~') == 0)
{
if(System.Web.HttpContext.Current.Request.ApplicationPath == "/")
{
path = path.Replace("~","");
}
else
path = path.Replace("~",System.Web.HttpContext.Current.Request.ApplicationPath);
return path;
}
else
return path;
}
private void InitFromConfiguration(string pageName)
{
this._config = (Configuration.BasePageConfiguration)Cache["BASE_CONFIGURATION_" + pageName];
if(this._config == null)
{
Configuration.BasePagesConfiguration baseConfiguration = (Configuration.BasePagesConfiguration)System.Configuration.ConfigurationSettings.GetConfig("base.configuration");
if(baseConfiguration == null)
return; //the base configuration was not set in the current web.config - exit now...
//load the current page's configuration and stick it into cache so it does not have to be reloaded on subsequent requests
this._config = baseConfiguration[pageName];
Cache.Add("BASE_CONFIGURATION_" + pageName,this._config,null,DateTime.MaxValue,TimeSpan.FromDays(100),System.Web.Caching.CacheItemPriority.NotRemovable,null);
}
}
#endregion
#region Virutal Methods
protected virtual void InitializeConfiguration(ref ConfigLoadingArgs configParams)
{}
/// <summary>
/// override this method in our child pages to allow us to set base page state before any rendering takes place
/// in the base page
/// </summary>
protected virtual void BasePreRender(BaseServerForm baseForm)
{}
/// <summary>
/// override this method to allow the base page to load the base UI template
/// the base UI template is of type BaseUITemplate BaseUITemplate is of type Usercontrol
/// </summary>
protected virtual void LoadBaseUITemplate(ref BasePageFramework.IBaseTemplate tmplt)
{}
/// <summary>
/// override in the base page so you can load user controls at the derived base page
/// where you want them to be loaded - this is done so the derived base page can subscribe to events
/// fired by these controls
/// </summary>
protected virtual void LoadTemplatePanels()
{}
/// <summary>
/// override this method to initialize the smart querystring with your derived smart querystring instance
/// </summary>
/// <param name="sqs">derived instance of a smart query string base class that Implements the ISmartQueryString interface</param>
protected virtual void InitSmartQueryString(ref ISmartQueryString isqs)
{}
/// <summary>
/// override this method to initialized the smart session state with your derived smart session instance
/// </summary>
/// <param name="ises">derirved smart session object that implements the ISmartSession Interface</param>
protected virtual void InitSmartSession(ref ISmartSession ises)
{}
/// <summary>
/// override this method to initialize the smart application state with your derived smart application instance
/// </summary>
/// <param name="iapp">derived smart application object that implements the ISmartApplication interface</param>
protected virtual void InitSmartApplication(ref ISmartApplication iapp)
{}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.