Minor changes to improve testability of helpers
[castle.git] / MonoRail / Castle.MonoRail.Framework / MonoRailHttpHandler.cs
blob932f092ba3815b9e9d0642f0730c699f5bc6c190
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.MonoRail.Framework
17 using System;
18 using System.Web;
19 using System.Web.SessionState;
20 using Castle.Core.Logging;
21 using Castle.MonoRail.Framework.Adapters;
23 /// <summary>
24 /// Implements <see cref="IHttpHandler"/> to dispatch the web
25 /// requests.
26 /// <seealso cref="MonoRailHttpHandlerFactory"/>
27 /// </summary>
28 public class MonoRailHttpHandler : IHttpHandler, IRequiresSessionState
30 /// <summary>Logger instance that won't be null, even when logging is disabled</summary>
31 private readonly ILogger logger;
33 /// <summary>
34 /// Constructs a <c>MonoRailHttpHandler</c>
35 /// </summary>
36 /// <param name="logger"></param>
37 public MonoRailHttpHandler(ILogger logger)
39 this.logger = logger;
42 #region IHttpHandler implementation
44 /// <summary>
45 /// Pendent
46 /// </summary>
47 /// <param name="context"></param>
48 public void ProcessRequest(HttpContext context)
50 IRailsEngineContext mrContext = EngineContextModule.ObtainRailsEngineContext(context);
52 Process(mrContext);
55 /// <summary>
56 /// Pendent
57 /// </summary>
58 public bool IsReusable
60 get { return true; }
63 #endregion
65 /// <summary>
66 /// Performs the base work of MonoRail. Extracts
67 /// the information from the URL, obtain the controller
68 /// that matches this information and dispatch the execution
69 /// to it.
70 /// </summary>
71 /// <param name="context"></param>
72 public virtual void Process(IRailsEngineContext context)
74 ControllerLifecycleExecutor executor =
75 (ControllerLifecycleExecutor) context.Items[ControllerLifecycleExecutor.ExecutorEntry];
77 DefaultRailsEngineContext contextImpl = (DefaultRailsEngineContext) context;
78 contextImpl.ResolveRequestSession();
80 context.Items["mr.controller"] = executor.Controller;
81 context.Items["mr.flash"] = executor.Controller.Flash;
82 context.Items["mr.propertybag"] = executor.Controller.PropertyBag;
83 context.Items["mr.session"] = context.Session;
85 // At this point, the before filters were executed.
86 // So we just need to perform the secondary initialization
87 // and invoke the action
89 try
91 if (executor.HasError) // Some error happened
93 executor.PerformErrorHandling();
95 else
97 executor.ProcessSelectedAction();
100 catch(Exception ex)
102 if (logger.IsErrorEnabled)
104 logger.Error("Error processing " + context.Url, ex);
107 throw;
109 finally
113 executor.Dispose();
115 finally
117 IControllerFactory controllerFactory =
118 (IControllerFactory) context.GetService(typeof(IControllerFactory));
120 controllerFactory.Release(executor.Controller);
123 if (logger.IsDebugEnabled)
125 Controller controller = executor.Controller;
127 logger.DebugFormat("Ending request process for '{0}'/'{1}.{2}' Extension '{3}' with url '{4}'",
128 controller.AreaName, controller.Name, controller.Action, context.UrlInfo.Extension, context.UrlInfo.UrlRaw);
131 // Remove items from flash before leaving the page
132 context.Flash.Sweep();
134 if (context.Flash.HasItemsToKeep)
136 context.Session[Flash.FlashKey] = context.Flash;
138 else if (context.Session.Contains(Flash.FlashKey))
140 context.Session.Remove(Flash.FlashKey);
145 /// <summary>
146 /// Can be overriden so new semantics can be supported.
147 /// </summary>
148 /// <param name="context"></param>
149 /// <returns></returns>
150 protected virtual UrlInfo ExtractUrlInfo(IRailsEngineContext context)
152 return context.UrlInfo;
155 /// <summary>
156 /// Gets the current context.
157 /// </summary>
158 /// <value>The current context.</value>
159 public static IRailsEngineContext CurrentContext
163 HttpContext context = HttpContext.Current;
165 // Are we in a web request?
166 if (context == null) return null;
168 return EngineContextModule.ObtainRailsEngineContext(context);