#region License
// Copyright (c) 2007-2008, James M. Curran
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion
namespace Castle.MonoRail.ViewComponents
{
#region Reference
using System;
using System.IO;
using System.Collections;
using Castle.MonoRail.Framework;
using Castle.MonoRail.Framework.Helpers;
using Castle.Core.Logging;
using System.Web;
using System.Collections.Specialized;
#endregion
///
/// Helper class to provide a some convenient methods for viewcomponents.
///
/// May one day be incorporated into base class.
public abstract class ViewComponentEx : ViewComponent
{
private ILogger logger;
public ILogger Logger
{
get
{
if (logger == null) logger = NullLogger.Instance;
return logger;
}
set
{
logger = value;
}
}
///
/// Renders the text, formatted.
///
/// The format.
/// The args.
public void RenderTextFormat(string format, params object[] args)
{
string content = String.Format(format, args);
base.RenderText(content);
}
///
/// Renders the optional section, or the default text, if section not present.
///
/// The section.
/// The default text.
protected bool RenderOptionalSection(string section, string defaultText)
{
if (Context.HasSection(section))
{
Context.RenderSection(section);
return true;
}
RenderText(defaultText);
return false;
}
///
/// Renders the optional section.
///
/// The section.
/// bool, [true] is the section was rendered
protected bool RenderOptionalSection(string section)
{
if (Context.HasSection(section))
{
Context.RenderSection(section);
return true;
}
return false;
}
///
/// Gets the section text.
///
/// The section.
///
public string GetSectionText(string section)
{
using (StringWriter sw = new StringWriter())
{
if (String.IsNullOrEmpty(section))
RenderBody(sw);
else
Context.RenderSection(section, sw);
return sw.ToString();
}
}
///
/// Gets the body text.
///
///
public string GetBodyText()
{
return GetSectionText(null);
}
///
/// Confirms a section is present.
///
/// Throws an exception if the given section is not present.
///
/// The section.
/// If specified section is not present.
public void ConfirmSectionPresent(string section)
{
if (!Context.HasSection(section))
{
string message = String.Format("{0}: you must supply a '{1}' section", Context.ComponentName, section);
throw new ViewComponentException(message);
}
}
///
/// Gets a boolean parameter value.
///
/// The key.
/// The value used if there is no parameter named key.
///
[Obsolete("use GetParamValue instead")]
public bool GetBoolParamValue(string key, bool defaultValue)
{
return GetParamValue(key, defaultValue);
}
public bool GetParamValue(string key, bool defaultValue)
{
object parmValue = Context.ComponentParameters[key];
bool value = defaultValue;
if (parmValue is string)
{
if (!Boolean.TryParse(parmValue as string, out value))
value = defaultValue;
}
else if (parmValue is bool)
{
value = (bool)parmValue;
}
return value;
}
public string GetParamValue(string key, string defaultValue)
{
return Context.ComponentParameters[key] as string ?? defaultValue;
}
///
/// Gets the param value.
///
///
/// The key.
/// The default value.
///
public E GetParamValue(string key, E defaultValue) where E:struct
{
object parmValue = Context.ComponentParameters[key];
E value = defaultValue;
if (parmValue is string)
{
try
{ value = (E)Enum.Parse(typeof(E), parmValue as string, true); }
catch
{ value = defaultValue; }
}
else if (parmValue is E)
{
value = (E)parmValue;
}
return value;
}
///
/// Makes an unique id.
///
/// The given prefix is prepended to the generated number.
/// The ID isn't actually guarenteed to be unique (which would require
/// using all 32 digits of the guid). But this produce ids sufficently
/// distinctive to generate multiple controls on a page.
///
/// The prefix.
/// A string usable as a Html element Id
public string MakeUniqueId(string prefix)
{
byte[] bytes = Guid.NewGuid().ToByteArray();
int a = BitConverter.ToInt32(bytes, 0);
int b = BitConverter.ToInt32(bytes, 4);
int c = BitConverter.ToInt32(bytes, 8);
int d = BitConverter.ToInt32(bytes, 12);
return prefix + (a ^ b ^ c ^ d).ToString("x08");
}
#region Render Composite Component
///
/// Renders the component.
///
/// Intended to render a viewComponent from within a different viewComponent.
/// Original concept devised by Joey Beninghove.
/// http://joeydotnet.com/blog/archive/2007/05/15/Creating-Composite-View-Components-In-MonoRail--Refactoring-Exercise.aspx
///
/// ("linkText=Search",
/// string.Format("formToSubmit={0}", searchFormName));
/// ]]>
/// The type of the ViewComponent.
/// The component params.
public void RenderComponent(IDictionary componentParams) where VC : ViewComponentEx, new()
{
ViewComponentEx component = new VC();
RenderComponent(component, componentParams);
}
///
/// Renders the component.
///
/// For full details,
///
/// (DictHelper.N("linkText","Search").N("formToSubmit", searchFormName);
/// ]]>
/// The type of the C.
/// The component params.
public void RenderComponent(params string[] componentParams) where VC : ViewComponentEx, new()
{
ViewComponentEx component = new VC();
RenderComponent(component, DictHelper.Create(componentParams));
}
///
/// Renders the component.
///
/// The component.
/// The component params.
/// For full details,
///
///
public void RenderComponent(ViewComponentEx component, params string[] componentParams)
{
RenderComponent(component, DictHelper.Create(componentParams));
}
///
/// Renders the component.
///
/// The component.
/// The component params.
/// For full details,
///
///
public void RenderComponent(ViewComponentEx component, IDictionary componentParams)
{
component.Init(EngineContext, Context);
foreach (DictionaryEntry dictionaryEntry in componentParams)
{
component.Context.ComponentParameters[dictionaryEntry.Key]= dictionaryEntry.Value;
}
component.Initialize();
component.Render();
string html = string.Empty;
component.Context.Writer.Write(html);
RenderText(html);
}
#endregion
}
///
/// Base class to be inherited by ViewComponents which access
/// the ASP.NET SiteMap. Handles the Provider & SiteMapProvider properties,
/// defaulting to the values in web.config, as does ASP.NET
///
/// Also added a SiteMapFile property, to set it more directly.
///
public abstract class ViewComponentUsingSiteMap : ViewComponentEx
{
///
/// Gets or sets the site map file.
///
/// The site map file.
[ViewComponentParam("SiteMapFile")]
public string SiteMapFile { get; set; }
SiteMapProvider m_Provider;
///
/// Gets or sets a that is associated with the ViewComponent.
///
/// The provider.
/// The Provider property specifies an instance of a site map provider to use with the control.
/// This provider may be different from the provider identified by the property, if set.
///
[ViewComponentParam]
public SiteMapProvider Provider
{
get
{
if (m_Provider == null)
{
if (!string.IsNullOrEmpty(SiteMapProvider))
{
m_Provider= SiteMap.Providers[SiteMapProvider];
}
else if (this.SiteMapFile ==null)
{
m_Provider= SiteMap.Provider;
}
if (m_Provider== null)
{
// Create an instance of the XmlSiteMapProvider class.
XmlSiteMapProvider testXmlProvider = new XmlSiteMapProvider();
NameValueCollection providerAttributes = new NameValueCollection(1);
providerAttributes.Add("siteMapFile", this.SiteMapFile ?? "~/web.sitemap");
// Initialize the provider with a provider name and file name.
testXmlProvider.Initialize("ViewComponentUsingSiteMapProvider", providerAttributes);
// Call the BuildSiteMap to load the site map information into memory.
testXmlProvider.BuildSiteMap();
m_Provider = testXmlProvider;
}
}
return m_Provider;
}
set
{
m_Provider = value;
}
}
///
/// Gets or sets the name of the used to render the site navigation control.
///
/// The site map provider.
[ViewComponentParam]
public string SiteMapProvider { get; set; }
}
}