View Javadoc
1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.web.controller;
17  
18  import org.kuali.rice.krad.uif.UifConstants;
19  import org.kuali.rice.krad.web.form.UifFormBase;
20  import org.springframework.core.MethodParameter;
21  import org.springframework.validation.BindException;
22  import org.springframework.validation.Errors;
23  import org.springframework.web.bind.ServletRequestDataBinder;
24  import org.springframework.web.bind.WebDataBinder;
25  import org.springframework.web.bind.annotation.ModelAttribute;
26  import org.springframework.web.bind.support.WebDataBinderFactory;
27  import org.springframework.web.context.request.NativeWebRequest;
28  import org.springframework.web.method.support.HandlerMethodArgumentResolver;
29  import org.springframework.web.method.support.ModelAndViewContainer;
30  
31  import javax.servlet.ServletRequest;
32  import java.util.Map;
33  
34  /**
35   * @author Kuali Rice Team (rice.collab@kuali.org)
36   */
37  public class UifDefaultFormMethodArgumentResolver implements HandlerMethodArgumentResolver {
38  
39      /**
40       * Default Constructor.
41       */
42      public UifDefaultFormMethodArgumentResolver() {
43          super();
44      }
45  
46      /**
47       * {@inheritDoc}
48       */
49      @Override
50      public boolean supportsParameter(MethodParameter parameter) {
51          boolean isUifForm = false;
52  
53          if (!parameter.hasParameterAnnotation(ModelAttribute.class) && UifFormBase.class.isAssignableFrom(
54                  parameter.getParameterType())) {
55              isUifForm = true;
56          }
57  
58          return isUifForm;
59      }
60  
61      /**
62       * {@inheritDoc}
63       */
64      @Override
65      public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
66              NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
67          String name = UifConstants.DEFAULT_MODEL_NAME;
68  
69          Object attribute = null;
70          if (mavContainer.containsAttribute(name)) {
71              attribute = mavContainer.getModel().get(name);
72          }
73  
74          WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
75          if (binder.getTarget() != null) {
76              ServletRequest servletRequest = webRequest.getNativeRequest(ServletRequest.class);
77              ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
78              servletBinder.bind(servletRequest);
79  
80              if (binder.getBindingResult().hasErrors()) {
81                  if (isBindExceptionRequired(parameter)) {
82                      throw new BindException(binder.getBindingResult());
83                  }
84              }
85          }
86  
87          Map<String, Object> bindingResultModel = binder.getBindingResult().getModel();
88          mavContainer.removeAttributes(bindingResultModel);
89          mavContainer.addAllAttributes(bindingResultModel);
90  
91          return binder.getTarget();
92      }
93  
94      /**
95       * Whether to raise a {@link BindException} on validation errors.
96       *
97       * @param parameter the method argument
98       * @return {@code true} if the next method argument is not of type {@link org.springframework.validation.Errors}.
99       */
100     protected boolean isBindExceptionRequired(MethodParameter parameter) {
101         int i = parameter.getParameterIndex();
102         Class<?>[] paramTypes = parameter.getMethod().getParameterTypes();
103         boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));
104 
105         return !hasBindingResult;
106     }
107 
108 }