1 /* Copyright 2006-2007 Graeme Rocher
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 package org
.codehaus
.groovy
.grails
.web
.binding
;
17 import groovy
.lang
.GroovySystem
;
18 import groovy
.lang
.MetaClass
;
19 import org
.apache
.commons
.collections
.CollectionUtils
;
20 import org
.codehaus
.groovy
.grails
.web
.servlet
.mvc
.GrailsParameterMap
;
21 import org
.codehaus
.groovy
.grails
.web
.servlet
.mvc
.GrailsWebRequest
;
22 import org
.springframework
.beans
.MutablePropertyValues
;
23 import org
.springframework
.validation
.BindingResult
;
24 import org
.springframework
.web
.context
.request
.RequestContextHolder
;
26 import javax
.servlet
.http
.HttpServletRequest
;
27 import java
.util
.ArrayList
;
28 import java
.util
.Collections
;
29 import java
.util
.List
;
33 * Utility methods to perform data binding from Grails objects
35 * @author Graeme Rocher
39 * Created: Sep 13, 2007
42 public class DataBindingUtils
{
45 * Binds the given source object to the given target object performing type conversion if necessary
47 * @param object The object to bind to
48 * @param source The source object
49 * @return A BindingResult or null if it wasn't successful
51 public static BindingResult
bindObjectToInstance(Object object
, Object source
) {
52 return bindObjectToInstance(object
, source
, Collections
.EMPTY_LIST
,Collections
.EMPTY_LIST
, null);
56 * Binds the given source object to the given target object performing type conversion if necessary
58 * @param object The object to bind to
59 * @param source The source object
60 * @param include The list of properties to include
61 * @param exclude The list of properties to exclude
63 * @return A BindingResult or null if it wasn't successful
65 public static BindingResult
bindObjectToInstance(Object object
, Object source
, List include
, List exclude
, String filter
) {
66 BindingResult bindingResult
= null;
67 if(source
instanceof GrailsParameterMap
) {
68 GrailsParameterMap parameterMap
= (GrailsParameterMap
)source
;
69 HttpServletRequest request
= parameterMap
.getRequest();
70 GrailsDataBinder dataBinder
= createDataBinder(object
, include
, exclude
, request
);
71 dataBinder
.bind(parameterMap
);
72 bindingResult
= dataBinder
.getBindingResult();
74 else if (source
instanceof HttpServletRequest
) {
75 HttpServletRequest request
= (HttpServletRequest
)source
;
76 GrailsDataBinder dataBinder
= createDataBinder(object
, include
, exclude
, request
);
77 dataBinder
.bind(request
);
78 performBindFromRequest(dataBinder
, request
,filter
);
79 bindingResult
= dataBinder
.getBindingResult();
81 else if(source
instanceof Map
) {
82 Map propertyMap
= (Map
)source
;
83 propertyMap
= convertPotentialGStrings(propertyMap
);
84 GrailsDataBinder binder
= createDataBinder(object
, include
, exclude
, null);
86 performBindFromPropertyValues(binder
, new MutablePropertyValues(propertyMap
),filter
);
87 bindingResult
= binder
.getBindingResult();
90 GrailsWebRequest webRequest
= (GrailsWebRequest
) RequestContextHolder
.getRequestAttributes();
91 if(webRequest
!= null) {
92 GrailsDataBinder binder
= createDataBinder(object
, include
, exclude
, webRequest
.getCurrentRequest());
93 HttpServletRequest request
= webRequest
.getCurrentRequest();
94 performBindFromRequest(binder
, request
,filter
);
99 MetaClass mc
= GroovySystem
.getMetaClassRegistry().getMetaClass(object
.getClass());
100 if(mc
.hasProperty(object
, "errors")!=null && bindingResult
!=null) {
101 mc
.setProperty(object
,"errors", bindingResult
);
103 return bindingResult
;
106 private static void performBindFromPropertyValues(GrailsDataBinder binder
, MutablePropertyValues mutablePropertyValues
, String filter
) {
108 binder
.bind(mutablePropertyValues
,filter
);
111 binder
.bind(mutablePropertyValues
);
115 private static void performBindFromRequest(GrailsDataBinder binder
, HttpServletRequest request
,String filter
) {
117 binder
.bind(request
,filter
);
120 binder
.bind(request
);
124 private static GrailsDataBinder
createDataBinder(Object object
, List include
, List exclude
, HttpServletRequest request
) {
126 GrailsDataBinder binder
;
128 binder
= GrailsDataBinder
.createBinder(object
, object
.getClass().getName(), request
);
131 binder
= GrailsDataBinder
.createBinder(object
, object
.getClass().getName());
133 includeExcludeFields(binder
, include
, exclude
);
137 private static Map
convertPotentialGStrings(Map args
) {
138 Map newArgs
= new java
.util
.HashMap();
139 for(java
.util
.Iterator i
= args
.keySet().iterator(); i
.hasNext();) {
140 Object key
= i
.next();
141 Object value
= args
.get(key
);
142 if(key
instanceof groovy
.lang
.GString
) {
143 key
= key
.toString();
145 if(value
instanceof groovy
.lang
.GString
) {
146 value
= value
.toString();
148 newArgs
.put(key
,value
);
153 private static void includeExcludeFields(GrailsDataBinder dataBinder
, List allowed
, List disallowed
) {
154 updateAllowed( dataBinder
, allowed
);
155 updateDisallowed( dataBinder
, disallowed
);
158 private static void updateAllowed(GrailsDataBinder binder
, List allowed
) {
159 if (allowed
!= null) {
160 String
[] currentAllowed
= binder
.getAllowedFields();
161 List newAllowed
= new ArrayList(allowed
);
162 CollectionUtils
.addAll( newAllowed
, currentAllowed
);
163 String
[] value
= new String
[newAllowed
.size()];
164 newAllowed
.toArray(value
);
165 binder
.setAllowedFields(value
);
169 private static void updateDisallowed( GrailsDataBinder binder
, List disallowed
) {
170 if (disallowed
!= null) {
171 String
[] currentDisallowed
= binder
.getDisallowedFields();
172 List newDisallowed
= new ArrayList(disallowed
);
173 CollectionUtils
.addAll( newDisallowed
, currentDisallowed
);
174 String
[] value
= new String
[newDisallowed
.size()];
175 newDisallowed
.toArray(value
);
176 binder
.setDisallowedFields(value
);