001 /**
002 * Copyright 2005-2012 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 */
016 package org.kuali.rice.krad.web.bind;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
020 import org.kuali.rice.krad.uif.UifParameters;
021 import org.kuali.rice.krad.uif.view.View;
022 import org.kuali.rice.krad.uif.UifConstants.ViewType;
023 import org.kuali.rice.krad.uif.service.ViewService;
024 import org.kuali.rice.krad.util.GlobalVariables;
025 import org.kuali.rice.krad.util.KRADUtils;
026 import org.kuali.rice.krad.web.form.UifFormBase;
027 import org.springframework.core.convert.ConversionService;
028 import org.springframework.util.Assert;
029 import org.springframework.validation.AbstractPropertyBindingResult;
030 import org.springframework.web.bind.ServletRequestDataBinder;
031
032 import javax.servlet.ServletRequest;
033 import javax.servlet.http.HttpServletRequest;
034 import java.util.Map;
035
036 /**
037 * Override of ServletRequestDataBinder in order to hook in the UifBeanPropertyBindingResult
038 * which instantiates a custom BeanWrapperImpl.
039 *
040 * @author Kuali Rice Team (rice.collab@kuali.org)
041 */
042 public class UifServletRequestDataBinder extends ServletRequestDataBinder {
043 protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(
044 UifServletRequestDataBinder.class);
045
046 private UifBeanPropertyBindingResult bindingResult;
047 private ConversionService conversionService;
048
049 public UifServletRequestDataBinder(Object target) {
050 super(target);
051 setBindingErrorProcessor(new UifBindingErrorProcessor());
052 }
053
054 public UifServletRequestDataBinder(Object target, String name) {
055 super(target, name);
056 setBindingErrorProcessor(new UifBindingErrorProcessor());
057 }
058
059 /**
060 * Allows for a custom binding result class.
061 *
062 * @see org.springframework.validation.DataBinder#initBeanPropertyAccess()
063 */
064 @Override
065 public void initBeanPropertyAccess() {
066 Assert.state(this.bindingResult == null,
067 "DataBinder is already initialized - call initBeanPropertyAccess before other configuration methods");
068 this.bindingResult = new UifBeanPropertyBindingResult(getTarget(), getObjectName(), isAutoGrowNestedPaths(),
069 getAutoGrowCollectionLimit());
070 if (this.conversionService != null) {
071 this.bindingResult.initConversion(this.conversionService);
072 }
073 }
074
075 /**
076 * Allows for the setting attributes to use to find the data dictionary data from Kuali
077 *
078 * @see org.springframework.validation.DataBinder#getInternalBindingResult()
079 */
080 @Override
081 protected AbstractPropertyBindingResult getInternalBindingResult() {
082 if (this.bindingResult == null) {
083 initBeanPropertyAccess();
084 }
085 return this.bindingResult;
086 }
087
088 /**
089 * Disallows direct field access for Kuali
090 *
091 * @see org.springframework.validation.DataBinder#initDirectFieldAccess()
092 */
093 @Override
094 public void initDirectFieldAccess() {
095 LOG.error("Direct Field access is not allowed in UifServletRequestDataBinder.");
096 throw new RuntimeException("Direct Field access is not allowed in Kuali");
097 }
098
099 @Override
100 @SuppressWarnings("unchecked")
101 public void bind(ServletRequest request) {
102 super.bind(request);
103
104 UifFormBase form = (UifFormBase) this.getTarget();
105
106 // back up previous view instance
107 View previousView = form.getView();
108 form.setPreviousView(previousView);
109
110 // check for request param that indicates to skip view initialize
111 Boolean skipViewInit = KRADUtils.getRequestParameterAsBoolean(request, UifParameters.SKIP_VIEW_INIT);
112 if ((skipViewInit == null) || !skipViewInit.booleanValue()) {
113 // initialize new view for request
114 View view = null;
115
116 String viewId = request.getParameter(UifParameters.VIEW_ID);
117 if (viewId != null) {
118 view = getViewService().getViewById(viewId);
119 } else {
120 // attempt to get view instance by type parameters
121 ViewType viewType = null;
122
123 String viewTypeName = request.getParameter(UifParameters.VIEW_TYPE_NAME);
124 viewType = StringUtils.isBlank(viewTypeName) ? form.getViewTypeName() : ViewType.valueOf(viewTypeName);
125
126 if (viewType != null) {
127 Map<String, String> parameterMap = KRADUtils.translateRequestParameterMap(
128 request.getParameterMap());
129 view = getViewService().getViewByType(viewType, parameterMap);
130 }
131
132 // if view not found attempt to find one based on the cached form
133 if (view == null) {
134 view = getViewFromPreviousModel(form);
135
136 if (view != null) {
137 LOG.warn("Obtained viewId from cached form, this may not be safe!");
138 }
139 }
140 }
141
142 if (view != null) {
143 form.setViewId(view.getId());
144 form.setView(view);
145 } else {
146 form.setViewId(null);
147 form.setView(null);
148 }
149 }
150
151 form.postBind((HttpServletRequest) request);
152
153 // add form to manager
154 GlobalVariables.getUifFormManager().addForm(form);
155 }
156
157 protected View getViewFromPreviousModel(UifFormBase form) {
158 // maybe we have a view id from the session form
159 if (form.getViewId() != null) {
160 return getViewService().getViewById(form.getViewId());
161 }
162
163 return null;
164 }
165
166 public ViewService getViewService() {
167 return KRADServiceLocatorWeb.getViewService();
168 }
169
170 }