1 // Copyright 2004-2008 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
.ActiveRecordSupport
18 using System
.Reflection
;
19 using Castle
.Components
.Binder
;
20 using Castle
.MonoRail
.Framework
;
23 /// Defines the behavior of
24 /// Autoload feature on <see cref="ARDataBinder"/>
26 public enum AutoLoadBehavior
29 /// Means that no autoload should be performed on the target
30 /// type or on nested types.
35 /// Means that autoload should be used for the target type
36 /// and the nested types (if present). This demands that
37 /// the primary key be present on the http request
42 /// Does not load the root type, but loads nested types
43 /// if the primary key is present. If not present, sets null on nested type.
48 /// Means that we should autoload, but if the key is
49 /// invalid, like <c>null</c>, 0 or an empty string, then just
50 /// create a new instance of the target type.
52 NewInstanceIfInvalidKey
,
55 /// Means that we should autoload target and nested types when the key is valid.
56 /// If the key is invalid, like <c>null</c>, 0 or an empty string, and the
57 /// instance is the root instance, then create a new instance of the target type.
58 /// If the key is invalid, and it's a nested instance, then set null on the nested type.
60 NewRootInstanceIfInvalidKey
,
63 /// Means that we should autoload, but if the key is
64 /// invalid, like <c>null</c>, 0 or an empty string, then just
71 /// Extends <see cref="DataBindAttribute"/> with
72 /// ActiveRecord specific functionallity
74 [AttributeUsage(AttributeTargets
.Parameter
), Serializable
]
75 public class ARDataBindAttribute
: DataBindAttribute
77 private AutoLoadBehavior autoLoad
= AutoLoadBehavior
.Never
;
78 private string expect
= null;
81 /// Defines a binder for the parameter
82 /// using the <see cref="ARDataBinder"/> and the
83 /// specified <c>prefix</c>.
86 /// This uses the default <see cref="AutoLoadBehavior"/>
87 /// whic is <see cref="AutoLoadBehavior.Never"/>
89 /// <param name="prefix">A name that prefixes the entries on the http request</param>
90 public ARDataBindAttribute(String prefix
) : base(prefix
)
95 /// Defines a binder for the parameter
96 /// using the <see cref="ARDataBinder"/> and the
97 /// specified <c>prefix</c>.
99 /// <param name="prefix">A name that prefixes the entries on the http request</param>
100 /// <param name="autoLoadBehavior">The predefined behavior the autoload feature should use</param>
101 public ARDataBindAttribute(String prefix
, AutoLoadBehavior autoLoadBehavior
) : base(prefix
)
103 autoLoad
= autoLoadBehavior
;
107 /// Defines the behavior the autoload feature
110 public AutoLoadBehavior AutoLoad
112 get { return autoLoad; }
113 set { autoLoad = value; }
117 /// Gets or sets the names of the collection that are expected to be binded.
118 /// If the binder does not find any value to an expected collection, it will clear to collection.
120 /// <value>The expect collections names, in a csv fashion.</value>
123 get { return expect; }
124 set { expect = value; }
128 /// Implementation of <see cref="IParameterBinder.Bind"/>
129 /// and it is used to read the data available and construct the
130 /// parameter type accordingly.
132 /// <param name="context">The context.</param>
133 /// <param name="controller">The controller instance</param>
134 /// <param name="controllerContext">The controller context.</param>
135 /// <param name="parameterInfo">The parameter info</param>
136 /// <returns>The bound instance</returns>
137 public override object Bind(IEngineContext context
, IController controller
, IControllerContext controllerContext
, ParameterInfo parameterInfo
)
139 ARDataBinder binder
= (ARDataBinder
) CreateBinder();
140 IValidatorAccessor validatorAccessor
= controller
as IValidatorAccessor
;
142 ConfigureValidator(validatorAccessor
, binder
);
144 binder
.AutoLoad
= autoLoad
;
146 CompositeNode node
= context
.Request
.ObtainParamsNode(From
);
148 object instance
= binder
.BindObject(parameterInfo
.ParameterType
, Prefix
, Exclude
, Allow
, Expect
, node
);
150 BindInstanceErrors(validatorAccessor
, binder
, instance
);
151 PopulateValidatorErrorSummary(validatorAccessor
, binder
, instance
);
156 protected override IDataBinder
CreateBinder()
158 return new ARDataBinder();