11/*
2- * Copyright 2002-2014 the original author or authors.
2+ * Copyright 2002-2016 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
4545import org .springframework .web .method .support .ModelAndViewContainer ;
4646
4747/**
48- * Provides methods to initialize the {@link Model} before controller method
49- * invocation and to update it afterwards .
48+ * Assist with initialization of the {@link Model} before controller method
49+ * invocation and with updates to it after the invocation .
5050 *
51- * <p>On initialization, the model is populated with attributes from the session
52- * and by invoking methods annotated with {@code @ModelAttribute}.
51+ * <p>On initialization the model is populated with attributes temporarily
52+ * stored in the session and through the invocation of {@code @ModelAttribute}
53+ * methods.
5354 *
54- * <p>On update, model attributes are synchronized with the session and also
55- * {@link BindingResult} attributes are added where missing.
55+ * <p>On update model attributes are synchronized with the session and also
56+ * {@link BindingResult} attributes are added if missing.
5657 *
5758 * @author Rossen Stoyanchev
5859 * @since 3.1
@@ -61,6 +62,7 @@ public final class ModelFactory {
6162
6263 private static final Log logger = LogFactory .getLog (ModelFactory .class );
6364
65+
6466 private final List <ModelMethod > modelMethods = new ArrayList <ModelMethod >();
6567
6668 private final WebDataBinderFactory dataBinderFactory ;
@@ -70,22 +72,23 @@ public final class ModelFactory {
7072
7173 /**
7274 * Create a new instance with the given {@code @ModelAttribute} methods.
73- * @param invocableMethods the {@code @ModelAttribute} methods to invoke
74- * @param dataBinderFactory for preparation of {@link BindingResult} attributes
75- * @param sessionAttributesHandler for access to session attributes
75+ * @param handlerMethods the {@code @ModelAttribute} methods to invoke
76+ * @param binderFactory for preparation of {@link BindingResult} attributes
77+ * @param attributeHandler for access to session attributes
7678 */
77- public ModelFactory (List <InvocableHandlerMethod > invocableMethods , WebDataBinderFactory dataBinderFactory ,
78- SessionAttributesHandler sessionAttributesHandler ) {
79+ public ModelFactory (List <InvocableHandlerMethod > handlerMethods ,
80+ WebDataBinderFactory binderFactory , SessionAttributesHandler attributeHandler ) {
7981
80- if (invocableMethods != null ) {
81- for (InvocableHandlerMethod method : invocableMethods ) {
82- this .modelMethods .add (new ModelMethod (method ));
82+ if (handlerMethods != null ) {
83+ for (InvocableHandlerMethod handlerMethod : handlerMethods ) {
84+ this .modelMethods .add (new ModelMethod (handlerMethod ));
8385 }
8486 }
85- this .dataBinderFactory = dataBinderFactory ;
86- this .sessionAttributesHandler = sessionAttributesHandler ;
87+ this .dataBinderFactory = binderFactory ;
88+ this .sessionAttributesHandler = attributeHandler ;
8789 }
8890
91+
8992 /**
9093 * Populate the model in the following order:
9194 * <ol>
@@ -96,25 +99,26 @@ public ModelFactory(List<InvocableHandlerMethod> invocableMethods, WebDataBinder
9699 * an exception if necessary.
97100 * </ol>
98101 * @param request the current request
99- * @param mavContainer a container with the model to be initialized
102+ * @param container a container with the model to be initialized
100103 * @param handlerMethod the method for which the model is initialized
101104 * @throws Exception may arise from {@code @ModelAttribute} methods
102105 */
103- public void initModel (NativeWebRequest request , ModelAndViewContainer mavContainer , HandlerMethod handlerMethod )
104- throws Exception {
106+ public void initModel (NativeWebRequest request , ModelAndViewContainer container ,
107+ HandlerMethod handlerMethod ) throws Exception {
105108
106109 Map <String , ?> sessionAttributes = this .sessionAttributesHandler .retrieveAttributes (request );
107- mavContainer .mergeAttributes (sessionAttributes );
110+ container .mergeAttributes (sessionAttributes );
108111
109- invokeModelAttributeMethods (request , mavContainer );
112+ invokeModelAttributeMethods (request , container );
110113
111114 for (String name : findSessionAttributeArguments (handlerMethod )) {
112- if (!mavContainer .containsAttribute (name )) {
115+ if (!container .containsAttribute (name )) {
113116 Object value = this .sessionAttributesHandler .retrieveAttribute (request , name );
114117 if (value == null ) {
115- throw new HttpSessionRequiredException ("Expected session attribute '" + name + "'" );
118+ throw new HttpSessionRequiredException (
119+ "Expected session attribute '" + name + "'" );
116120 }
117- mavContainer .addAttribute (name , value );
121+ container .addAttribute (name , value );
118122 }
119123 }
120124 }
@@ -123,30 +127,31 @@ public void initModel(NativeWebRequest request, ModelAndViewContainer mavContain
123127 * Invoke model attribute methods to populate the model.
124128 * Attributes are added only if not already present in the model.
125129 */
126- private void invokeModelAttributeMethods (NativeWebRequest request , ModelAndViewContainer mavContainer )
127- throws Exception {
130+ private void invokeModelAttributeMethods (NativeWebRequest request ,
131+ ModelAndViewContainer container ) throws Exception {
128132
129133 while (!this .modelMethods .isEmpty ()) {
130- InvocableHandlerMethod attrMethod = getNextModelMethod (mavContainer ).getHandlerMethod ();
131- String modelName = attrMethod .getMethodAnnotation (ModelAttribute .class ).value ();
132- if (mavContainer .containsAttribute (modelName )) {
134+ InvocableHandlerMethod modelMethod = getNextModelMethod (container ).getHandlerMethod ();
135+ ModelAttribute annot = modelMethod .getMethodAnnotation (ModelAttribute .class );
136+ String modelName = annot .value ();
137+ if (container .containsAttribute (modelName )) {
133138 continue ;
134139 }
135140
136- Object returnValue = attrMethod .invokeForRequest (request , mavContainer );
141+ Object returnValue = modelMethod .invokeForRequest (request , container );
137142
138- if (!attrMethod .isVoid ()){
139- String returnValueName = getNameForReturnValue (returnValue , attrMethod .getReturnType ());
140- if (!mavContainer .containsAttribute (returnValueName )) {
141- mavContainer .addAttribute (returnValueName , returnValue );
143+ if (!modelMethod .isVoid ()){
144+ String returnValueName = getNameForReturnValue (returnValue , modelMethod .getReturnType ());
145+ if (!container .containsAttribute (returnValueName )) {
146+ container .addAttribute (returnValueName , returnValue );
142147 }
143148 }
144149 }
145150 }
146151
147- private ModelMethod getNextModelMethod (ModelAndViewContainer mavContainer ) {
152+ private ModelMethod getNextModelMethod (ModelAndViewContainer container ) {
148153 for (ModelMethod modelMethod : this .modelMethods ) {
149- if (modelMethod .checkDependencies (mavContainer )) {
154+ if (modelMethod .checkDependencies (container )) {
150155 if (logger .isTraceEnabled ()) {
151156 logger .trace ("Selected @ModelAttribute method " + modelMethod );
152157 }
@@ -157,7 +162,7 @@ private ModelMethod getNextModelMethod(ModelAndViewContainer mavContainer) {
157162 ModelMethod modelMethod = this .modelMethods .get (0 );
158163 if (logger .isTraceEnabled ()) {
159164 logger .trace ("Selected @ModelAttribute method (not present: " +
160- modelMethod .getUnresolvedDependencies (mavContainer )+ ") " + modelMethod );
165+ modelMethod .getUnresolvedDependencies (container )+ ") " + modelMethod );
161166 }
162167 this .modelMethods .remove (modelMethod );
163168 return modelMethod ;
@@ -171,7 +176,8 @@ private List<String> findSessionAttributeArguments(HandlerMethod handlerMethod)
171176 for (MethodParameter parameter : handlerMethod .getMethodParameters ()) {
172177 if (parameter .hasParameterAnnotation (ModelAttribute .class )) {
173178 String name = getNameForParameter (parameter );
174- if (this .sessionAttributesHandler .isHandlerSessionAttribute (name , parameter .getParameterType ())) {
179+ Class <?> paramType = parameter .getParameterType ();
180+ if (this .sessionAttributesHandler .isHandlerSessionAttribute (name , paramType )) {
175181 result .add (name );
176182 }
177183 }
@@ -189,8 +195,8 @@ private List<String> findSessionAttributeArguments(HandlerMethod handlerMethod)
189195 */
190196 public static String getNameForParameter (MethodParameter parameter ) {
191197 ModelAttribute annot = parameter .getParameterAnnotation (ModelAttribute .class );
192- String attrName = (annot != null ) ? annot .value () : null ;
193- return StringUtils .hasText (attrName ) ? attrName : Conventions .getVariableNameForParameter (parameter );
198+ String name = (annot != null ) ? annot .value () : null ;
199+ return StringUtils .hasText (name ) ? name : Conventions .getVariableNameForParameter (parameter );
194200 }
195201
196202 /**
@@ -211,7 +217,8 @@ public static String getNameForReturnValue(Object returnValue, MethodParameter r
211217 }
212218 else {
213219 Method method = returnType .getMethod ();
214- Class <?> resolvedType = GenericTypeResolver .resolveReturnType (method , returnType .getContainingClass ());
220+ Class <?> containingClass = returnType .getContainingClass ();
221+ Class <?> resolvedType = GenericTypeResolver .resolveReturnType (method , containingClass );
215222 return Conventions .getVariableNameForReturnType (method , resolvedType , returnValue );
216223 }
217224 }
@@ -220,18 +227,18 @@ public static String getNameForReturnValue(Object returnValue, MethodParameter r
220227 * Promote model attributes listed as {@code @SessionAttributes} to the session.
221228 * Add {@link BindingResult} attributes where necessary.
222229 * @param request the current request
223- * @param mavContainer contains the model to update
230+ * @param container contains the model to update
224231 * @throws Exception if creating BindingResult attributes fails
225232 */
226- public void updateModel (NativeWebRequest request , ModelAndViewContainer mavContainer ) throws Exception {
227- ModelMap defaultModel = mavContainer .getDefaultModel ();
228- if (mavContainer .getSessionStatus ().isComplete ()){
233+ public void updateModel (NativeWebRequest request , ModelAndViewContainer container ) throws Exception {
234+ ModelMap defaultModel = container .getDefaultModel ();
235+ if (container .getSessionStatus ().isComplete ()){
229236 this .sessionAttributesHandler .cleanupAttributes (request );
230237 }
231238 else {
232239 this .sessionAttributesHandler .storeAttributes (request , defaultModel );
233240 }
234- if (!mavContainer .isRequestHandled () && mavContainer .getModel () == defaultModel ) {
241+ if (!container .isRequestHandled () && container .getModel () == defaultModel ) {
235242 updateBindingResult (request , defaultModel );
236243 }
237244 }
@@ -248,7 +255,7 @@ private void updateBindingResult(NativeWebRequest request, ModelMap model) throw
248255 String bindingResultKey = BindingResult .MODEL_KEY_PREFIX + name ;
249256
250257 if (!model .containsAttribute (bindingResultKey )) {
251- WebDataBinder dataBinder = dataBinderFactory .createBinder (request , value , name );
258+ WebDataBinder dataBinder = this . dataBinderFactory .createBinder (request , value , name );
252259 model .put (bindingResultKey , dataBinder .getBindingResult ());
253260 }
254261 }
0 commit comments