From: <sv...@ca...> - 2005-10-27 00:23:59
|
User: hammett Date: 2005/10/26 08:19 PM Added: /trunk/MonoRail/Castle.MonoRail.Framework/ IMonoRailExtension.cs /trunk/MonoRail/Castle.MonoRail.Framework/Extensions/ /trunk/MonoRail/Castle.MonoRail.Framework/Extensions/Session/ CustomSessionExtension.cs, ICustomSessionFactory.cs Modified: /trunk/MonoRail/Castle.MonoRail.Framework/ Castle.MonoRail.Framework.csproj, MonoRailHttpHandler.cs, MonoRailHttpHandlerFactory.cs, ProcessEngine.cs, ProcessEngineFactory.cs /trunk/MonoRail/Castle.MonoRail.Framework/Adapters/ RailsEngineContextAdapter.cs /trunk/MonoRail/Castle.MonoRail.Framework/Configuration/ MonoRailConfiguration.cs, MonoRailSectionHandler.cs Log: - Initial Extensions support - Custom Session extension - Config minor refactorings File Changes: Directory: /trunk/MonoRail/Castle.MonoRail.Framework/Adapters/ ============================================================== File [modified]: RailsEngineContextAdapter.cs Delta lines: +6 -5 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/Adapters/RailsEngineContextAdapter.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/Adapters/RailsEngineContextAdapter.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -15,12 +15,12 @@ namespace Castle.MonoRail.Framework.Adapters { using System; - using System.Collections; - using System.Collections.Specialized; using System.Web; using System.Web.Caching; + using System.Web.SessionState; using System.Security.Principal; - using System.Web.SessionState; + using System.Collections; + using System.Collections.Specialized; using Castle.MonoRail.Framework; using Castle.MonoRail.Framework.Internal; @@ -101,14 +101,14 @@ { object session; - // Windows and Testing if(_context.Items["AspSession"] != null) { + // Windows and Testing session = _context.Items["AspSession"]; } - // Mono else { + // Mono session = _context.Session; } @@ -124,6 +124,7 @@ return _session; } + set { _session = value; } } public IRequest Request Directory: /trunk/MonoRail/Castle.MonoRail.Framework/ ===================================================== File [modified]: Castle.MonoRail.Framework.csproj Delta lines: +15 -0 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/Castle.MonoRail.Framework.csproj 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/Castle.MonoRail.Framework.csproj 2005-10-27 00:18:59 UTC (rev 1232) @@ -148,6 +148,11 @@ BuildAction = "Compile" /> <File + RelPath = "IMonoRailExtension.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "IPropertyError.cs" SubType = "Code" BuildAction = "Compile" @@ -374,6 +379,16 @@ BuildAction = "EmbeddedResource" /> <File + RelPath = "Extensions\Session\CustomSessionExtension.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "Extensions\Session\ICustomSessionFactory.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Filters\AntiGoogleWebAcceleratorFilter.cs" SubType = "Code" BuildAction = "Compile" File [added]: IMonoRailExtension.cs Delta lines: +40 -0 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/IMonoRailExtension.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/IMonoRailExtension.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -0,0 +1,40 @@ +// Copyright 2004-2005 Castle Project - http://www.castleproject.org/ +// +// 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. + +namespace Castle.MonoRail.Framework +{ + using System; + + using Castle.MonoRail.Framework.Configuration; + + /// <summary> + /// Contract for extensions that want to hook + /// on MonoRail's events + /// </summary> + /// <remarks> + /// Extensions implementations must be thread safe + /// </remarks> + public interface IMonoRailExtension + { + /// <summary> + /// Implementors have a chance to + /// </summary> + /// <param name="configuration"></param> + void Init(MonoRailConfiguration configuration); + + void OnRailsContextCreated(IRailsEngineContext context); + + void OnRailsContextDiscarded(IRailsEngineContext context); + } +} File [modified]: MonoRailHttpHandler.cs Delta lines: +17 -5 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/MonoRailHttpHandler.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/MonoRailHttpHandler.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -18,7 +18,6 @@ using System.Web; using System.Web.SessionState; - using Castle.MonoRail.Framework; using Castle.MonoRail.Framework.Adapters; using Castle.MonoRail.Framework.Internal; @@ -32,16 +31,29 @@ private String _url; public MonoRailHttpHandler( String url, IViewEngine viewEngine, - IControllerFactory controllerFactory, IFilterFactory filterFactory, IResourceFactory resourceFactory, - IScaffoldingSupport scaffoldingSupport, IViewComponentFactory viewCompFactory) - : base(controllerFactory, viewEngine, filterFactory, resourceFactory, scaffoldingSupport, viewCompFactory) + IControllerFactory controllerFactory, IFilterFactory filterFactory, + IResourceFactory resourceFactory, IScaffoldingSupport scaffoldingSupport, + IViewComponentFactory viewCompFactory, IMonoRailExtension[] extensions) + : base(controllerFactory, viewEngine, filterFactory, resourceFactory, + scaffoldingSupport, viewCompFactory, extensions) { _url = url; } public void ProcessRequest(HttpContext context) { - Process(new RailsEngineContextAdapter(context, _url)); + RailsEngineContextAdapter mrContext = new RailsEngineContextAdapter(context, _url); + + RaiseEngineContextCreated(mrContext); + + try + { + Process(mrContext); + } + finally + { + RaiseEngineContextDiscarded(mrContext); + } } public bool IsReusable File [modified]: MonoRailHttpHandlerFactory.cs Delta lines: +4 -5 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/MonoRailHttpHandlerFactory.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/MonoRailHttpHandlerFactory.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -31,18 +31,17 @@ public virtual IHttpHandler GetHandler(HttpContext context, String requestType, String url, String pathTranslated) { - #if ALLOWTEST String isTest = context.Request.Headers["IsTestWorkerRequest"]; - if ("true".Equals(isTest)) + if ("true" == isTest) { Castle.MonoRail.Framework.Internal.Test.TestContextHolder.SetContext(context); } #endif - - return new MonoRailHttpHandler(url, _viewEngine, _controllerFactory, - _filterFactory, _resourceFactory, _scaffoldingSupport, _viewCompFactory); + return new MonoRailHttpHandler(url, _viewEngine, + _controllerFactory, _filterFactory, _resourceFactory, + _scaffoldingSupport, _viewCompFactory, extensions); } public virtual void ReleaseHandler(IHttpHandler handler) File [modified]: ProcessEngine.cs Delta lines: +58 -22 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/ProcessEngine.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/ProcessEngine.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -29,6 +29,8 @@ /// </remarks> public class ProcessEngine : MarshalByRefObject { + #region Fields + internal static readonly String RailsContextKey = "rails.context"; private IControllerFactory controllerFactory; @@ -37,23 +39,29 @@ private IResourceFactory resourceFactory; private IScaffoldingSupport scaffoldingSupport; private IViewComponentFactory viewCompFactory; - private ControllerDescriptorBuilder controllerDescriptorBuilder = new ControllerDescriptorBuilder(); + private readonly ControllerDescriptorBuilder controllerDescriptorBuilder = new ControllerDescriptorBuilder(); + private readonly IMonoRailExtension[] extensions; + #endregion + + #region Constructors + public ProcessEngine(IControllerFactory controllerFactory, IViewEngine viewEngine) : this(controllerFactory, viewEngine, new DefaultFilterFactory(), - new DefaultResourceFactory(), null, new DefaultViewComponentFactory()) + new DefaultResourceFactory(), null, new DefaultViewComponentFactory(), new IMonoRailExtension[0]) { } public ProcessEngine(IControllerFactory controllerFactory, IViewEngine viewEngine, IViewComponentFactory viewCompFactory) : this(controllerFactory, viewEngine, new DefaultFilterFactory(), - new DefaultResourceFactory(), null, viewCompFactory) + new DefaultResourceFactory(), null, viewCompFactory, new IMonoRailExtension[0]) { } public ProcessEngine(IControllerFactory controllerFactory, IViewEngine viewEngine, IFilterFactory filterFactory, - IResourceFactory resourceFactory, IScaffoldingSupport scaffoldingSupport, IViewComponentFactory viewCompFactory) + IResourceFactory resourceFactory, IScaffoldingSupport scaffoldingSupport, + IViewComponentFactory viewCompFactory, IMonoRailExtension[] extensions) { this.controllerFactory = controllerFactory; this.viewEngine = viewEngine; @@ -61,8 +69,13 @@ this.resourceFactory = resourceFactory; this.scaffoldingSupport = scaffoldingSupport; this.viewCompFactory = viewCompFactory; + this.extensions = extensions; } + #endregion + + #region Properties + public IControllerFactory ControllerFactory { get { return controllerFactory; } @@ -94,6 +107,25 @@ } /// <summary> + /// Returns the MonoRail context assosciated with the current + /// request if one is available, otherwise <c>null</c>. + /// </summary> + public static IRailsEngineContext CurrentContext + { + get + { + HttpContext context = HttpContext.Current; + + // Are we in a web request? + if (context == null) return null; + + return context.Items[RailsContextKey] as IRailsEngineContext; + } + } + + #endregion + + /// <summary> /// Performs the base work of MonoRail. Extracts /// the information from the URL, obtain the controller /// that matches this information and dispatch the execution @@ -104,7 +136,8 @@ { HttpContext httpContext = context.UnderlyingContext; - // Push the IRailsEngineContext into the HttpContext so that we can access it from outside of MonoRail + // Push the IRailsEngineContext into the HttpContext so + // that we can access it from outside of MonoRail if (httpContext != null && !httpContext.Items.Contains(RailsContextKey)) { httpContext.Items.Add(RailsContextKey, context); @@ -134,23 +167,6 @@ controllerFactory.Release(controller); } } - - /// <summary> - /// Returns the MonoRail context assosciated with the current - /// request if one is available, otherwise <c>null</c>. - /// </summary> - public static IRailsEngineContext CurrentContext - { - get - { - HttpContext context = HttpContext.Current; - - // Are we in a web request? - if (context == null) return null; - - return context.Items[RailsContextKey] as IRailsEngineContext; - } - } /// <summary> /// Can be overriden so new semantics can be supported. @@ -163,5 +179,25 @@ return UrlTokenizer.ExtractInfo(context.Url, vdir); } + + protected void RaiseEngineContextCreated(IRailsEngineContext context) + { + if (extensions.Length == 0) return; + + foreach(IMonoRailExtension extension in extensions) + { + extension.OnRailsContextCreated(context); + } + } + + protected void RaiseEngineContextDiscarded(IRailsEngineContext context) + { + if (extensions.Length == 0) return; + + foreach(IMonoRailExtension extension in extensions) + { + extension.OnRailsContextDiscarded(context); + } + } } } File [modified]: ProcessEngineFactory.cs Delta lines: +33 -6 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/ProcessEngineFactory.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/ProcessEngineFactory.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -15,8 +15,10 @@ namespace Castle.MonoRail.Framework { using System; + using System.Collections; + + using Castle.MonoRail.Framework.Internal; using Castle.MonoRail.Framework.Configuration; - using Castle.MonoRail.Framework.Internal; using Castle.MonoRail.Framework.Views.Aspx; @@ -29,6 +31,7 @@ protected IControllerFactory _controllerFactory; protected IScaffoldingSupport _scaffoldingSupport; protected IViewComponentFactory _viewCompFactory; + protected IMonoRailExtension[] extensions; public ProcessEngineFactory() : this(null) { @@ -45,6 +48,7 @@ _config = config; } + InitializeExtensions(); InitializeControllerFactory(); InitializeViewComponentFactory(); InitializeFilterFactory(); @@ -58,7 +62,8 @@ public ProcessEngine Create() { return new ProcessEngine(_controllerFactory, _viewEngine, - _filterFactory, _resourceFactory, _scaffoldingSupport, _viewCompFactory); + _filterFactory, _resourceFactory, _scaffoldingSupport, + _viewCompFactory, extensions); } public MonoRailConfiguration Config @@ -81,7 +86,8 @@ { if (_config.CustomViewEngineType != null) { - _viewEngine = (IViewEngine) Activator.CreateInstance(_config.CustomViewEngineType); + _viewEngine = (IViewEngine) + Activator.CreateInstance(_config.CustomViewEngineType); } else { @@ -112,7 +118,8 @@ { if (_config.CustomViewComponentFactoryType != null) { - _viewCompFactory = (IViewComponentFactory) Activator.CreateInstance(_config.CustomViewComponentFactoryType); + _viewCompFactory = (IViewComponentFactory) + Activator.CreateInstance(_config.CustomViewComponentFactoryType); } else { @@ -131,7 +138,8 @@ { if (_config.CustomResourceFactoryType != null) { - _resourceFactory = (IResourceFactory) Activator.CreateInstance(_config.CustomResourceFactoryType); + _resourceFactory = (IResourceFactory) + Activator.CreateInstance(_config.CustomResourceFactoryType); } else { @@ -143,7 +151,8 @@ { if (_config.ScaffoldingType != null) { - _scaffoldingSupport = (IScaffoldingSupport) Activator.CreateInstance(_config.ScaffoldingType); + _scaffoldingSupport = (IScaffoldingSupport) + Activator.CreateInstance(_config.ScaffoldingType); } } @@ -166,6 +175,24 @@ _controllerFactory = factory; } } + + protected virtual void InitializeExtensions() + { + ArrayList extensionList = new ArrayList(); + + foreach(Type extensionType in Config.Extensions) + { + IMonoRailExtension extension = + Activator.CreateInstance( extensionType ) as IMonoRailExtension; + + extension.Init(Config); + + extensionList.Add(extension); + } + + extensions = (IMonoRailExtension[]) + extensionList.ToArray( typeof(IMonoRailExtension) ); + } private void ConnectViewComponentFactoryToViewEngine() { Directory: /trunk/MonoRail/Castle.MonoRail.Framework/Configuration/ =================================================================== File [modified]: MonoRailConfiguration.cs Delta lines: +22 -7 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/Configuration/MonoRailConfiguration.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/Configuration/MonoRailConfiguration.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -1,6 +1,3 @@ -using System; -using System.Collections; -using System.Configuration; // Copyright 2004-2005 Castle Project - http://www.castleproject.org/ // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,16 +14,22 @@ namespace Castle.MonoRail.Framework.Configuration { + using System; + using System.Xml; + using System.Collections; + using System.Configuration; + public class MonoRailConfiguration { private static readonly string DefaultScaffoldType = "Castle.MonoRail.ActiveRecordScaffold.ScaffoldingSupport, Castle.MonoRail.ActiveRecordScaffold"; public static readonly string SectionName = "monoRail"; + private bool _viewsXhtmlRendering; private IList _controllers = new ArrayList(); private IList _components = new ArrayList(); private IList _routingRules = new ArrayList(); - private bool _viewsXhtmlRendering; + private IList _extensions = new ArrayList(); private String _viewsPhysicalPath; private String _customControllerFactory; private String _customViewComponentFactory; @@ -34,6 +37,7 @@ private String _customResourceFactory; private String _customEngineTypeName; private String _scaffoldingTypeName = DefaultScaffoldType; + private XmlNode section; public MonoRailConfiguration() { @@ -42,7 +46,6 @@ public IList ControllerAssemblies { get { return _controllers; } - } public IList ComponentsAssemblies @@ -55,6 +58,12 @@ get { return _routingRules; } } + public IList Extensions + { + get { return _extensions; } + set { _extensions = value; } + } + public String ViewsPhysicalPath { get { return _viewsPhysicalPath; } @@ -133,6 +142,12 @@ get { return _scaffoldingTypeName != null ? GetType(_scaffoldingTypeName, true) : null; } } + public XmlNode ConfigSection + { + get { return section; } + set { section = value; } + } + internal static MonoRailConfiguration GetConfig() { MonoRailConfiguration config = (MonoRailConfiguration) @@ -147,12 +162,12 @@ return config; } - internal static Type GetType(String typeName) + public static Type GetType(String typeName) { return GetType(typeName, false); } - internal static Type GetType(String typeName, bool ignoreError) + public static Type GetType(String typeName, bool ignoreError) { Type loadedType = Type.GetType(typeName, false, false); File [modified]: MonoRailSectionHandler.cs Delta lines: +116 -22 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/Configuration/MonoRailSectionHandler.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/Configuration/MonoRailSectionHandler.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -15,6 +15,7 @@ namespace Castle.MonoRail.Framework.Configuration { using System; + using System.Collections; using System.IO; using System.Xml; using System.Configuration; @@ -22,22 +23,36 @@ using Castle.MonoRail.Framework; using Castle.MonoRail.Framework.Internal; - + /// <summary> + /// Parses the Xml element that represents + /// the MonoRail configuration on the xml associated with + /// the AppDomain (usually web.config) + /// </summary> public class MonoRailSectionHandler : IConfigurationSectionHandler { + #region Constants + private static readonly String Controllers_Node_Name = "controllers"; private static readonly String Components_Node_Name = "components"; private static readonly String Views_Node_Name = "viewEngine"; private static readonly String Routing_Node_Name = "routing"; + private static readonly String Extensions_Node_Name = "extensions"; + private static readonly String Extension_Node_Name = "extension"; private static readonly String Custom_Controller_Factory_Node_Name = "customControllerFactory"; private static readonly String Custom_Component_Factory_Node_Name = "customComponentFactory"; private static readonly String Custom_Filter_Factory_Node_Name = "customFilterFactory"; private static readonly String View_Path_Root = "viewPathRoot"; + #endregion + + #region IConfigurationSectionHandler implementation + public object Create(object parent, object configContext, XmlNode section) { MonoRailConfiguration config = new MonoRailConfiguration(); + config.ConfigSection = section; + XmlAttribute useWindsorAtt = section.Attributes["useWindsorIntegration"]; if (useWindsorAtt != null && "true".Equals(useWindsorAtt.Value)) @@ -80,6 +95,10 @@ { ProcessRoutingNode(node, config); } + else if ( String.Compare(Extensions_Node_Name, node.Name, true) == 0 ) + { + ProcessExtensionsNode(node, config); + } else { throw new ConfigurationException("Unknown node: " + node.Name); @@ -91,13 +110,10 @@ return config; } - private void ConfigureWindsorIntegration(MonoRailConfiguration config) - { - config.CustomControllerFactory = "Castle.MonoRail.WindsorExtension.WindsorControllerFactory, Castle.MonoRail.WindsorExtension"; - config.CustomFilterFactory = "Castle.MonoRail.WindsorExtension.WindsorFilterFactory, Castle.MonoRail.WindsorExtension"; - config.CustomViewComponentFactory = "Castle.MonoRail.WindsorExtension.WindsorViewComponentFactory, Castle.MonoRail.WindsorExtension"; - } + #endregion + #region Factories Configuration + private void ProcessFilterFactoryNode(XmlNode node, MonoRailConfiguration config) { XmlAttribute type = node.Attributes["type"]; @@ -134,6 +150,10 @@ config.CustomViewComponentFactory = type.Value; } + #endregion + + #region View Configuration + private void ProcessViewNode(XmlNode node, MonoRailConfiguration config) { XmlAttribute viewPath = node.Attributes[View_Path_Root]; @@ -175,6 +195,10 @@ } } + #endregion + + #region Controllers Configuration + private void ProcessControllersNode(XmlNode controllersNode, MonoRailConfiguration config) { foreach(XmlNode node in controllersNode.ChildNodes) @@ -185,6 +209,22 @@ } } + private void ProcessControllerEntry(XmlNode controllerEntry, MonoRailConfiguration config) + { + if (!controllerEntry.HasChildNodes) + { + throw new ConfigurationException("Inside the node controllers, you have to specify the assemblies " + + "through the value of each child node"); + } + + String assemblyName = controllerEntry.FirstChild.Value; + config.ControllerAssemblies.Add( assemblyName ); + } + + #endregion + + #region Components Configuration + private void ProcessComponentsNode(XmlNode controllersNode, MonoRailConfiguration config) { foreach(XmlNode node in controllersNode.ChildNodes) @@ -207,17 +247,9 @@ config.ComponentsAssemblies.Add( assemblyName ); } - private void ProcessControllerEntry(XmlNode controllerEntry, MonoRailConfiguration config) - { - if (!controllerEntry.HasChildNodes) - { - throw new ConfigurationException("Inside the node controllers, you have to specify the assemblies " + - "through the value of each child node"); - } + #endregion - String assemblyName = controllerEntry.FirstChild.Value; - config.ControllerAssemblies.Add( assemblyName ); - } + #region Routing Configuration private void ProcessRoutingNode(XmlNode routingNode, MonoRailConfiguration config) { @@ -249,11 +281,45 @@ config.RoutingRules.Add( new RoutingRule(pattern.Trim(), replace.Trim()) ); } + #endregion + + #region Extensions Configuration + + private void ProcessExtensionsNode(XmlNode routingNode, MonoRailConfiguration config) + { + foreach(XmlNode node in routingNode.ChildNodes) + { + if (node.NodeType != XmlNodeType.Element) continue; + + if (node.Name != Extension_Node_Name) + { + String message = String.Format("Unexpected node '{0}' within '{1}' node. " + + "Expected {2}", node.Name, Extensions_Node_Name, Extension_Node_Name); + throw new ConfigurationException(message); + } + + XmlAttribute typeAtt = node.Attributes["type"]; + + if (typeAtt == null || typeAtt.Value.Length == 0) + { + String message = String.Format("An {0} node must have a 'type' attribute " + + "to declare the extension full type name", Extension_Node_Name); + throw new ConfigurationException(message); + } + + config.Extensions.Add( typeAtt.Value ); + } + } + + #endregion + + #region Configuration Validation + protected void Validate(MonoRailConfiguration config) { if (config.CustomControllerFactory != null) { - ValidateType(config.CustomControllerFactory, typeof(IControllerFactory)); + ValidateTypeImplements(config.CustomControllerFactory, typeof(IControllerFactory)); } else { @@ -263,17 +329,31 @@ "at least one assembly entry"); } } + + IList extensionTypes = new ArrayList(); + + foreach(String typeName in config.Extensions) + { + Type extensionType = MonoRailConfiguration.GetType(typeName); + + ValidateTypeImplements(extensionType, typeof(IMonoRailExtension)); + + extensionTypes.Add(extensionType); + } + + config.Extensions = extensionTypes; + if (config.CustomFilterFactory != null) { - ValidateType(config.CustomFilterFactory, typeof(IFilterFactory)); + ValidateTypeImplements(config.CustomFilterFactory, typeof(IFilterFactory)); } if (config.CustomViewComponentFactory != null) { - ValidateType(config.CustomViewComponentFactory, typeof(IViewComponentFactory)); + ValidateTypeImplements(config.CustomViewComponentFactory, typeof(IViewComponentFactory)); } if (config.CustomEngineTypeName != null) { - ValidateType(config.CustomEngineTypeName, typeof(IViewEngine)); + ValidateTypeImplements(config.CustomEngineTypeName, typeof(IViewEngine)); } if (config.ViewsPhysicalPath == null || config.ViewsPhysicalPath.Length == 0) { @@ -292,7 +372,7 @@ } } - private void ValidateType(String name, Type expectedType) + private void ValidateTypeImplements(String name, Type expectedType) { Type type = Type.GetType(name, false, false); @@ -302,6 +382,11 @@ throw new ConfigurationException(message); } + ValidateTypeImplements(type, expectedType); + } + + private void ValidateTypeImplements(Type type, Type expectedType) + { if (!expectedType.IsAssignableFrom(type)) { String message = String.Format("Type {0} does not implement {1}", @@ -309,5 +394,14 @@ throw new ConfigurationException(message); } } + + #endregion + + private void ConfigureWindsorIntegration(MonoRailConfiguration config) + { + config.CustomControllerFactory = "Castle.MonoRail.WindsorExtension.WindsorControllerFactory, Castle.MonoRail.WindsorExtension"; + config.CustomFilterFactory = "Castle.MonoRail.WindsorExtension.WindsorFilterFactory, Castle.MonoRail.WindsorExtension"; + config.CustomViewComponentFactory = "Castle.MonoRail.WindsorExtension.WindsorViewComponentFactory, Castle.MonoRail.WindsorExtension"; + } } } Directory: /trunk/MonoRail/Castle.MonoRail.Framework/Extensions/Session/ ======================================================================== File [added]: CustomSessionExtension.cs Delta lines: +81 -0 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/Extensions/Session/CustomSessionExtension.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/Extensions/Session/CustomSessionExtension.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -0,0 +1,81 @@ +// Copyright 2004-2005 Castle Project - http://www.castleproject.org/ +// +// 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. + +namespace Castle.MonoRail.Framework.Extensions.Session +{ + using System; + using System.Xml; + using System.Collections; + using System.Configuration; + + using Castle.MonoRail.Framework.Adapters; + using Castle.MonoRail.Framework.Configuration; + + + /// <summary> + /// + /// </summary> + public class CustomSessionExtension : IMonoRailExtension + { + private ICustomSessionFactory customSession; + + public CustomSessionExtension() + { + } + + public void Init(MonoRailConfiguration configuration) + { + XmlAttribute customSessionAtt = + configuration.ConfigSection.Attributes["customsession"]; + + if (customSessionAtt == null || customSessionAtt.Value.Length == 0) + { + throw new ConfigurationException("The CustomSessionExtension requires that " + + "the type that implements ICustomSessionFactory be specified through the " + + "'customsession' attribute on 'monoRail' configuration node"); + } + + Type customSessType = MonoRailConfiguration.GetType(customSessionAtt.Value); + + if (customSessType == null) + { + throw new ConfigurationException("The Type for the custom session could not be loaded. " + + customSessionAtt.Value); + } + + try + { + customSession = (ICustomSessionFactory) + Activator.CreateInstance(customSessType); + } + catch(InvalidCastException) + { + throw new ConfigurationException("The Type for the custom session must " + + "implement ICustomSessionFactory. " + customSessionAtt.Value); + } + } + + public void OnRailsContextCreated(IRailsEngineContext context) + { + IDictionary session = customSession.ObtainSession(context); + + (context as RailsEngineContextAdapter).Session = session; + } + + public void OnRailsContextDiscarded(IRailsEngineContext context) + { + customSession.PersistSession(context.Session, context); + } + } +} File [added]: ICustomSessionFactory.cs Delta lines: +27 -0 =================================================================== --- trunk/MonoRail/Castle.MonoRail.Framework/Extensions/Session/ICustomSessionFactory.cs 2005-10-26 21:12:50 UTC (rev 1231) +++ trunk/MonoRail/Castle.MonoRail.Framework/Extensions/Session/ICustomSessionFactory.cs 2005-10-27 00:18:59 UTC (rev 1232) @@ -0,0 +1,27 @@ +// Copyright 2004-2005 Castle Project - http://www.castleproject.org/ +// +// 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. + +namespace Castle.MonoRail.Framework.Extensions.Session +{ + using System; + using System.Collections; + + + public interface ICustomSessionFactory + { + IDictionary ObtainSession(IRailsEngineContext context); + + void PersistSession(IDictionary session, IRailsEngineContext context); + } +} |