Source Code Cross Referenced for RequestDispatcher.java in  » Web-Server » Winstone » winstone » 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 Server » Winstone » winstone 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
003:         * Distributed under the terms of either:
004:         * - the common development and distribution license (CDDL), v1.0; or
005:         * - the GNU Lesser General Public License, v2.1 or later
006:         */
007:        package winstone;
008:
009:        import java.io.IOException;
010:        import java.util.ArrayList;
011:        import java.util.List;
012:        import java.util.Map;
013:
014:        import javax.servlet.ServletException;
015:        import javax.servlet.ServletRequest;
016:        import javax.servlet.ServletRequestWrapper;
017:        import javax.servlet.ServletResponse;
018:        import javax.servlet.ServletResponseWrapper;
019:
020:        /**
021:         * This class implements both the RequestDispatcher and FilterChain components. On 
022:         * the first call to include() or forward(), it starts the filter chain execution
023:         * if one exists. On the final doFilter() or if there is no chain, we call the include()
024:         * or forward() again, and the servlet is executed.
025:         * 
026:         * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
027:         * @version $Id: RequestDispatcher.java,v 1.18 2007/04/23 02:55:35 rickknowles Exp $
028:         */
029:        public class RequestDispatcher implements 
030:                javax.servlet.RequestDispatcher, javax.servlet.FilterChain {
031:
032:            static final String INCLUDE_REQUEST_URI = "javax.servlet.include.request_uri";
033:            static final String INCLUDE_CONTEXT_PATH = "javax.servlet.include.context_path";
034:            static final String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
035:            static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
036:            static final String INCLUDE_QUERY_STRING = "javax.servlet.include.query_string";
037:
038:            static final String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri";
039:            static final String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path";
040:            static final String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
041:            static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
042:            static final String FORWARD_QUERY_STRING = "javax.servlet.forward.query_string";
043:
044:            static final String ERROR_STATUS_CODE = "javax.servlet.error.status_code";
045:            static final String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type";
046:            static final String ERROR_MESSAGE = "javax.servlet.error.message";
047:            static final String ERROR_EXCEPTION = "javax.servlet.error.exception";
048:            static final String ERROR_REQUEST_URI = "javax.servlet.error.request_uri";
049:            static final String ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name";
050:
051:            private WebAppConfiguration webAppConfig;
052:            private ServletConfiguration servletConfig;
053:
054:            private String servletPath;
055:            private String pathInfo;
056:            private String queryString;
057:            private String requestURI;
058:
059:            private Integer errorStatusCode;
060:            private Throwable errorException;
061:            private String errorSummaryMessage;
062:
063:            private AuthenticationHandler authHandler;
064:
065:            private Mapping forwardFilterPatterns[];
066:            private Mapping includeFilterPatterns[];
067:            private FilterConfiguration matchingFilters[];
068:            private int matchingFiltersEvaluated;
069:
070:            private Boolean doInclude;
071:            private boolean isErrorDispatch;
072:            private boolean useRequestAttributes;
073:
074:            private WebAppConfiguration includedWebAppConfig;
075:            private ServletConfiguration includedServletConfig;
076:
077:            /**
078:             * Constructor. This initializes the filter chain and sets up the details
079:             * needed to handle a servlet excecution, such as security constraints,
080:             * filters, etc.
081:             */
082:            public RequestDispatcher(WebAppConfiguration webAppConfig,
083:                    ServletConfiguration servletConfig) {
084:                this .servletConfig = servletConfig;
085:                this .webAppConfig = webAppConfig;
086:
087:                this .matchingFiltersEvaluated = 0;
088:            }
089:
090:            public void setForNamedDispatcher(Mapping forwardFilterPatterns[],
091:                    Mapping includeFilterPatterns[]) {
092:                this .forwardFilterPatterns = forwardFilterPatterns;
093:                this .includeFilterPatterns = includeFilterPatterns;
094:                this .matchingFilters = null; // set after the call to forward or include
095:                this .useRequestAttributes = false;
096:                this .isErrorDispatch = false;
097:            }
098:
099:            public void setForURLDispatcher(String servletPath,
100:                    String pathInfo, String queryString,
101:                    String requestURIInsideWebapp,
102:                    Mapping forwardFilterPatterns[],
103:                    Mapping includeFilterPatterns[]) {
104:                this .servletPath = servletPath;
105:                this .pathInfo = pathInfo;
106:                this .queryString = queryString;
107:                this .requestURI = requestURIInsideWebapp;
108:
109:                this .forwardFilterPatterns = forwardFilterPatterns;
110:                this .includeFilterPatterns = includeFilterPatterns;
111:                this .matchingFilters = null; // set after the call to forward or include
112:                this .useRequestAttributes = true;
113:                this .isErrorDispatch = false;
114:            }
115:
116:            public void setForErrorDispatcher(String servletPath,
117:                    String pathInfo, String queryString, int statusCode,
118:                    String summaryMessage, Throwable exception,
119:                    String errorHandlerURI, Mapping errorFilterPatterns[]) {
120:                this .servletPath = servletPath;
121:                this .pathInfo = pathInfo;
122:                this .queryString = queryString;
123:                this .requestURI = errorHandlerURI;
124:
125:                this .errorStatusCode = new Integer(statusCode);
126:                this .errorException = exception;
127:                this .errorSummaryMessage = summaryMessage;
128:                this .matchingFilters = getMatchingFilters(errorFilterPatterns,
129:                        this .webAppConfig, servletPath
130:                                + (pathInfo == null ? "" : pathInfo),
131:                        getName(), "ERROR", (servletPath != null));
132:                this .useRequestAttributes = true;
133:                this .isErrorDispatch = true;
134:            }
135:
136:            public void setForInitialDispatcher(String servletPath,
137:                    String pathInfo, String queryString,
138:                    String requestURIInsideWebapp,
139:                    Mapping requestFilterPatterns[],
140:                    AuthenticationHandler authHandler) {
141:                this .servletPath = servletPath;
142:                this .pathInfo = pathInfo;
143:                this .queryString = queryString;
144:                this .requestURI = requestURIInsideWebapp;
145:                this .authHandler = authHandler;
146:                this .matchingFilters = getMatchingFilters(
147:                        requestFilterPatterns, this .webAppConfig, servletPath
148:                                + (pathInfo == null ? "" : pathInfo),
149:                        getName(), "REQUEST", (servletPath != null));
150:                this .useRequestAttributes = false;
151:                this .isErrorDispatch = false;
152:            }
153:
154:            public String getName() {
155:                return this .servletConfig.getServletName();
156:            }
157:
158:            /**
159:             * Includes the execution of a servlet into the current request
160:             * 
161:             * Note this method enters itself twice: once with the initial call, and once again 
162:             * when all the filters have completed.
163:             */
164:            public void include(ServletRequest request, ServletResponse response)
165:                    throws ServletException, IOException {
166:
167:                // On the first call, log and initialise the filter chain
168:                if (this .doInclude == null) {
169:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
170:                            "RequestDispatcher.IncludeMessage", new String[] {
171:                                    getName(), this .requestURI });
172:
173:                    WinstoneRequest wr = getUnwrappedRequest(request);
174:                    // Add the query string to the included query string stack
175:                    wr.addIncludeQueryParameters(this .queryString);
176:
177:                    // Set request attributes
178:                    if (useRequestAttributes) {
179:                        wr.addIncludeAttributes(this .webAppConfig
180:                                .getContextPath()
181:                                + this .requestURI, this .webAppConfig
182:                                .getContextPath(), this .servletPath,
183:                                this .pathInfo, this .queryString);
184:                    }
185:                    // Add another include buffer to the response stack
186:                    WinstoneResponse wresp = getUnwrappedResponse(response);
187:                    wresp.startIncludeBuffer();
188:
189:                    this .includedServletConfig = wr.getServletConfig();
190:                    this .includedWebAppConfig = wr.getWebAppConfig();
191:                    wr.setServletConfig(this .servletConfig);
192:                    wr.setWebAppConfig(this .webAppConfig);
193:                    wresp.setWebAppConfig(this .webAppConfig);
194:
195:                    this .doInclude = Boolean.TRUE;
196:                }
197:
198:                if (this .matchingFilters == null) {
199:                    this .matchingFilters = getMatchingFilters(
200:                            this .includeFilterPatterns, this .webAppConfig,
201:                            this .servletPath
202:                                    + (this .pathInfo == null ? ""
203:                                            : this .pathInfo), getName(),
204:                            "INCLUDE", (this .servletPath != null));
205:                }
206:                try {
207:                    // Make sure the filter chain is exhausted first
208:                    if (this .matchingFiltersEvaluated < this .matchingFilters.length) {
209:                        doFilter(request, response);
210:                        finishInclude(request, response);
211:                    } else {
212:                        try {
213:                            this .servletConfig.execute(request, response,
214:                                    this .webAppConfig.getContextPath()
215:                                            + this .requestURI);
216:                        } finally {
217:                            if (this .matchingFilters.length == 0) {
218:                                finishInclude(request, response);
219:                            }
220:                        }
221:                    }
222:                } catch (Throwable err) {
223:                    finishInclude(request, response);
224:                    if (err instanceof  ServletException) {
225:                        throw (ServletException) err;
226:                    } else if (err instanceof  IOException) {
227:                        throw (IOException) err;
228:                    } else if (err instanceof  Error) {
229:                        throw (Error) err;
230:                    } else {
231:                        throw (RuntimeException) err;
232:                    }
233:                }
234:            }
235:
236:            private void finishInclude(ServletRequest request,
237:                    ServletResponse response) throws IOException {
238:                WinstoneRequest wr = getUnwrappedRequest(request);
239:                wr.removeIncludeQueryString();
240:
241:                // Set request attributes
242:                if (useRequestAttributes) {
243:                    wr.removeIncludeAttributes();
244:                }
245:                // Remove the include buffer from the response stack
246:                WinstoneResponse wresp = getUnwrappedResponse(response);
247:                wresp.finishIncludeBuffer();
248:
249:                if (this .includedServletConfig != null) {
250:                    wr.setServletConfig(this .includedServletConfig);
251:                    this .includedServletConfig = null;
252:                }
253:
254:                if (this .includedWebAppConfig != null) {
255:                    wr.setWebAppConfig(this .includedWebAppConfig);
256:                    wresp.setWebAppConfig(this .includedWebAppConfig);
257:                    this .includedWebAppConfig = null;
258:                }
259:            }
260:
261:            /**
262:             * Forwards to another servlet, and when it's finished executing that other
263:             * servlet, cut off execution.
264:             * 
265:             * Note this method enters itself twice: once with the initial call, and once again 
266:             * when all the filters have completed.
267:             */
268:            public void forward(ServletRequest request, ServletResponse response)
269:                    throws ServletException, IOException {
270:
271:                // Only on the first call to forward, we should set any forwarding attributes
272:                if (this .doInclude == null) {
273:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
274:                            "RequestDispatcher.ForwardMessage", new String[] {
275:                                    getName(), this .requestURI });
276:                    if (response.isCommitted()) {
277:                        throw new IllegalStateException(
278:                                Launcher.RESOURCES
279:                                        .getString("RequestDispatcher.ForwardCommitted"));
280:                    }
281:
282:                    WinstoneRequest req = getUnwrappedRequest(request);
283:                    WinstoneResponse rsp = getUnwrappedResponse(response);
284:
285:                    // Clear the include stack if one has been accumulated
286:                    rsp.resetBuffer();
287:                    req.clearIncludeStackForForward();
288:                    rsp.clearIncludeStackForForward();
289:
290:                    // Set request attributes (because it's the first step in the filter chain of a forward or error)
291:                    if (useRequestAttributes) {
292:                        req.setAttribute(FORWARD_REQUEST_URI, req
293:                                .getRequestURI());
294:                        req.setAttribute(FORWARD_CONTEXT_PATH, req
295:                                .getContextPath());
296:                        req.setAttribute(FORWARD_SERVLET_PATH, req
297:                                .getServletPath());
298:                        req.setAttribute(FORWARD_PATH_INFO, req.getPathInfo());
299:                        req.setAttribute(FORWARD_QUERY_STRING, req
300:                                .getQueryString());
301:
302:                        if (this .isErrorDispatch) {
303:                            req.setAttribute(ERROR_REQUEST_URI, req
304:                                    .getRequestURI());
305:                            req.setAttribute(ERROR_STATUS_CODE,
306:                                    this .errorStatusCode);
307:                            req
308:                                    .setAttribute(
309:                                            ERROR_MESSAGE,
310:                                            errorSummaryMessage != null ? errorSummaryMessage
311:                                                    : "");
312:                            if (req.getServletConfig() != null) {
313:                                req.setAttribute(ERROR_SERVLET_NAME, req
314:                                        .getServletConfig().getServletName());
315:                            }
316:
317:                            if (this .errorException != null) {
318:                                req.setAttribute(ERROR_EXCEPTION_TYPE,
319:                                        this .errorException.getClass());
320:                                req.setAttribute(ERROR_EXCEPTION,
321:                                        this .errorException);
322:                            }
323:
324:                            // Revert back to the original request and response
325:                            rsp.setErrorStatusCode(this .errorStatusCode
326:                                    .intValue());
327:                            request = req;
328:                            response = rsp;
329:                        }
330:                    }
331:
332:                    req.setServletPath(this .servletPath);
333:                    req.setPathInfo(this .pathInfo);
334:                    req.setRequestURI(this .webAppConfig.getContextPath()
335:                            + this .requestURI);
336:                    req.setForwardQueryString(this .queryString);
337:                    req.setWebAppConfig(this .webAppConfig);
338:                    req.setServletConfig(this .servletConfig);
339:                    req.setRequestAttributeListeners(this .webAppConfig
340:                            .getRequestAttributeListeners());
341:
342:                    rsp.setWebAppConfig(this .webAppConfig);
343:
344:                    // Forwards haven't set up the filter pattern set yet
345:                    if (this .matchingFilters == null) {
346:                        this .matchingFilters = getMatchingFilters(
347:                                this .forwardFilterPatterns, this .webAppConfig,
348:                                this .servletPath
349:                                        + (this .pathInfo == null ? ""
350:                                                : this .pathInfo), getName(),
351:                                "FORWARD", (this .servletPath != null));
352:                    }
353:
354:                    // Otherwise we are an initial or error dispatcher, so check security if initial -
355:                    // if we should not continue, return
356:                    else if (!this .isErrorDispatch
357:                            && !continueAfterSecurityCheck(request, response)) {
358:                        return;
359:                    }
360:
361:                    this .doInclude = Boolean.FALSE;
362:                }
363:
364:                // Make sure the filter chain is exhausted first
365:                boolean outsideFilter = (this .matchingFiltersEvaluated == 0);
366:                if (this .matchingFiltersEvaluated < this .matchingFilters.length) {
367:                    doFilter(request, response);
368:                } else {
369:                    this .servletConfig.execute(request, response,
370:                            this .webAppConfig.getContextPath()
371:                                    + this .requestURI);
372:                }
373:                // Stop any output after the final filter has been executed (e.g. from forwarding servlet)
374:                if (outsideFilter) {
375:                    WinstoneResponse rsp = getUnwrappedResponse(response);
376:                    rsp.flushBuffer();
377:                    rsp.getWinstoneOutputStream().setClosed(true);
378:                }
379:            }
380:
381:            private boolean continueAfterSecurityCheck(ServletRequest request,
382:                    ServletResponse response) throws IOException,
383:                    ServletException {
384:                // Evaluate security constraints
385:                if (this .authHandler != null) {
386:                    return this .authHandler.processAuthentication(request,
387:                            response, this .servletPath
388:                                    + (this .pathInfo == null ? ""
389:                                            : this .pathInfo));
390:                } else {
391:                    return true;
392:                }
393:            }
394:
395:            /**
396:             * Handles the processing of the chain of filters, so that we process them
397:             * all, then pass on to the main servlet
398:             */
399:            public void doFilter(ServletRequest request,
400:                    ServletResponse response) throws ServletException,
401:                    IOException {
402:                // Loop through the filter mappings until we hit the end
403:                while (this .matchingFiltersEvaluated < this .matchingFilters.length) {
404:
405:                    FilterConfiguration filter = this .matchingFilters[this .matchingFiltersEvaluated++];
406:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
407:                            "RequestDispatcher.ExecutingFilter", filter
408:                                    .getFilterName());
409:                    filter.execute(request, response, this );
410:                    return;
411:                }
412:
413:                // Forward / include as requested in the beginning
414:                if (this .doInclude == null)
415:                    return; // will never happen, because we can't call doFilter before forward/include
416:                else if (this .doInclude.booleanValue())
417:                    include(request, response);
418:                else
419:                    forward(request, response);
420:            }
421:
422:            /**
423:             * Caches the filter matching, so that if the same URL is requested twice, we don't recalculate the
424:             * filter matching every time. 
425:             */
426:            private static FilterConfiguration[] getMatchingFilters(
427:                    Mapping filterPatterns[], WebAppConfiguration webAppConfig,
428:                    String fullPath, String servletName,
429:                    String filterChainType, boolean isURLBasedMatch) {
430:
431:                String cacheKey = null;
432:                if (isURLBasedMatch) {
433:                    cacheKey = filterChainType + ":URI:" + fullPath;
434:                } else {
435:                    cacheKey = filterChainType + ":Servlet:" + servletName;
436:                }
437:                FilterConfiguration matchingFilters[] = null;
438:                Map cache = webAppConfig.getFilterMatchCache();
439:                synchronized (cache) {
440:                    matchingFilters = (FilterConfiguration[]) cache
441:                            .get(cacheKey);
442:                    if (matchingFilters == null) {
443:                        Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
444:                                "RequestDispatcher.CalcFilterChain", cacheKey);
445:                        List outFilters = new ArrayList();
446:                        for (int n = 0; n < filterPatterns.length; n++) {
447:                            // Get the pattern and eval it, bumping up the eval'd count
448:                            Mapping filterPattern = filterPatterns[n];
449:
450:                            // If the servlet name matches this name, execute it
451:                            if ((filterPattern.getLinkName() != null)
452:                                    && (filterPattern.getLinkName().equals(
453:                                            servletName) || filterPattern
454:                                            .getLinkName().equals("*"))) {
455:                                outFilters.add(webAppConfig.getFilters().get(
456:                                        filterPattern.getMappedTo()));
457:                            }
458:                            // If the url path matches this filters mappings
459:                            else if ((filterPattern.getLinkName() == null)
460:                                    && isURLBasedMatch
461:                                    && filterPattern
462:                                            .match(fullPath, null, null)) {
463:                                outFilters.add(webAppConfig.getFilters().get(
464:                                        filterPattern.getMappedTo()));
465:                            }
466:                        }
467:                        matchingFilters = (FilterConfiguration[]) outFilters
468:                                .toArray(new FilterConfiguration[0]);
469:                        cache.put(cacheKey, matchingFilters);
470:                    } else {
471:                        Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
472:                                "RequestDispatcher.UseCachedFilterChain",
473:                                cacheKey);
474:                    }
475:                }
476:                return matchingFilters;
477:            }
478:
479:            /**
480:             * Unwrap back to the original container allocated request object
481:             */
482:            protected WinstoneRequest getUnwrappedRequest(ServletRequest request) {
483:                ServletRequest workingRequest = request;
484:                while (workingRequest instanceof  ServletRequestWrapper) {
485:                    workingRequest = ((ServletRequestWrapper) workingRequest)
486:                            .getRequest();
487:                }
488:                return (WinstoneRequest) workingRequest;
489:            }
490:
491:            /**
492:             * Unwrap back to the original container allocated response object
493:             */
494:            protected WinstoneResponse getUnwrappedResponse(
495:                    ServletResponse response) {
496:                ServletResponse workingResponse = response;
497:                while (workingResponse instanceof  ServletResponseWrapper) {
498:                    workingResponse = ((ServletResponseWrapper) workingResponse)
499:                            .getResponse();
500:                }
501:                return (WinstoneResponse) workingResponse;
502:            }
503:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.