Source Code Cross Referenced for Dispatcher.java in  » Web-Framework » struts-2.0.11 » org » apache » struts2 » dispatcher » 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 » Web Framework » struts 2.0.11 » org.apache.struts2.dispatcher 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id: Dispatcher.java 566474 2007-08-16 02:55:44Z jholmes $
003:         *
004:         * Licensed to the Apache Software Foundation (ASF) under one
005:         * or more contributor license agreements.  See the NOTICE file
006:         * distributed with this work for additional information
007:         * regarding copyright ownership.  The ASF licenses this file
008:         * to you under the Apache License, Version 2.0 (the
009:         * "License"); you may not use this file except in compliance
010:         * with the License.  You may obtain a copy of the License at
011:         *
012:         *  http://www.apache.org/licenses/LICENSE-2.0
013:         *
014:         * Unless required by applicable law or agreed to in writing,
015:         * software distributed under the License is distributed on an
016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017:         * KIND, either express or implied.  See the License for the
018:         * specific language governing permissions and limitations
019:         * under the License.
020:         */
021:        package org.apache.struts2.dispatcher;
022:
023:        import java.io.File;
024:        import java.io.IOException;
025:        import java.net.MalformedURLException;
026:        import java.net.URL;
027:        import java.util.ArrayList;
028:        import java.util.HashMap;
029:        import java.util.List;
030:        import java.util.Locale;
031:        import java.util.Map;
032:
033:        import javax.servlet.ServletContext;
034:        import javax.servlet.ServletException;
035:        import javax.servlet.http.HttpServletRequest;
036:        import javax.servlet.http.HttpServletResponse;
037:
038:        import org.apache.commons.logging.Log;
039:        import org.apache.commons.logging.LogFactory;
040:        import org.apache.struts2.ServletActionContext;
041:        import org.apache.struts2.StrutsConstants;
042:        import org.apache.struts2.StrutsStatics;
043:        import org.apache.struts2.config.*;
044:        import org.apache.struts2.config.ClasspathConfigurationProvider.ClasspathPageLocator;
045:        import org.apache.struts2.config.ClasspathConfigurationProvider.PageLocator;
046:        import org.apache.struts2.dispatcher.mapper.ActionMapping;
047:        import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
048:        import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
049:        import org.apache.struts2.util.AttributeMap;
050:        import org.apache.struts2.util.ClassLoaderUtils;
051:        import org.apache.struts2.util.ObjectFactoryDestroyable;
052:        import org.apache.struts2.views.freemarker.FreemarkerManager;
053:
054:        import com.opensymphony.xwork2.util.FileManager;
055:        import com.opensymphony.xwork2.*;
056:        import com.opensymphony.xwork2.Result;
057:        import com.opensymphony.xwork2.config.Configuration;
058:        import com.opensymphony.xwork2.config.ConfigurationException;
059:        import com.opensymphony.xwork2.config.ConfigurationManager;
060:        import com.opensymphony.xwork2.config.ConfigurationProvider;
061:        import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
062:        import com.opensymphony.xwork2.inject.Container;
063:        import com.opensymphony.xwork2.inject.ContainerBuilder;
064:        import com.opensymphony.xwork2.inject.Inject;
065:        import com.opensymphony.xwork2.util.LocalizedTextUtil;
066:        import com.opensymphony.xwork2.util.ObjectTypeDeterminer;
067:        import com.opensymphony.xwork2.util.ObjectTypeDeterminerFactory;
068:        import com.opensymphony.xwork2.util.ValueStack;
069:        import com.opensymphony.xwork2.util.ValueStackFactory;
070:        import com.opensymphony.xwork2.util.location.Location;
071:        import com.opensymphony.xwork2.util.location.LocationUtils;
072:        import com.opensymphony.xwork2.util.location.LocatableProperties;
073:        import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
074:
075:        import freemarker.template.Template;
076:
077:        /**
078:         * A utility class the actual dispatcher delegates most of its tasks to. Each instance
079:         * of the primary dispatcher holds an instance of this dispatcher to be shared for
080:         * all requests.
081:         *
082:         * @see org.apache.struts2.dispatcher.FilterDispatcher
083:         * @see org.apache.struts2.portlet.dispatcher.Jsr168Dispatcher
084:         */
085:        public class Dispatcher {
086:
087:            /**
088:             * Provide a logging instance.
089:             */
090:            private static final Log LOG = LogFactory.getLog(Dispatcher.class);
091:
092:            /**
093:             * Provide a thread local instance.
094:             */
095:            private static ThreadLocal<Dispatcher> instance = new ThreadLocal<Dispatcher>();
096:
097:            /**
098:             * Store list of DispatcherListeners.
099:             */
100:            private static List<DispatcherListener> dispatcherListeners = new ArrayList<DispatcherListener>();
101:
102:            /**
103:             * Store ConfigurationManager instance, set on init.
104:             */
105:            private ConfigurationManager configurationManager;
106:
107:            /**
108:             * Store whether portlet support is active
109:             * (set to true by Jsr168Dispatcher).
110:             */
111:            private static boolean portletSupportActive;
112:
113:            /**
114:             * Store state of  StrutsConstants.STRUTS_DEVMODE setting.
115:             */
116:            private static boolean devMode;
117:
118:            /**
119:             * Store state of StrutsConstants.STRUTS_I18N_ENCODING setting.
120:             */
121:            private static String defaultEncoding;
122:
123:            /**
124:             * Store state of StrutsConstants.STRUTS_LOCALE setting.
125:             */
126:            private static String defaultLocale;
127:
128:            /**
129:             * Store state of StrutsConstants.STRUTS_MULTIPART_SAVEDIR setting.
130:             */
131:            private static String multipartSaveDir;
132:
133:            /**
134:             * Provide list of default configuration files.
135:             */
136:            private static final String DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml";
137:
138:            /**
139:             * Store state of STRUTS_DISPATCHER_PARAMETERSWORKAROUND.
140:             * <p/>
141:             * The workaround is for WebLogic.
142:             * We try to autodect WebLogic on Dispatcher init.
143:             * The workaround can also be enabled manually.
144:             */
145:            private boolean paramsWorkaroundEnabled = false;
146:
147:            /**
148:             * Provide the dispatcher instance for the current thread.
149:             *
150:             * @return The dispatcher instance
151:             */
152:            public static Dispatcher getInstance() {
153:                return instance.get();
154:            }
155:
156:            /**
157:             * Store the dispatcher instance for this thread.
158:             *
159:             * @param instance The instance
160:             */
161:            public static void setInstance(Dispatcher instance) {
162:                Dispatcher.instance.set(instance);
163:
164:                // Tie the ObjectFactory threadlocal instance to this Dispatcher instance
165:                if (instance != null) {
166:                    Container cont = instance.getContainer();
167:                    if (cont != null) {
168:                        ObjectFactory.setObjectFactory(cont
169:                                .getInstance(ObjectFactory.class));
170:                    } else {
171:                        LOG
172:                                .warn("This dispatcher instance doesn't have a container, so the object factory won't be set.");
173:                    }
174:                } else {
175:                    ObjectFactory.setObjectFactory(null);
176:                }
177:            }
178:
179:            /**
180:             * Add a dispatcher lifecycle listener.
181:             *
182:             * @param listener The listener to add
183:             */
184:            public static synchronized void addDispatcherListener(
185:                    DispatcherListener listener) {
186:                dispatcherListeners.add(listener);
187:            }
188:
189:            /**
190:             * Remove a specific dispatcher lifecycle listener.
191:             *
192:             * @param listener The listener
193:             */
194:            public static synchronized void removeDispatcherListener(
195:                    DispatcherListener listener) {
196:                dispatcherListeners.remove(listener);
197:            }
198:
199:            private ServletContext servletContext;
200:            private Map<String, String> initParams;
201:
202:            /**
203:             * Create the Dispatcher instance for a given ServletContext and set of initialization parameters.
204:             *
205:             * @param servletContext Our servlet context
206:             * @param initParams The set of initialization parameters
207:             */
208:            public Dispatcher(ServletContext servletContext,
209:                    Map<String, String> initParams) {
210:                this .servletContext = servletContext;
211:                this .initParams = initParams;
212:            }
213:
214:            /**
215:             * Modify state of StrutsConstants.STRUTS_DEVMODE setting.
216:             * @param mode New setting
217:             */
218:            @Inject(StrutsConstants.STRUTS_DEVMODE)
219:            public static void setDevMode(String mode) {
220:                devMode = "true".equals(mode);
221:            }
222:
223:            /**
224:             * Modify state of StrutsConstants.STRUTS_LOCALE setting.
225:             * @param val New setting
226:             */
227:            @Inject(value=StrutsConstants.STRUTS_LOCALE,required=false)
228:            public static void setDefaultLocale(String val) {
229:                defaultLocale = val;
230:            }
231:
232:            /**
233:             * Modify state of StrutsConstants.STRUTS_I18N_ENCODING setting.
234:             * @param val New setting
235:             */
236:            @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
237:            public static void setDefaultEncoding(String val) {
238:                defaultEncoding = val;
239:            }
240:
241:            /**
242:             * Modify state of StrutsConstants.STRUTS_MULTIPART_SAVEDIR setting.
243:             * @param val New setting
244:             */
245:            @Inject(StrutsConstants.STRUTS_MULTIPART_SAVEDIR)
246:            public static void setMultipartSaveDir(String val) {
247:                multipartSaveDir = val;
248:            }
249:
250:            /**
251:             * Releases all instances bound to this dispatcher instance.
252:             */
253:            public void cleanup() {
254:
255:                // clean up ObjectFactory
256:                ObjectFactory objectFactory = getContainer().getInstance(
257:                        ObjectFactory.class);
258:                if (objectFactory == null) {
259:                    LOG
260:                            .warn("Object Factory is null, something is seriously wrong, no clean up will be performed");
261:                }
262:                if (objectFactory instanceof  ObjectFactoryDestroyable) {
263:                    try {
264:                        ((ObjectFactoryDestroyable) objectFactory).destroy();
265:                    } catch (Exception e) {
266:                        // catch any exception that may occured during destroy() and log it
267:                        LOG.error(
268:                                "exception occurred while destroying ObjectFactory ["
269:                                        + objectFactory + "]", e);
270:                    }
271:                }
272:
273:                // clean up Dispatcher itself for this thread
274:                instance.set(null);
275:
276:                // clean up DispatcherListeners
277:                synchronized (Dispatcher.class) {
278:                    if (dispatcherListeners.size() > 0) {
279:                        for (DispatcherListener l : dispatcherListeners) {
280:                            l.dispatcherDestroyed(this );
281:                        }
282:                    }
283:                }
284:
285:                // clean up configuration
286:                configurationManager.destroyConfiguration();
287:                configurationManager = null;
288:            }
289:
290:            private void init_DefaultProperties() {
291:                configurationManager
292:                        .addConfigurationProvider(new DefaultPropertiesProvider());
293:            }
294:
295:            private void init_LegacyStrutsProperties() {
296:                configurationManager
297:                        .addConfigurationProvider(new LegacyPropertiesConfigurationProvider());
298:            }
299:
300:            private void init_TraditionalXmlConfigurations() {
301:                String configPaths = initParams.get("config");
302:                if (configPaths == null) {
303:                    configPaths = DEFAULT_CONFIGURATION_PATHS;
304:                }
305:                String[] files = configPaths.split("\\s*[,]\\s*");
306:                for (String file : files) {
307:                    if (file.endsWith(".xml")) {
308:                        if ("xwork.xml".equals(file)) {
309:                            configurationManager
310:                                    .addConfigurationProvider(new XmlConfigurationProvider(
311:                                            file, false));
312:                        } else {
313:                            configurationManager
314:                                    .addConfigurationProvider(new StrutsXmlConfigurationProvider(
315:                                            file, false, servletContext));
316:                        }
317:                    } else {
318:                        throw new IllegalArgumentException(
319:                                "Invalid configuration file name");
320:                    }
321:                }
322:            }
323:
324:            private void init_ZeroConfiguration() {
325:                String packages = initParams.get("actionPackages");
326:                if (packages != null) {
327:                    String[] names = packages.split("\\s*[,]\\s*");
328:                    // Initialize the classloader scanner with the configured packages
329:                    if (names.length > 0) {
330:                        ClasspathConfigurationProvider provider = new ClasspathConfigurationProvider(
331:                                names);
332:                        provider.setPageLocator(new ServletContextPageLocator(
333:                                servletContext));
334:                        configurationManager.addConfigurationProvider(provider);
335:                    }
336:                }
337:            }
338:
339:            private void init_CustomConfigurationProviders() {
340:                String configProvs = initParams.get("configProviders");
341:                if (configProvs != null) {
342:                    String[] classes = configProvs.split("\\s*[,]\\s*");
343:                    for (String cname : classes) {
344:                        try {
345:                            Class cls = ClassLoaderUtils.loadClass(cname, this 
346:                                    .getClass());
347:                            ConfigurationProvider prov = (ConfigurationProvider) cls
348:                                    .newInstance();
349:                            configurationManager.addConfigurationProvider(prov);
350:                        } catch (InstantiationException e) {
351:                            throw new ConfigurationException(
352:                                    "Unable to instantiate provider: " + cname,
353:                                    e);
354:                        } catch (IllegalAccessException e) {
355:                            throw new ConfigurationException(
356:                                    "Unable to access provider: " + cname, e);
357:                        } catch (ClassNotFoundException e) {
358:                            throw new ConfigurationException(
359:                                    "Unable to locate provider class: " + cname,
360:                                    e);
361:                        }
362:                    }
363:                }
364:            }
365:
366:            private void init_MethodConfigurationProvider() {
367:                // See https://issues.apache.org/struts/browse/WW-1522
368:                /*
369:                com.opensymphony.xwork2.inject.DependencyException: com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=org.apache.struts2.dispatcher.mapper.ActionMapper, name='default'] in public static void org.apache.struts2.dispatcher.FilterDispatcher.setActionMapper(org.apache.struts2.dispatcher.mapper.ActionMapper).
370:                at com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMembers(ContainerImpl.java:135)
371:                at com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMethods(ContainerImpl.java:104)
372:                at com.opensymphony.xwork2.inject.ContainerImpl.injectStatics(ContainerImpl.java:89)
373:                at com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:494)
374:                at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reload(DefaultConfiguration.java:140)
375:                at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:52)
376:                at org.apache.struts2.dispatcher.Dispatcher.init_MethodConfigurationProvider(Dispatcher.java:347)
377:                at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:421)
378:                at org.apache.struts2.config.MethodConfigurationProviderTest.setUp(MethodConfigurationProviderTest.java:68)
379:                at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
380:                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
381:                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
382:                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
383:                at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
384:                Caused by: com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=org.apache.struts2.dispatcher.mapper.ActionMapper, name='default'] in public static void org.apache.struts2.dispatcher.FilterDispatcher.setActionMapper(org.apache.struts2.dispatcher.mapper.ActionMapper).
385:                at com.opensymphony.xwork2.inject.ContainerImpl.createParameterInjector(ContainerImpl.java:217)
386:                at com.opensymphony.xwork2.inject.ContainerImpl.getParametersInjectors(ContainerImpl.java:207)
387:                at com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.<init>(ContainerImpl.java:260)
388:                at com.opensymphony.xwork2.inject.ContainerImpl$3.create(ContainerImpl.java:108)
389:                at com.opensymphony.xwork2.inject.ContainerImpl$3.create(ContainerImpl.java:106)
390:                at com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMembers(ContainerImpl.java:132)
391:                ... 26 more
392:
393:                    MethodConfigurationProvider provider = new MethodConfigurationProvider();
394:                    provider.init(configurationManager.getConfiguration());
395:                    provider.loadPackages();
396:                 */
397:            }
398:
399:            private void init_FilterInitParameters() {
400:                configurationManager
401:                        .addConfigurationProvider(new ConfigurationProvider() {
402:                            public void destroy() {
403:                            }
404:
405:                            public void init(Configuration configuration)
406:                                    throws ConfigurationException {
407:                            }
408:
409:                            public void loadPackages()
410:                                    throws ConfigurationException {
411:                            }
412:
413:                            public boolean needsReload() {
414:                                return false;
415:                            }
416:
417:                            public void register(ContainerBuilder builder,
418:                                    LocatableProperties props)
419:                                    throws ConfigurationException {
420:                                props.putAll(initParams);
421:                            }
422:                        });
423:            }
424:
425:            private void init_AliasStandardObjects() {
426:                configurationManager
427:                        .addConfigurationProvider(new BeanSelectionProvider());
428:            }
429:
430:            private Container init_PreloadConfiguration() {
431:                Configuration config = configurationManager.getConfiguration();
432:                Container container = config.getContainer();
433:
434:                boolean reloadi18n = Boolean.valueOf(container.getInstance(
435:                        String.class, StrutsConstants.STRUTS_I18N_RELOAD));
436:                LocalizedTextUtil.setReloadBundles(reloadi18n);
437:
438:                ObjectTypeDeterminer objectTypeDeterminer = container
439:                        .getInstance(ObjectTypeDeterminer.class);
440:                ObjectTypeDeterminerFactory.setInstance(objectTypeDeterminer);
441:
442:                return container;
443:            }
444:
445:            private void init_CheckConfigurationReloading(Container container) {
446:                FileManager
447:                        .setReloadingConfigs("true"
448:                                .equals(container
449:                                        .getInstance(
450:                                                String.class,
451:                                                StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD)));
452:            }
453:
454:            private void init_CheckWebLogicWorkaround(Container container) {
455:                // test whether param-access workaround needs to be enabled
456:                if (servletContext != null
457:                        && servletContext.getServerInfo() != null
458:                        && servletContext.getServerInfo().indexOf("WebLogic") >= 0) {
459:                    LOG
460:                            .info("WebLogic server detected. Enabling Struts parameter access work-around.");
461:                    paramsWorkaroundEnabled = true;
462:                } else {
463:                    paramsWorkaroundEnabled = "true"
464:                            .equals(container
465:                                    .getInstance(
466:                                            String.class,
467:                                            StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND));
468:                }
469:
470:                synchronized (Dispatcher.class) {
471:                    if (dispatcherListeners.size() > 0) {
472:                        for (DispatcherListener l : dispatcherListeners) {
473:                            l.dispatcherInitialized(this );
474:                        }
475:                    }
476:                }
477:
478:            }
479:
480:            /**
481:             * Load configurations, including both XML and zero-configuration strategies,
482:             * and update optional settings, including whether to reload configurations and resource files.
483:             */
484:            public void init() {
485:
486:                if (configurationManager == null) {
487:                    configurationManager = new ConfigurationManager(
488:                            BeanSelectionProvider.DEFAULT_BEAN_NAME);
489:                }
490:
491:                init_DefaultProperties(); // [1]
492:                init_TraditionalXmlConfigurations(); // [2]
493:                init_LegacyStrutsProperties(); // [3]
494:                init_ZeroConfiguration(); // [4]
495:                init_CustomConfigurationProviders(); // [5]
496:                init_MethodConfigurationProvider();
497:                init_FilterInitParameters(); // [6]
498:                init_AliasStandardObjects(); // [7]
499:
500:                Container container = init_PreloadConfiguration();
501:                init_CheckConfigurationReloading(container);
502:                init_CheckWebLogicWorkaround(container);
503:
504:            }
505:
506:            /**
507:             * Load Action class for mapping and invoke the appropriate Action method, or go directly to the Result.
508:             * <p/>
509:             * This method first creates the action context from the given parameters,
510:             * and then loads an <tt>ActionProxy</tt> from the given action name and namespace.
511:             * After that, the Action method is executed and output channels through the response object.
512:             * Actions not found are sent back to the user via the {@link Dispatcher#sendError} method,
513:             * using the 404 return code.
514:             * All other errors are reported by throwing a ServletException.
515:             *
516:             * @param request  the HttpServletRequest object
517:             * @param response the HttpServletResponse object
518:             * @param mapping  the action mapping object
519:             * @throws ServletException when an unknown error occurs (not a 404, but typically something that
520:             *                          would end up as a 5xx by the servlet container)
521:             * @param context Our ServletContext object
522:             */
523:            public void serviceAction(HttpServletRequest request,
524:                    HttpServletResponse response, ServletContext context,
525:                    ActionMapping mapping) throws ServletException {
526:
527:                Map<String, Object> extraContext = createContextMap(request,
528:                        response, mapping, context);
529:
530:                // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
531:                ValueStack stack = (ValueStack) request
532:                        .getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
533:                if (stack != null) {
534:                    extraContext.put(ActionContext.VALUE_STACK,
535:                            ValueStackFactory.getFactory().createValueStack(
536:                                    stack));
537:                }
538:
539:                String timerKey = "Handling request from Dispatcher";
540:                try {
541:                    UtilTimerStack.push(timerKey);
542:                    String namespace = mapping.getNamespace();
543:                    String name = mapping.getName();
544:                    String method = mapping.getMethod();
545:
546:                    Configuration config = configurationManager
547:                            .getConfiguration();
548:                    ActionProxy proxy = config.getContainer().getInstance(
549:                            ActionProxyFactory.class).createActionProxy(
550:                            namespace, name, extraContext, true, false);
551:                    proxy.setMethod(method);
552:                    request.setAttribute(
553:                            ServletActionContext.STRUTS_VALUESTACK_KEY, proxy
554:                                    .getInvocation().getStack());
555:
556:                    // if the ActionMapping says to go straight to a result, do it!
557:                    if (mapping.getResult() != null) {
558:                        Result result = mapping.getResult();
559:                        result.execute(proxy.getInvocation());
560:                    } else {
561:                        proxy.execute();
562:                    }
563:
564:                    // If there was a previous value stack then set it back onto the request
565:                    if (stack != null) {
566:                        request.setAttribute(
567:                                ServletActionContext.STRUTS_VALUESTACK_KEY,
568:                                stack);
569:                    }
570:                } catch (ConfigurationException e) {
571:                    LOG.error("Could not find action or result", e);
572:                    sendError(request, response, context,
573:                            HttpServletResponse.SC_NOT_FOUND, e);
574:                } catch (Exception e) {
575:                    throw new ServletException(e);
576:                } finally {
577:                    UtilTimerStack.pop(timerKey);
578:                }
579:            }
580:
581:            /**
582:             * Create a context map containing all the wrapped request objects
583:             *
584:             * @param request The servlet request
585:             * @param response The servlet response
586:             * @param mapping The action mapping
587:             * @param context The servlet context
588:             * @return A map of context objects
589:             */
590:            public Map<String, Object> createContextMap(
591:                    HttpServletRequest request, HttpServletResponse response,
592:                    ActionMapping mapping, ServletContext context) {
593:
594:                // request map wrapping the http request objects
595:                Map requestMap = new RequestMap(request);
596:
597:                // parameters map wrapping the http paraneters.
598:                Map params = null;
599:                if (mapping != null) {
600:                    params = mapping.getParams();
601:                }
602:                Map requestParams = new HashMap(request.getParameterMap());
603:                if (params != null) {
604:                    params.putAll(requestParams);
605:                } else {
606:                    params = requestParams;
607:                }
608:
609:                // session map wrapping the http session
610:                Map session = new SessionMap(request);
611:
612:                // application map wrapping the ServletContext
613:                Map application = new ApplicationMap(context);
614:
615:                Map<String, Object> extraContext = createContextMap(requestMap,
616:                        params, session, application, request, response,
617:                        context);
618:                extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);
619:                return extraContext;
620:            }
621:
622:            /**
623:             * Merge all application and servlet attributes into a single <tt>HashMap</tt> to represent the entire
624:             * <tt>Action</tt> context.
625:             *
626:             * @param requestMap     a Map of all request attributes.
627:             * @param parameterMap   a Map of all request parameters.
628:             * @param sessionMap     a Map of all session attributes.
629:             * @param applicationMap a Map of all servlet context attributes.
630:             * @param request        the HttpServletRequest object.
631:             * @param response       the HttpServletResponse object.
632:             * @param servletContext the ServletContextmapping object.
633:             * @return a HashMap representing the <tt>Action</tt> context.
634:             */
635:            public HashMap<String, Object> createContextMap(Map requestMap,
636:                    Map parameterMap, Map sessionMap, Map applicationMap,
637:                    HttpServletRequest request, HttpServletResponse response,
638:                    ServletContext servletContext) {
639:                HashMap<String, Object> extraContext = new HashMap<String, Object>();
640:                extraContext.put(ActionContext.PARAMETERS, new HashMap(
641:                        parameterMap));
642:                extraContext.put(ActionContext.SESSION, sessionMap);
643:                extraContext.put(ActionContext.APPLICATION, applicationMap);
644:
645:                Locale locale;
646:                if (defaultLocale != null) {
647:                    locale = LocalizedTextUtil.localeFromString(defaultLocale,
648:                            request.getLocale());
649:                } else {
650:                    locale = request.getLocale();
651:                }
652:
653:                extraContext.put(ActionContext.LOCALE, locale);
654:                //extraContext.put(ActionContext.DEV_MODE, Boolean.valueOf(devMode));
655:
656:                extraContext.put(StrutsStatics.HTTP_REQUEST, request);
657:                extraContext.put(StrutsStatics.HTTP_RESPONSE, response);
658:                extraContext.put(StrutsStatics.SERVLET_CONTEXT, servletContext);
659:
660:                // helpers to get access to request/session/application scope
661:                extraContext.put("request", requestMap);
662:                extraContext.put("session", sessionMap);
663:                extraContext.put("application", applicationMap);
664:                extraContext.put("parameters", parameterMap);
665:
666:                AttributeMap attrMap = new AttributeMap(extraContext);
667:                extraContext.put("attr", attrMap);
668:
669:                return extraContext;
670:            }
671:
672:            /**
673:             * Return the path to save uploaded files to (this is configurable).
674:             *
675:             * @return the path to save uploaded files to
676:             * @param servletContext Our ServletContext
677:             */
678:            private String getSaveDir(ServletContext servletContext) {
679:                String saveDir = multipartSaveDir.trim();
680:
681:                if (saveDir.equals("")) {
682:                    File tempdir = (File) servletContext
683:                            .getAttribute("javax.servlet.context.tempdir");
684:                    LOG
685:                            .info("Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir");
686:
687:                    if (tempdir != null) {
688:                        saveDir = tempdir.toString();
689:                    }
690:                } else {
691:                    File multipartSaveDir = new File(saveDir);
692:
693:                    if (!multipartSaveDir.exists()) {
694:                        multipartSaveDir.mkdir();
695:                    }
696:                }
697:
698:                if (LOG.isDebugEnabled()) {
699:                    LOG.debug("saveDir=" + saveDir);
700:                }
701:
702:                return saveDir;
703:            }
704:
705:            /**
706:             * Prepare a request, including setting the encoding and locale.
707:             *
708:             * @param request The request
709:             * @param response The response
710:             */
711:            public void prepare(HttpServletRequest request,
712:                    HttpServletResponse response) {
713:                String encoding = null;
714:                if (defaultEncoding != null) {
715:                    encoding = defaultEncoding;
716:                }
717:
718:                Locale locale = null;
719:                if (defaultLocale != null) {
720:                    locale = LocalizedTextUtil.localeFromString(defaultLocale,
721:                            request.getLocale());
722:                }
723:
724:                if (encoding != null) {
725:                    try {
726:                        request.setCharacterEncoding(encoding);
727:                    } catch (Exception e) {
728:                        LOG.error("Error setting character encoding to '"
729:                                + encoding + "' - ignoring.", e);
730:                    }
731:                }
732:
733:                if (locale != null) {
734:                    response.setLocale(locale);
735:                }
736:
737:                if (paramsWorkaroundEnabled) {
738:                    request.getParameter("foo"); // simply read any parameter (existing or not) to "prime" the request
739:                }
740:            }
741:
742:            /**
743:             * Wrap and return the given request or return the original request object.
744:             * </p>
745:             * This method transparently handles multipart data as a wrapped class around the given request.
746:             * Override this method to handle multipart requests in a special way or to handle other types of requests.
747:             * Note, {@link org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper} is
748:             * flexible - look first to that object before overriding this method to handle multipart data.
749:             *
750:             * @param request the HttpServletRequest object.
751:             * @param servletContext Our ServletContext object
752:             * @return a wrapped request or original request.
753:             * @see org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper
754:             * @throws java.io.IOException on any error.
755:             */
756:            public HttpServletRequest wrapRequest(HttpServletRequest request,
757:                    ServletContext servletContext) throws IOException {
758:                // don't wrap more than once
759:                if (request instanceof  StrutsRequestWrapper) {
760:                    return request;
761:                }
762:
763:                String content_type = request.getContentType();
764:                if (content_type != null
765:                        && content_type.indexOf("multipart/form-data") != -1) {
766:                    MultiPartRequest multi = getContainer().getInstance(
767:                            MultiPartRequest.class);
768:                    request = new MultiPartRequestWrapper(multi, request,
769:                            getSaveDir(servletContext));
770:                } else {
771:                    request = new StrutsRequestWrapper(request);
772:                }
773:
774:                return request;
775:            }
776:
777:            /**
778:             * Send an HTTP error response code.
779:             *
780:             * @param request  the HttpServletRequest object.
781:             * @param response the HttpServletResponse object.
782:             * @param code     the HttpServletResponse error code (see {@link javax.servlet.http.HttpServletResponse} for possible error codes).
783:             * @param e        the Exception that is reported.
784:             * @param ctx      the ServletContext object.
785:             */
786:            public void sendError(HttpServletRequest request,
787:                    HttpServletResponse response, ServletContext ctx, int code,
788:                    Exception e) {
789:                if (devMode) {
790:                    response.setContentType("text/html");
791:
792:                    try {
793:                        FreemarkerManager mgr = getContainer().getInstance(
794:                                FreemarkerManager.class);
795:
796:                        freemarker.template.Configuration config = mgr
797:                                .getConfiguration(ctx);
798:                        Template template = config
799:                                .getTemplate("/org/apache/struts2/dispatcher/error.ftl");
800:
801:                        List<Throwable> chain = new ArrayList<Throwable>();
802:                        Throwable cur = e;
803:                        chain.add(cur);
804:                        while ((cur = cur.getCause()) != null) {
805:                            chain.add(cur);
806:                        }
807:
808:                        HashMap<String, Object> data = new HashMap<String, Object>();
809:                        data.put("exception", e);
810:                        data.put("unknown", Location.UNKNOWN);
811:                        data.put("chain", chain);
812:                        data.put("locator", new Locator());
813:                        template.process(data, response.getWriter());
814:                        response.getWriter().close();
815:                    } catch (Exception exp) {
816:                        try {
817:                            response.sendError(code,
818:                                    "Unable to show problem report: " + exp);
819:                        } catch (IOException ex) {
820:                            // we're already sending an error, not much else we can do if more stuff breaks
821:                        }
822:                    }
823:                } else {
824:                    try {
825:                        // WW-1977: Only put errors in the request when code is a 500 error
826:                        if (code == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
827:                            // send a http error response to use the servlet defined error handler
828:                            // make the exception availible to the web.xml defined error page
829:                            request.setAttribute(
830:                                    "javax.servlet.error.exception", e);
831:
832:                            // for compatibility
833:                            request.setAttribute(
834:                                    "javax.servlet.jsp.jspException", e);
835:                        }
836:
837:                        // send the error response
838:                        response.sendError(code, e.getMessage());
839:                    } catch (IOException e1) {
840:                        // we're already sending an error, not much else we can do if more stuff breaks
841:                    }
842:                }
843:            }
844:
845:            /**
846:             * Return <tt>true</tt>, if portlet support is active, <tt>false</tt> otherwise.
847:             *
848:             * @return <tt>true</tt>, if portlet support is active, <tt>false</tt> otherwise.
849:             */
850:            public boolean isPortletSupportActive() {
851:                return portletSupportActive;
852:            }
853:
854:            /**
855:             * Modify the portlet support mode.
856:             * @param portletSupportActive <tt>true</tt> or <tt>false</tt>
857:             */
858:            public static void setPortletSupportActive(
859:                    boolean portletSupportActive) {
860:                Dispatcher.portletSupportActive = portletSupportActive;
861:            }
862:
863:            /**
864:             * Search classpath for a page.
865:             */
866:            private final class ServletContextPageLocator implements 
867:                    PageLocator {
868:                private final ServletContext context;
869:                private ClasspathPageLocator classpathPageLocator = new ClasspathPageLocator();
870:
871:                private ServletContextPageLocator(ServletContext context) {
872:                    this .context = context;
873:                }
874:
875:                public URL locate(String path) {
876:                    URL url = null;
877:                    try {
878:                        url = context.getResource(path);
879:                        if (url == null) {
880:                            url = classpathPageLocator.locate(path);
881:                        }
882:                    } catch (MalformedURLException e) {
883:                        if (LOG.isDebugEnabled()) {
884:                            LOG.debug("Unable to resolve path " + path
885:                                    + " against the servlet context");
886:                        }
887:                    }
888:                    return url;
889:                }
890:            }
891:
892:            /**
893:             * Provide an accessor class for static XWork utility.
894:             */
895:            public class Locator {
896:                public Location getLocation(Object obj) {
897:                    Location loc = LocationUtils.getLocation(obj);
898:                    if (loc == null) {
899:                        return Location.UNKNOWN;
900:                    }
901:                    return loc;
902:                }
903:            }
904:
905:            /**
906:             * Expose the ConfigurationManager instance.
907:             *
908:             * @return The instance
909:             */
910:            public ConfigurationManager getConfigurationManager() {
911:                return configurationManager;
912:            }
913:
914:            /**
915:             * Modify the ConfigurationManager instance
916:             *
917:             * @param mgr The configuration manager
918:             */
919:            public void setConfigurationManager(ConfigurationManager mgr) {
920:                this .configurationManager = mgr;
921:            }
922:
923:            /**
924:             * Expose the dependency injection container.
925:             * @return Our dependency injection container
926:             */
927:            public Container getContainer() {
928:                ConfigurationManager mgr = getConfigurationManager();
929:                if (mgr == null) {
930:                    throw new IllegalStateException(
931:                            "The configuration manager shouldn't be null");
932:                } else {
933:                    Configuration config = mgr.getConfiguration();
934:                    if (config == null) {
935:                        throw new IllegalStateException(
936:                                "Unable to load configuration");
937:                    } else {
938:                        return config.getContainer();
939:                    }
940:                }
941:            }
942:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.