Source Code Cross Referenced for BaseCommandController.java in  » J2EE » spring-framework-2.0.6 » org » springframework » web » portlet » mvc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.0.6 » org.springframework.web.portlet.mvc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 the original author or authors.
003:         *
004:         * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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:
017:        package org.springframework.web.portlet.mvc;
018:
019:        import javax.portlet.ActionRequest;
020:        import javax.portlet.PortletException;
021:        import javax.portlet.PortletRequest;
022:        import javax.portlet.PortletSession;
023:        import javax.portlet.RenderRequest;
024:
025:        import org.springframework.beans.BeanUtils;
026:        import org.springframework.beans.PropertyEditorRegistrar;
027:        import org.springframework.validation.BindException;
028:        import org.springframework.validation.BindingErrorProcessor;
029:        import org.springframework.validation.MessageCodesResolver;
030:        import org.springframework.validation.ValidationUtils;
031:        import org.springframework.validation.Validator;
032:        import org.springframework.web.portlet.bind.PortletRequestDataBinder;
033:        import org.springframework.web.portlet.handler.PortletSessionRequiredException;
034:
035:        /**
036:         * <p>Controller implementation which creates an object (the command object) on
037:         * receipt of a request and attempts to populate this object with request parameters.</p>
038:         *
039:         * <p>This controller is the base for all controllers wishing to populate
040:         * JavaBeans based on request parameters, validate the content of such
041:         * JavaBeans using {@link Validator Validators} and use custom editors (in the form of
042:         * {@link java.beans.PropertyEditor PropertyEditors}) to transform 
043:         * objects into strings and vice versa, for example. Three notions are mentioned here:</p>
044:         *
045:         * <p><b>Command class:</b><br>
046:         * An instance of the command class will be created for each request and populated
047:         * with request parameters. A command class can basically be any Java class; the only
048:         * requirement is a no-arg constructor. The command class should preferably be a
049:         * JavaBean in order to be able to populate bean properties with request parameters.</p>
050:         *
051:         * <p><b>Populating using request parameters and PropertyEditors:</b><br>
052:         * Upon receiving a request, any BaseCommandController will attempt to fill the
053:         * command object using the request parameters. This is done using the typical
054:         * and well-known JavaBeans property notation. When a request parameter named
055:         * <code>'firstName'</code> exists, the framework will attempt to call 
056:         * <code>setFirstName([value])</code> passing the value of the parameter. Nested properties
057:         * are of course supported. For instance a parameter named <code>'address.city'</code>
058:         * will result in a <code>getAddress().setCity([value])</code> call on the
059:         * command class.</p>
060:         *
061:         * <p>It's important to realize that you are not limited to String arguments in
062:         * your JavaBeans. Using the PropertyEditor-notion as supplied by the
063:         * java.beans package, you will be able to transform Strings to Objects and
064:         * the other way around. For instance <code>setLocale(Locale loc)</code> is
065:         * perfectly possible for a request parameter named <code>locale</code> having
066:         * a value of <code>en</code>, as long as you register the appropriate
067:         * PropertyEditor in the Controller (see {@link #initBinder initBinder()}
068:         * for more information on that matter).</p>
069:         *
070:         * <p><b>Validators:</b>
071:         * After the controller has successfully populated the command object with
072:         * parameters from the request, it will use any configured validators to
073:         * validate the object. Validation results will be put in a
074:         * {@link org.springframework.validation.Errors Errors} object which can be
075:         * used in a View to render any input problems.</p>
076:         *
077:         * <p><b><a name="workflow">Workflow
078:         * (<a href="AbstractController.html#workflow">and that defined by superclass</a>):</b><br>
079:         * Since this class is an abstract base class for more specific implementation,
080:         * it does not override the <code>handleRequestInternal()</code> methods and also has no
081:         * actual workflow. Implementing classes like
082:         * {@link AbstractFormController AbstractFormController},
083:         * {@link AbstractCommandController AbstractCommandController},
084:         * {@link SimpleFormController SimpleFormController} and
085:         * {@link AbstractWizardFormController AbstractWizardFormController}
086:         * provide actual functionality and workflow.
087:         * More information on workflow performed by superclasses can be found
088:         * <a href="AbstractController.html#workflow">here</a>.</p>
089:         *
090:         * <p><b><a name="config">Exposed configuration properties</a>
091:         * (<a href="AbstractController.html#config">and those defined by superclass</a>):</b><br>
092:         * <table border="1">
093:         *  <tr>
094:         *      <td><b>name</b></th>
095:         *      <td><b>default</b></td>
096:         *      <td><b>description</b></td>
097:         *  </tr>
098:         *  <tr>
099:         *      <td>commandName</td>
100:         *      <td>command</td>
101:         *      <td>the name to use when binding the instantiated command class
102:         *          to the request</td>
103:         *  </tr>
104:         *  <tr>
105:         *      <td>commandClass</td>
106:         *      <td><i>null</i></td>
107:         *      <td>the class to use upon receiving a request and which to fill
108:         *          using the request parameters. What object is used and whether
109:         *          or not it should be created is defined by extending classes
110:         *          and their configuration properties and methods.</td>
111:         *  </tr>
112:         *  <tr>
113:         *      <td>validators</td>
114:         *      <td><i>null</i></td>
115:         *      <td>Array of Validator beans. The validator will be called at appropriate
116:         *          places in the workflow of subclasses (have a look at those for more info)
117:         *          to validate the command object.</td>
118:         *  </tr>
119:         *  <tr>
120:         *      <td>validator</td>
121:         *      <td><i>null</i></td>
122:         *      <td>Short-form property for setting only one Validator bean (usually passed in
123:         *          using a &lt;ref bean="beanId"/&gt; property.</td>
124:         *  </tr>
125:         *  <tr>
126:         *      <td>validateOnBinding</td>
127:         *      <td>true</td>
128:         *      <td>Indicates whether or not to validate the command object after the
129:         *          object has been populated with request parameters.</td>
130:         *  </tr>
131:         * </table>
132:         * </p>
133:         *
134:         * <p>Thanks to Rainer Schmitz and Nick Lothian for their suggestions!
135:         *
136:         * @author Juergen Hoeller
137:         * @author John A. Lewis
138:         * @since 2.0
139:         */
140:        public abstract class BaseCommandController extends AbstractController {
141:
142:            /**
143:             * Unlike the Servlet version of these classes, we have to deal with the
144:             * two-phase nature of the porlet request. To do this, we need to pass
145:             * forward the command object and the bind/validation errors that occured
146:             * on the command object from the action phase to the render phase.
147:             * The only direct way to pass things forward and preserve them for each
148:             * render request is through render parameters, but these are limited to
149:             * String objects and we need to pass more complicated objects. The only
150:             * other way to do this is in the session. The bad thing about using the
151:             * session is that we have no way of knowing when we are done re-rendering
152:             * the request and so we don't know when we can remove the objects from
153:             * the session. So we will end up polluting the session with old objects
154:             * when we finally leave the render of this controller and move on to 
155:             * somthing else. To minimize the pollution, we will use a static string
156:             * value as the session attribute name. At least this way we are only ever
157:             * leaving one orphaned set behind. The methods that return these names
158:             * can be overridden if you want to use a different method, but be aware
159:             * of the session pollution that may occur.
160:             */
161:            private static final String RENDER_COMMAND_SESSION_ATTRIBUTE = "org.springframework.web.portlet.mvc.RenderCommand";
162:
163:            private static final String RENDER_ERRORS_SESSION_ATTRIBUTE = "org.springframework.web.portlet.mvc.RenderErrors";
164:
165:            public static final String DEFAULT_COMMAND_NAME = "command";
166:
167:            private String commandName = DEFAULT_COMMAND_NAME;
168:
169:            private Class commandClass;
170:
171:            private Validator[] validators;
172:
173:            private boolean validateOnBinding = true;
174:
175:            private MessageCodesResolver messageCodesResolver;
176:
177:            private BindingErrorProcessor bindingErrorProcessor;
178:
179:            private PropertyEditorRegistrar[] propertyEditorRegistrars;
180:
181:            /**
182:             * Set the name of the command in the model.
183:             * The command object will be included in the model under this name.
184:             */
185:            public final void setCommandName(String commandName) {
186:                this .commandName = commandName;
187:            }
188:
189:            /**
190:             * Return the name of the command in the model.
191:             */
192:            public final String getCommandName() {
193:                return this .commandName;
194:            }
195:
196:            /**
197:             * Set the command class for this controller.
198:             * An instance of this class gets populated and validated on each request.
199:             */
200:            public final void setCommandClass(Class commandClass) {
201:                this .commandClass = commandClass;
202:            }
203:
204:            /**
205:             * Return the command class for this controller.
206:             */
207:            public final Class getCommandClass() {
208:                return this .commandClass;
209:            }
210:
211:            /**
212:             * Set the primary Validator for this controller. The Validator
213:             * must support the specified command class. If there are one
214:             * or more existing validators set already when this method is
215:             * called, only the specified validator will be kept. Use
216:             * {@link #setValidators(Validator[])} to set multiple validators.
217:             */
218:            public final void setValidator(Validator validator) {
219:                this .validators = new Validator[] { validator };
220:            }
221:
222:            /**
223:             * @return the primary Validator for this controller.
224:             */
225:            public final Validator getValidator() {
226:                return (validators != null && validators.length > 0 ? validators[0]
227:                        : null);
228:            }
229:
230:            /**
231:             * Set the Validators for this controller.
232:             * The Validator must support the specified command class.
233:             */
234:            public final void setValidators(Validator[] validators) {
235:                this .validators = validators;
236:            }
237:
238:            /**
239:             * Return the Validators for this controller.
240:             */
241:            public final Validator[] getValidators() {
242:                return validators;
243:            }
244:
245:            /**
246:             * Set if the Validator should get applied when binding.
247:             */
248:            public final void setValidateOnBinding(boolean validateOnBinding) {
249:                this .validateOnBinding = validateOnBinding;
250:            }
251:
252:            /**
253:             * Return if the Validator should get applied when binding.
254:             */
255:            public final boolean isValidateOnBinding() {
256:                return validateOnBinding;
257:            }
258:
259:            /**
260:             * Set the strategy to use for resolving errors into message codes.
261:             * Applies the given strategy to all data binders used by this controller.
262:             * <p>Default is null, i.e. using the default strategy of the data binder.
263:             * @see #createBinder
264:             * @see org.springframework.validation.DataBinder#setMessageCodesResolver
265:             */
266:            public final void setMessageCodesResolver(
267:                    MessageCodesResolver messageCodesResolver) {
268:                this .messageCodesResolver = messageCodesResolver;
269:            }
270:
271:            /**
272:             * Return the strategy to use for resolving errors into message codes.
273:             */
274:            public final MessageCodesResolver getMessageCodesResolver() {
275:                return messageCodesResolver;
276:            }
277:
278:            /**
279:             * Set the strategy to use for processing binding errors, that is,
280:             * required field errors and <code>PropertyAccessException</code>s.
281:             * <p>Default is <code>null</code>, i.e. using the default strategy of
282:             * the data binder.
283:             * @see #createBinder
284:             * @see org.springframework.validation.DataBinder#setBindingErrorProcessor
285:             */
286:            public final void setBindingErrorProcessor(
287:                    BindingErrorProcessor bindingErrorProcessor) {
288:                this .bindingErrorProcessor = bindingErrorProcessor;
289:            }
290:
291:            /**
292:             * Return the strategy to use for processing binding errors.
293:             */
294:            public final BindingErrorProcessor getBindingErrorProcessor() {
295:                return bindingErrorProcessor;
296:            }
297:
298:            /**
299:             * Specify a single PropertyEditorRegistrar to be applied
300:             * to every DataBinder that this controller uses.
301:             * <p>Allows for factoring out the registration of PropertyEditors
302:             * to separate objects, as an alternative to <code>initBinder</code>.
303:             * @see #initBinder
304:             */
305:            public final void setPropertyEditorRegistrar(
306:                    PropertyEditorRegistrar propertyEditorRegistrar) {
307:                this .propertyEditorRegistrars = new PropertyEditorRegistrar[] { propertyEditorRegistrar };
308:            }
309:
310:            /**
311:             * Specify one or more PropertyEditorRegistrars to be applied
312:             * to every DataBinder that this controller uses.
313:             * <p>Allows for factoring out the registration of PropertyEditors
314:             * to separate objects, as alternative to <code>initBinder</code>.
315:             * @see #initBinder
316:             */
317:            public final void setPropertyEditorRegistrars(
318:                    PropertyEditorRegistrar[] propertyEditorRegistrars) {
319:                this .propertyEditorRegistrars = propertyEditorRegistrars;
320:            }
321:
322:            /**
323:             * Return the PropertyEditorRegistrars to be applied
324:             * to every DataBinder that this controller uses.
325:             */
326:            public final PropertyEditorRegistrar[] getPropertyEditorRegistrars() {
327:                return propertyEditorRegistrars;
328:            }
329:
330:            protected void initApplicationContext() {
331:                if (this .validators != null) {
332:                    for (int i = 0; i < this .validators.length; i++) {
333:                        if (this .commandClass != null
334:                                && !this .validators[i]
335:                                        .supports(this .commandClass))
336:                            throw new IllegalArgumentException("Validator ["
337:                                    + this .validators[i]
338:                                    + "] does not support command class ["
339:                                    + this .commandClass.getName() + "]");
340:                    }
341:                }
342:            }
343:
344:            /**
345:             * Retrieve a command object for the given request.
346:             * <p>Default implementation calls <code>createCommand</code>.
347:             * Subclasses can override this.
348:             * @param request current portlet request
349:             * @return object command to bind onto
350:             * @see #createCommand
351:             */
352:            protected Object getCommand(PortletRequest request)
353:                    throws Exception {
354:                return createCommand();
355:            }
356:
357:            /**
358:             * Create a new command instance for the command class of this controller.
359:             * <p>This implementation uses <code>BeanUtils.instantiateClass</code>,
360:             * so the command needs to have a no-arg constructor (supposed to be
361:             * public, but not required to).
362:             * @return the new command instance
363:             * @throws Exception if the command object could not be instantiated
364:             * @see org.springframework.beans.BeanUtils#instantiateClass(Class)
365:             */
366:            protected final Object createCommand() throws Exception {
367:                if (this .commandClass == null) {
368:                    throw new IllegalStateException(
369:                            "Cannot create command without commandClass being set - "
370:                                    + "either set commandClass or (in a form controller) override formBackingObject");
371:                }
372:                if (logger.isDebugEnabled()) {
373:                    logger.debug("Creating new command of class ["
374:                            + this .commandClass.getName() + "]");
375:                }
376:                return BeanUtils.instantiateClass(this .commandClass);
377:            }
378:
379:            /**
380:             * Check if the given command object is a valid for this controller,
381:             * i.e. its command class.
382:             * @param command the command object to check
383:             * @return if the command object is valid for this controller
384:             */
385:            protected final boolean checkCommand(Object command) {
386:                return (this .commandClass == null || this .commandClass
387:                        .isInstance(command));
388:            }
389:
390:            /**
391:             * Bind the parameters of the given request to the given command object.
392:             * @param request current portlet request
393:             * @param command the command to bind onto
394:             * @return the PortletRequestDataBinder instance for additional custom validation
395:             * @throws Exception in case of invalid state or arguments
396:             */
397:            protected final PortletRequestDataBinder bindAndValidate(
398:                    PortletRequest request, Object command) throws Exception {
399:
400:                PortletRequestDataBinder binder = createBinder(request, command);
401:                if (!suppressBinding(request)) {
402:                    binder.bind(request);
403:                    BindException errors = new BindException(binder
404:                            .getBindingResult());
405:                    onBind(request, command, errors);
406:                    if (this .validators != null && isValidateOnBinding()
407:                            && !suppressValidation(request)) {
408:                        for (int i = 0; i < this .validators.length; i++) {
409:                            ValidationUtils.invokeValidator(this .validators[i],
410:                                    command, errors);
411:                        }
412:                    }
413:                    onBindAndValidate(request, command, errors);
414:                }
415:                return binder;
416:            }
417:
418:            /**
419:             * Return whether to suppress binding for the given request.
420:             * <p>Default implementation always returns "false". Can be overridden
421:             * in subclasses to suppress validation, for example, if a special
422:             * request parameter is set.
423:             * @param request current portlet request
424:             * @return whether to suppress binding for the given request
425:             * @see #suppressValidation
426:             */
427:            protected boolean suppressBinding(PortletRequest request) {
428:                return false;
429:            }
430:
431:            /**
432:             * Create a new binder instance for the given command and request.
433:             * <p>Called by <code>bindAndValidate</code>. Can be overridden to plug in
434:             * custom PortletRequestDataBinder instances.
435:             * <p>The default implementation creates a standard PortletRequestDataBinder and
436:             * invokes <code>prepareBinder</code> and <code>initBinder</code>.
437:             * <p>Note that neither <code>prepareBinder</code> nor <code>initBinder</code>
438:             * will be invoked automatically if you override this method! Call those methods
439:             * at appropriate points of your overridden method.
440:             * @param request current portlet request
441:             * @param command the command to bind onto
442:             * @return the new binder instance
443:             * @throws Exception in case of invalid state or arguments
444:             * @see #bindAndValidate
445:             * @see #prepareBinder
446:             * @see #initBinder
447:             */
448:            protected PortletRequestDataBinder createBinder(
449:                    PortletRequest request, Object command) throws Exception {
450:
451:                PortletRequestDataBinder binder = new PortletRequestDataBinder(
452:                        command, getCommandName());
453:                prepareBinder(binder);
454:                initBinder(request, binder);
455:                return binder;
456:            }
457:
458:            /**
459:             * Prepare the given binder, applying the specified MessageCodesResolver,
460:             * BindingErrorProcessor and PropertyEditorRegistrars (if any).
461:             * Called by <code>createBinder</code>.
462:             * @param binder the new binder instance
463:             * @see #createBinder
464:             * @see #setMessageCodesResolver
465:             * @see #setBindingErrorProcessor
466:             */
467:            protected final void prepareBinder(PortletRequestDataBinder binder) {
468:                if (useDirectFieldAccess()) {
469:                    binder.initDirectFieldAccess();
470:                }
471:                if (this .messageCodesResolver != null) {
472:                    binder.setMessageCodesResolver(this .messageCodesResolver);
473:                }
474:                if (this .bindingErrorProcessor != null) {
475:                    binder.setBindingErrorProcessor(this .bindingErrorProcessor);
476:                }
477:                if (this .propertyEditorRegistrars != null) {
478:                    for (int i = 0; i < this .propertyEditorRegistrars.length; i++) {
479:                        this .propertyEditorRegistrars[i]
480:                                .registerCustomEditors(binder);
481:                    }
482:                }
483:            }
484:
485:            /**
486:             * Determine whether to use direct field access instead of bean property access.
487:             * Applied by <code>prepareBinder</code>.
488:             * <p>Default is "false". Can be overridden in subclasses.
489:             * @see #prepareBinder
490:             * @see org.springframework.validation.DataBinder#initDirectFieldAccess()
491:             */
492:            protected boolean useDirectFieldAccess() {
493:                return false;
494:            }
495:
496:            /**
497:             * Initialize the given binder instance, for example with custom editors.
498:             * Called by <code>createBinder</code>.
499:             * <p>This method allows you to register custom editors for certain fields of your
500:             * command class. For instance, you will be able to transform Date objects into a
501:             * String pattern and back, in order to allow your JavaBeans to have Date properties
502:             * and still be able to set and display them in an HTML interface.
503:             * <p>Default implementation is empty.
504:             * @param request current portlet request
505:             * @param binder new binder instance
506:             * @throws Exception in case of invalid state or arguments
507:             * @see #createBinder
508:             * @see org.springframework.validation.DataBinder#registerCustomEditor
509:             * @see org.springframework.beans.propertyeditors.CustomDateEditor
510:             */
511:            protected void initBinder(PortletRequest request,
512:                    PortletRequestDataBinder binder) throws Exception {
513:            }
514:
515:            /**
516:             * Callback for custom post-processing in terms of binding.
517:             * Called on each submit, after standard binding but before validation.
518:             * <p>Default implementation delegates to <code>onBind(request, command)</code>.
519:             * @param request current portlet request
520:             * @param command the command object to perform further binding on
521:             * @param errors validation errors holder, allowing for additional
522:             * custom registration of binding errors
523:             * @throws Exception in case of invalid state or arguments
524:             * @see #bindAndValidate
525:             * @see #onBind(PortletRequest, Object)
526:             */
527:            protected void onBind(PortletRequest request, Object command,
528:                    BindException errors) throws Exception {
529:
530:                onBind(request, command);
531:            }
532:
533:            /**
534:             * Callback for custom post-processing in terms of binding.
535:             * Called by the default implementation of the <code>onBind</code> version with
536:             * all parameters, after standard binding but before validation.
537:             * <p>Default implementation is empty.
538:             * @param request current portlet request
539:             * @param command the command object to perform further binding on
540:             * @throws Exception in case of invalid state or arguments
541:             * @see #onBind(PortletRequest, Object, BindException)
542:             */
543:            protected void onBind(PortletRequest request, Object command)
544:                    throws Exception {
545:            }
546:
547:            /**
548:             * Return whether to suppress validation for the given request.
549:             * <p>Default implementation always returns "false". Can be overridden
550:             * in subclasses to suppress validation, for example, if a special
551:             * request parameter is set.
552:             * @param request current portlet request
553:             * @return whether to suppress validation for the given request
554:             */
555:            protected boolean suppressValidation(PortletRequest request) {
556:                return false;
557:            }
558:
559:            /**
560:             * Callback for custom post-processing in terms of binding and validation.
561:             * Called on each submit, after standard binding and validation,
562:             * but before error evaluation.
563:             * <p>Default implementation is empty.
564:             * @param request current portlet request
565:             * @param command the command object, still allowing for further binding
566:             * @param errors validation errors holder, allowing for additional
567:             * custom validation
568:             * @throws Exception in case of invalid state or arguments
569:             * @see #bindAndValidate
570:             * @see org.springframework.validation.Errors
571:             */
572:            protected void onBindAndValidate(PortletRequest request,
573:                    Object command, BindException errors) throws Exception {
574:            }
575:
576:            /**
577:             * Return the name of the session attribute that holds
578:             * the render phase command object for this form controller.
579:             * @return the name of the render phase command object session attribute
580:             * @see javax.portlet.PortletSession#getAttribute
581:             */
582:            protected String getRenderCommandSessionAttributeName() {
583:                return RENDER_COMMAND_SESSION_ATTRIBUTE;
584:            }
585:
586:            /** 
587:             * Return the name of the session attribute that holds
588:             * the render phase command object for this form controller.
589:             * @return the name of the render phase command object session attribute
590:             * @see javax.portlet.PortletSession#getAttribute
591:             */
592:            protected String getRenderErrorsSessionAttributeName() {
593:                return RENDER_ERRORS_SESSION_ATTRIBUTE;
594:            }
595:
596:            /**
597:             * Get the command object cached for the render phase.
598:             * @see #getRenderErrors
599:             * @see #getRenderCommandSessionAttributeName
600:             * @see #setRenderCommandAndErrors
601:             */
602:            protected final Object getRenderCommand(RenderRequest request)
603:                    throws PortletException {
604:                PortletSession session = request.getPortletSession(false);
605:                if (session == null) {
606:                    throw new PortletSessionRequiredException(
607:                            "Could not obtain portlet session");
608:                }
609:                Object command = session
610:                        .getAttribute(getRenderCommandSessionAttributeName());
611:                if (command == null) {
612:                    throw new PortletSessionRequiredException(
613:                            "Could not obtain command object from portlet session");
614:                }
615:                return command;
616:            }
617:
618:            /**
619:             * Get the bind and validation errors cached for the render phase.
620:             * @see #getRenderCommand
621:             * @see #getRenderErrorsSessionAttributeName
622:             * @see #setRenderCommandAndErrors
623:             */
624:            protected final BindException getRenderErrors(RenderRequest request)
625:                    throws PortletException {
626:                PortletSession session = request.getPortletSession(false);
627:                if (session == null) {
628:                    throw new PortletSessionRequiredException(
629:                            "Could not obtain portlet session");
630:                }
631:                BindException errors = (BindException) session
632:                        .getAttribute(getRenderErrorsSessionAttributeName());
633:                if (errors == null) {
634:                    throw new PortletSessionRequiredException(
635:                            "Could not obtain errors object from portlet session");
636:                }
637:                return errors;
638:            }
639:
640:            /**
641:             * Set the command object and errors object for the render phase.
642:             * @param request the current action request
643:             * @param command the command object to preserve for the render phase
644:             * @param errors the errors from binding and validation to preserve for the render phase
645:             * @see #getRenderCommand
646:             * @see #getRenderErrors
647:             * @see #getRenderCommandSessionAttributeName
648:             * @see #getRenderErrorsSessionAttributeName
649:             */
650:            protected final void setRenderCommandAndErrors(
651:                    ActionRequest request, Object command, BindException errors)
652:                    throws Exception {
653:
654:                logger
655:                        .debug("Storing command and error objects in session for render phase");
656:                PortletSession session = request.getPortletSession();
657:                session.setAttribute(getRenderCommandSessionAttributeName(),
658:                        command);
659:                session.setAttribute(getRenderErrorsSessionAttributeName(),
660:                        errors);
661:            }
662:
663:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.