001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krad.web.controller; 017 018import org.kuali.rice.krad.uif.UifConstants; 019import org.kuali.rice.krad.web.form.UifFormBase; 020import org.springframework.core.MethodParameter; 021import org.springframework.validation.BindException; 022import org.springframework.validation.Errors; 023import org.springframework.web.bind.ServletRequestDataBinder; 024import org.springframework.web.bind.WebDataBinder; 025import org.springframework.web.bind.annotation.ModelAttribute; 026import org.springframework.web.bind.support.WebDataBinderFactory; 027import org.springframework.web.context.request.NativeWebRequest; 028import org.springframework.web.method.support.HandlerMethodArgumentResolver; 029import org.springframework.web.method.support.ModelAndViewContainer; 030 031import javax.servlet.ServletRequest; 032import java.util.Map; 033 034/** 035 * @author Kuali Rice Team (rice.collab@kuali.org) 036 */ 037public class UifDefaultFormMethodArgumentResolver implements HandlerMethodArgumentResolver { 038 039 /** 040 * Default Constructor. 041 */ 042 public UifDefaultFormMethodArgumentResolver() { 043 super(); 044 } 045 046 /** 047 * {@inheritDoc} 048 */ 049 @Override 050 public boolean supportsParameter(MethodParameter parameter) { 051 boolean isUifForm = false; 052 053 if (!parameter.hasParameterAnnotation(ModelAttribute.class) && UifFormBase.class.isAssignableFrom( 054 parameter.getParameterType())) { 055 isUifForm = true; 056 } 057 058 return isUifForm; 059 } 060 061 /** 062 * {@inheritDoc} 063 */ 064 @Override 065 public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, 066 NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { 067 String name = UifConstants.DEFAULT_MODEL_NAME; 068 069 Object attribute = null; 070 if (mavContainer.containsAttribute(name)) { 071 attribute = mavContainer.getModel().get(name); 072 } 073 074 WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name); 075 if (binder.getTarget() != null) { 076 ServletRequest servletRequest = webRequest.getNativeRequest(ServletRequest.class); 077 ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder; 078 servletBinder.bind(servletRequest); 079 080 if (binder.getBindingResult().hasErrors()) { 081 if (isBindExceptionRequired(parameter)) { 082 throw new BindException(binder.getBindingResult()); 083 } 084 } 085 } 086 087 Map<String, Object> bindingResultModel = binder.getBindingResult().getModel(); 088 mavContainer.removeAttributes(bindingResultModel); 089 mavContainer.addAllAttributes(bindingResultModel); 090 091 return binder.getTarget(); 092 } 093 094 /** 095 * Whether to raise a {@link BindException} on validation errors. 096 * 097 * @param parameter the method argument 098 * @return {@code true} if the next method argument is not of type {@link org.springframework.validation.Errors}. 099 */ 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}