1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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
18 using System
.Reflection
;
19 using Castle
.MonoRail
.Framework
.Descriptors
;
22 /// Associates a rescue template with a <see cref="IController"/> or an action
23 /// (method). The rescue is invoked in response to some exception during the
24 /// action processing.
27 /// The view must exist in the <c>rescues</c> folder in your view folder
29 [AttributeUsage(AttributeTargets
.Class
|AttributeTargets
.Method
, AllowMultiple
=true), Serializable
]
30 public class RescueAttribute
: Attribute
, IRescueDescriptorBuilder
32 private readonly String viewName
;
33 private readonly Type exceptionType
;
34 private readonly Type rescueController
;
35 private readonly MethodInfo rescueMethod
;
38 /// Constructs a RescueAttribute with the template name.
40 /// <param name="viewName">The view to use in the event of error</param>
41 public RescueAttribute(String viewName
) : this(viewName
, typeof(Exception
))
46 /// Constructs a RescueAttribute with the template name and exception type.
48 /// <param name="viewName">The view to use in the event of error</param>
49 /// <param name="exceptionType">The exception to match</param>
50 public RescueAttribute(String viewName
, Type exceptionType
)
52 if (viewName
== null || viewName
.Length
== 0)
54 throw new ArgumentNullException("viewName");
57 if (exceptionType
!= null && !typeof(Exception
).IsAssignableFrom(exceptionType
))
59 throw new ArgumentException("exceptionType must be a type assignable from Exception");
62 this.viewName
= viewName
;
63 this.exceptionType
= exceptionType
;
67 /// Use a controller to perform any actions on rescue. The view defaults to the rescues views.
69 /// <param name="rescueController">The controller to use to perform the rescue</param>
70 public RescueAttribute(Type rescueController
) : this(rescueController
, typeof(Exception
))
75 /// Use a controller to perform any actions on rescue. The view defaults to the rescues views.
77 /// <param name="rescueController">The controller to use to perform the rescue</param>
78 /// <param name="exceptionType">The exception to rescue for</param>
79 public RescueAttribute(Type rescueController
, Type exceptionType
) : this(rescueController
, null, exceptionType
)
84 /// Use a controller to perform any actions on rescue. The view defaults to the rescues views.
86 /// <param name="rescueController">The controller to use to perform the rescue</param>
87 /// <param name="rescueMethod">The method on the controller to use</param>
88 public RescueAttribute(Type rescueController
, string rescueMethod
)
89 : this(rescueController
, rescueMethod
, typeof(Exception
))
94 /// Use a controller to perform any actions on rescue. The view defaults to the rescues views.
96 /// <param name="rescueController">The controller to use to perform the rescue</param>
97 /// <param name="exceptionType">The exception to rescue for</param>
98 /// <param name="rescueMethod">The method on the controller to use</param>
99 public RescueAttribute(Type rescueController
, string rescueMethod
, Type exceptionType
)
101 if (!typeof(IRescueController
).IsAssignableFrom(rescueController
) && rescueMethod
== null)
103 throw new ArgumentException(string.Format("{0} does not implement {1}, and there is no rescueMethod defined. " +
104 "You can either inform a method to use through the 'rescueMethod' parameter or make the " +
105 "controller implement the IRescueController interface" , rescueController
.Name
, typeof(IRescueController
).Name
));
108 if (!typeof(IController
).IsAssignableFrom(rescueController
))
110 throw new ArgumentException(string.Format("{0} does not inherit from the Controller class", rescueController
.Name
));
113 this.rescueController
= rescueController
;
114 this.exceptionType
= exceptionType
;
115 this.rescueMethod
= (rescueMethod
!= null ? rescueController
.GetMethod(rescueMethod
) : null);
119 /// Gets the view name to use
121 public String ViewName
123 get { return viewName; }
127 /// Gets the exception type
129 public Type ExceptionType
131 get { return exceptionType; }
135 /// The controller to use for rescue
137 public Type RescueController
139 get { return rescueController; }
143 /// The method on the rescue controller to use
145 public MethodInfo RescueMethod
147 get { return rescueMethod; }
151 /// <see cref="IRescueDescriptorBuilder"/> implementation.
152 /// Builds the rescue descriptors.
154 /// <returns></returns>
155 public RescueDescriptor
[] BuildRescueDescriptors()
157 if (rescueController
!= null)
159 MethodInfo method
= (rescueMethod
?? typeof(IRescueController
).GetMethod("Rescue"));
160 return new RescueDescriptor
[] { new RescueDescriptor(rescueController, method, ExceptionType) }
;
163 return new RescueDescriptor
[] { new RescueDescriptor(viewName, exceptionType) }
;