refactored PageHandlerFactory and AbstractHandlerFactory
This commit is contained in:
@@ -86,20 +86,11 @@ namespace Spring.Web.Script.Services
|
||||
public override IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
|
||||
{
|
||||
string filename = VirtualPathUtility.ToAbsolute(context.Request.FilePath);
|
||||
string cacheKey = (string)webServiceData_GetCacheKey.Invoke(
|
||||
null, new object[] { VirtualPathUtility.ToAbsolute(context.Request.FilePath) });
|
||||
string cacheKey = (string)webServiceData_GetCacheKey.Invoke(null, new object[] { filename });
|
||||
object webServiceData = context.Cache.Get(cacheKey);
|
||||
if (webServiceData == null)
|
||||
{
|
||||
IConfigurableApplicationContext appContext =
|
||||
WebApplicationContext.GetContext(url) as IConfigurableApplicationContext;
|
||||
|
||||
if (appContext == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Implementations of IApplicationContext must also implement IConfigurableApplicationContext");
|
||||
}
|
||||
|
||||
IConfigurableApplicationContext appContext = base.GetCheckedApplicationContext(url);
|
||||
string appRelativeVirtualPath = WebUtils.GetAppRelativePath(url);
|
||||
NamedObjectDefinition nod = FindWebObjectDefinition(appRelativeVirtualPath, appContext.ObjectFactory);
|
||||
|
||||
@@ -126,5 +117,18 @@ namespace Spring.Web.Script.Services
|
||||
{
|
||||
this.scriptHandlerFactory.ReleaseHandler(handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a handler instance for the given URL.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="HttpContext"/> instance for this request.</param>
|
||||
/// <param name="requestType">The HTTP data transfer method (GET, POST, ...)</param>
|
||||
/// <param name="url">The requested <see cref="HttpRequest.RawUrl"/>.</param>
|
||||
/// <param name="physicalPath">The physical path of the requested resource.</param>
|
||||
/// <returns>A handler instance for the current request.</returns>
|
||||
protected override IHttpHandler CreateHandlerInstance( HttpContext context, string requestType, string url, string physicalPath )
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,14 @@
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using Common.Logging;
|
||||
using Spring.Collections;
|
||||
using Spring.Context;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Util;
|
||||
|
||||
@@ -43,17 +48,24 @@ namespace Spring.Web.Support
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
public abstract class AbstractHandlerFactory : IHttpHandlerFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds all handlers having <see cref="IHttpHandler.IsReusable"/> == true.
|
||||
/// </summary>
|
||||
private readonly IDictionary _reusableHandlerCache = new CaseInsensitiveHashtable();
|
||||
|
||||
/// <summary>
|
||||
/// Holds the shared logger for all factories.
|
||||
/// </summary>
|
||||
protected readonly ILog Log;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the
|
||||
/// <see cref="Spring.Web.Support.AbstractHandlerFactory"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This is an abstract class and as such provides no public constructors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
protected AbstractHandlerFactory()
|
||||
{}
|
||||
{
|
||||
this.Log = LogManager.GetLogger( this.GetType() );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an appropriate <see cref="System.Web.IHttpHandler"/> implementation.
|
||||
@@ -66,15 +78,59 @@ namespace Spring.Web.Support
|
||||
/// The HTTP method of the request.
|
||||
/// </param>
|
||||
/// <param name="url">The request URL.</param>
|
||||
/// <param name="pathTranslated">
|
||||
/// <param name="physicalPath">
|
||||
/// The physical path of the requested resource.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A new <see cref="System.Web.IHttpHandler"/> object that processes
|
||||
/// the request.
|
||||
/// </returns>
|
||||
public abstract IHttpHandler GetHandler(
|
||||
HttpContext context, string requestType, string url, string pathTranslated);
|
||||
public virtual IHttpHandler GetHandler( HttpContext context, string requestType, string url, string physicalPath )
|
||||
{
|
||||
bool isDebug = Log.IsDebugEnabled;
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (isDebug)
|
||||
Log.Debug( string.Format( "GetHandler():resolving url '{0}'", url ) );
|
||||
|
||||
#endregion
|
||||
|
||||
IHttpHandler handler = null;
|
||||
lock (_reusableHandlerCache.SyncRoot)
|
||||
{
|
||||
handler = (IHttpHandler)_reusableHandlerCache[url];
|
||||
}
|
||||
|
||||
if (handler != null)
|
||||
{
|
||||
#region Instrumentation
|
||||
|
||||
if (isDebug)
|
||||
{
|
||||
Log.Debug( string.Format( "GetHandler():resolved url '{0}' from reusable handler cache", url ) );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
lock (_reusableHandlerCache.SyncRoot)
|
||||
{
|
||||
handler = (IHttpHandler)_reusableHandlerCache[url];
|
||||
if (handler == null)
|
||||
{
|
||||
handler = CreateHandlerInstance( context, requestType, url, physicalPath );
|
||||
|
||||
if (handler.IsReusable)
|
||||
{
|
||||
_reusableHandlerCache[url] = handler;
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables a factory to release an existing
|
||||
@@ -83,8 +139,61 @@ namespace Spring.Web.Support
|
||||
/// <param name="handler">
|
||||
/// The <see cref="System.Web.IHttpHandler"/> object to release.
|
||||
/// </param>
|
||||
public virtual void ReleaseHandler(IHttpHandler handler)
|
||||
{}
|
||||
public virtual void ReleaseHandler( IHttpHandler handler )
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Create a handler instance for the given URL.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="HttpContext"/> instance for this request.</param>
|
||||
/// <param name="requestType">The HTTP data transfer method (GET, POST, ...)</param>
|
||||
/// <param name="url">The requested <see cref="HttpRequest.RawUrl"/>.</param>
|
||||
/// <param name="physicalPath">The physical path of the requested resource.</param>
|
||||
/// <returns>A handler instance for processing the current request.</returns>
|
||||
protected abstract IHttpHandler CreateHandlerInstance( HttpContext context, string requestType, string url, string physicalPath );
|
||||
|
||||
/// <summary>
|
||||
/// Get the application context instance corresponding to the given absolute url and checks
|
||||
/// it for <see cref="IConfigurableApplicationContext"/> contract and being not null.
|
||||
/// </summary>
|
||||
/// <param name="url">the absolute url</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// if no context is found
|
||||
/// </exception>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// if context is not an <see cref="IConfigurableApplicationContext"/>
|
||||
/// </exception>
|
||||
/// <returns>teh application context instance corresponding to the given absolute url.</returns>
|
||||
/// <remarks>
|
||||
/// Calls <see cref="GetContext"/> to obtain a context instance.
|
||||
/// </remarks>
|
||||
protected IConfigurableApplicationContext GetCheckedApplicationContext( string url )
|
||||
{
|
||||
IApplicationContext appContext = GetContext( url );
|
||||
if (appContext == null)
|
||||
{
|
||||
throw new ArgumentException( string.Format( "no application context for virtual path '{0}'", url ) );
|
||||
}
|
||||
if (!(appContext is IConfigurableApplicationContext))
|
||||
{
|
||||
throw new InvalidOperationException( string.Format( "application context '{0}' for virtual path '{1}' must implement IConfigurableApplicationContext", appContext.ToString(), url ) );
|
||||
}
|
||||
return (IConfigurableApplicationContext)appContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the unchecked, raw application context for the given virtual path.
|
||||
/// </summary>
|
||||
/// <param name="virtualPath">the virtual path to get the context for.</param>
|
||||
/// <returns>the context or null.</returns>
|
||||
/// <remarks>
|
||||
/// Subclasses may override this method to change the context source.
|
||||
/// By default, <see cref="WebApplicationContext.GetContext"/> is used for obtaining context instances.
|
||||
/// </remarks>
|
||||
protected virtual IApplicationContext GetContext( string virtualPath )
|
||||
{
|
||||
return WebApplicationContext.GetContext( virtualPath );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DO NOT USE - this is subject to change!
|
||||
@@ -98,27 +207,29 @@ namespace Spring.Web.Support
|
||||
/// <remarks>
|
||||
/// Resolve an object definition by url.
|
||||
/// </remarks>
|
||||
protected internal static NamedObjectDefinition FindWebObjectDefinition(string appRelativeVirtualPath, IConfigurableListableObjectFactory objectFactory)
|
||||
protected internal static NamedObjectDefinition FindWebObjectDefinition( string appRelativeVirtualPath, IConfigurableListableObjectFactory objectFactory )
|
||||
{
|
||||
ILog Log = LogManager.GetLogger(typeof(AbstractHandlerFactory));
|
||||
ILog Log = LogManager.GetLogger( typeof( AbstractHandlerFactory ) );
|
||||
bool isDebug = Log.IsDebugEnabled;
|
||||
|
||||
// lookup definition using app-relative url
|
||||
if (isDebug) Log.Debug(string.Format("GetHandler():looking up definition for app-relative url '{0}'", appRelativeVirtualPath));
|
||||
if (isDebug)
|
||||
Log.Debug( string.Format( "GetHandler():looking up definition for app-relative url '{0}'", appRelativeVirtualPath ) );
|
||||
string objectDefinitionName = appRelativeVirtualPath;
|
||||
IObjectDefinition pageDefinition = objectFactory.GetObjectDefinition(appRelativeVirtualPath, true);
|
||||
IObjectDefinition pageDefinition = objectFactory.GetObjectDefinition( appRelativeVirtualPath, true );
|
||||
|
||||
if (pageDefinition == null)
|
||||
{
|
||||
// try using pagename+extension and pagename only
|
||||
string pageExtension = Path.GetExtension(appRelativeVirtualPath);
|
||||
string pageName = WebUtils.GetPageName(appRelativeVirtualPath);
|
||||
string pageExtension = Path.GetExtension( appRelativeVirtualPath );
|
||||
string pageName = WebUtils.GetPageName( appRelativeVirtualPath );
|
||||
// only looks in the specified object factory -- it will *not* search parent contexts
|
||||
pageDefinition = objectFactory.GetObjectDefinition(pageName + pageExtension, false);
|
||||
pageDefinition = objectFactory.GetObjectDefinition( pageName + pageExtension, false );
|
||||
if (pageDefinition == null)
|
||||
{
|
||||
pageDefinition = objectFactory.GetObjectDefinition(pageName, false);
|
||||
if (pageDefinition != null) objectDefinitionName = pageName;
|
||||
pageDefinition = objectFactory.GetObjectDefinition( pageName, false );
|
||||
if (pageDefinition != null)
|
||||
objectDefinitionName = pageName;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -128,20 +239,21 @@ namespace Spring.Web.Support
|
||||
if (pageDefinition != null)
|
||||
{
|
||||
if (isDebug)
|
||||
Log.Debug(string.Format("GetHandler():found definition for page-name '{0}'", objectDefinitionName));
|
||||
Log.Debug( string.Format( "GetHandler():found definition for page-name '{0}'", objectDefinitionName ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDebug)
|
||||
Log.Debug(string.Format("GetHandler():no definition found for page-name '{0}'", pageName));
|
||||
Log.Debug( string.Format( "GetHandler():no definition found for page-name '{0}'", pageName ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDebug) Log.Debug(string.Format("GetHandler():found definition for page-url '{0}'", appRelativeVirtualPath));
|
||||
if (isDebug)
|
||||
Log.Debug( string.Format( "GetHandler():found definition for page-url '{0}'", appRelativeVirtualPath ) );
|
||||
}
|
||||
|
||||
return (pageDefinition == null) ? (NamedObjectDefinition)null : new NamedObjectDefinition(objectDefinitionName, pageDefinition);
|
||||
return (pageDefinition == null) ? (NamedObjectDefinition)null : new NamedObjectDefinition( objectDefinitionName, pageDefinition );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -155,7 +267,7 @@ namespace Spring.Web.Support
|
||||
/// <summary>
|
||||
/// DO NOT USE
|
||||
/// </summary>
|
||||
public NamedObjectDefinition(string name, IObjectDefinition objectDefinition)
|
||||
public NamedObjectDefinition( string name, IObjectDefinition objectDefinition )
|
||||
{
|
||||
_name = name;
|
||||
_objectDefinition = objectDefinition;
|
||||
@@ -178,5 +290,4 @@ namespace Spring.Web.Support
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -68,10 +68,6 @@ namespace Spring.Web.Support
|
||||
/// <author>Aleksandar Seovic</author>
|
||||
public class PageHandlerFactory : AbstractHandlerFactory
|
||||
{
|
||||
private readonly ILog Log = LogManager.GetLogger(typeof(PageHandlerFactory));
|
||||
|
||||
private readonly IDictionary pageHandlerWrappers = new CaseInsensitiveHashtable(); //CollectionsUtil.CreateCaseInsensitiveHashtable();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves instance of the configured page from Spring web application context,
|
||||
/// or if page is not defined in Spring config file tries to find it using standard
|
||||
@@ -82,76 +78,59 @@ namespace Spring.Web.Support
|
||||
/// <param name="url">Requested page URL</param>
|
||||
/// <param name="physicalPath">Translated server path for the page</param>
|
||||
/// <returns>Instance of the IHttpHandler object that should be used to process request.</returns>
|
||||
public override IHttpHandler GetHandler(HttpContext context, string requestType, string url, string physicalPath)
|
||||
public override IHttpHandler GetHandler( HttpContext context, string requestType, string url, string physicalPath )
|
||||
{
|
||||
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
|
||||
new SecurityPermission( SecurityPermissionFlag.UnmanagedCode ).Assert();
|
||||
|
||||
bool isDebug = Log.IsDebugEnabled;
|
||||
|
||||
if (isDebug) Log.Debug(string.Format("GetHandler():resolving url '{0}'", url));
|
||||
return base.GetHandler(context, requestType, url, physicalPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a handler instance for the given URL.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="HttpContext"/> instance for this request.</param>
|
||||
/// <param name="requestType">The HTTP data transfer method (GET, POST, ...)</param>
|
||||
/// <param name="url">The requested <see cref="HttpRequest.RawUrl"/>.</param>
|
||||
/// <param name="physicalPath">The physical path of the requested resource.</param>
|
||||
/// <returns>A handler instance for the current request.</returns>
|
||||
protected override IHttpHandler CreateHandlerInstance( HttpContext context, string requestType, string url, string physicalPath )
|
||||
{
|
||||
IHttpHandler pageHandlerWrapper;
|
||||
IConfigurableApplicationContext appContext = GetCheckedApplicationContext( url );
|
||||
|
||||
lock (pageHandlerWrappers.SyncRoot)
|
||||
if (appContext == null)
|
||||
{
|
||||
pageHandlerWrapper = (PageHandlerWrapper)pageHandlerWrappers[url];
|
||||
throw new InvalidOperationException(
|
||||
"Implementations of IApplicationContext must also implement IConfigurableApplicationContext" );
|
||||
}
|
||||
|
||||
if (pageHandlerWrapper != null)
|
||||
string appRelativeVirtualPath = WebUtils.GetAppRelativePath( url );
|
||||
NamedObjectDefinition namedPageDefinition = FindWebObjectDefinition( appRelativeVirtualPath, appContext.ObjectFactory );
|
||||
|
||||
if (namedPageDefinition != null)
|
||||
{
|
||||
if (isDebug)
|
||||
Type pageType = namedPageDefinition.ObjectDefinition.ObjectType;
|
||||
if (typeof( IRequiresSessionState ).IsAssignableFrom( pageType ))
|
||||
{
|
||||
Log.Debug(string.Format("GetHandler():resolved url '{0}' from reusable handler cache", url));
|
||||
pageHandlerWrapper = new SessionAwarePageHandlerWrapper( appContext, namedPageDefinition.Name, url, null );
|
||||
}
|
||||
else
|
||||
{
|
||||
pageHandlerWrapper = new PageHandlerWrapper( appContext, namedPageDefinition.Name, url, null );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IConfigurableApplicationContext appContext =
|
||||
WebApplicationContext.GetContext(url) as IConfigurableApplicationContext;
|
||||
|
||||
if (appContext == null)
|
||||
Type pageType = WebObjectUtils.GetCompiledPageType( url );
|
||||
if (typeof( IRequiresSessionState ).IsAssignableFrom( pageType ))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Implementations of IApplicationContext must also implement IConfigurableApplicationContext");
|
||||
}
|
||||
|
||||
string appRelativeVirtualPath = WebUtils.GetAppRelativePath(url);
|
||||
NamedObjectDefinition namedPageDefinition = FindWebObjectDefinition(appRelativeVirtualPath, appContext.ObjectFactory);
|
||||
|
||||
if (namedPageDefinition != null)
|
||||
{
|
||||
Type pageType = namedPageDefinition.ObjectDefinition.ObjectType;
|
||||
if (typeof(IRequiresSessionState).IsAssignableFrom(pageType))
|
||||
{
|
||||
pageHandlerWrapper = new SessionAwarePageHandlerWrapper(appContext, namedPageDefinition.Name, url, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
pageHandlerWrapper = new PageHandlerWrapper(appContext, namedPageDefinition.Name, url, null);
|
||||
}
|
||||
pageHandlerWrapper = new SessionAwarePageHandlerWrapper( appContext, appRelativeVirtualPath, url, physicalPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
Type pageType = WebObjectUtils.GetCompiledPageType(url);
|
||||
if (typeof(IRequiresSessionState).IsAssignableFrom(pageType))
|
||||
{
|
||||
pageHandlerWrapper = new SessionAwarePageHandlerWrapper(appContext, appRelativeVirtualPath, url, physicalPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
pageHandlerWrapper = new PageHandlerWrapper(appContext, appRelativeVirtualPath, url, physicalPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (pageHandlerWrapper.IsReusable)
|
||||
{
|
||||
lock (pageHandlerWrappers.SyncRoot)
|
||||
{
|
||||
pageHandlerWrappers[url] = pageHandlerWrapper;
|
||||
}
|
||||
pageHandlerWrapper = new PageHandlerWrapper( appContext, appRelativeVirtualPath, url, physicalPath );
|
||||
}
|
||||
}
|
||||
|
||||
return pageHandlerWrapper;
|
||||
}
|
||||
}
|
||||
@@ -169,15 +148,15 @@ namespace Spring.Web.Support
|
||||
{
|
||||
#if NET_2_0 && !MONO_2_0
|
||||
private static readonly FieldInfo fiHttpContext_CurrentHandler =
|
||||
typeof(HttpContext).GetField("_currentHandler", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
typeof( HttpContext ).GetField( "_currentHandler", BindingFlags.NonPublic | BindingFlags.Instance );
|
||||
#endif
|
||||
#if MONO_2_0
|
||||
private static readonly FieldInfo fiHttpContext_CurrentHandler =
|
||||
typeof(HttpContext).GetField("handler", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
#endif
|
||||
#if NET_2_0 || !MONO_2_0
|
||||
private static readonly MethodInfo miPage_SetPreviousPage =
|
||||
typeof(System.Web.UI.Page).GetMethod("SetPreviousPage", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
private static readonly MethodInfo miPage_SetPreviousPage =
|
||||
typeof( System.Web.UI.Page ).GetMethod( "SetPreviousPage", BindingFlags.NonPublic | BindingFlags.Instance );
|
||||
#endif
|
||||
|
||||
private readonly IApplicationContext appContext;
|
||||
@@ -202,7 +181,7 @@ namespace Spring.Web.Support
|
||||
/// <param name="pageName">Name of the page object to execute.</param>
|
||||
/// <param name="url">Requested page URL.</param>
|
||||
/// <param name="path">Translated server path for the page.</param>
|
||||
public PageHandlerWrapper(IApplicationContext appContext, string pageName, string url, string path)
|
||||
public PageHandlerWrapper( IApplicationContext appContext, string pageName, string url, string path )
|
||||
{
|
||||
this.appContext = appContext;
|
||||
this.pageId = pageName;
|
||||
@@ -215,8 +194,8 @@ namespace Spring.Web.Support
|
||||
/// </summary>
|
||||
/// <param name="appContext">Application context instance to retrieve page from.</param>
|
||||
/// <param name="pageName">Name of the page object to execute.</param>
|
||||
public PageHandlerWrapper(IApplicationContext appContext, string pageName)
|
||||
: this(appContext, pageName, null, null)
|
||||
public PageHandlerWrapper( IApplicationContext appContext, string pageName )
|
||||
: this( appContext, pageName, null, null )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -245,7 +224,7 @@ namespace Spring.Web.Support
|
||||
|
||||
#endregion
|
||||
|
||||
void IHttpHandler.ProcessRequest(HttpContext context)
|
||||
void IHttpHandler.ProcessRequest( HttpContext context )
|
||||
{
|
||||
IHttpHandler handler = cachedHandler;
|
||||
|
||||
@@ -257,11 +236,12 @@ namespace Spring.Web.Support
|
||||
}
|
||||
else
|
||||
{
|
||||
handler = GetOrCreateProcessHandler(context);
|
||||
handler = GetOrCreateProcessHandler( context );
|
||||
}
|
||||
|
||||
// note, that we don't care about sync here. The last call wins (it's the most current handler instance anyway)
|
||||
if (handler.IsReusable) cachedHandler = handler;
|
||||
if (handler.IsReusable)
|
||||
cachedHandler = handler;
|
||||
}
|
||||
|
||||
// replace handler proxy on context with "real" handler
|
||||
@@ -276,29 +256,29 @@ namespace Spring.Web.Support
|
||||
// fix this...
|
||||
if (this == context.CurrentHandler)
|
||||
{
|
||||
fiHttpContext_CurrentHandler.SetValue(context, handler);
|
||||
fiHttpContext_CurrentHandler.SetValue( context, handler );
|
||||
}
|
||||
|
||||
if (handler is System.Web.UI.Page)
|
||||
{
|
||||
System.Web.UI.Page page = (Page) handler;
|
||||
System.Web.UI.Page page = (Page)handler;
|
||||
|
||||
// TODO: to fix this would require a change to the Mono source as there is no mechanisim (public or private) for explicitly setting the
|
||||
// PreviousPage at the moment
|
||||
// TODO: to fix this would require a change to the Mono source as there is no mechanisim (public or private) for explicitly setting the
|
||||
// PreviousPage at the moment
|
||||
#if !MONO_2_0
|
||||
// During Server.Transfer/Execute() the PreviousPage property gets set
|
||||
if (this.PreviousPage != null)
|
||||
{
|
||||
miPage_SetPreviousPage.Invoke(page, new object[] { this.PreviousPage });
|
||||
miPage_SetPreviousPage.Invoke( page, new object[] { this.PreviousPage } );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
ApplySharedState(handler);
|
||||
ApplyDependencyInjection(handler);
|
||||
ApplySharedState( handler );
|
||||
ApplyDependencyInjection( handler );
|
||||
|
||||
handler.ProcessRequest(context);
|
||||
handler.ProcessRequest( context );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -316,7 +296,7 @@ namespace Spring.Web.Support
|
||||
private IHttpHandler CreatePageInstance()
|
||||
{
|
||||
IHttpHandler handler;
|
||||
handler = WebObjectUtils.CreatePageInstance(url);
|
||||
handler = WebObjectUtils.CreatePageInstance( url );
|
||||
if (handler is IApplicationContextAware)
|
||||
{
|
||||
((IApplicationContextAware)handler).ApplicationContext = appContext;
|
||||
@@ -327,21 +307,21 @@ namespace Spring.Web.Support
|
||||
/// <summary>
|
||||
/// Gets or - if not found - creates a process handler instance.
|
||||
/// </summary>
|
||||
private IHttpHandler GetOrCreateProcessHandler(HttpContext context)
|
||||
private IHttpHandler GetOrCreateProcessHandler( HttpContext context )
|
||||
{
|
||||
IHttpHandler handler = null;
|
||||
string processId = context.Request[AbstractProcessHandler.ProcessIdParamName];
|
||||
if (processId != null)
|
||||
{
|
||||
handler = (IHttpHandler)ProcessManager.GetProcess(processId);
|
||||
handler = (IHttpHandler)ProcessManager.GetProcess( processId );
|
||||
}
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
handler = (IHttpHandler)this.appContext.GetObject(this.pageId);
|
||||
handler = (IHttpHandler)this.appContext.GetObject( this.pageId );
|
||||
if (handler is IProcess)
|
||||
{
|
||||
((IProcess)handler).Start(url);
|
||||
((IProcess)handler).Start( url );
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
@@ -351,11 +331,11 @@ namespace Spring.Web.Support
|
||||
/// Apply dependency injection stuff on the handler.
|
||||
/// </summary>
|
||||
/// <param name="handler"></param>
|
||||
private void ApplyDependencyInjection(IHttpHandler handler)
|
||||
private void ApplyDependencyInjection( IHttpHandler handler )
|
||||
{
|
||||
if (handler is Control)
|
||||
{
|
||||
ControlInterceptor.EnsureControlIntercepted(appContext, (Control)handler);
|
||||
ControlInterceptor.EnsureControlIntercepted( appContext, (Control)handler );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -369,11 +349,11 @@ namespace Spring.Web.Support
|
||||
/// <summary>
|
||||
/// Applies <see cref="HandlerState"/> to the given handler if applicable.
|
||||
/// </summary>
|
||||
private void ApplySharedState(IHttpHandler handler)
|
||||
private void ApplySharedState( IHttpHandler handler )
|
||||
{
|
||||
if (handler is ISharedStateAware)
|
||||
{
|
||||
CheckIfPageWasRecompiled(handler);
|
||||
CheckIfPageWasRecompiled( handler );
|
||||
((ISharedStateAware)handler).SharedState = this.handlerState;
|
||||
}
|
||||
}
|
||||
@@ -382,7 +362,7 @@ namespace Spring.Web.Support
|
||||
/// Checks, if page has been recompiled. Creates/discards handlerState if necessary.
|
||||
/// </summary>
|
||||
/// <param name="handler"></param>
|
||||
private void CheckIfPageWasRecompiled(IHttpHandler handler)
|
||||
private void CheckIfPageWasRecompiled( IHttpHandler handler )
|
||||
{
|
||||
if (handlerType != handler.GetType())
|
||||
{
|
||||
@@ -415,8 +395,8 @@ namespace Spring.Web.Support
|
||||
/// <param name="pageName">Name of the page object to execute.</param>
|
||||
/// <param name="url">Requested page URL.</param>
|
||||
/// <param name="path">Translated server path for the page.</param>
|
||||
public SessionAwarePageHandlerWrapper(IApplicationContext appContext, string pageName, string url, string path)
|
||||
: base(appContext, pageName, url, path)
|
||||
public SessionAwarePageHandlerWrapper( IApplicationContext appContext, string pageName, string url, string path )
|
||||
: base( appContext, pageName, url, path )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -425,8 +405,8 @@ namespace Spring.Web.Support
|
||||
/// </summary>
|
||||
/// <param name="appContext">Application context instance to retrieve page from.</param>
|
||||
/// <param name="pageName">Name of the page object to execute.</param>
|
||||
public SessionAwarePageHandlerWrapper(IApplicationContext appContext, string pageName)
|
||||
: base(appContext, pageName)
|
||||
public SessionAwarePageHandlerWrapper( IApplicationContext appContext, string pageName )
|
||||
: base( appContext, pageName )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<%@ Page language="c#" EnableSessionState="ReadOnly" AutoEventWireup="false" Inherits="Spring.Web.UI.Page" %><script language="c#" runat="server">
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
try
|
||||
{
|
||||
Session["disablesSession"] = "somevalue";
|
||||
NUnit.Framework.Assert.Fail("must not be able to write to session");
|
||||
}
|
||||
catch(HttpException)
|
||||
{}
|
||||
}
|
||||
</script><%=Session.IsReadOnly?"OK":"NOK"%>
|
||||
@@ -131,6 +131,7 @@
|
||||
<EmbeddedResource Include="Context\Support\HttpApplicationConfigurerTests.xml" />
|
||||
<Content Include="Data\Spring\Context\Support\WebApplicationContextTests\Dummy.aspx" />
|
||||
<Content Include="Data\Spring\Objects\Factory\Support\TestForm.aspx" />
|
||||
<Content Include="Data\Spring\Web\Support\PageHandlerFactoryTests\ReadOnlySession.aspx" />
|
||||
<Content Include="Data\Spring\Web\Support\PageHandlerFactoryTests\TransferAfterSetResult.aspx" />
|
||||
<Content Include="Data\Spring\Web\Support\PageHandlerFactoryTests\MaintainsSession1.aspx" />
|
||||
<Content Include="Data\Spring\Web\Support\PageHandlerFactoryTests\MaintainsSession2.aspx" />
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
using System;
|
||||
using System.Web;
|
||||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using Spring.Context;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
@@ -35,51 +37,180 @@ namespace Spring.Web.Support
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
[TestFixture]
|
||||
public class AbstractHandlerFactoryTests : AbstractHandlerFactory
|
||||
public class AbstractHandlerFactoryTests
|
||||
{
|
||||
private class Type1 {}
|
||||
|
||||
#region TestFindWebObjectDefinition Helper
|
||||
|
||||
private class TestFindWebObjectDefinitionHandlerFactory : AbstractHandlerFactory
|
||||
{
|
||||
private class Type1 { }
|
||||
|
||||
public void TestFindWebObjectDefinition()
|
||||
{
|
||||
NamedObjectDefinition nod;
|
||||
|
||||
nod = Find( "/path/o1.ext", "/path/o1.ext" );
|
||||
Assert.AreEqual( typeof( Type1 ), nod.ObjectDefinition.ObjectType );
|
||||
Assert.AreEqual( "/path/o1.ext", nod.Name );
|
||||
|
||||
nod = Find( "/path/o1.ext", "/o1.ext" );
|
||||
Assert.IsNull( nod );
|
||||
|
||||
nod = Find( "/path/o1.ext", "/path/o1" );
|
||||
Assert.IsNull( nod );
|
||||
|
||||
nod = Find( "/path/o1.ext", "o1.ext" );
|
||||
Assert.AreEqual( typeof( Type1 ), nod.ObjectDefinition.ObjectType );
|
||||
Assert.AreEqual( "o1.ext", nod.Name );
|
||||
|
||||
nod = Find( "/path/o1.ext", "o1" );
|
||||
Assert.AreEqual( typeof( Type1 ), nod.ObjectDefinition.ObjectType );
|
||||
Assert.AreEqual( "o1", nod.Name );
|
||||
}
|
||||
|
||||
private static NamedObjectDefinition Find( string url, string objectName )
|
||||
{
|
||||
DefaultListableObjectFactory of = new DefaultListableObjectFactory();
|
||||
RootObjectDefinition rod = new RootObjectDefinition( typeof( Type1 ) );
|
||||
of.RegisterObjectDefinition( objectName, rod );
|
||||
|
||||
return FindWebObjectDefinition( url, of );
|
||||
}
|
||||
|
||||
#region AbstractHandlerFactory implementations
|
||||
|
||||
protected override IHttpHandler CreateHandlerInstance( HttpContext context, string requestType, string url, string physicalPath )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion TestFindWebObjectDefinition Helper
|
||||
|
||||
[Test]
|
||||
public void FindWebObjectDefinition()
|
||||
{
|
||||
NamedObjectDefinition nod;
|
||||
|
||||
nod = Find("/path/o1.ext", "/path/o1.ext");
|
||||
Assert.AreEqual( typeof(Type1), nod.ObjectDefinition.ObjectType);
|
||||
Assert.AreEqual( "/path/o1.ext", nod.Name);
|
||||
|
||||
nod = Find("/path/o1.ext", "/o1.ext");
|
||||
Assert.IsNull(nod);
|
||||
|
||||
nod = Find("/path/o1.ext", "/path/o1");
|
||||
Assert.IsNull(nod);
|
||||
|
||||
nod = Find("/path/o1.ext", "o1.ext");
|
||||
Assert.AreEqual(typeof(Type1), nod.ObjectDefinition.ObjectType);
|
||||
Assert.AreEqual("o1.ext", nod.Name);
|
||||
|
||||
nod = Find("/path/o1.ext", "o1");
|
||||
Assert.AreEqual(typeof(Type1), nod.ObjectDefinition.ObjectType);
|
||||
Assert.AreEqual("o1", nod.Name);
|
||||
TestFindWebObjectDefinitionHandlerFactory f = new TestFindWebObjectDefinitionHandlerFactory();
|
||||
f.TestFindWebObjectDefinition();
|
||||
}
|
||||
|
||||
private NamedObjectDefinition Find(string url, string objectName)
|
||||
#region TestHandlerFactory
|
||||
|
||||
public class TestHandlerFactory : AbstractHandlerFactory
|
||||
{
|
||||
DefaultListableObjectFactory of = new DefaultListableObjectFactory();
|
||||
RootObjectDefinition rod = new RootObjectDefinition(typeof(Type1));
|
||||
of.RegisterObjectDefinition(objectName, rod);
|
||||
public new IConfigurableApplicationContext GetCheckedApplicationContext(string virtualPath)
|
||||
{
|
||||
return base.GetCheckedApplicationContext(virtualPath);
|
||||
}
|
||||
|
||||
return FindWebObjectDefinition( url, of );
|
||||
protected override IHttpHandler CreateHandlerInstance(HttpContext context, string requestType, string url, string physicalPath )
|
||||
{
|
||||
return CreateHandlerInstanceStub(context, requestType, url, physicalPath);
|
||||
}
|
||||
|
||||
public virtual IHttpHandler CreateHandlerInstanceStub(HttpContext context, string requestType, string url, string physicalPath)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override IApplicationContext GetContext( string virtualPath )
|
||||
{
|
||||
return GetContextStub( virtualPath );
|
||||
}
|
||||
|
||||
public virtual IApplicationContext GetContextStub( string virtualPath )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
#region AbstractHandlerFactory implementations
|
||||
|
||||
public override IHttpHandler GetHandler(HttpContext context, string requestType, string url,
|
||||
string pathTranslated)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[Test]
|
||||
public void GetCheckedApplicationContextThrowsExceptionsOnNonConfigurableContexts()
|
||||
{
|
||||
MockRepository mocks = new MockRepository();
|
||||
TestHandlerFactory f = (TestHandlerFactory) mocks.PartialMock(typeof(TestHandlerFactory));
|
||||
IApplicationContext simpleAppContext = (IApplicationContext) mocks.Stub(typeof(IApplicationContext));
|
||||
IConfigurableApplicationContext allowedAppContext = (IConfigurableApplicationContext) mocks.Stub(typeof(IConfigurableApplicationContext));
|
||||
|
||||
using(mocks.Record())
|
||||
{
|
||||
Expect.Call(f.GetContextStub("/NullContext")).Return(null);
|
||||
Expect.Call(f.GetContextStub("/NonConfigurableContext")).Return(simpleAppContext);
|
||||
Expect.Call(f.GetContextStub("/AllowedContext")).Return(allowedAppContext);
|
||||
}
|
||||
|
||||
// (context == null) -> ArgumentException
|
||||
try
|
||||
{
|
||||
f.GetCheckedApplicationContext("/NullContext");
|
||||
Assert.Fail("should throw ArgumentException");
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{}
|
||||
|
||||
// !(context is IConfigurableApplicationContext) -> InvalidOperationException
|
||||
try
|
||||
{
|
||||
f.GetCheckedApplicationContext("/NonConfigurableContext");
|
||||
Assert.Fail("should throw InvalidOperationException");
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{}
|
||||
|
||||
// (context is IConfigurableApplicationContext) -> OK
|
||||
Assert.AreSame(allowedAppContext, f.GetCheckedApplicationContext("/AllowedContext"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CachesReusableHandlers()
|
||||
{
|
||||
MockRepository mocks = new MockRepository();
|
||||
TestHandlerFactory f = (TestHandlerFactory) mocks.PartialMock(typeof(TestHandlerFactory));
|
||||
IHttpHandler reusableHandler = (IHttpHandler) mocks.Stub(typeof(IHttpHandler));
|
||||
Expect.Call(reusableHandler.IsReusable).Return(true);
|
||||
IHttpHandler reusableHandler2 = (IHttpHandler) mocks.Stub(typeof(IHttpHandler));
|
||||
Expect.Call(reusableHandler2.IsReusable).Return(true);
|
||||
|
||||
// if (IHttpHandler.IsReusable == true) => always returns the same handler instance
|
||||
// - CreateHandlerInstance() is only called once
|
||||
using(mocks.Record())
|
||||
{
|
||||
Expect.Call(f.CreateHandlerInstanceStub(null, null, "reusable", null)).Return(reusableHandler);
|
||||
}
|
||||
using (mocks.Playback())
|
||||
{
|
||||
Assert.AreSame( reusableHandler, f.GetHandler( null, null, "reusable", null ) );
|
||||
Assert.AreSame( reusableHandler, f.GetHandler( null, null, "reusable", null ) );
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DoesntCacheNonReusableHandlers()
|
||||
{
|
||||
MockRepository mocks = new MockRepository();
|
||||
TestHandlerFactory f = (TestHandlerFactory) mocks.PartialMock(typeof(TestHandlerFactory));
|
||||
IHttpHandler nonReusableHandler = (IHttpHandler) mocks.DynamicMock(typeof(IHttpHandler));
|
||||
Expect.Call(nonReusableHandler.IsReusable).Return(false);
|
||||
IHttpHandler nonReusableHandler2 = (IHttpHandler) mocks.DynamicMock(typeof(IHttpHandler));
|
||||
Expect.Call(nonReusableHandler2.IsReusable).Return(false);
|
||||
|
||||
// if (IHttpHandler.IsReusable == false) => always create new handler instance
|
||||
// - CreateHandlerInstance() is called for each request
|
||||
using(mocks.Record())
|
||||
{
|
||||
Expect.Call(f.CreateHandlerInstanceStub(null, null, "notreusable", null)).Return(nonReusableHandler);
|
||||
Expect.Call(f.CreateHandlerInstanceStub(null, null, "notreusable", null)).Return(nonReusableHandler2);
|
||||
}
|
||||
using (mocks.Playback())
|
||||
{
|
||||
Assert.AreSame( nonReusableHandler, f.GetHandler( null, null, "notreusable", null ) );
|
||||
Assert.AreSame( nonReusableHandler2, f.GetHandler( null, null, "notreusable", null ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,14 @@ namespace Spring.Web.Support
|
||||
Assert.AreEqual("OK", result);
|
||||
}
|
||||
|
||||
[Test, Explicit]
|
||||
public void UsesReadonlySession()
|
||||
{
|
||||
AspTestClient client = new AspTestClient();
|
||||
string result = client.GetPage("ReadOnlySession.aspx");
|
||||
Assert.AreEqual("OK", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MaintainsSession()
|
||||
{
|
||||
@@ -60,7 +68,7 @@ namespace Spring.Web.Support
|
||||
result = client.GetPage("MaintainsSession2.aspx");
|
||||
Assert.AreEqual("OK", result);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void BCLPageHandlerFactoryBehavior()
|
||||
{
|
||||
@@ -125,4 +133,14 @@ namespace Spring.Web.Support
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
public class PageHandlerFactoryStandaloneTests
|
||||
{
|
||||
[Test]
|
||||
public void PageUsesReadonlySessionState()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user