Source Code Cross Referenced for DispatcherPortlet.java in  » J2EE » spring-framework-2.0.6 » org » springframework » web » portlet » 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 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2002-2007 the original author or authors.
0003:         *
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         *      http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:
0017:        package org.springframework.web.portlet;
0018:
0019:        import java.io.IOException;
0020:        import java.util.ArrayList;
0021:        import java.util.Collections;
0022:        import java.util.Iterator;
0023:        import java.util.List;
0024:        import java.util.Map;
0025:        import java.util.Properties;
0026:
0027:        import javax.portlet.ActionRequest;
0028:        import javax.portlet.ActionResponse;
0029:        import javax.portlet.PortletException;
0030:        import javax.portlet.PortletRequest;
0031:        import javax.portlet.PortletResponse;
0032:        import javax.portlet.PortletSession;
0033:        import javax.portlet.RenderRequest;
0034:        import javax.portlet.RenderResponse;
0035:        import javax.portlet.UnavailableException;
0036:
0037:        import org.apache.commons.logging.Log;
0038:        import org.apache.commons.logging.LogFactory;
0039:
0040:        import org.springframework.beans.BeansException;
0041:        import org.springframework.beans.factory.BeanFactoryUtils;
0042:        import org.springframework.beans.factory.BeanInitializationException;
0043:        import org.springframework.beans.factory.NoSuchBeanDefinitionException;
0044:        import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
0045:        import org.springframework.context.ApplicationContext;
0046:        import org.springframework.context.i18n.LocaleContext;
0047:        import org.springframework.context.i18n.LocaleContextHolder;
0048:        import org.springframework.context.i18n.SimpleLocaleContext;
0049:        import org.springframework.core.OrderComparator;
0050:        import org.springframework.core.io.ClassPathResource;
0051:        import org.springframework.core.io.support.PropertiesLoaderUtils;
0052:        import org.springframework.util.ClassUtils;
0053:        import org.springframework.util.StringUtils;
0054:        import org.springframework.web.context.request.RequestAttributes;
0055:        import org.springframework.web.context.request.RequestContextHolder;
0056:        import org.springframework.web.multipart.MultipartException;
0057:        import org.springframework.web.portlet.context.PortletRequestAttributes;
0058:        import org.springframework.web.portlet.multipart.MultipartActionRequest;
0059:        import org.springframework.web.portlet.multipart.PortletMultipartResolver;
0060:        import org.springframework.web.servlet.View;
0061:        import org.springframework.web.servlet.ViewRendererServlet;
0062:        import org.springframework.web.servlet.ViewResolver;
0063:
0064:        /**
0065:         * Central dispatcher for use within the Portlet MVC framework, e.g. for web UI
0066:         * controllers. Dispatches to registered handlers for processing a portlet request.
0067:         *
0068:         * <p>This portlet is very flexible: It can be used with just about any workflow,
0069:         * with the installation of the appropriate adapter classes. It offers the
0070:         * following functionality that distinguishes it from other request-driven
0071:         * portlet MVC frameworks:
0072:         *
0073:         * <ul>
0074:         * <li>It is based around a JavaBeans configuration mechanism.
0075:         *
0076:         * <li>It can use any {@link HandlerMapping} implementation - pre-built or provided
0077:         * as part of an application - to control the routing of requests to handler objects.
0078:         * Default is {@link org.springframework.web.portlet.handler.PortletModeHandlerMapping}.
0079:         * HandlerMapping objects can be defined as beans in the portlet's application context,
0080:         * implementing the HandlerMapping interface, overriding the default HandlerMapping
0081:         * if present. HandlerMappings can be given any bean name (they are tested by type).
0082:         *
0083:         * <li>It can use any {@link HandlerAdapter}; this allows to use any handler interface.
0084:         * The default adapter is {@link org.springframework.web.portlet.mvc.SimpleControllerHandlerAdapter}
0085:         * for Spring's {@link org.springframework.web.portlet.mvc.Controller} interface.
0086:         * HandlerAdapter objects can be added as beans in the application context,
0087:         * overriding the default HandlerAdapter. Like HandlerMappings, HandlerAdapters
0088:         * can be given any bean name (they are tested by type).
0089:         *
0090:         * <li>The dispatcher's exception resolution strategy can be specified via a
0091:         * {@link HandlerExceptionResolver}, for example mapping certain exceptions to
0092:         * error pages. Default is none. Additional HandlerExceptionResolvers can be added
0093:         * through the application context. HandlerExceptionResolver can be given any
0094:         * bean name (they are tested by type).
0095:         *
0096:         * <li>Its view resolution strategy can be specified via a {@link ViewResolver}
0097:         * implementation, resolving symbolic view names into View objects. Default is
0098:         * {@link org.springframework.web.servlet.view.InternalResourceViewResolver}.
0099:         * ViewResolver objects can be added as beans in the application context,
0100:         * overriding the default ViewResolver. ViewResolvers can be given any bean name
0101:         * (they are tested by type).
0102:         *
0103:         * <li>The dispatcher's strategy for resolving multipart requests is determined by a
0104:         * {@link org.springframework.web.portlet.multipart.PortletMultipartResolver} implementation.
0105:         * An implementations for Jakarta Commons FileUpload is included:
0106:         * {@link org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver}.
0107:         * The MultipartResolver bean name is "portletMultipartResolver"; default is none.
0108:         * </ul>
0109:         *
0110:         * <p><b>A web application can define any number of DispatcherPortlets.</b>
0111:         * Each portlet will operate in its own namespace, loading its own application
0112:         * context with mappings, handlers, etc. Only the root application context
0113:         * as loaded by {@link org.springframework.web.context.ContextLoaderListener},
0114:         * if any, will be shared.
0115:         *
0116:         * <p>Thanks to Rainer Schmitz and Nick Lothian for their suggestions!
0117:         *
0118:         * @author William G. Thompson, Jr.
0119:         * @author John A. Lewis
0120:         * @author Juergen Hoeller
0121:         * @since 2.0
0122:         * @see org.springframework.web.portlet.mvc.Controller
0123:         * @see org.springframework.web.servlet.ViewRendererServlet
0124:         * @see org.springframework.web.context.ContextLoaderListener
0125:         */
0126:        public class DispatcherPortlet extends FrameworkPortlet {
0127:
0128:            /**
0129:             * Well-known name for the PortletMultipartResolver object in the bean factory for this namespace.
0130:             */
0131:            public static final String MULTIPART_RESOLVER_BEAN_NAME = "portletMultipartResolver";
0132:
0133:            /**
0134:             * Well-known name for the HandlerMapping object in the bean factory for this namespace.
0135:             * Only used when "detectAllHandlerMappings" is turned off.
0136:             * @see #setDetectAllViewResolvers
0137:             */
0138:            public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
0139:
0140:            /**
0141:             * Well-known name for the HandlerAdapter object in the bean factory for this namespace.
0142:             * Only used when "detectAllHandlerAdapters" is turned off.
0143:             * @see #setDetectAllHandlerAdapters
0144:             */
0145:            public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
0146:
0147:            /**
0148:             * Well-known name for the HandlerExceptionResolver object in the bean factory for this
0149:             * namespace. Only used when "detectAllHandlerExceptionResolvers" is turned off.
0150:             * @see #setDetectAllViewResolvers
0151:             */
0152:            public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
0153:
0154:            /**
0155:             * Well-known name for the ViewResolver object in the bean factory for this namespace.
0156:             */
0157:            public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
0158:
0159:            /**
0160:             * Default URL to ViewRendererServlet. This bridge servlet is used to convert
0161:             * portlet render requests to servlet requests in order to leverage the view support
0162:             * in the <code>org.springframework.web.view</code> package.
0163:             */
0164:            public static final String DEFAULT_VIEW_RENDERER_URL = "/WEB-INF/servlet/view";
0165:
0166:            /**
0167:             * Request attribute to hold the currently chosen HandlerExecutionChain.
0168:             * Only used for internal optimizations.
0169:             */
0170:            public static final String HANDLER_EXECUTION_CHAIN_ATTRIBUTE = DispatcherPortlet.class
0171:                    .getName()
0172:                    + ".HANDLER";
0173:
0174:            /**
0175:             * Unlike the Servlet version of this class, we have to deal with the
0176:             * two-phase nature of the portlet request. To do this, we need to pass
0177:             * forward any exception that occurs during the action phase, so that
0178:             * it can be displayed in the render phase. The only direct way to pass
0179:             * things forward and preserve them for each render request is through
0180:             * render parameters, but these are limited to String objects and we need
0181:             * to pass the Exception itself. The only other way to do this is in the
0182:             * session. The bad thing about using the session is that we have no way
0183:             * of knowing when we are done re-rendering the request and so we don't
0184:             * know when we can remove the objects from the session. So we will end
0185:             * up polluting the session with an old exception when we finally leave
0186:             * the render phase of one request and move on to something else.
0187:             */
0188:            public static final String ACTION_EXCEPTION_SESSION_ATTRIBUTE = DispatcherPortlet.class
0189:                    .getName()
0190:                    + ".ACTION_EXCEPTION";
0191:
0192:            /**
0193:             * This render parameter is used to indicate forward to the render phase
0194:             * that an exception occurred during the action phase.
0195:             */
0196:            public static final String ACTION_EXCEPTION_RENDER_PARAMETER = "actionException";
0197:
0198:            /**
0199:             * Log category to use when no mapped handler is found for a request.
0200:             */
0201:            public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.portlet.PageNotFound";
0202:
0203:            /**
0204:             * Name of the class path resource (relative to the DispatcherPortlet class)
0205:             * that defines DispatcherPortet's default strategy names.
0206:             */
0207:            private static final String DEFAULT_STRATEGIES_PATH = "DispatcherPortlet.properties";
0208:
0209:            /**
0210:             * Additional logger to use when no mapped handler is found for a request.
0211:             */
0212:            protected static final Log pageNotFoundLogger = LogFactory
0213:                    .getLog(PAGE_NOT_FOUND_LOG_CATEGORY);
0214:
0215:            private static final Properties defaultStrategies;
0216:
0217:            static {
0218:                // Load default strategy implementations from properties file.
0219:                // This is currently strictly internal and not meant to be customized
0220:                // by application developers.
0221:                try {
0222:                    ClassPathResource resource = new ClassPathResource(
0223:                            DEFAULT_STRATEGIES_PATH, DispatcherPortlet.class);
0224:                    defaultStrategies = PropertiesLoaderUtils
0225:                            .loadProperties(resource);
0226:                } catch (IOException ex) {
0227:                    throw new IllegalStateException(
0228:                            "Could not load 'DispatcherPortlet.properties': "
0229:                                    + ex.getMessage());
0230:                }
0231:            }
0232:
0233:            /** Detect all HandlerMappings or just expect "handlerMapping" bean? */
0234:            private boolean detectAllHandlerMappings = true;
0235:
0236:            /** Detect all HandlerAdapters or just expect "handlerAdapter" bean? */
0237:            private boolean detectAllHandlerAdapters = true;
0238:
0239:            /** Detect all HandlerExceptionResolvers or just expect "handlerExceptionResolver" bean? */
0240:            private boolean detectAllHandlerExceptionResolvers = true;
0241:
0242:            /** Detect all ViewResolvers or just expect "viewResolver" bean? */
0243:            private boolean detectAllViewResolvers = true;
0244:
0245:            /** URL that points to the ViewRendererServlet */
0246:            private String viewRendererUrl = DEFAULT_VIEW_RENDERER_URL;
0247:
0248:            /** Expose LocaleContext and RequestAttributes as inheritable for child threads? */
0249:            private boolean threadContextInheritable = false;
0250:
0251:            /** MultipartResolver used by this portlet */
0252:            private PortletMultipartResolver multipartResolver;
0253:
0254:            /** List of HandlerMappings used by this portlet */
0255:            private List handlerMappings;
0256:
0257:            /** List of HandlerAdapters used by this portlet */
0258:            private List handlerAdapters;
0259:
0260:            /** List of HandlerExceptionResolvers used by this portlet */
0261:            private List handlerExceptionResolvers;
0262:
0263:            /** List of ViewResolvers used by this portlet */
0264:            private List viewResolvers;
0265:
0266:            /**
0267:             * Set whether to detect all HandlerMapping beans in this portlet's context.
0268:             * Else, just a single bean with name "handlerMapping" will be expected.
0269:             * <p>Default is true. Turn this off if you want this portlet to use a
0270:             * single HandlerMapping, despite multiple HandlerMapping beans being
0271:             * defined in the context.
0272:             */
0273:            public void setDetectAllHandlerMappings(
0274:                    boolean detectAllHandlerMappings) {
0275:                this .detectAllHandlerMappings = detectAllHandlerMappings;
0276:            }
0277:
0278:            /**
0279:             * Set whether to detect all HandlerAdapter beans in this portlet's context.
0280:             * Else, just a single bean with name "handlerAdapter" will be expected.
0281:             * <p>Default is "true". Turn this off if you want this portlet to use a
0282:             * single HandlerAdapter, despite multiple HandlerAdapter beans being
0283:             * defined in the context.
0284:             */
0285:            public void setDetectAllHandlerAdapters(
0286:                    boolean detectAllHandlerAdapters) {
0287:                this .detectAllHandlerAdapters = detectAllHandlerAdapters;
0288:            }
0289:
0290:            /**
0291:             * Set whether to detect all HandlerExceptionResolver beans in this portlet's context.
0292:             * Else, just a single bean with name "handlerExceptionResolver" will be expected.
0293:             * <p>Default is true. Turn this off if you want this portlet to use a
0294:             * single HandlerExceptionResolver, despite multiple HandlerExceptionResolver
0295:             * beans being defined in the context.
0296:             */
0297:            public void setDetectAllHandlerExceptionResolvers(
0298:                    boolean detectAllHandlerExceptionResolvers) {
0299:                this .detectAllHandlerExceptionResolvers = detectAllHandlerExceptionResolvers;
0300:            }
0301:
0302:            /**
0303:             * Set whether to detect all ViewResolver beans in this portlet's context.
0304:             * Else, just a single bean with name "viewResolver" will be expected.
0305:             * <p>Default is true. Turn this off if you want this portlet to use a
0306:             * single ViewResolver, despite multiple ViewResolver beans being
0307:             * defined in the context.
0308:             */
0309:            public void setDetectAllViewResolvers(boolean detectAllViewResolvers) {
0310:                this .detectAllViewResolvers = detectAllViewResolvers;
0311:            }
0312:
0313:            /**
0314:             * Set the URL to the ViewRendererServlet. That servlet is used to
0315:             * ultimately render all views in the portlet application.
0316:             */
0317:            public void setViewRendererUrl(String viewRendererUrl) {
0318:                this .viewRendererUrl = viewRendererUrl;
0319:            }
0320:
0321:            /**
0322:             * Set whether to expose the LocaleContext and RequestAttributes as inheritable
0323:             * for child threads (using an {@link java.lang.InheritableThreadLocal}).
0324:             * <p>Default is "false", to avoid side effects on spawned background threads.
0325:             * Switch this to "true" to enable inheritance for custom child threads which
0326:             * are spawned during request processing and only used for this request
0327:             * (that is, ending after their initial task, without reuse of the thread).
0328:             * <p><b>WARNING:</b> Do not use inheritance for child threads if you are
0329:             * accessing a thread pool which is configured to potentially add new threads
0330:             * on demand (e.g. a JDK {@link java.util.concurrent.ThreadPoolExecutor}),
0331:             * since this will expose the inherited context to such a pooled thread.
0332:             */
0333:            public void setThreadContextInheritable(
0334:                    boolean threadContextInheritable) {
0335:                this .threadContextInheritable = threadContextInheritable;
0336:            }
0337:
0338:            /**
0339:             * This implementation calls {@link #initStrategies}.
0340:             */
0341:            public void onRefresh(ApplicationContext context) {
0342:                initStrategies(context);
0343:            }
0344:
0345:            /**
0346:             * Refresh the strategy objects that this portlet uses.
0347:             * <p>May be overridden in subclasses in order to initialize
0348:             * further strategy objects.
0349:             */
0350:            protected void initStrategies(ApplicationContext context) {
0351:                initMultipartResolver(context);
0352:                initHandlerMappings(context);
0353:                initHandlerAdapters(context);
0354:                initHandlerExceptionResolvers(context);
0355:                initViewResolvers(context);
0356:            }
0357:
0358:            /**
0359:             * Initialize the PortletMultipartResolver used by this class.
0360:             * <p>If no valid bean is defined with the given name in the BeanFactory
0361:             * for this namespace, no multipart handling is provided.
0362:             */
0363:            private void initMultipartResolver(ApplicationContext context) {
0364:                try {
0365:                    this .multipartResolver = (PortletMultipartResolver) context
0366:                            .getBean(MULTIPART_RESOLVER_BEAN_NAME,
0367:                                    PortletMultipartResolver.class);
0368:                    if (logger.isDebugEnabled()) {
0369:                        logger.debug("Using MultipartResolver ["
0370:                                + this .multipartResolver + "]");
0371:                    }
0372:                } catch (NoSuchBeanDefinitionException ex) {
0373:                    // Default is no multipart resolver.
0374:                    this .multipartResolver = null;
0375:                    if (logger.isDebugEnabled()) {
0376:                        logger
0377:                                .debug("Unable to locate PortletMultipartResolver with name '"
0378:                                        + MULTIPART_RESOLVER_BEAN_NAME
0379:                                        + "': no multipart request handling provided");
0380:                    }
0381:                }
0382:            }
0383:
0384:            /**
0385:             * Initialize the HandlerMappings used by this class.
0386:             * <p>If no HandlerMapping beans are defined in the BeanFactory
0387:             * for this namespace, we default to PortletModeHandlerMapping.
0388:             */
0389:            private void initHandlerMappings(ApplicationContext context) {
0390:                this .handlerMappings = null;
0391:
0392:                if (this .detectAllHandlerMappings) {
0393:                    // Find all HandlerMappings in the ApplicationContext,
0394:                    // including ancestor contexts.
0395:                    Map matchingBeans = BeanFactoryUtils
0396:                            .beansOfTypeIncludingAncestors(context,
0397:                                    HandlerMapping.class, true, false);
0398:                    if (!matchingBeans.isEmpty()) {
0399:                        this .handlerMappings = new ArrayList(matchingBeans
0400:                                .values());
0401:                        // We keep HandlerMappings in sorted order.
0402:                        Collections.sort(this .handlerMappings,
0403:                                new OrderComparator());
0404:                    }
0405:                } else {
0406:                    try {
0407:                        Object hm = context.getBean(HANDLER_MAPPING_BEAN_NAME,
0408:                                HandlerMapping.class);
0409:                        this .handlerMappings = Collections.singletonList(hm);
0410:                    } catch (NoSuchBeanDefinitionException ex) {
0411:                        // Ignore, we'll add a default HandlerMapping later.
0412:                    }
0413:                }
0414:
0415:                // Ensure we have at least one HandlerMapping, by registering
0416:                // a default HandlerMapping if no other mappings are found.
0417:                if (this .handlerMappings == null) {
0418:                    this .handlerMappings = getDefaultStrategies(context,
0419:                            HandlerMapping.class);
0420:                    if (logger.isDebugEnabled()) {
0421:                        logger.debug("No HandlerMappings found in portlet '"
0422:                                + getPortletName() + "': using default");
0423:                    }
0424:                }
0425:            }
0426:
0427:            /**
0428:             * Initialize the HandlerAdapters used by this class.
0429:             * <p>If no HandlerAdapter beans are defined in the BeanFactory
0430:             * for this namespace, we default to SimpleControllerHandlerAdapter.
0431:             */
0432:            private void initHandlerAdapters(ApplicationContext context) {
0433:                this .handlerAdapters = null;
0434:
0435:                if (this .detectAllHandlerAdapters) {
0436:                    // Find all HandlerAdapters in the ApplicationContext,
0437:                    // including ancestor contexts.
0438:                    Map matchingBeans = BeanFactoryUtils
0439:                            .beansOfTypeIncludingAncestors(context,
0440:                                    HandlerAdapter.class, true, false);
0441:                    if (!matchingBeans.isEmpty()) {
0442:                        this .handlerAdapters = new ArrayList(matchingBeans
0443:                                .values());
0444:                        // We keep HandlerAdapters in sorted order.
0445:                        Collections.sort(this .handlerAdapters,
0446:                                new OrderComparator());
0447:                    }
0448:                } else {
0449:                    try {
0450:                        Object ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME,
0451:                                HandlerAdapter.class);
0452:                        this .handlerAdapters = Collections.singletonList(ha);
0453:                    } catch (NoSuchBeanDefinitionException ex) {
0454:                        // Ignore, we'll add a default HandlerAdapter later.
0455:                    }
0456:                }
0457:
0458:                // Ensure we have at least some HandlerAdapters, by registering
0459:                // default HandlerAdapters if no other adapters are found.
0460:                if (this .handlerAdapters == null) {
0461:                    this .handlerAdapters = getDefaultStrategies(context,
0462:                            HandlerAdapter.class);
0463:                    if (logger.isDebugEnabled()) {
0464:                        logger.debug("No HandlerAdapters found in portlet '"
0465:                                + getPortletName() + "': using default");
0466:                    }
0467:                }
0468:            }
0469:
0470:            /**
0471:             * Initialize the HandlerExceptionResolver used by this class.
0472:             * <p>If no bean is defined with the given name in the BeanFactory
0473:             * for this namespace, we default to no exception resolver.
0474:             */
0475:            private void initHandlerExceptionResolvers(
0476:                    ApplicationContext context) {
0477:                this .handlerExceptionResolvers = null;
0478:
0479:                if (this .detectAllHandlerExceptionResolvers) {
0480:                    // Find all HandlerExceptionResolvers in the ApplicationContext,
0481:                    // including ancestor contexts.
0482:                    Map matchingBeans = BeanFactoryUtils
0483:                            .beansOfTypeIncludingAncestors(context,
0484:                                    HandlerExceptionResolver.class, true, false);
0485:                    if (!matchingBeans.isEmpty()) {
0486:                        this .handlerExceptionResolvers = new ArrayList(
0487:                                matchingBeans.values());
0488:                        // We keep HandlerExceptionResolvers in sorted order.
0489:                        Collections.sort(this .handlerExceptionResolvers,
0490:                                new OrderComparator());
0491:                    }
0492:                } else {
0493:                    try {
0494:                        Object her = context.getBean(
0495:                                HANDLER_EXCEPTION_RESOLVER_BEAN_NAME,
0496:                                HandlerExceptionResolver.class);
0497:                        this .handlerExceptionResolvers = Collections
0498:                                .singletonList(her);
0499:                    } catch (NoSuchBeanDefinitionException ex) {
0500:                        // Ignore, no HandlerExceptionResolver is fine too.
0501:                    }
0502:                }
0503:
0504:                // Just for consistency, check for default HandlerExceptionResolvers...
0505:                // There aren't any in usual scenarios.
0506:                if (this .handlerExceptionResolvers == null) {
0507:                    this .handlerExceptionResolvers = getDefaultStrategies(
0508:                            context, HandlerExceptionResolver.class);
0509:                    if (logger.isDebugEnabled()) {
0510:                        logger
0511:                                .debug("No HandlerExceptionResolvers found in portlet '"
0512:                                        + getPortletName() + "': using default");
0513:                    }
0514:                }
0515:            }
0516:
0517:            /**
0518:             * Initialize the ViewResolvers used by this class.
0519:             * <p>If no ViewResolver beans are defined in the BeanFactory
0520:             * for this namespace, we default to InternalResourceViewResolver.
0521:             */
0522:            private void initViewResolvers(ApplicationContext context) {
0523:                this .viewResolvers = null;
0524:
0525:                if (this .detectAllViewResolvers) {
0526:                    // Find all ViewResolvers in the ApplicationContext,
0527:                    // including ancestor contexts.
0528:                    Map matchingBeans = BeanFactoryUtils
0529:                            .beansOfTypeIncludingAncestors(context,
0530:                                    ViewResolver.class, true, false);
0531:                    if (!matchingBeans.isEmpty()) {
0532:                        this .viewResolvers = new ArrayList(matchingBeans
0533:                                .values());
0534:                        // We keep ViewResolvers in sorted order.
0535:                        Collections.sort(this .viewResolvers,
0536:                                new OrderComparator());
0537:                    }
0538:                } else {
0539:                    try {
0540:                        Object vr = context.getBean(VIEW_RESOLVER_BEAN_NAME,
0541:                                ViewResolver.class);
0542:                        this .viewResolvers = Collections.singletonList(vr);
0543:                    } catch (NoSuchBeanDefinitionException ex) {
0544:                        // Ignore, we'll add a default ViewResolver later.
0545:                    }
0546:                }
0547:
0548:                // Ensure we have at least one ViewResolver, by registering
0549:                // a default ViewResolver if no other resolvers are found.
0550:                if (this .viewResolvers == null) {
0551:                    this .viewResolvers = getDefaultStrategies(context,
0552:                            ViewResolver.class);
0553:                    if (logger.isDebugEnabled()) {
0554:                        logger.debug("No ViewResolvers found in portlet '"
0555:                                + getPortletName() + "': using default");
0556:                    }
0557:                }
0558:            }
0559:
0560:            /**
0561:             * Return the default strategy object for the given strategy interface.
0562:             * <p>The default implementation delegates to {@link #getDefaultStrategies},
0563:             * expecting a single object in the list.
0564:             * @param context the current Portlet ApplicationContext
0565:             * @param strategyInterface the strategy interface
0566:             * @return the corresponding strategy object
0567:             * @throws BeansException if initialization failed
0568:             * @see #getDefaultStrategies
0569:             */
0570:            protected Object getDefaultStrategy(ApplicationContext context,
0571:                    Class strategyInterface) throws BeansException {
0572:                List strategies = getDefaultStrategies(context,
0573:                        strategyInterface);
0574:                if (strategies.size() != 1) {
0575:                    throw new BeanInitializationException(
0576:                            "DispatcherPortlet needs exactly 1 strategy for interface ["
0577:                                    + strategyInterface.getName() + "]");
0578:                }
0579:                return strategies.get(0);
0580:            }
0581:
0582:            /**
0583:             * Create a List of default strategy objects for the given strategy interface.
0584:             * <p>The default implementation uses the "DispatcherPortlet.properties" file
0585:             * (in the same package as the DispatcherPortlet class) to determine the class names.
0586:             * It instantiates the strategy objects and satisifies ApplicationContextAware
0587:             * if necessary.
0588:             * @param context the current Portlet ApplicationContext
0589:             * @param strategyInterface the strategy interface
0590:             * @return the List of corresponding strategy objects
0591:             * @throws BeansException if initialization failed
0592:             */
0593:            protected List getDefaultStrategies(ApplicationContext context,
0594:                    Class strategyInterface) throws BeansException {
0595:                String key = strategyInterface.getName();
0596:                List strategies = null;
0597:                String value = defaultStrategies.getProperty(key);
0598:                if (value != null) {
0599:                    String[] classNames = StringUtils
0600:                            .commaDelimitedListToStringArray(value);
0601:                    strategies = new ArrayList(classNames.length);
0602:                    for (int i = 0; i < classNames.length; i++) {
0603:                        String className = classNames[i];
0604:                        try {
0605:                            Class clazz = ClassUtils.forName(className,
0606:                                    getClass().getClassLoader());
0607:                            Object strategy = createDefaultStrategy(context,
0608:                                    clazz);
0609:                            strategies.add(strategy);
0610:                        } catch (ClassNotFoundException ex) {
0611:                            throw new BeanInitializationException(
0612:                                    "Could not find DispatcherPortlet's default strategy class ["
0613:                                            + className + "] for interface ["
0614:                                            + key + "]", ex);
0615:                        } catch (LinkageError err) {
0616:                            throw new BeanInitializationException(
0617:                                    "Error loading DispatcherPortlet's default strategy class ["
0618:                                            + className
0619:                                            + "] for interface ["
0620:                                            + key
0621:                                            + "]: problem with class file or dependent class",
0622:                                    err);
0623:                        }
0624:                    }
0625:                } else {
0626:                    strategies = Collections.EMPTY_LIST;
0627:                }
0628:                return strategies;
0629:            }
0630:
0631:            /**
0632:             * Create a default strategy.
0633:             * <p>The default implementation uses
0634:             * {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory#createBean}.
0635:             * @param context the current Portlet ApplicationContext
0636:             * @param clazz the strategy implementation class to instantiate
0637:             * @return the fully configured strategy instance
0638:             * @throws BeansException if initialization failed
0639:             * @see org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory()
0640:             */
0641:            protected Object createDefaultStrategy(ApplicationContext context,
0642:                    Class clazz) throws BeansException {
0643:                return context.getAutowireCapableBeanFactory().createBean(
0644:                        clazz, AutowireCapableBeanFactory.AUTOWIRE_NO, false);
0645:            }
0646:
0647:            /**
0648:             * Obtain this portlet's PortletMultipartResolver, if any.
0649:             * @return the PortletMultipartResolver used by this portlet, or <code>null</code>
0650:             * if none (indicating that no multipart support is available)
0651:             */
0652:            public PortletMultipartResolver getMultipartResolver() {
0653:                return this .multipartResolver;
0654:            }
0655:
0656:            /**
0657:             * Processes the actual dispatching to the handler for action requests.
0658:             * <p>The handler will be obtained by applying the portlet's HandlerMappings in order.
0659:             * The HandlerAdapter will be obtained by querying the portlet's installed
0660:             * HandlerAdapters to find the first that supports the handler class.
0661:             * @param request current portlet action request
0662:             * @param response current portlet Action response
0663:             * @throws Exception in case of any kind of processing failure
0664:             */
0665:            protected void doActionService(ActionRequest request,
0666:                    ActionResponse response) throws Exception {
0667:                if (logger.isDebugEnabled()) {
0668:                    logger.debug("DispatcherPortlet with name '"
0669:                            + getPortletName() + "' received action request");
0670:                }
0671:
0672:                // Expose current LocaleResolver and request as LocaleContext.
0673:                LocaleContext previousLocaleContext = LocaleContextHolder
0674:                        .getLocaleContext();
0675:                LocaleContextHolder.setLocaleContext(
0676:                        buildLocaleContext(request),
0677:                        this .threadContextInheritable);
0678:
0679:                // Expose current RequestAttributes to current thread.
0680:                RequestAttributes previousRequestAttributes = RequestContextHolder
0681:                        .getRequestAttributes();
0682:                PortletRequestAttributes requestAttributes = new PortletRequestAttributes(
0683:                        request);
0684:                RequestContextHolder.setRequestAttributes(requestAttributes,
0685:                        this .threadContextInheritable);
0686:
0687:                if (logger.isDebugEnabled()) {
0688:                    logger.debug("Bound action request context to thread: "
0689:                            + request);
0690:                }
0691:
0692:                ActionRequest processedRequest = request;
0693:                HandlerExecutionChain mappedHandler = null;
0694:                int interceptorIndex = -1;
0695:
0696:                try {
0697:                    processedRequest = checkMultipart(request);
0698:
0699:                    // Determine handler for the current request.
0700:                    mappedHandler = getHandler(processedRequest, false);
0701:                    if (mappedHandler == null
0702:                            || mappedHandler.getHandler() == null) {
0703:                        noHandlerFound(processedRequest, response);
0704:                        return;
0705:                    }
0706:
0707:                    // Apply preHandle methods of registered interceptors.
0708:                    if (mappedHandler.getInterceptors() != null) {
0709:                        for (int i = 0; i < mappedHandler.getInterceptors().length; i++) {
0710:                            HandlerInterceptor interceptor = mappedHandler
0711:                                    .getInterceptors()[i];
0712:                            if (!interceptor.preHandleAction(processedRequest,
0713:                                    response, mappedHandler.getHandler())) {
0714:                                triggerAfterActionCompletion(mappedHandler,
0715:                                        interceptorIndex, processedRequest,
0716:                                        response, null);
0717:                                return;
0718:                            }
0719:                            interceptorIndex = i;
0720:                        }
0721:                    }
0722:
0723:                    // Actually invoke the handler.
0724:                    HandlerAdapter ha = getHandlerAdapter(mappedHandler
0725:                            .getHandler());
0726:                    ha.handleAction(processedRequest, response, mappedHandler
0727:                            .getHandler());
0728:
0729:                    // Trigger after-completion for successful outcome.
0730:                    triggerAfterActionCompletion(mappedHandler,
0731:                            interceptorIndex, processedRequest, response, null);
0732:                }
0733:
0734:                catch (Exception ex) {
0735:                    // Trigger after-completion for thrown exception.
0736:                    triggerAfterActionCompletion(mappedHandler,
0737:                            interceptorIndex, processedRequest, response, ex);
0738:                    // Forward the exception to the render phase to be displayed.
0739:                    logger
0740:                            .debug(
0741:                                    "Caught exception during action phase - forwarding to render phase",
0742:                                    ex);
0743:                    PortletSession session = request.getPortletSession();
0744:                    session
0745:                            .setAttribute(ACTION_EXCEPTION_SESSION_ATTRIBUTE,
0746:                                    ex);
0747:                    response.setRenderParameter(
0748:                            ACTION_EXCEPTION_RENDER_PARAMETER, ex.toString());
0749:                } catch (Error err) {
0750:                    PortletException ex = new PortletException(
0751:                            "Error occured during request processing: "
0752:                                    + err.getMessage(), err);
0753:                    // Trigger after-completion for thrown exception.
0754:                    triggerAfterActionCompletion(mappedHandler,
0755:                            interceptorIndex, processedRequest, response, ex);
0756:                    throw ex;
0757:                }
0758:
0759:                finally {
0760:                    // Clean up any resources used by a multipart request.
0761:                    if (processedRequest instanceof  MultipartActionRequest
0762:                            && processedRequest != request) {
0763:                        this .multipartResolver
0764:                                .cleanupMultipart((MultipartActionRequest) processedRequest);
0765:                    }
0766:
0767:                    // Reset thread-bound context.
0768:                    RequestContextHolder.setRequestAttributes(
0769:                            previousRequestAttributes,
0770:                            this .threadContextInheritable);
0771:                    LocaleContextHolder.setLocaleContext(previousLocaleContext,
0772:                            this .threadContextInheritable);
0773:
0774:                    // Clear request attributes.
0775:                    requestAttributes.requestCompleted();
0776:                    if (logger.isDebugEnabled()) {
0777:                        logger
0778:                                .debug("Cleared thread-bound action request context: "
0779:                                        + request);
0780:                    }
0781:                }
0782:            }
0783:
0784:            /**
0785:             * Processes the actual dispatching to the handler for render requests.
0786:             * <p>The handler will be obtained by applying the portlet's HandlerMappings in order.
0787:             * The HandlerAdapter will be obtained by querying the portlet's installed
0788:             * HandlerAdapters to find the first that supports the handler class.
0789:             * @param request current portlet render request
0790:             * @param response current portlet render response
0791:             * @throws Exception in case of any kind of processing failure
0792:             */
0793:            protected void doRenderService(RenderRequest request,
0794:                    RenderResponse response) throws Exception {
0795:                if (logger.isDebugEnabled()) {
0796:                    logger.debug("DispatcherPortlet with name '"
0797:                            + getPortletName() + "' received render request");
0798:                }
0799:
0800:                // Expose current LocaleResolver and request as LocaleContext.
0801:                LocaleContext previousLocaleContext = LocaleContextHolder
0802:                        .getLocaleContext();
0803:                LocaleContextHolder.setLocaleContext(
0804:                        buildLocaleContext(request),
0805:                        this .threadContextInheritable);
0806:
0807:                // Expose current RequestAttributes to current thread.
0808:                RequestAttributes previousRequestAttributes = RequestContextHolder
0809:                        .getRequestAttributes();
0810:                PortletRequestAttributes requestAttributes = new PortletRequestAttributes(
0811:                        request);
0812:                RequestContextHolder.setRequestAttributes(requestAttributes,
0813:                        this .threadContextInheritable);
0814:
0815:                if (logger.isDebugEnabled()) {
0816:                    logger.debug("Bound render request context to thread: "
0817:                            + request);
0818:                }
0819:
0820:                RenderRequest processedRequest = request;
0821:                HandlerExecutionChain mappedHandler = null;
0822:                int interceptorIndex = -1;
0823:
0824:                try {
0825:                    ModelAndView mv = null;
0826:                    try {
0827:                        // Check for forwarded exception from the action phase
0828:                        PortletSession session = request
0829:                                .getPortletSession(false);
0830:                        if (session != null) {
0831:                            if (request
0832:                                    .getParameter(ACTION_EXCEPTION_RENDER_PARAMETER) != null) {
0833:                                Exception ex = (Exception) session
0834:                                        .getAttribute(ACTION_EXCEPTION_SESSION_ATTRIBUTE);
0835:                                if (ex != null) {
0836:                                    logger
0837:                                            .debug("Render phase found exception caught during action phase - rethrowing it");
0838:                                    throw ex;
0839:                                }
0840:                            } else {
0841:                                session
0842:                                        .removeAttribute(ACTION_EXCEPTION_SESSION_ATTRIBUTE);
0843:                            }
0844:                        }
0845:
0846:                        // Determine handler for the current request.
0847:                        mappedHandler = getHandler(processedRequest, false);
0848:                        if (mappedHandler == null
0849:                                || mappedHandler.getHandler() == null) {
0850:                            noHandlerFound(processedRequest, response);
0851:                            return;
0852:                        }
0853:
0854:                        // Apply preHandle methods of registered interceptors.
0855:                        if (mappedHandler.getInterceptors() != null) {
0856:                            for (int i = 0; i < mappedHandler.getInterceptors().length; i++) {
0857:                                HandlerInterceptor interceptor = mappedHandler
0858:                                        .getInterceptors()[i];
0859:                                if (!interceptor.preHandleRender(
0860:                                        processedRequest, response,
0861:                                        mappedHandler.getHandler())) {
0862:                                    triggerAfterRenderCompletion(mappedHandler,
0863:                                            interceptorIndex, processedRequest,
0864:                                            response, null);
0865:                                    return;
0866:                                }
0867:                                interceptorIndex = i;
0868:                            }
0869:                        }
0870:
0871:                        // Actually invoke the handler.
0872:                        HandlerAdapter ha = getHandlerAdapter(mappedHandler
0873:                                .getHandler());
0874:                        mv = ha.handleRender(processedRequest, response,
0875:                                mappedHandler.getHandler());
0876:
0877:                        // Apply postHandle methods of registered interceptors.
0878:                        if (mappedHandler.getInterceptors() != null) {
0879:                            for (int i = mappedHandler.getInterceptors().length - 1; i >= 0; i--) {
0880:                                HandlerInterceptor interceptor = mappedHandler
0881:                                        .getInterceptors()[i];
0882:                                interceptor.postHandleRender(processedRequest,
0883:                                        response, mappedHandler.getHandler(),
0884:                                        mv);
0885:                            }
0886:                        }
0887:                    } catch (ModelAndViewDefiningException ex) {
0888:                        logger
0889:                                .debug(
0890:                                        "ModelAndViewDefiningException encountered",
0891:                                        ex);
0892:                        mv = ex.getModelAndView();
0893:                    } catch (Exception ex) {
0894:                        Object handler = (mappedHandler != null ? mappedHandler
0895:                                .getHandler() : null);
0896:                        mv = processHandlerException(request, response,
0897:                                handler, ex);
0898:                    }
0899:
0900:                    // Did the handler return a view to render?
0901:                    if (mv != null && !mv.isEmpty()) {
0902:                        render(mv, processedRequest, response);
0903:                    } else {
0904:                        if (logger.isDebugEnabled()) {
0905:                            logger
0906:                                    .debug("Null ModelAndView returned to DispatcherPortlet with name '"
0907:                                            + getPortletName()
0908:                                            + "': assuming HandlerAdapter completed request handling");
0909:                        }
0910:                    }
0911:
0912:                    // Trigger after-completion for successful outcome.
0913:                    triggerAfterRenderCompletion(mappedHandler,
0914:                            interceptorIndex, processedRequest, response, null);
0915:                }
0916:
0917:                catch (Exception ex) {
0918:                    // Trigger after-completion for thrown exception.
0919:                    triggerAfterRenderCompletion(mappedHandler,
0920:                            interceptorIndex, processedRequest, response, ex);
0921:                    throw ex;
0922:                } catch (Error err) {
0923:                    PortletException ex = new PortletException(
0924:                            "Error occured during request processing: "
0925:                                    + err.getMessage(), err);
0926:                    // Trigger after-completion for thrown exception.
0927:                    triggerAfterRenderCompletion(mappedHandler,
0928:                            interceptorIndex, processedRequest, response, ex);
0929:                    throw ex;
0930:                }
0931:
0932:                finally {
0933:                    // Reset thread-bound context.
0934:                    RequestContextHolder.setRequestAttributes(
0935:                            previousRequestAttributes,
0936:                            this .threadContextInheritable);
0937:                    LocaleContextHolder.setLocaleContext(previousLocaleContext,
0938:                            this .threadContextInheritable);
0939:
0940:                    // Clear request attributes.
0941:                    requestAttributes.requestCompleted();
0942:                    if (logger.isDebugEnabled()) {
0943:                        logger
0944:                                .debug("Cleared thread-bound render request context: "
0945:                                        + request);
0946:                    }
0947:                }
0948:            }
0949:
0950:            /**
0951:             * Build a LocaleContext for the given request, exposing the request's
0952:             * primary locale as current locale.
0953:             * @param request current HTTP request
0954:             * @return the corresponding LocaleContext
0955:             */
0956:            protected LocaleContext buildLocaleContext(PortletRequest request) {
0957:                return new SimpleLocaleContext(request.getLocale());
0958:            }
0959:
0960:            /**
0961:             * Convert the request into a multipart request, and make multipart resolver available.
0962:             * If no multipart resolver is set, simply use the existing request.
0963:             * @param request current HTTP request
0964:             * @return the processed request (multipart wrapper if necessary)
0965:             */
0966:            protected ActionRequest checkMultipart(ActionRequest request)
0967:                    throws MultipartException {
0968:                if (this .multipartResolver != null
0969:                        && this .multipartResolver.isMultipart(request)) {
0970:                    if (request instanceof  MultipartActionRequest) {
0971:                        logger
0972:                                .debug("Request is already a MultipartActionRequest - probably in a forward");
0973:                    } else {
0974:                        return this .multipartResolver.resolveMultipart(request);
0975:                    }
0976:                }
0977:                // If not returned before: return original request.
0978:                return request;
0979:            }
0980:
0981:            /**
0982:             * Return the HandlerExecutionChain for this request.
0983:             * Try all handler mappings in order.
0984:             * @param request current portlet request
0985:             * @param cache whether to cache the HandlerExecutionChain in a request attribute
0986:             * @return the HandlerExceutionChain, or null if no handler could be found
0987:             */
0988:            protected HandlerExecutionChain getHandler(PortletRequest request,
0989:                    boolean cache) throws Exception {
0990:                HandlerExecutionChain handler = (HandlerExecutionChain) request
0991:                        .getAttribute(HANDLER_EXECUTION_CHAIN_ATTRIBUTE);
0992:                if (handler != null) {
0993:                    if (!cache) {
0994:                        request
0995:                                .removeAttribute(HANDLER_EXECUTION_CHAIN_ATTRIBUTE);
0996:                    }
0997:                    return handler;
0998:                }
0999:
1000:                Iterator it = this .handlerMappings.iterator();
1001:                while (it.hasNext()) {
1002:                    HandlerMapping hm = (HandlerMapping) it.next();
1003:                    if (logger.isDebugEnabled()) {
1004:                        logger.debug("Testing handler map [" + hm
1005:                                + "] in DispatcherPortlet with name '"
1006:                                + getPortletName() + "'");
1007:                    }
1008:                    handler = hm.getHandler(request);
1009:                    if (handler != null) {
1010:                        if (cache) {
1011:                            request.setAttribute(
1012:                                    HANDLER_EXECUTION_CHAIN_ATTRIBUTE, handler);
1013:                        }
1014:                        return handler;
1015:                    }
1016:                }
1017:                return null;
1018:            }
1019:
1020:            /**
1021:             * No handler found -> throw appropriate exception.
1022:             * @param request current portlet request
1023:             * @param response current portlet response
1024:             */
1025:            protected void noHandlerFound(PortletRequest request,
1026:                    PortletResponse response) throws PortletException {
1027:                if (pageNotFoundLogger.isWarnEnabled()) {
1028:                    pageNotFoundLogger
1029:                            .warn("No mapping found for current request "
1030:                                    + "in DispatcherPortlet with name '"
1031:                                    + getPortletName()
1032:                                    + "'"
1033:                                    + " mode '"
1034:                                    + request.getPortletMode()
1035:                                    + "'"
1036:                                    + " type '"
1037:                                    + (request instanceof  ActionRequest ? "action"
1038:                                            : "render") + "'" + " session '"
1039:                                    + request.getRequestedSessionId() + "'"
1040:                                    + " user '"
1041:                                    + getUsernameForRequest(request) + "'");
1042:                }
1043:                throw new UnavailableException("No handler found for request");
1044:            }
1045:
1046:            /**
1047:             * Return the HandlerAdapter for this handler object.
1048:             * @param handler the handler object to find an adapter for
1049:             * @throws PortletException if no HandlerAdapter can be found for the handler.
1050:             * This is a fatal error.
1051:             */
1052:            protected HandlerAdapter getHandlerAdapter(Object handler)
1053:                    throws PortletException {
1054:                Iterator it = this .handlerAdapters.iterator();
1055:                while (it.hasNext()) {
1056:                    HandlerAdapter ha = (HandlerAdapter) it.next();
1057:                    if (logger.isDebugEnabled()) {
1058:                        logger.debug("Testing handler adapter [" + ha + "]");
1059:                    }
1060:                    if (ha.supports(handler)) {
1061:                        return ha;
1062:                    }
1063:                }
1064:                throw new PortletException(
1065:                        "No adapter for handler ["
1066:                                + handler
1067:                                + "]: Does your handler implement a supported interface like Controller?");
1068:            }
1069:
1070:            /**
1071:             * Determine an error ModelAndView via the registered HandlerExceptionResolvers.
1072:             * @param request current portlet request
1073:             * @param response current portlet response
1074:             * @param handler the executed handler, or null if none chosen at the time of
1075:             * the exception (for example, if multipart resolution failed)
1076:             * @param ex the exception that got thrown during handler execution
1077:             * @return a corresponding ModelAndView to forward to
1078:             * @throws Exception if no error ModelAndView found
1079:             */
1080:            protected ModelAndView processHandlerException(
1081:                    RenderRequest request, RenderResponse response,
1082:                    Object handler, Exception ex) throws Exception {
1083:
1084:                ModelAndView exMv = null;
1085:                for (Iterator it = this .handlerExceptionResolvers.iterator(); exMv == null
1086:                        && it.hasNext();) {
1087:                    HandlerExceptionResolver resolver = (HandlerExceptionResolver) it
1088:                            .next();
1089:                    exMv = resolver.resolveException(request, response,
1090:                            handler, ex);
1091:                }
1092:                if (exMv != null) {
1093:                    if (logger.isDebugEnabled()) {
1094:                        logger
1095:                                .debug("HandlerExceptionResolver returned ModelAndView ["
1096:                                        + exMv + "] for exception");
1097:                    }
1098:                    logger
1099:                            .warn(
1100:                                    "Handler execution resulted in exception - forwarding to resolved error view",
1101:                                    ex);
1102:                    return exMv;
1103:                } else {
1104:                    throw ex;
1105:                }
1106:            }
1107:
1108:            /**
1109:             * Trigger afterCompletion callbacks on the mapped HandlerInterceptors.
1110:             * Will just invoke afterCompletion for all interceptors whose preHandle
1111:             * invocation has successfully completed and returned true.
1112:             * @param mappedHandler the mapped HandlerExecutionChain
1113:             * @param interceptorIndex index of last interceptor that successfully completed
1114:             * @param ex Exception thrown on handler execution, or null if none
1115:             * @see HandlerInterceptor#afterRenderCompletion
1116:             */
1117:            private void triggerAfterActionCompletion(
1118:                    HandlerExecutionChain mappedHandler, int interceptorIndex,
1119:                    ActionRequest request, ActionResponse response, Exception ex)
1120:                    throws Exception {
1121:
1122:                // Apply afterCompletion methods of registered interceptors.
1123:                if (mappedHandler != null) {
1124:                    if (mappedHandler.getInterceptors() != null) {
1125:                        for (int i = interceptorIndex; i >= 0; i--) {
1126:                            HandlerInterceptor interceptor = mappedHandler
1127:                                    .getInterceptors()[i];
1128:                            try {
1129:                                interceptor.afterActionCompletion(request,
1130:                                        response, mappedHandler.getHandler(),
1131:                                        ex);
1132:                            } catch (Throwable ex2) {
1133:                                logger
1134:                                        .error(
1135:                                                "HandlerInterceptor.afterCompletion threw exception",
1136:                                                ex2);
1137:                            }
1138:                        }
1139:                    }
1140:                }
1141:            }
1142:
1143:            /**
1144:             * Render the given ModelAndView. This is the last stage in handling a request.
1145:             * It may involve resolving the view by name.
1146:             * @param mv the ModelAndView to render
1147:             * @param request current portlet render request
1148:             * @param response current portlet render response
1149:             * @throws Exception if there's a problem rendering the view
1150:             */
1151:            protected void render(ModelAndView mv, RenderRequest request,
1152:                    RenderResponse response) throws Exception {
1153:                View view = null;
1154:                if (mv.isReference()) {
1155:                    // We need to resolve the view name.
1156:                    view = resolveViewName(mv.getViewName(), mv
1157:                            .getModelInternal(), request);
1158:                    if (view == null) {
1159:                        throw new PortletException(
1160:                                "Could not resolve view with name '"
1161:                                        + mv.getViewName()
1162:                                        + "' in portlet with name '"
1163:                                        + getPortletName() + "'");
1164:                    }
1165:                } else {
1166:                    // No need to lookup: the ModelAndView object contains the actual View object.
1167:                    Object viewObject = mv.getView();
1168:                    if (viewObject == null) {
1169:                        throw new PortletException("ModelAndView [" + mv
1170:                                + "] neither contains a view name nor a "
1171:                                + "View object in portlet with name '"
1172:                                + getPortletName() + "'");
1173:                    }
1174:                    if (!(viewObject instanceof  View)) {
1175:                        throw new PortletException(
1176:                                "View object ["
1177:                                        + viewObject
1178:                                        + "] is not an instance of [org.springframework.web.servlet.View] - "
1179:                                        + "DispatcherPortlet does not support any other view types");
1180:                    }
1181:                    view = (View) viewObject;
1182:                }
1183:
1184:                if (view == null) {
1185:                    throw new PortletException(
1186:                            "Could not resolve view with name '"
1187:                                    + mv.getViewName()
1188:                                    + "' in portlet with name '"
1189:                                    + getPortletName() + "'");
1190:                }
1191:
1192:                // Set the content type on the response if needed and if possible.
1193:                // The Portlet spec requires the content type to be set on the RenderResponse;
1194:                // it's not sufficient to let the View set it on the ServletResponse.
1195:                if (response.getContentType() != null) {
1196:                    if (logger.isDebugEnabled()) {
1197:                        logger
1198:                                .debug("Portlet response content type already set to ["
1199:                                        + response.getContentType() + "]");
1200:                    }
1201:                } else {
1202:                    // No Portlet content type specified yet -> use the view-determined type.
1203:                    String contentType = view.getContentType();
1204:                    if (contentType != null) {
1205:                        if (logger.isDebugEnabled()) {
1206:                            logger
1207:                                    .debug("Setting portlet response content type to view-determined type ["
1208:                                            + contentType + "]");
1209:                        }
1210:                        response.setContentType(contentType);
1211:                    }
1212:                }
1213:
1214:                // Expose Portlet ApplicationContext to view objects.
1215:                request.setAttribute(
1216:                        ViewRendererServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE,
1217:                        getPortletApplicationContext());
1218:
1219:                // These attributes are required by the ViewRendererServlet.
1220:                request.setAttribute(ViewRendererServlet.VIEW_ATTRIBUTE, view);
1221:                request.setAttribute(ViewRendererServlet.MODEL_ATTRIBUTE, mv
1222:                        .getModel());
1223:
1224:                // Unclude the content of the view in the render response.
1225:                getPortletContext().getRequestDispatcher(this .viewRendererUrl)
1226:                        .include(request, response);
1227:            }
1228:
1229:            /**
1230:             * Resolve the given view name into a View object (to be rendered).
1231:             * <p>Default implementations asks all ViewResolvers of this dispatcher.
1232:             * Can be overridden for custom resolution strategies, potentially based
1233:             * on specific model attributes or request parameters.
1234:             * @param viewName the name of the view to resolve
1235:             * @param model the model to be passed to the view
1236:             * @param request current portlet render request
1237:             * @return the View object, or null if none found
1238:             * @throws Exception if the view cannot be resolved
1239:             * (typically in case of problems creating an actual View object)
1240:             * @see ViewResolver#resolveViewName
1241:             */
1242:            protected View resolveViewName(String viewName, Map model,
1243:                    RenderRequest request) throws Exception {
1244:                for (Iterator it = this .viewResolvers.iterator(); it.hasNext();) {
1245:                    ViewResolver viewResolver = (ViewResolver) it.next();
1246:                    View view = viewResolver.resolveViewName(viewName, request
1247:                            .getLocale());
1248:                    if (view != null) {
1249:                        return view;
1250:                    }
1251:                }
1252:                return null;
1253:            }
1254:
1255:            /**
1256:             * Trigger afterCompletion callbacks on the mapped HandlerInterceptors.
1257:             * Will just invoke afterCompletion for all interceptors whose preHandle
1258:             * invocation has successfully completed and returned true.
1259:             * @param mappedHandler the mapped HandlerExecutionChain
1260:             * @param interceptorIndex index of last interceptor that successfully completed
1261:             * @param ex Exception thrown on handler execution, or null if none
1262:             * @see HandlerInterceptor#afterRenderCompletion
1263:             */
1264:            private void triggerAfterRenderCompletion(
1265:                    HandlerExecutionChain mappedHandler, int interceptorIndex,
1266:                    RenderRequest request, RenderResponse response, Exception ex)
1267:                    throws Exception {
1268:
1269:                // Apply afterCompletion methods of registered interceptors.
1270:                if (mappedHandler != null) {
1271:                    if (mappedHandler.getInterceptors() != null) {
1272:                        for (int i = interceptorIndex; i >= 0; i--) {
1273:                            HandlerInterceptor interceptor = mappedHandler
1274:                                    .getInterceptors()[i];
1275:                            try {
1276:                                interceptor.afterRenderCompletion(request,
1277:                                        response, mappedHandler.getHandler(),
1278:                                        ex);
1279:                            } catch (Throwable ex2) {
1280:                                logger
1281:                                        .error(
1282:                                                "HandlerInterceptor.afterCompletion threw exception",
1283:                                                ex2);
1284:                            }
1285:                        }
1286:                    }
1287:                }
1288:            }
1289:
1290:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.