Source Code Cross Referenced for WebAppServlet.java in  » Web-Server » Acme-WebServer » rogatkin » web » 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 » Acme WebServer » rogatkin.web 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* tjws - WebAppServlet.java
0002:         * Copyright (C) 1999-2007 Dmitriy Rogatkin.  All rights reserved.
0003:         * Redistribution and use in source and binary forms, with or without
0004:         * modification, are permitted provided that the following conditions
0005:         * are met:
0006:         * 1. Redistributions of source code must retain the above copyright
0007:         *    notice, this list of conditions and the following disclaimer.
0008:         * 2. Redistributions in binary form must reproduce the above copyright
0009:         *    notice, this list of conditions and the following disclaimer in the
0010:         *    documentation and/or other materials provided with the distribution.
0011:         *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0012:         *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0013:         *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0014:         *  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
0015:         *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0016:         *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0017:         *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0018:         *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0019:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0020:         *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0021:         *
0022:         *  $Id: WebAppServlet.java,v 1.52 2008/01/19 07:08:00 dmitriy Exp $
0023:         * Created on Dec 14, 2004
0024:         */
0025:
0026:        package rogatkin.web;
0027:
0028:        import java.io.File;
0029:        import java.io.FileFilter;
0030:        import java.io.FileInputStream;
0031:        import java.io.IOException;
0032:        import java.io.InputStream;
0033:        import java.io.InputStreamReader;
0034:        import java.io.OutputStream;
0035:        import java.io.PrintWriter;
0036:        import java.lang.reflect.InvocationHandler;
0037:        import java.lang.reflect.InvocationTargetException;
0038:        import java.lang.reflect.Method;
0039:        import java.lang.reflect.Proxy;
0040:        import java.net.MalformedURLException;
0041:        import java.net.URL;
0042:        import java.net.URLClassLoader;
0043:        import java.text.DateFormat;
0044:        import java.util.ArrayList;
0045:        import java.util.Arrays;
0046:        import java.util.Collections;
0047:        import java.util.Enumeration;
0048:        import java.util.EventListener;
0049:        import java.util.HashMap;
0050:        import java.util.Hashtable;
0051:        import java.util.Iterator;
0052:        import java.util.List;
0053:        import java.util.Map;
0054:        import java.util.Set;
0055:        import java.util.TreeSet;
0056:        import java.util.Vector;
0057:        import java.util.regex.Pattern;
0058:        import java.util.zip.GZIPOutputStream;
0059:
0060:        import javax.net.ssl.SSLPeerUnverifiedException;
0061:        import javax.net.ssl.SSLSession;
0062:        import javax.net.ssl.SSLSocket;
0063:
0064:        import javax.servlet.Filter;
0065:        import javax.servlet.FilterChain;
0066:        import javax.servlet.FilterConfig;
0067:        import javax.servlet.RequestDispatcher;
0068:        import javax.servlet.Servlet;
0069:        import javax.servlet.ServletConfig;
0070:        import javax.servlet.ServletContext;
0071:        import javax.servlet.ServletContextAttributeEvent;
0072:        import javax.servlet.ServletContextAttributeListener;
0073:        import javax.servlet.ServletContextEvent;
0074:        import javax.servlet.ServletContextListener;
0075:        import javax.servlet.ServletException;
0076:        import javax.servlet.ServletRequest;
0077:        import javax.servlet.ServletRequestAttributeEvent;
0078:        import javax.servlet.ServletRequestAttributeListener;
0079:        import javax.servlet.ServletRequestEvent;
0080:        import javax.servlet.ServletRequestListener;
0081:        import javax.servlet.ServletResponse;
0082:        import javax.servlet.UnavailableException;
0083:        import javax.servlet.http.HttpServlet;
0084:        import javax.servlet.http.HttpServletRequest;
0085:        import javax.servlet.http.HttpServletRequestWrapper;
0086:        import javax.servlet.http.HttpServletResponse;
0087:        import javax.servlet.http.HttpServletResponseWrapper;
0088:        import javax.servlet.http.HttpSession;
0089:        import javax.servlet.http.HttpSessionListener;
0090:        import javax.xml.XMLConstants;
0091:        import javax.xml.namespace.NamespaceContext;
0092:        import javax.xml.xpath.XPath;
0093:        import javax.xml.xpath.XPathConstants;
0094:        import javax.xml.xpath.XPathExpressionException;
0095:        import javax.xml.xpath.XPathFactory;
0096:
0097:        import org.w3c.dom.Node;
0098:        import org.w3c.dom.NodeList;
0099:        import org.xml.sax.InputSource;
0100:
0101:        import Acme.Utils;
0102:        import Acme.Serve.Serve;
0103:
0104:        /**
0105:         * @author dmitriy
0106:         * 
0107:         * 
0108:         */
0109:        public class WebAppServlet extends HttpServlet implements 
0110:                ServletContext {
0111:            public static final String DEF_DEBUG = "rogatkin.webapp.debug";
0112:
0113:            public static final String WAR_NAME_AS_CONTEXTPATH = "tjws.wardeploy.warname-as-context";
0114:
0115:            protected static final String WEBAPPCLASSLOADER = "rogatkin.webapp.AppClassLoader";
0116:
0117:            protected static final String WEBAPPINITTIMEOUT = "rogatkin.webapp.%sinit.timeout";
0118:
0119:            List<ServletAccessDescr> servlets;
0120:
0121:            List<FilterAccessDescriptor> filters;
0122:
0123:            URL[] cpUrls;
0124:
0125:            URLClassLoader ucl;
0126:
0127:            File deployDir;
0128:
0129:            Serve server;
0130:
0131:            int sessionTimeout;
0132:
0133:            int initTimeout;
0134:
0135:            // / context methods
0136:            protected String contextName;
0137:
0138:            protected String contextPath;
0139:
0140:            protected Hashtable<String, Object> attributes;
0141:
0142:            protected Hashtable<String, String> contextParameters;
0143:
0144:            protected List<String> welcomeFiles;
0145:
0146:            protected List<ErrorPageDescr> errorPages;
0147:
0148:            protected List<EventListener> listeners;
0149:
0150:            protected List<HttpSessionListener> sessionListeners;
0151:
0152:            protected ArrayList<ServletRequestListener> requestListeners;
0153:
0154:            protected ArrayList<ServletRequestAttributeListener> attributeListeners;
0155:
0156:            protected Map<String, String> mimes;
0157:
0158:            private boolean applyCompression;
0159:
0160:            protected static interface Openable {
0161:                Object getOrigin();
0162:            }
0163:
0164:            protected static class MappingEntry {
0165:                String servPath;
0166:
0167:                Pattern pathPat;
0168:
0169:                MappingEntry(String path, String pattern) {
0170:                    servPath = path;
0171:                    pathPat = Pattern.compile(pattern);
0172:                }
0173:
0174:                public String toString() {
0175:                    return String.format("Mapping of %s with regexp pat %s",
0176:                            servPath, pathPat);
0177:                }
0178:            }
0179:
0180:            protected class ServletAccessDescr implements  ServletConfig {
0181:                String className;
0182:
0183:                String name;
0184:
0185:                Servlet instance;
0186:
0187:                // String servPath;
0188:
0189:                // String pathPat;
0190:
0191:                MappingEntry[] mapping;
0192:
0193:                Map<String, String> initParams;
0194:
0195:                String label;
0196:
0197:                boolean loadOnStart;
0198:
0199:                String descr;
0200:
0201:                long timeToReactivate; // if servlet suspended
0202:
0203:                public java.lang.String getServletName() {
0204:                    return name;
0205:                }
0206:
0207:                public java.util.Enumeration getInitParameterNames() {
0208:                    return new Enumeration<String>() {
0209:                        Iterator<String> i;
0210:                        {
0211:                            i = initParams.keySet().iterator();
0212:                        }
0213:
0214:                        public boolean hasMoreElements() {
0215:                            return i.hasNext();
0216:                        }
0217:
0218:                        public String nextElement() {
0219:                            return i.next();
0220:                        }
0221:                    };
0222:                }
0223:
0224:                public ServletContext getServletContext() {
0225:                    return WebAppServlet.this ;
0226:                }
0227:
0228:                public String getInitParameter(java.lang.String name) {
0229:                    return initParams.get(name);
0230:                }
0231:
0232:                public void add(MappingEntry entry) {
0233:                    if (mapping == null)
0234:                        mapping = new MappingEntry[1];
0235:                    else { // can't use copyOf in 1.5
0236:                        MappingEntry[] copy = new MappingEntry[mapping.length + 1];
0237:                        System.arraycopy(mapping, 0, copy, 0, mapping.length);
0238:                        mapping = copy;
0239:                    }
0240:                    mapping[mapping.length - 1] = entry;
0241:                }
0242:
0243:                int matchPath(String path) {
0244:                    if (mapping == null)
0245:                        return -1;
0246:                    for (int i = 0; i < mapping.length; i++)
0247:                        if (mapping[i].pathPat.matcher(path).matches())
0248:                            return i;
0249:                    return -1;
0250:                }
0251:
0252:                public String toString() {
0253:                    return "Servlet " + name + " class " + className
0254:                            + " path/patern " + Arrays.toString(mapping)
0255:                            + " init" + initParams + " inst " + instance;
0256:                }
0257:            }
0258:
0259:            static enum DispatchFilterType {
0260:                FORWARD, INCLUDE, REQUEST, ERROR
0261:            };
0262:
0263:            protected class FilterAccessDescriptor extends ServletAccessDescr
0264:                    implements  FilterConfig {
0265:                String[] servletNames;
0266:
0267:                Filter filterInstance;
0268:
0269:                DispatchFilterType[] dispatchTypes;
0270:
0271:                public java.lang.String getFilterName() {
0272:                    return name;
0273:                }
0274:
0275:                public void add(String name) {
0276:                    // note the local name shadows name as class memeber
0277:                    if (servletNames == null)
0278:                        servletNames = new String[1];
0279:                    else
0280:                        servletNames = Utils.copyOf(servletNames,
0281:                                servletNames.length + 1);
0282:                    servletNames[servletNames.length - 1] = name;
0283:                }
0284:
0285:                public void add(DispatchFilterType dispatcher) {
0286:                    if (dispatchTypes == null)
0287:                        dispatchTypes = new DispatchFilterType[1];
0288:                    else {
0289:                        DispatchFilterType[] copy = new DispatchFilterType[dispatchTypes.length + 1];
0290:                        System.arraycopy(dispatchTypes, 0, copy, 0,
0291:                                dispatchTypes.length);
0292:                        dispatchTypes = copy;
0293:                    }
0294:                    dispatchTypes[dispatchTypes.length - 1] = dispatcher;
0295:                }
0296:
0297:                int matchServlet(String servletName) {
0298:                    if (servletNames == null)
0299:                        return -1;
0300:                    for (int i = 0; i < this .servletNames.length; i++)
0301:                        if (servletNames[i].equals(servletName))
0302:                            return i;
0303:                    return -1;
0304:                }
0305:
0306:                boolean matchDispatcher(DispatchFilterType dispatcher) {
0307:                    if (dispatchTypes == null)
0308:                        if (dispatcher.equals(DispatchFilterType.REQUEST))
0309:                            return true;
0310:                        else
0311:                            return false;
0312:                    for (int i = 0; i < dispatchTypes.length; i++)
0313:                        if (dispatcher.equals(dispatchTypes[i]))
0314:                            return true;
0315:                    return false;
0316:                }
0317:
0318:                public String toString() {
0319:                    return String.format(
0320:                            "Filter for servlets %s and types %s based on %s",
0321:                            Arrays.toString(servletNames), Arrays
0322:                                    .toString(dispatchTypes), super .toString());
0323:                }
0324:            }
0325:
0326:            protected static class ErrorPageDescr {
0327:                String errorPage;
0328:
0329:                Class exception;
0330:
0331:                int errorCode;
0332:
0333:                ErrorPageDescr(String page, String exClass, String code) {
0334:                    if (page == null || page.length() == 0
0335:                            || page.charAt(0) != '/')
0336:                        throw new IllegalArgumentException("Error page path '"
0337:                                + page + "' must start with '/'");
0338:                    if (page.charAt(0) == '/')
0339:                        errorPage = page;
0340:                    else
0341:                        errorPage = "/" + page;
0342:                    try {
0343:                        exception = Class.forName(exClass);
0344:                    } catch (Exception e) {
0345:
0346:                    }
0347:                    try {
0348:                        errorCode = Integer.parseInt(code);
0349:                    } catch (Exception e) {
0350:
0351:                    }
0352:                }
0353:            }
0354:
0355:            protected WebAppServlet(String context) {
0356:                this .contextPath = "/" + context;
0357:                attributes = new Hashtable<String, Object>();
0358:                contextParameters = new Hashtable<String, String>();
0359:                applyCompression = System.getProperty("tjws.webapp." + context
0360:                        + ".compressresponse") != null;
0361:                if (applyCompression == false)
0362:                    applyCompression = System
0363:                            .getProperty("tjws.fileservlet.usecompression") != null;
0364:                // TODO consider
0365:                // _DEBUG = System.getProperty(getClass().getName() + ".debug") != null;
0366:            }
0367:
0368:            public static WebAppServlet create(File deployDir, String context,
0369:                    Serve server) throws ServletException {
0370:                XPath xp = XPathFactory.newInstance().newXPath();
0371:                final WebAppServlet result = new WebAppServlet(context);
0372:                result.server = server;
0373:                try {
0374:                    result.makeCP(deployDir); // /web-app
0375:                    Node document = (Node) xp.evaluate("/*", new InputSource(
0376:                            new FileInputStream(new File(deployDir,
0377:                                    "WEB-INF/web.xml"))), XPathConstants.NODE);
0378:                    final String namespaceURI = document.getNamespaceURI();
0379:                    String prefix = namespaceURI == null ? "" : "j2ee:";
0380:                    xp.setNamespaceContext(new NamespaceContext() {
0381:                        public String getNamespaceURI(String prefix) {
0382:                            // System.err.printf("Resolver called with %s%n", prefix);
0383:                            if (prefix == null)
0384:                                throw new IllegalArgumentException(
0385:                                        "Prefix is null.");
0386:                            if (namespaceURI == null)
0387:                                return XMLConstants.NULL_NS_URI;
0388:                            if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX))
0389:                                return namespaceURI;
0390:                            if ("j2ee".equals(prefix))
0391:                                return namespaceURI;
0392:                            return XMLConstants.NULL_NS_URI;
0393:                        }
0394:
0395:                        public String getPrefix(String arg0) {
0396:                            throw new UnsupportedOperationException(
0397:                                    "getPrefix(" + arg0 + ");");
0398:                        }
0399:
0400:                        public Iterator getPrefixes(String arg0) {
0401:                            throw new UnsupportedOperationException(
0402:                                    "getPrefixes(" + arg0 + ");");
0403:                        }
0404:                    });
0405:                    document = (Node) xp.evaluate("//" + prefix + "web-app",
0406:                            document, XPathConstants.NODE);
0407:                    if ("yes".equals(System
0408:                            .getProperty(WAR_NAME_AS_CONTEXTPATH)) == false)
0409:                        result.contextName = (String) xp.evaluate(prefix
0410:                                + "display-name", document,
0411:                                XPathConstants.STRING);
0412:                    if (result.contextName == null
0413:                            || result.contextName.length() == 0)
0414:                        result.contextName = context;
0415:                    else
0416:                        result.contextPath = "/" + result.contextName;
0417:                    // context parameters
0418:                    NodeList nodes = (NodeList) xp
0419:                            .evaluate(prefix + "context-param", document,
0420:                                    XPathConstants.NODESET);
0421:                    int nodesLen = nodes.getLength();
0422:                    for (int p = 0; p < nodesLen; p++) {
0423:                        result.contextParameters.put((String) xp.evaluate(
0424:                                prefix + "param-name", nodes.item(p),
0425:                                XPathConstants.STRING), (String) xp.evaluate(
0426:                                prefix + "param-value", nodes.item(p),
0427:                                XPathConstants.STRING));
0428:                    }
0429:                    // session-config <session-timeout>
0430:                    Number num = (Number) xp.evaluate(prefix
0431:                            + "session-config/" + prefix + "session-timeout",
0432:                            document, XPathConstants.NUMBER);
0433:                    if (num != null)
0434:                        result.sessionTimeout = num.intValue();
0435:                    if (result.sessionTimeout < 0)
0436:                        result.sessionTimeout = 0;
0437:                    else
0438:                        result.sessionTimeout *= 60;
0439:                    result.initTimeout = 10;
0440:                    String initTimeoutStr = System.getProperty(String.format(
0441:                            WEBAPPINITTIMEOUT, result.contextName + "."));
0442:                    if (initTimeoutStr == null)
0443:                        initTimeoutStr = System.getProperty(String.format(
0444:                                WEBAPPINITTIMEOUT, ""));
0445:                    if (initTimeoutStr != null)
0446:                        try {
0447:                            result.initTimeout = Integer
0448:                                    .parseInt(initTimeoutStr);
0449:                            if (result.initTimeout < 2)
0450:                                result.initTimeout = 10;
0451:                        } catch (Exception e) {
0452:
0453:                        }
0454:                    Thread.currentThread().setContextClassLoader(result.ucl);
0455:                    // listeners listener-class
0456:                    nodes = (NodeList) xp.evaluate(prefix + "listener/"
0457:                            + prefix + "listener-class", document,
0458:                            XPathConstants.NODESET);
0459:                    nodesLen = nodes.getLength();
0460:                    if (nodesLen > 0) {
0461:                        result.listeners = new ArrayList<EventListener>(
0462:                                nodesLen);
0463:                        for (int i = 0; i < nodesLen; i++)
0464:                            try {
0465:                                EventListener eventListener = (EventListener) result.ucl
0466:                                        .loadClass(
0467:                                                nodes.item(i).getTextContent()
0468:                                                        .trim()).newInstance();
0469:                                if (eventListener instanceof  HttpSessionListener) {
0470:                                    if (result.sessionListeners == null)
0471:                                        result.sessionListeners = new ArrayList<HttpSessionListener>(
0472:                                                nodesLen);
0473:                                    result.sessionListeners
0474:                                            .add((HttpSessionListener) eventListener);
0475:                                }
0476:                                if (eventListener instanceof  ServletRequestListener) {
0477:                                    if (result.requestListeners == null)
0478:                                        result.requestListeners = new ArrayList<ServletRequestListener>(
0479:                                                nodesLen);
0480:                                    result.requestListeners
0481:                                            .add((ServletRequestListener) eventListener);
0482:                                }
0483:                                if (eventListener instanceof  ServletRequestAttributeListener) {
0484:                                    if (result.attributeListeners == null)
0485:                                        result.attributeListeners = new ArrayList<ServletRequestAttributeListener>(
0486:                                                nodesLen);
0487:                                    result.attributeListeners
0488:                                            .add((ServletRequestAttributeListener) eventListener);
0489:                                }
0490:                                result.listeners.add(eventListener); // because the same class can implement other listener interfaces
0491:                            } catch (Exception e) {
0492:                                result.log("Event listener "
0493:                                        + nodes.item(i).getTextContent()
0494:                                        + " can't be created.", e);
0495:                            } catch (Error e) {
0496:                                result.log("Event listener "
0497:                                        + nodes.item(i).getTextContent()
0498:                                        + " can't be created.", e);
0499:                            }
0500:                    }
0501:                    // restore sessions for this context
0502:                    // serve.sessions.restore for the current context
0503:
0504:                    // notify context listeners
0505:                    if (result.listeners != null)
0506:                        for (EventListener listener : result.listeners) {
0507:                            if (listener instanceof  ServletContextListener) {
0508:                                final ServletContextListener contListener = (ServletContextListener) listener;
0509:                                contListener
0510:                                        .contextInitialized(new ServletContextEvent(
0511:                                                result));
0512:                            }
0513:                        }
0514:                    // process filters
0515:                    nodes = (NodeList) xp.evaluate(prefix + "filter", document,
0516:                            XPathConstants.NODESET);
0517:                    nodesLen = nodes.getLength();
0518:                    result.filters = new ArrayList<FilterAccessDescriptor>(
0519:                            nodesLen);
0520:                    for (int i = 0; i < nodesLen; i++) {
0521:                        Node n = nodes.item(i);
0522:                        FilterAccessDescriptor fad = result
0523:                                .createFilterDescriptor();
0524:                        fad.name = (String) xp.evaluate(prefix + "filter-name",
0525:                                n, XPathConstants.STRING);
0526:                        fad.className = (String) xp.evaluate(prefix
0527:                                + "filter-class", n, XPathConstants.STRING);
0528:                        if (fad.className == null)
0529:                            throw new ServletException(
0530:                                    String
0531:                                            .format(
0532:                                                    "Filter %s specified without or empty class.",
0533:                                                    fad.name));
0534:                        else
0535:                            fad.className = fad.className.trim();
0536:                        fad.label = (String) xp.evaluate(prefix
0537:                                + "display-name", n, XPathConstants.STRING);
0538:                        fad.descr = (String) xp.evaluate(
0539:                                prefix + "description", n,
0540:                                XPathConstants.STRING);
0541:                        NodeList params = (NodeList) xp.evaluate(prefix
0542:                                + "init-param", n, XPathConstants.NODESET);
0543:                        fad.initParams = new HashMap<String, String>(params
0544:                                .getLength());
0545:                        for (int p = 0; p < params.getLength(); p++) {
0546:                            fad.initParams.put((String) xp.evaluate(prefix
0547:                                    + "param-name", params.item(p),
0548:                                    XPathConstants.STRING), (String) xp
0549:                                    .evaluate(prefix + "param-value", params
0550:                                            .item(p), XPathConstants.STRING));
0551:                        }
0552:                        result.filters.add(fad);
0553:                    }
0554:                    // process filter's mapping
0555:                    for (FilterAccessDescriptor fad : result.filters) {
0556:                        nodes = (NodeList) xp.evaluate(prefix
0557:                                + "filter-mapping[" + prefix + "filter-name=\""
0558:                                + fad.name + "\"]", document,
0559:                                XPathConstants.NODESET);
0560:                        nodesLen = nodes.getLength();
0561:                        if (nodesLen == 0)
0562:                            throw new ServletException(String.format(
0563:                                    "No mappings were found for filter %s",
0564:                                    fad.name));
0565:                        for (int i = 0; i < nodesLen; i++) {
0566:                            Node n = nodes.item(i);
0567:                            NodeList clarifications = (NodeList) xp.evaluate(
0568:                                    prefix + "url-pattern", n,
0569:                                    XPathConstants.NODESET);
0570:                            int claLen = clarifications.getLength();
0571:                            for (int j = 0; j < claLen; j++) {
0572:                                String mapUrl = clarifications.item(j)
0573:                                        .getTextContent();
0574:                                if (mapUrl == null || mapUrl.length() == 0)
0575:                                    continue;
0576:                                fad.add(new MappingEntry(clearPath(mapUrl),
0577:                                        buildREbyPathPatt(mapUrl)));
0578:                            }
0579:                            clarifications = (NodeList) xp.evaluate(prefix
0580:                                    + "dispatcher", n, XPathConstants.NODESET);
0581:                            claLen = clarifications.getLength();
0582:                            for (int j = 0; j < claLen; j++) {
0583:                                String filterType = clarifications.item(j)
0584:                                        .getTextContent();
0585:                                if (filterType == null
0586:                                        || filterType.length() == 0)
0587:                                    fad.add(DispatchFilterType.REQUEST);
0588:                                else
0589:                                    fad.add(DispatchFilterType
0590:                                            .valueOf(filterType));
0591:                            }
0592:                            clarifications = (NodeList) xp
0593:                                    .evaluate(prefix + "servlet-name", n,
0594:                                            XPathConstants.NODESET);
0595:                            claLen = clarifications.getLength();
0596:                            for (int j = 0; j < claLen; j++) {
0597:                                // adding servlet name
0598:                                fad
0599:                                        .add(clarifications.item(j)
0600:                                                .getTextContent());
0601:                            }
0602:                        }
0603:                        result.newFilterInstance(fad);
0604:                    }
0605:                    // servlets
0606:                    nodes = (NodeList) xp.evaluate(prefix + "servlet",
0607:                            document, XPathConstants.NODESET);
0608:                    nodesLen = nodes.getLength();
0609:                    result.servlets = new ArrayList<ServletAccessDescr>(
0610:                            nodesLen + 1); // +jsp
0611:                    for (int i = 0; i < nodesLen; i++) {
0612:                        Node n = nodes.item(i);
0613:                        ServletAccessDescr sad = result.createDescriptor();
0614:                        sad.name = (String) xp.evaluate(
0615:                                prefix + "servlet-name", n,
0616:                                XPathConstants.STRING);
0617:                        sad.className = (String) xp.evaluate(prefix
0618:                                + "servlet-class", n, XPathConstants.STRING);
0619:                        if (sad.className == null
0620:                                || sad.className.length() == 0) {
0621:                            String jspFile = (String) xp.evaluate(prefix
0622:                                    + "jsp-file", n, XPathConstants.STRING);
0623:                            if (jspFile != null) {
0624:                                result
0625:                                        .log(String
0626:                                                .format(
0627:                                                        "Not supported servlet option jsp-file %s for %s, ignored.",
0628:                                                        jspFile, sad.name));
0629:                                continue;
0630:                            } else
0631:                                throw new ServletException(
0632:                                        String
0633:                                                .format(
0634:                                                        "Servlet %s specified without class or jsp file.",
0635:                                                        sad.name));
0636:                        } else
0637:                            sad.className = sad.className.trim();
0638:                        sad.label = (String) xp.evaluate(prefix
0639:                                + "display-name", n, XPathConstants.STRING);
0640:                        sad.descr = (String) xp.evaluate(
0641:                                prefix + "description", n,
0642:                                XPathConstants.STRING);
0643:                        String loadOnStartVal = (String) xp.evaluate(prefix
0644:                                + "load-on-startup", n, XPathConstants.STRING);
0645:                        sad.loadOnStart = loadOnStartVal != null
0646:                                && loadOnStartVal.length() > 0;
0647:                        NodeList params = (NodeList) xp.evaluate(prefix
0648:                                + "init-param", n, XPathConstants.NODESET);
0649:                        sad.initParams = new HashMap<String, String>(params
0650:                                .getLength());
0651:                        for (int p = 0; p < params.getLength(); p++) {
0652:                            sad.initParams.put((String) xp.evaluate(prefix
0653:                                    + "param-name", params.item(p),
0654:                                    XPathConstants.STRING), (String) xp
0655:                                    .evaluate(prefix + "param-value", params
0656:                                            .item(p), XPathConstants.STRING));
0657:                        }
0658:                        result.servlets.add(sad);
0659:                    }
0660:                    // get mappings
0661:                    ServletAccessDescr wasDefault = null;
0662:                    for (ServletAccessDescr sad : result.servlets) {
0663:                        nodes = (NodeList) xp.evaluate(prefix
0664:                                + "servlet-mapping[" + prefix
0665:                                + "servlet-name=\"" + sad.name + "\"]",
0666:                                document, XPathConstants.NODESET);
0667:                        nodesLen = nodes.getLength();
0668:                        // System.err.printf("Found %d mappings for %s%n", nodesLen, sad);
0669:                        if (nodesLen == 0) {
0670:                            // no mapping at all
0671:                            String urlPat = "/" + sad.name + "/*";
0672:                            sad.add(new MappingEntry(clearPath(urlPat),
0673:                                    buildREbyPathPatt(urlPat)));
0674:                        } else
0675:                            for (int i = 0; i < nodesLen; i++) {
0676:                                NodeList maps = (NodeList) xp.evaluate(prefix
0677:                                        + "url-pattern", nodes.item(i),
0678:                                        XPathConstants.NODESET);
0679:                                int mapsLen = maps.getLength();
0680:                                // System.err.printf("Found %d patterns for %s%n", mapsLen, sad);
0681:                                if (mapsLen == 0) {
0682:                                    // mapping with empty pattern
0683:                                    String urlPat = "/" + sad.name + "/*";
0684:                                    sad.add(new MappingEntry(clearPath(urlPat),
0685:                                            buildREbyPathPatt(urlPat)));
0686:                                } else {
0687:                                    for (int j = 0; j < mapsLen; j++) {
0688:                                        String urlPat = maps.item(j)
0689:                                                .getTextContent();
0690:                                        if (urlPat.equals("/"))
0691:                                            if (wasDefault != null)
0692:                                                throw new ServletException(
0693:                                                        "More than one default servlets defined "
0694:                                                                + sad);
0695:                                            else
0696:                                                wasDefault = sad;
0697:                                        sad.add(new MappingEntry(
0698:                                                clearPath(urlPat),
0699:                                                buildREbyPathPatt(urlPat)));
0700:                                    }
0701:                                }
0702:                            }
0703:                        // System.err.printf("Servlet %s, path:%s\n", sad, sad.servPath);
0704:                        if (sad.loadOnStart)
0705:                            result.newInstance(sad);
0706:                    }
0707:                    // additional jsp mapping
0708:                    nodes = (NodeList) xp.evaluate(prefix + "jsp-config/"
0709:                            + prefix + "jsp-property-group/" + prefix
0710:                            + "url-pattern", document, XPathConstants.NODESET);
0711:                    nodesLen = nodes.getLength();
0712:                    if (nodesLen > 0) {
0713:                        List<String> jspPats = new ArrayList<String>(nodesLen);
0714:                        for (int i = 0; i < nodesLen; i++) {
0715:                            jspPats.add(nodes.item(i).getTextContent());
0716:                        }
0717:                        result.addJSPServlet(jspPats);
0718:                    } else
0719:                        result.addJSPServlet(null);
0720:                    if (wasDefault != null) {
0721:                        // re-add at the end
0722:                        result.servlets.remove(wasDefault);
0723:                        result.servlets.add(wasDefault);
0724:                    }
0725:                    // welcome files
0726:                    nodes = (NodeList) xp.evaluate(prefix
0727:                            + "welcome-file-list/" + prefix + "welcome-file",
0728:                            document, XPathConstants.NODESET);
0729:                    result.welcomeFiles = new ArrayList<String>(nodes
0730:                            .getLength() + 1);
0731:                    nodesLen = nodes.getLength();
0732:                    if (nodesLen > 0)
0733:                        for (int wfi = 0; wfi < nodesLen; wfi++)
0734:                            result.welcomeFiles.add(nodes.item(wfi)
0735:                                    .getTextContent());
0736:                    else {
0737:                        result.welcomeFiles.add("index.html");
0738:                        result.welcomeFiles.add("index.jsp");
0739:                    }
0740:                    // error pages
0741:                    nodes = (NodeList) xp.evaluate(prefix + "error-page",
0742:                            document, XPathConstants.NODESET);
0743:                    nodesLen = nodes.getLength();
0744:                    if (nodesLen > 0) {
0745:                        result.errorPages = new ArrayList<ErrorPageDescr>(
0746:                                nodesLen);
0747:                        for (int i = 0; i < nodesLen; i++) {
0748:                            Node n = nodes.item(i);
0749:                            result.errorPages
0750:                                    .add(new WebAppServlet.ErrorPageDescr(
0751:                                            (String) xp.evaluate(prefix
0752:                                                    + "location", n,
0753:                                                    XPathConstants.STRING),
0754:                                            (String) xp.evaluate(prefix
0755:                                                    + "exception-type", n,
0756:                                                    XPathConstants.STRING),
0757:                                            (String) xp.evaluate(prefix
0758:                                                    + "error-code", n,
0759:                                                    XPathConstants.STRING)));
0760:                        }
0761:                    }
0762:                    // mime types
0763:                    nodes = (NodeList) xp.evaluate(prefix + "mime-mapping",
0764:                            document, XPathConstants.NODESET);
0765:                    nodesLen = nodes.getLength();
0766:                    if (nodesLen > 0) {
0767:                        result.mimes = new HashMap<String, String>(nodesLen);
0768:                        for (int i = 0; i < nodesLen; i++) {
0769:                            Node n = nodes.item(i);
0770:                            result.mimes.put(((String) xp.evaluate(prefix
0771:                                    + "extension", n, XPathConstants.STRING))
0772:                                    .toLowerCase(), (String) xp.evaluate(prefix
0773:                                    + "mime-type", n, XPathConstants.STRING));
0774:                        }
0775:                    }
0776:                } catch (IOException ioe) {
0777:                    throw new ServletException("A problem in reading web.xml.",
0778:                            ioe);
0779:                } catch (XPathExpressionException xpe) {
0780:                    xpe.printStackTrace();
0781:                    throw new ServletException("A problem in parsing web.xml.",
0782:                            xpe);
0783:                } // finally { // streams will be closed by InputSource
0784:                return result;
0785:            }
0786:
0787:            static <D extends ServletAccessDescr> void addMultiple(
0788:                    NodeList list, D d) {
0789:                // TODO can be solution for more compact code
0790:            }
0791:
0792:            static public String buildREbyPathPatt(String pathPat) {
0793:                if (pathPat.equals("/"))
0794:                    return "/.*";
0795:                if (pathPat.startsWith("*."))
0796:                    return pathPat.replace(".", "\\.").replace("?", ".")
0797:                            .replace("*", ".*").replace("|", "\\|"); // +"\\??.*";
0798:                // TODO think more
0799:                int wcp = pathPat.indexOf('*');
0800:                //if (wcp > 0 && pathPat.charAt(wcp - 1) == '/')
0801:                //pathPat = pathPat.substring(0, wcp - 1) + '*';
0802:                pathPat = pathPat.replace(".", "\\.").replace("?", ".")
0803:                        .replace("*", ".*");
0804:                if (wcp < 0)
0805:                    if (pathPat.endsWith("/") == false)
0806:                        pathPat += "/?";
0807:                return pathPat;
0808:            }
0809:
0810:            static public String clearPath(String pathMask) {
0811:                if (pathMask.equals("/"))
0812:                    return pathMask;
0813:                if (pathMask.startsWith("*."))
0814:                    return "/";
0815:                int wcp = pathMask.indexOf('*');
0816:                if (wcp < 0)
0817:                    return pathMask;
0818:                return pathMask.substring(0, wcp);
0819:            }
0820:
0821:            protected static Serve.ServeConnection toServeConnection(
0822:                    Object proxy) {
0823:                if (proxy instanceof  Openable) {
0824:                    Object servCon = ((Openable) proxy).getOrigin();
0825:                    if (servCon instanceof  Serve.ServeConnection)
0826:                        return (Serve.ServeConnection) servCon;
0827:                }
0828:                return null;
0829:            }
0830:
0831:            public void service(ServletRequest req, ServletResponse res)
0832:                    throws ServletException, IOException {
0833:                // new Exception("call trace").printStackTrace();
0834:                // TODO check access rights
0835:                Thread.currentThread().setContextClassLoader(ucl);
0836:                if (req.isSecure())
0837:                    fillSecureAttrs(req);
0838:                final HttpServletRequest hreq = (HttpServletRequest) req;
0839:                if (this .requestListeners != null) {
0840:                    ServletRequestEvent e = new ServletRequestEvent(this , hreq);
0841:                    for (ServletRequestListener rlistener : requestListeners)
0842:                        rlistener.requestInitialized(e);
0843:                }
0844:                try {
0845:                    String path = hreq.getPathInfo();
0846:                    // TODO: wrap request to implement methods like getRequestDispatcher()
0847:                    // which supports relative path, no leading / means relative to currently called
0848:                    if (_DEBUG)
0849:                        System.err
0850:                                .printf(
0851:                                        "Full req:%s, ContextPath: %s, ServletPath:%s, pathInfo:%s\n",
0852:                                        hreq.getRequestURI(), hreq
0853:                                                .getContextPath(), hreq
0854:                                                .getServletPath(), path);
0855:                    SimpleFilterChain sfc = new SimpleFilterChain();
0856:                    if (path != null) {
0857:                        // note a limitation, servlet name can't start with /WEB-INF
0858:                        if (path.regionMatches(true, 0, "/WEB-INF", 0,
0859:                                "/WEB-INF".length())) {
0860:                            ((HttpServletResponse) res)
0861:                                    .sendError(HttpServletResponse.SC_FORBIDDEN);
0862:                            return;
0863:                        }
0864:                        for (FilterAccessDescriptor fad : filters)
0865:                            if (fad.matchDispatcher(DispatchFilterType.REQUEST)
0866:                                    && fad.matchPath(path) >= 0)
0867:                                sfc.add(fad);
0868:                        for (ServletAccessDescr sad : servlets) {
0869:                            if (_DEBUG)
0870:                                System.err.println("Trying match " + path
0871:                                        + " to " + Arrays.toString(sad.mapping)
0872:                                        + " = " + sad.matchPath(path));
0873:                            int patIndex;
0874:                            if ((patIndex = sad.matchPath(path)) >= 0) {
0875:                                if (sad.instance == null) {
0876:                                    if (sad.loadOnStart == false)
0877:                                        synchronized (sad) {
0878:                                            if (sad.instance == null)
0879:                                                newInstance(sad);
0880:                                        }
0881:                                    if (sad.instance == null) {
0882:                                        sad.loadOnStart |= true; // mark unsuccessful instantiation and ban the servlet?
0883:                                        ((HttpServletResponse) res)
0884:                                                .sendError(
0885:                                                        HttpServletResponse.SC_GONE,
0886:                                                        "Servlet "
0887:                                                                + sad.name
0888:                                                                + " hasn't been instantiated successfully or has been unloaded.");
0889:                                        return;
0890:                                    }
0891:                                } else {
0892:                                    if (sad.timeToReactivate > 0) {
0893:                                        if (sad.timeToReactivate > System
0894:                                                .currentTimeMillis()) {
0895:                                            ((HttpServletResponse) res)
0896:                                                    .setIntHeader(
0897:                                                            "Retry-After",
0898:                                                            (int) (sad.timeToReactivate - System
0899:                                                                    .currentTimeMillis()) / 1000 + 1);
0900:                                            //((HttpServletResponse) res).setDateHeader("Retry-After", new Date(sad.timeToReactivate));
0901:                                            ((HttpServletResponse) res)
0902:                                                    .sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
0903:                                            return;
0904:                                        } else
0905:                                            sad.timeToReactivate = 0;
0906:                                    }
0907:                                }
0908:                                for (FilterAccessDescriptor fad : filters)
0909:                                    if (fad
0910:                                            .matchDispatcher(DispatchFilterType.REQUEST)
0911:                                            && fad.matchServlet(sad.name) >= 0)
0912:                                        sfc.add(fad);
0913:                                // sfc.add(fad.filterInstance);
0914:                                // System.err.println("used:"+ sad.servPath+", wanted:"+((WebAppServlet) sad.getServletContext()).contextPath);
0915:                                sfc.setFilter(new WebAppContextFilter(
0916:                                        sad.mapping[patIndex].servPath));
0917:                                // add servlet in chain
0918:                                sfc.setServlet(sad);
0919:                                sfc.reset();
0920:                                sfc.doFilter(req, res);
0921:                                return;
0922:                            }
0923:                        }
0924:                    } else {
0925:                        ((HttpServletResponse) res).sendRedirect(hreq
0926:                                .getRequestURI()
0927:                                + "/");
0928:                        return;
0929:                    }
0930:
0931:                    // no matching, process as file
0932:                    sfc.setFilter(new WebAppContextFilter());
0933:                    sfc.setServlet(new HttpServlet() {
0934:                        public void service(ServletRequest req,
0935:                                ServletResponse res) throws ServletException,
0936:                                IOException {
0937:                            String path = ((HttpServletRequest) req)
0938:                                    .getPathTranslated();
0939:                            returnFileContent(path, (HttpServletRequest) req,
0940:                                    (HttpServletResponse) res);
0941:                        }
0942:                    });
0943:                    sfc.reset();
0944:                    sfc.doFilter(req, res);
0945:                } finally {
0946:                    if (this .requestListeners != null) {
0947:                        ServletRequestEvent e = new ServletRequestEvent(this ,
0948:                                hreq);
0949:                        for (ServletRequestListener rlistener : requestListeners)
0950:                            rlistener.requestDestroyed(e);
0951:                    }
0952:                }
0953:            }
0954:
0955:            protected void fillSecureAttrs(ServletRequest req) {
0956:                Serve.ServeConnection scon = toServeConnection(req);
0957:                if (scon != null) {
0958:                    if (scon.getSocket() instanceof  SSLSocket) {
0959:                        SSLSocket ssocket = (SSLSocket) scon.getSocket();
0960:                        SSLSession ssess = ssocket.getSession();
0961:                        String cipherSuite = ssess.getCipherSuite();
0962:
0963:                        req.setAttribute("javax.servlet.request.cipher_suite",
0964:                                cipherSuite);
0965:                        int cipherBits = 0;
0966:                        // TODO cache in session
0967:                        if (cipherSuite.indexOf("128") > 0)
0968:                            cipherBits = 128;
0969:                        else if (cipherSuite.indexOf("40") > 0)
0970:                            cipherBits = 40;
0971:                        else if (cipherSuite.indexOf("3DES") > 0)
0972:                            cipherBits = 168;
0973:                        else if (cipherSuite.indexOf("IDEA") > 0)
0974:                            cipherBits = 128;
0975:                        else if (cipherSuite.indexOf("DES") > 0)
0976:                            cipherBits = 56;
0977:                        req.setAttribute("javax.servlet.request.key_size",
0978:                                cipherBits);
0979:                        try {
0980:                            req.setAttribute(
0981:                                    "javax.servlet.request.X509Certificate",
0982:                                    ssess.getPeerCertificateChain());
0983:                        } catch (SSLPeerUnverifiedException e) {
0984:                        }
0985:                    }
0986:                }
0987:            }
0988:
0989:            protected SimpleFilterChain buildFilterChain(String servletName,
0990:                    String requestPath, DispatchFilterType filterType) {
0991:                SimpleFilterChain sfc = new SimpleFilterChain();
0992:                // add path filters
0993:                if (requestPath != null)
0994:                    for (FilterAccessDescriptor fad : filters)
0995:                        if (fad.matchDispatcher(filterType)
0996:                                && fad.matchPath(requestPath) >= 0)
0997:                            sfc.add(fad);
0998:                // add name filters
0999:                if (servletName != null)
1000:                    for (FilterAccessDescriptor fad : filters)
1001:                        if (fad.matchDispatcher(DispatchFilterType.REQUEST)
1002:                                && fad.matchServlet(servletName) >= 0)
1003:                            sfc.add(fad);
1004:                return sfc;
1005:            }
1006:
1007:            protected void returnFileContent(String path,
1008:                    HttpServletRequest req, HttpServletResponse res)
1009:                    throws IOException, ServletException {
1010:                // Note : can't call or forward to file servlet since it can be not installed
1011:                File fpath = new File(path);
1012:                if (fpath.isDirectory()) {
1013:                    File baseDir = fpath;
1014:                    for (String indexPage : welcomeFiles) {
1015:                        fpath = new File(baseDir, indexPage);
1016:                        if (fpath.exists() && fpath.isFile()) {
1017:                            if (indexPage.charAt(0) != '/')
1018:                                indexPage = "/" + indexPage;
1019:                            RequestDispatcher rd = req
1020:                                    .getRequestDispatcher(indexPage);
1021:                            if (rd != null) {
1022:                                rd.forward(req, res);
1023:                                return;
1024:                            }
1025:                            break;
1026:                        }
1027:                    }
1028:                }
1029:                if (fpath.exists() == false) {
1030:                    res.sendError(res.SC_NOT_FOUND);
1031:                    return;
1032:                }
1033:                if (fpath.isFile() == false) {
1034:                    res.sendError(res.SC_FORBIDDEN);
1035:                    return;
1036:                }
1037:
1038:                String temp = getMimeType(fpath.getName());
1039:                res.setContentType(temp);
1040:
1041:                long lastMod = fpath.lastModified();
1042:                res.setDateHeader("Last-modified", lastMod);
1043:                String ifModSinceStr = req.getHeader("If-Modified-Since");
1044:                long ifModSince = -1;
1045:                if (ifModSinceStr != null) {
1046:                    int semi = ifModSinceStr.indexOf(';');
1047:                    if (semi != -1)
1048:                        ifModSinceStr = ifModSinceStr.substring(0, semi);
1049:                    try {
1050:                        ifModSince = DateFormat.getDateInstance().parse(
1051:                                ifModSinceStr).getTime();
1052:                    } catch (Exception ignore) {
1053:                    }
1054:                }
1055:                if (ifModSince != -1 && ifModSince >= lastMod) {
1056:                    res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
1057:                    return;
1058:                }
1059:                // TODO add range handling
1060:                boolean doCompress = false;
1061:                if (applyCompression && temp != null && temp.startsWith("text")) {
1062:                    temp = req.getHeader("Accept-Encoding");
1063:                    if (temp != null && temp.indexOf("gzip") >= 0) {
1064:                        res.setHeader("Content-Encoding", "gzip");
1065:                        doCompress = true;
1066:                    }
1067:                }
1068:
1069:                if ("HEAD".equals(req.getMethod())) {
1070:                    res.setHeader("Content-Length", Long.toString(fpath
1071:                            .length()));
1072:                    return;
1073:                }
1074:                OutputStream os = null;
1075:                InputStream is = null;
1076:                try {
1077:                    is = new FileInputStream(fpath);
1078:                    os = res.getOutputStream();
1079:                    if (doCompress)
1080:                        os = new GZIPOutputStream(os);
1081:                    else
1082:                        res.setHeader("Content-Length", Long.toString(fpath
1083:                                .length()));
1084:                    WarRoller.copyStream(is, os);
1085:                    if (doCompress)
1086:                        ((GZIPOutputStream) os).finish();
1087:                } catch (IllegalStateException ise) {
1088:                    // assure length
1089:                    res.setHeader("Content-Length", Long.toString(fpath
1090:                            .length()));
1091:                    PrintWriter pw = res.getWriter();
1092:                    // TODO decide on encoding/charset used by the reader
1093:                    String charSetName = res.getCharacterEncoding();
1094:                    if (charSetName == null)
1095:                        charSetName = Utils.ISO_8859_1;
1096:                    Utils
1097:                            .copyStream(new InputStreamReader(is, charSetName),
1098:                                    pw);
1099:                    // consider Writer is OK to do not close
1100:                    // consider underneath stream closing OK
1101:                } finally {
1102:                    try {
1103:                        is.close();
1104:                    } catch (Exception x) {
1105:                    }
1106:                    try {
1107:                        if (os != null)
1108:                            os.close();
1109:                    } catch (Exception x) {
1110:                    }
1111:                }
1112:
1113:            }
1114:
1115:            protected void addJSPServlet(List<String> patterns) {
1116:                ServletAccessDescr sad = createDescriptor();
1117:                // get class name from serve
1118:                sad.initParams = new HashMap<String, String>(10);
1119:                Map<String, String> arguments = (Map<String, String>) server.arguments;
1120:                sad.className = arguments.get(Serve.ARG_JSP);
1121:                if (sad.className == null) {
1122:                    sad.className = "org.gjt.jsp.JSPServlet";
1123:                    sad.initParams.put("repository", new File(deployDir, "~~~")
1124:                            .getPath());
1125:                    sad.initParams.put("debug", System.getProperty(getClass()
1126:                            .getName()
1127:                            + ".debug") != null ? "yes" : "no");
1128:                    sad.initParams.put("classloadername", WEBAPPCLASSLOADER);
1129:                } else {
1130:                    String pnpx = sad.className + '.';
1131:                    int cnl = pnpx.length();
1132:                    String classPath = Utils.calculateClassPath(ucl);
1133:                    for (String ipn : arguments.keySet())
1134:                        if (ipn.startsWith(pnpx))
1135:                            sad.initParams.put(ipn.substring(cnl),
1136:                                    arguments.get(ipn).replace("%context%",
1137:                                            contextName).replace("%deploydir%",
1138:                                            deployDir.getPath()).replace(
1139:                                            "%classloader%", WEBAPPCLASSLOADER)
1140:                                            .replace("%classpath%", classPath));
1141:                }
1142:                sad.descr = "JSP support servlet";
1143:                sad.label = "JSP";
1144:                sad.loadOnStart = false;
1145:                sad.name = "jsp";
1146:                String jspPat;
1147:                if (patterns == null || patterns.size() == 0)
1148:                    jspPat = "/.*\\.jsp";
1149:                else {
1150:                    jspPat = buildREbyPathPatt(patterns.get(0));
1151:                    for (int i = 1; i < patterns.size(); i++)
1152:                        jspPat += "|" + buildREbyPathPatt(patterns.get(i));
1153:                }
1154:                sad.add(new MappingEntry("/", jspPat));
1155:                servlets.add(sad);
1156:            }
1157:
1158:            protected ServletAccessDescr createDescriptor() {
1159:                return new ServletAccessDescr();
1160:            }
1161:
1162:            protected FilterAccessDescriptor createFilterDescriptor() {
1163:                return new FilterAccessDescriptor();
1164:            }
1165:
1166:            protected void makeCP(File dd) throws IOException {
1167:                deployDir = dd.getCanonicalFile();
1168:                final List<URL> urls = new ArrayList<URL>();
1169:                // add servlet classes
1170:                ClassLoader cl = getClass().getClassLoader();
1171:                while (cl != null) {
1172:                    if (cl instanceof  URLClassLoader) {
1173:                        if (((URLClassLoader) cl)
1174:                                .findResource("javax/servlet/jsp/JspPage.class") != null
1175:                                || ((URLClassLoader) cl)
1176:                                        .findResource("javax/servlet/http/HttpServlet.class") != null) {
1177:                            for (URL url : ((URLClassLoader) cl).getURLs())
1178:                                urls.add(url);
1179:                        }
1180:                    }
1181:                    cl = cl.getParent();
1182:                }
1183:                File classesFile = new File(deployDir, "WEB-INF/classes");
1184:                if (classesFile.exists() && classesFile.isDirectory())
1185:                    try {
1186:                        urls.add(classesFile.toURL());
1187:                    } catch (java.net.MalformedURLException mfe) {
1188:
1189:                    }
1190:                File libFile = new File(deployDir, "WEB-INF/lib");
1191:                libFile.listFiles(new FileFilter() {
1192:                    public boolean accept(File file) {
1193:                        String name = file.getName().toLowerCase();
1194:                        if (name.endsWith(".jar") || name.endsWith(".zip"))
1195:                            try {
1196:                                urls.add(file.toURL());
1197:                            } catch (java.net.MalformedURLException mfe) {
1198:
1199:                            }
1200:                        return false;
1201:                    }
1202:                });
1203:                cpUrls = urls.toArray(new URL[urls.size()]);
1204:                //ucl = URLClassLoader.newInstance(cpUrls, getClass().getClassLoader());
1205:                ucl = new URLClassLoader(cpUrls, getClass().getClassLoader()) {
1206:                    @Override
1207:                    public URL getResource(String name) {
1208:                        URL url = super .getResource(name);
1209:
1210:                        if (url == null && name.startsWith("/")) {
1211:                            url = super .getResource(name.substring(1));
1212:                        }
1213:                        return url;
1214:                    }
1215:                };
1216:
1217:                setAttribute(WEBAPPCLASSLOADER, ucl);
1218:                // System.err.println("CP "+urls+"\nLoader:"+ucl);
1219:            }
1220:
1221:            protected Servlet newInstance(final ServletAccessDescr descr)
1222:                    throws ServletException {
1223:                try {
1224:                    // System.err.printf("new instance %s %s%n", descr.className, Arrays.toString(ucl.getURLs()));
1225:                    final Servlet servlet = (Servlet) ucl.loadClass(
1226:                            descr.className).newInstance();
1227:                    final ServletException[] exHolder = new ServletException[1];
1228:                    Thread initThread = new Thread("Init thread of "
1229:                            + contextName) {
1230:                        public void run() {
1231:                            try {
1232:                                servlet.init(descr);
1233:                            } catch (ServletException se) {
1234:                                exHolder[0] = se;
1235:                            }
1236:                        }
1237:                    };
1238:                    initThread.start();
1239:                    initThread.join(initTimeout * 1000);
1240:                    if (initThread.isAlive() == true)
1241:                        throw new ServletException("Init of " + contextName
1242:                                + " exceeded allocated time (" + initTimeout
1243:                                + " secs)");
1244:                    if (exHolder[0] != null)
1245:                        throw exHolder[0];
1246:                    descr.instance = servlet;
1247:                    return descr.instance;
1248:                    // TODO think about setting back context loader
1249:                } catch (InstantiationException ie) {
1250:                    throw new ServletException("Servlet class "
1251:                            + descr.className + " can't instantiate. ", ie);
1252:                } catch (IllegalAccessException iae) {
1253:                    throw new ServletException("Servlet class "
1254:                            + descr.className + " can't access. ", iae);
1255:                } catch (ClassNotFoundException cnfe) {
1256:                    log("", cnfe);
1257:                    throw new ServletException("Servlet class "
1258:                            + descr.className + " not found. ", cnfe);
1259:                } catch (Error e) {
1260:                    throw new ServletException(
1261:                            "Servlet class "
1262:                                    + descr.className
1263:                                    + " can't be instantiated or initialized due an error.",
1264:                            e);
1265:                } catch (Throwable t) {
1266:                    if (t instanceof  ThreadDeath)
1267:                        throw (ThreadDeath) t;
1268:                    throw new ServletException(
1269:                            "Servlet class "
1270:                                    + descr.className
1271:                                    + " can't be instantiated or initialized due an exception.",
1272:                            t);
1273:                }
1274:            }
1275:
1276:            protected Filter newFilterInstance(FilterAccessDescriptor descr)
1277:                    throws ServletException {
1278:                try {
1279:                    descr.filterInstance = (Filter) ucl.loadClass(
1280:                            descr.className).newInstance();
1281:                    descr.filterInstance.init(descr);
1282:                } catch (InstantiationException ie) {
1283:                    throw new ServletException("Filter class "
1284:                            + descr.className + " can't instantiate. ", ie);
1285:                } catch (IllegalAccessException iae) {
1286:                    throw new ServletException("Filter class "
1287:                            + descr.className + " can't access. ", iae);
1288:                } catch (ClassNotFoundException cnfe) {
1289:                    throw new ServletException("Filter class "
1290:                            + descr.className + " not found. ", cnfe);
1291:                }
1292:                return descr.filterInstance;
1293:            }
1294:
1295:            /*
1296:             * protected URL toURL(File file) throws MalformedURLException { System.err.println("file:/"+file.getAbsolutePath()+(file.isDirectory()?"/":"")); return new
1297:             * URL("file:/"+file.getAbsolutePath()+(file.isDirectory()?"/":"")); }
1298:             */
1299:
1300:            // /////////////////////////////////////////////////////////////////////////////////
1301:            // context methods
1302:            public String getContextPath() {
1303:                return contextPath;
1304:            }
1305:
1306:            public String getServletContextName() {
1307:                return contextName;
1308:            }
1309:
1310:            public void removeAttribute(java.lang.String name) {
1311:                Object value = attributes.remove(name);
1312:                if (listeners != null)
1313:                    for (EventListener listener : listeners)
1314:                        if (listener instanceof  ServletContextAttributeListener)
1315:                            ((ServletContextAttributeListener) listener)
1316:                                    .attributeRemoved(new ServletContextAttributeEvent(
1317:                                            this , name, value));
1318:            }
1319:
1320:            public void setAttribute(java.lang.String name,
1321:                    java.lang.Object object) {
1322:                // log("Set attr:"+name+" to "+object);
1323:                if (object == null) {
1324:                    removeAttribute(name);
1325:                    return;
1326:                }
1327:                Object oldObj = attributes.put(name, object);
1328:                if (listeners != null)
1329:                    for (EventListener listener : listeners) {
1330:                        if (listener instanceof  ServletContextAttributeListener)
1331:                            if (oldObj == null)
1332:                                ((ServletContextAttributeListener) listener)
1333:                                        .attributeAdded(new ServletContextAttributeEvent(
1334:                                                this , name, object));
1335:                            else
1336:                                ((ServletContextAttributeListener) listener)
1337:                                        .attributeReplaced(new ServletContextAttributeEvent(
1338:                                                this , name, object));
1339:                    }
1340:            }
1341:
1342:            public java.util.Enumeration getAttributeNames() {
1343:                return attributes.keys();
1344:            }
1345:
1346:            public java.lang.Object getAttribute(java.lang.String name) {
1347:                // log("context: "+this+" return attr:"+name+" as "+attributes.get(name));
1348:                return attributes.get(name);
1349:            }
1350:
1351:            public java.lang.String getServerInfo() {
1352:                return "TJWS/J2EE container, Copyright &copy; 2008 Dmitriy Rogatkin";
1353:            }
1354:
1355:            public java.lang.String getRealPath(java.lang.String path) {
1356:                path = validatePath(path);
1357:                if (path == null)
1358:                    return deployDir.toString();
1359:                else
1360:                    return new File(deployDir, path).toString();
1361:            }
1362:
1363:            public void log(java.lang.String msg) {
1364:                server.log((contextName == null ? "" : contextName) + "> "
1365:                        + msg);
1366:            }
1367:
1368:            public void log(java.lang.Exception exception, java.lang.String msg) {
1369:                server.log(exception, (contextName == null ? "" : contextName)
1370:                        + "> " + msg);
1371:            }
1372:
1373:            public void log(java.lang.String message,
1374:                    java.lang.Throwable throwable) {
1375:                server.log((contextName == null ? "" : contextName) + "> "
1376:                        + message, throwable);
1377:            }
1378:
1379:            public java.util.Enumeration getServletNames() {
1380:                Vector<String> result = new Vector<String>();
1381:                for (ServletAccessDescr sad : servlets)
1382:                    result.add(sad.name);
1383:                return result.elements();
1384:            }
1385:
1386:            public java.util.Enumeration getServlets() {
1387:                Vector<Servlet> result = new Vector<Servlet>();
1388:                for (ServletAccessDescr sad : servlets)
1389:                    result.add(sad.instance);
1390:                return result.elements();
1391:
1392:            }
1393:
1394:            public Servlet getServlet(java.lang.String name)
1395:                    throws ServletException {
1396:                for (ServletAccessDescr sad : servlets)
1397:                    if (name.equals(sad.name))
1398:                        return sad.instance;
1399:                throw new ServletException("No servlet " + name);
1400:            }
1401:
1402:            public RequestDispatcher getNamedDispatcher(java.lang.String name) {
1403:                for (ServletAccessDescr sad : servlets)
1404:                    if (name.equals(sad.name)) {
1405:                        if (sad.instance == null && sad.loadOnStart == false)
1406:                            try {
1407:                                newInstance(sad);
1408:                            } catch (ServletException se) {
1409:                            }
1410:                        if (sad.instance != null)
1411:                            return new SimpleDispatcher(name, sad.instance);
1412:                        else
1413:                            break;
1414:                    }
1415:                return null;
1416:            }
1417:
1418:            public RequestDispatcher getRequestDispatcher(java.lang.String path) {
1419:                if (_DEBUG)
1420:                    System.err.printf("getRequestDispatcher(%s)%n", path);
1421:                if (path == null || path.length() == 0 || path.charAt(0) != '/')
1422:                    return null; // path must start with / for call from context
1423:                // look for servlets first
1424:                int sp = path.indexOf('?');
1425:                if (sp < 0)
1426:                    sp = path.indexOf('#'); // exclude possible fragment
1427:                // if (sp < 0)
1428:                // sp = path.indexOf(Serve.ServeConnection.SESSION_URL_NAME);
1429:                String clearPath = sp < 0 ? path : path.substring(0, sp);
1430:                for (ServletAccessDescr sad : servlets) {
1431:                    if (_DEBUG)
1432:                        System.err
1433:                                .printf(
1434:                                        "For dispatcher trying match %s (%s) %s = %b%n",
1435:                                        path, clearPath, Arrays
1436:                                                .toString(sad.mapping), sad
1437:                                                .matchPath(clearPath));
1438:                    int patIndex;
1439:                    if ((patIndex = sad.matchPath(clearPath)) >= 0) {
1440:                        if (sad.instance == null && sad.loadOnStart == false)
1441:                            try {
1442:                                synchronized (sad) {
1443:                                    if (sad.instance == null)
1444:                                        newInstance(sad);
1445:                                }
1446:                            } catch (ServletException se) {
1447:                                log(
1448:                                        String
1449:                                                .format(
1450:                                                        "Can't instantiate an instance of %s exception %s",
1451:                                                        sad, se), se
1452:                                                .getRootCause());
1453:                            }
1454:                        if (sad.instance != null)
1455:                            return new SimpleDispatcher(sad.instance,
1456:                                    sad.mapping[patIndex].servPath, path);
1457:                        else
1458:                            return null; // servlet not working
1459:                    }
1460:                }
1461:                // no matching servlets, check for resources
1462:                try {
1463:                    if (_DEBUG)
1464:                        System.err.printf("Dispatching to resource %s%n", path);
1465:                    if (getResource(path) == null)
1466:                        throw new MalformedURLException(); // check path is valid
1467:                    return new SimpleDispatcher(new HttpServlet() {
1468:                        public void service(ServletRequest req,
1469:                                ServletResponse res) throws ServletException,
1470:                                IOException {
1471:                            String path;
1472:                            if (((HttpServletRequest) req)
1473:                                    .getAttribute("javax.servlet.include.request_uri") != null)
1474:                                path = req
1475:                                        .getRealPath((String) req
1476:                                                .getAttribute("javax.servlet.include.path_info"));
1477:                            else
1478:                                path = ((HttpServletRequest) req)
1479:                                        .getPathTranslated();
1480:                            if (_DEBUG)
1481:                                System.err
1482:                                        .printf(
1483:                                                "Dispatched file servlet for %s translated %s%n",
1484:                                                path,
1485:                                                ((HttpServletRequest) req)
1486:                                                        .getPathTranslated());
1487:                            returnFileContent(path, (HttpServletRequest) req,
1488:                                    (HttpServletResponse) res);
1489:                        }
1490:                    }, path);
1491:                } catch (MalformedURLException mfe) {
1492:                }
1493:                return null;
1494:            }
1495:
1496:            public java.io.InputStream getResourceAsStream(java.lang.String path) {
1497:                try {
1498:                    return getResource(path).openStream();
1499:                } catch (NullPointerException npe) {
1500:                    if (_DEBUG)
1501:                        System.err.println("URL can't be created for :" + path);
1502:                } catch (IOException ioe) {
1503:                    if (_DEBUG)
1504:                        ioe.printStackTrace();
1505:                }
1506:                return null;
1507:            }
1508:
1509:            public java.net.URL getResource(java.lang.String path)
1510:                    throws java.net.MalformedURLException {
1511:                if (path.charAt(0) != '/')
1512:                    throw new MalformedURLException("Path: " + path
1513:                            + " has to start with '/'");
1514:                int pp = path.indexOf('?');
1515:                // no check for # ?
1516:                try {
1517:                    return new File(getRealPath((pp > 0 ? path.substring(0, pp)
1518:                            : path))).getCanonicalFile().toURL();
1519:                } catch (IOException io) {
1520:                }
1521:                return null;
1522:            }
1523:
1524:            public java.util.Set getResourcePaths(java.lang.String path) {
1525:                if (path.charAt(0) != '/')
1526:                    throw new IllegalArgumentException(
1527:                            "getResourcePaths: path parameters must begin with '/'");
1528:                int pp = path.indexOf('?');
1529:                if (pp > 0)
1530:                    path = path.substring(0, pp);
1531:                File dir = new File(getRealPath(path));
1532:                if (dir.exists() == false || dir.isDirectory() == false)
1533:                    return null;
1534:                Set<String> set = new TreeSet<String>();
1535:                String[] els = dir.list();
1536:                for (String el : els) {
1537:                    String fp = path + "/" + el;
1538:                    if (new File(getRealPath(fp)).isDirectory())
1539:                        fp += "/";
1540:                    set.add("/" + fp);
1541:                }
1542:                return set;
1543:            }
1544:
1545:            public java.lang.String getMimeType(java.lang.String file) {
1546:                if (mimes != null && file != null) {
1547:                    int p = file.lastIndexOf('.');
1548:                    if (p > 0) {
1549:                        String result = mimes.get(file.substring(p)
1550:                                .toLowerCase());
1551:                        if (result != null)
1552:                            return result;
1553:                    }
1554:                }
1555:                return server.getMimeType(file);
1556:            }
1557:
1558:            public int getMinorVersion() {
1559:                return 5;
1560:            }
1561:
1562:            public int getMajorVersion() {
1563:                return 2;
1564:            }
1565:
1566:            public ServletContext getContext(java.lang.String uripath) {
1567:                Servlet servlet = server.getServlet(uripath);
1568:                if (servlet != null)
1569:                    return servlet.getServletConfig().getServletContext();
1570:                return null;
1571:            }
1572:
1573:            public java.lang.String getInitParameter(java.lang.String name) {
1574:                return contextParameters.get(name);
1575:            }
1576:
1577:            public java.util.Enumeration getInitParameterNames() {
1578:                return contextParameters.keys();
1579:            }
1580:
1581:            protected void setErrorAttributes(ServletRequest req, int status,
1582:                    String msg, String servletName, String requestURI,
1583:                    Throwable t, Class eclass) {
1584:                req.setAttribute("javax.servlet.error.status_code", status);
1585:                req.setAttribute("javax.servlet.error.exception_type ", eclass);
1586:                req.setAttribute("javax.servlet.error.message", msg);
1587:                req.setAttribute("javax.servlet.error.exception", t);
1588:                req.setAttribute("javax.servlet.error.request_uri", requestURI);
1589:                req.setAttribute("javax.servlet.error.servlet_name",
1590:                        servletName);
1591:            }
1592:
1593:            public static String validatePath(String path) {
1594:                return Utils.canonicalizePath(path);
1595:            }
1596:
1597:            public void destroy() {
1598:                Thread.currentThread().setContextClassLoader(ucl);
1599:                if (filters != null)
1600:                    for (FilterAccessDescriptor fad : filters)
1601:                        if (fad.filterInstance != null)
1602:                            fad.filterInstance.destroy();
1603:                for (ServletAccessDescr sad : servlets)
1604:                    if (sad.instance != null)
1605:                        sad.instance.destroy();
1606:                if (listeners != null)
1607:                    for (int i = listeners.size() - 1; i > -1; i--) {
1608:                        EventListener listener = listeners.get(i);
1609:                        if (listener instanceof  ServletContextListener)
1610:                            ((ServletContextListener) listener)
1611:                                    .contextDestroyed(new ServletContextEvent(
1612:                                            this ));
1613:                    }
1614:                Enumeration e = getAttributeNames();
1615:                while (e.hasMoreElements())
1616:                    removeAttribute((String) e.nextElement());
1617:                // log("Destroy");
1618:            }
1619:
1620:            protected class SimpleDispatcher implements  RequestDispatcher {
1621:                Servlet servlet;
1622:
1623:                String servletPath;
1624:
1625:                String path;
1626:
1627:                String named;
1628:
1629:                SimpleDispatcher(Servlet s, String p) {
1630:                    this (s, null, p);
1631:                }
1632:
1633:                SimpleDispatcher(String n, Servlet s) {
1634:                    this (s, null, null);
1635:                    named = n;
1636:                }
1637:
1638:                SimpleDispatcher(Servlet s, String sp, String p) {
1639:                    servlet = s;
1640:                    path = p;
1641:                    servletPath = sp;
1642:                    //if (servletPath.length() > 1 && servletPath.endsWith("/"))
1643:                    //	servletPath = servletPath.substring(0, servletPath.length()-1);
1644:                    // ending '/' adjustment done on demand
1645:                }
1646:
1647:                // //////////////////////////////////////////////////////////////////
1648:                // interface RequestDispatcher
1649:
1650:                public void forward(ServletRequest request,
1651:                        ServletResponse response) throws ServletException,
1652:                        java.io.IOException {
1653:                    if (_DEBUG)
1654:                        System.err.printf("FORWARD path: %s, servlet: %s%n",
1655:                                path, servlet);
1656:                    response.reset(); // drop all previously putting data and headers
1657:                    SimpleFilterChain sfc = buildFilterChain(
1658:                            named,
1659:                            path,
1660:                            request
1661:                                    .getAttribute("javax.servlet.error.status_code") == null ? DispatchFilterType.FORWARD
1662:                                    : DispatchFilterType.ERROR);
1663:                    sfc.setServlet(servlet);
1664:                    sfc.reset();
1665:                    sfc.doFilter(new DispatchedRequest(
1666:                            (HttpServletRequest) request, true), response);
1667:                    // servlet.service(new DispatchedRequest((HttpServletRequest) request, true), response);
1668:                    Serve.ServeConnection scon = toServeConnection(response);
1669:                    if (scon != null)
1670:                        scon.closeStreams();
1671:                }
1672:
1673:                public void include(ServletRequest request,
1674:                        final ServletResponse response)
1675:                        throws ServletException, java.io.IOException {
1676:                    Serve.ServeConnection scon = toServeConnection(response);
1677:                    if (scon != null)
1678:                        scon.setInInclude(true);
1679:                    if (_DEBUG)
1680:                        System.err
1681:                                .printf(
1682:                                        "INCLUDE path: %s, servlet: %s, servlet path %s%n",
1683:                                        path, servlet, servletPath);
1684:                    try {
1685:                        SimpleFilterChain sfc = buildFilterChain(named, path,
1686:                                DispatchFilterType.INCLUDE);
1687:                        sfc.setServlet(servlet);
1688:                        sfc.reset();
1689:                        sfc.doFilter(new DispatchedRequest(
1690:                                (HttpServletRequest) request, false),
1691:                                new HttpServletResponseWrapper(
1692:                                        (HttpServletResponse) response) {
1693:                                    // TODO review match to 2.5, some calls are allowed now
1694:                                    public void addDateHeader(
1695:                                            java.lang.String name, long date) {
1696:                                    }
1697:
1698:                                    public void setDateHeader(
1699:                                            java.lang.String name, long date) {
1700:                                    }
1701:
1702:                                    public void setHeader(
1703:                                            java.lang.String name,
1704:                                            java.lang.String value) {
1705:                                    }
1706:
1707:                                    public void addHeader(
1708:                                            java.lang.String name,
1709:                                            java.lang.String value) {
1710:                                    }
1711:
1712:                                    public void setIntHeader(
1713:                                            java.lang.String name, int value) {
1714:                                    }
1715:
1716:                                    public void addIntHeader(
1717:                                            java.lang.String name, int value) {
1718:                                    }
1719:
1720:                                    public void setStatus(int sc) {
1721:                                    }
1722:
1723:                                    public void setStatus(int sc,
1724:                                            java.lang.String sm) {
1725:                                    }
1726:
1727:                                    public void sendRedirect(
1728:                                            java.lang.String location)
1729:                                            throws java.io.IOException {
1730:                                    }
1731:
1732:                                    public void sendError(int sc)
1733:                                            throws java.io.IOException {
1734:                                    }
1735:
1736:                                    public void sendError(int sc,
1737:                                            java.lang.String msg)
1738:                                            throws java.io.IOException {
1739:                                    }
1740:
1741:                                    public void reset() {
1742:                                    }
1743:
1744:                                    public void setLocale(java.util.Locale loc) {
1745:                                    }
1746:
1747:                                    public void resetBuffer() {
1748:                                    }
1749:
1750:                                    public void setContentType(
1751:                                            java.lang.String type) {
1752:                                    }
1753:
1754:                                    public void setContentLength(int len) {
1755:                                    }
1756:
1757:                                    public void setCharacterEncoding(
1758:                                            java.lang.String charset) {
1759:                                    }
1760:                                });
1761:                    } finally {
1762:                        if (scon != null)
1763:                            scon.setInInclude(false);
1764:                    }
1765:                }
1766:
1767:                class DispatchedRequest extends HttpServletRequestWrapper {
1768:                    boolean forward;
1769:
1770:                    DispatchedRequest(HttpServletRequest request,
1771:                            boolean forward) {
1772:                        super (request);
1773:                        this .forward = forward;
1774:                    }
1775:
1776:                    public java.lang.String getPathInfo() {
1777:                        if (forward)
1778:                            return getPathInfo1();
1779:                        return super .getPathInfo();
1780:                    }
1781:
1782:                    public java.lang.String getPathInfo1() {
1783:                        if (path == null)
1784:                            return super .getPathInfo();
1785:                        if (path.equals("/") || "/".equals(servletPath))
1786:                            return null;
1787:                        int qp = path.indexOf('?');
1788:                        int sp = servletPath == null ? -1 : path
1789:                                .indexOf(servletPath);
1790:                        if (sp >= 0) {
1791:                            sp += servletPath.length()
1792:                                    - (servletPath.endsWith("/") ? 1 : 0);
1793:                            if (_DEBUG)
1794:                                System.err
1795:                                        .printf(
1796:                                                "FORWARD get pathinfo path %s, servlet %s, sp %d, qp %d, res %s%n",
1797:                                                path, servletPath, sp, qp, path
1798:                                                        .substring(sp));
1799:                            if (qp > sp)
1800:                                return path.substring(sp, qp);
1801:                            else
1802:                                return path.substring(sp);
1803:                        }
1804:                        if (_DEBUG)
1805:                            System.err.printf("FORWARD get pathinfo ret: %s%n",
1806:                                    path);
1807:                        return path;
1808:                    }
1809:
1810:                    public java.lang.String getPathTranslated() {
1811:                        return getRealPath(getPathInfo());
1812:                    }
1813:
1814:                    public java.lang.String getRealPath(java.lang.String path) {
1815:                        return WebAppServlet.this .getRealPath(path);
1816:                    }
1817:
1818:                    public String getServletPath() {
1819:                        if (forward)
1820:                            return getServletPath1();
1821:                        return super .getServletPath();
1822:                    }
1823:
1824:                    public String getServletPath1() {
1825:                        if (servletPath != null)
1826:                            if (servletPath.equals("/"))
1827:                                return path;
1828:                            else
1829:                                return servletPath.endsWith("/") ? servletPath
1830:                                        .substring(0, servletPath.length() - 1)
1831:                                        : servletPath;
1832:                        return super .getServletPath();
1833:                    }
1834:
1835:                    public String getRequestURI1() {
1836:                        if (path == null)
1837:                            if (servletPath != null)
1838:                                return servletPath;
1839:                            else
1840:                                return null;
1841:                        int qp = path.indexOf('?');
1842:                        if (qp > 0)
1843:                            return path.substring(0, qp);
1844:                        return path;
1845:                    }
1846:
1847:                    public String getRequestURI() {
1848:                        if (forward)
1849:                            return getRequestURI1();
1850:                        return super .getRequestURI();
1851:                    }
1852:
1853:                    public String getContextPath() {
1854:                        return contextPath;
1855:                    }
1856:
1857:                    public String getQueryString1() {
1858:                        if (path == null)
1859:                            return null;
1860:                        int qp = path.indexOf('?');
1861:                        if (qp > 0 && qp < path.length() - 1)
1862:                            return path.substring(qp + 1);
1863:                        return null;
1864:                    }
1865:
1866:                    public String getQueryString() {
1867:                        if (forward)
1868:                            return getQueryString1();
1869:                        return super .getQueryString();
1870:                    }
1871:
1872:                    public java.util.Enumeration getAttributeNames() {
1873:                        List<String> attributes = new ArrayList<String>(10);
1874:                        if (named == null) {
1875:                            if (forward) {
1876:                                attributes
1877:                                        .add("javax.servlet.forward.request_uri");
1878:                                attributes
1879:                                        .add("javax.servlet.forward.context_path");
1880:                                attributes
1881:                                        .add("javax.servlet.forward.servlet_path");
1882:                                attributes
1883:                                        .add("javax.servlet.forward.path_info");
1884:                                attributes
1885:                                        .add("javax.servlet.forward.query_string");
1886:                            } else {
1887:                                attributes
1888:                                        .add("javax.servlet.include.request_uri");
1889:                                attributes
1890:                                        .add("javax.servlet.include.path_info");
1891:                                attributes
1892:                                        .add("javax.servlet.include.context_path");
1893:                                attributes
1894:                                        .add("javax.servlet.include.servlet_path");
1895:                                attributes
1896:                                        .add("javax.servlet.include.query_string");
1897:                            }
1898:                        }
1899:                        Enumeration e = super .getAttributeNames();
1900:                        while (e.hasMoreElements())
1901:                            attributes.add((String) e.nextElement());
1902:                        return Collections.enumeration(attributes);
1903:                    }
1904:
1905:                    public Object getAttribute(String name) {
1906:                        if (named == null) {
1907:                            if (forward) {
1908:                                if ("javax.servlet.forward.request_uri"
1909:                                        .equals(name))
1910:                                    return super .getRequestURI();
1911:                                else if ("javax.servlet.forward.context_path"
1912:                                        .equals(name))
1913:                                    return super .getContextPath();
1914:                                else if ("javax.servlet.forward.servlet_path"
1915:                                        .equals(name))
1916:                                    return super .getServletPath();
1917:                                else if ("javax.servlet.forward.path_info"
1918:                                        .equals(name))
1919:                                    return super .getPathInfo();
1920:                                else if ("javax.servlet.forward.query_string"
1921:                                        .equals(name))
1922:                                    return super .getQueryString();
1923:                            } else {
1924:                                if ("javax.servlet.include.request_uri"
1925:                                        .equals(name))
1926:                                    return getRequestURI1();
1927:                                else if ("javax.servlet.include.path_info"
1928:                                        .equals(name))
1929:                                    return getPathInfo1();
1930:                                else if ("javax.servlet.include.context_path"
1931:                                        .equals(name))
1932:                                    return getContextPath();
1933:                                else if ("javax.servlet.include.query_string"
1934:                                        .equals(name))
1935:                                    return getQueryString1();
1936:                                else if ("javax.servlet.include.servlet_path"
1937:                                        .equals(name))
1938:                                    return getServletPath1();
1939:                            }
1940:                        }
1941:                        // System.err.printf("!!!return attr:%s=%s%n", name, super.getAttribute(name));
1942:                        return super .getAttribute(name);
1943:                    }
1944:
1945:                    // @Override
1946:                    // public void setAttribute(String name, Object value) {
1947:                    //    System.err.printf("!!!Set attr %s=%s%n", name, value);
1948:                    //    super.setAttribute(name, value);
1949:                    // }
1950:
1951:                    @Override
1952:                    public RequestDispatcher getRequestDispatcher(String path) {
1953:                        if (_DEBUG)
1954:                            System.err
1955:                                    .printf(
1956:                                            "Request %s processing requested from %s%n",
1957:                                            path, forward ? "FORWARD"
1958:                                                    : "INCLUDE");
1959:                        if (path.charAt(0) != '/')
1960:                            path = getServletPath() + '/' + path;
1961:                        return WebAppServlet.this .getRequestDispatcher(path);
1962:                    }
1963:
1964:                    public String getParameter(String name) {
1965:                        Map<String, String[]> params = createParameters();
1966:                        String[] result = params.get(name);
1967:                        if (result != null)
1968:                            return result[0];
1969:                        return super .getParameter(name);
1970:                    }
1971:
1972:                    public Map getParameterMap() {
1973:                        Map result = super .getParameterMap();
1974:                        result.putAll(createParameters());
1975:                        return result;
1976:                    }
1977:
1978:                    public Enumeration getParameterNames() {
1979:                        Map params = getParameterMap();
1980:                        Hashtable result = new Hashtable();
1981:                        result.putAll(params);
1982:                        return result.keys();
1983:                    }
1984:
1985:                    public String[] getParameterValues(String name) {
1986:                        Map<String, String[]> params = createParameters();
1987:                        String[] result = params.get(name);
1988:                        if (result != null)
1989:                            return result;
1990:                        return super .getParameterValues(name);
1991:                    }
1992:
1993:                    protected Map<String, String[]> createParameters() {
1994:                        String query = getQueryString();
1995:                        if (query != null)
1996:                            return Acme.Utils.parseQueryString(query, null);
1997:                        return new Hashtable<String, String[]>();
1998:                    }
1999:                }
2000:            }
2001:
2002:            // ////////////// Filter methods /////////////////////
2003:            protected class WebAppContextFilter implements  Filter {
2004:                String servPathHolder;
2005:
2006:                WebAppContextFilter(String servletPath) {
2007:                    if (servletPath != null)
2008:                        servPathHolder = servletPath;
2009:                    else
2010:                        throw new NullPointerException("Servlet path is null");
2011:                }
2012:
2013:                WebAppContextFilter() {
2014:                    this ("/");
2015:                }
2016:
2017:                public void init(FilterConfig filterConfig)
2018:                        throws ServletException {
2019:                }
2020:
2021:                public void doFilter(final ServletRequest request,
2022:                        ServletResponse response, FilterChain chain)
2023:                        throws java.io.IOException, ServletException {
2024:                    final HttpServletRequest hreq = (HttpServletRequest) request;
2025:                    final HttpServletResponse hres = (HttpServletResponse) response;
2026:                    chain
2027:                            .doFilter(
2028:                                    (HttpServletRequest) Proxy
2029:                                            .newProxyInstance(
2030:                                                    javax.servlet.http.HttpServletRequest.class
2031:                                                            .getClassLoader(),
2032:                                                    new Class[] {
2033:                                                            javax.servlet.http.HttpServletRequest.class,
2034:                                                            Openable.class },
2035:                                                    new InvocationHandler() {
2036:                                                        public Object invoke(
2037:                                                                Object proxy,
2038:                                                                Method method,
2039:                                                                Object[] args)
2040:                                                                throws Throwable {
2041:                                                            String mn = method
2042:                                                                    .getName();
2043:                                                            if (mn
2044:                                                                    .equals("getServletPath")) {
2045:                                                                if (_DEBUG)
2046:                                                                    System.err
2047:                                                                            .println("getServletPath() "
2048:                                                                                    + extractPath(
2049:                                                                                            hreq
2050:                                                                                                    .getRequestURI(),
2051:                                                                                            contextPath,
2052:                                                                                            servPathHolder,
2053:                                                                                            false));
2054:                                                                return extractPath(
2055:                                                                        hreq
2056:                                                                                .getRequestURI(),
2057:                                                                        contextPath,
2058:                                                                        servPathHolder,
2059:                                                                        false);
2060:                                                            } else if (mn
2061:                                                                    .equals("getPathInfo")) {
2062:                                                                if (_DEBUG)
2063:                                                                    System.err
2064:                                                                            .println("getPathInfo() "
2065:                                                                                    + extractPath(
2066:                                                                                            hreq
2067:                                                                                                    .getRequestURI(),
2068:                                                                                            contextPath,
2069:                                                                                            servPathHolder,
2070:                                                                                            true));
2071:                                                                return extractPath(
2072:                                                                        hreq
2073:                                                                                .getRequestURI(),
2074:                                                                        contextPath,
2075:                                                                        servPathHolder,
2076:                                                                        true);
2077:                                                            } else if (mn
2078:                                                                    .equals("getRealPath")) {
2079:                                                                if (_DEBUG)
2080:                                                                    System.err
2081:                                                                            .println("Path:"
2082:                                                                                    + args[0]);
2083:                                                                return getRealPath((String) args[0]);
2084:                                                            } else if (mn
2085:                                                                    .equals("getPathTranslated")) {
2086:                                                                return getRealPath(hreq
2087:                                                                        .getPathInfo());
2088:                                                            } else if (mn
2089:                                                                    .equals("getRequestDispatcher")) {
2090:                                                                String url = (String) args[0];
2091:                                                                if (url
2092:                                                                        .charAt(0) != '/')
2093:                                                                    url = extractPath(
2094:                                                                            hreq
2095:                                                                                    .getRequestURI(),
2096:                                                                            contextPath,
2097:                                                                            servPathHolder,
2098:                                                                            false)
2099:                                                                            + '/'
2100:                                                                            + url;
2101:                                                                // System.err.printf("req.getDispatcher(%s), %s%n", url, extractPath(hreq.getRequestURI(), contextPath, servPathHolder, false));
2102:                                                                return getRequestDispatcher(url);
2103:                                                            } else if (mn
2104:                                                                    .equals("getContextPath")) {
2105:                                                                return contextPath;
2106:                                                            } else if (mn
2107:                                                                    .equals("getSession")) {
2108:                                                                // System.err.println("getsession");
2109:                                                                HttpSession session = (HttpSession) method
2110:                                                                        .invoke(
2111:                                                                                hreq,
2112:                                                                                args);
2113:                                                                // TODO some overhead is here, context and listeners will be overloaded each time
2114:                                                                // time of accessing session while it's new
2115:                                                                if (session instanceof  Serve.AcmeSession
2116:                                                                        && (session
2117:                                                                                .getServletContext() == null || session
2118:                                                                                .isNew())) {
2119:                                                                    // System.err.println("set listeners & context");
2120:                                                                    ((Serve.AcmeSession) session)
2121:                                                                            .setListeners(WebAppServlet.this .sessionListeners);
2122:                                                                    ((Serve.AcmeSession) session)
2123:                                                                            .setServletContext(WebAppServlet.this );
2124:                                                                    if (sessionTimeout > 0)
2125:                                                                        session
2126:                                                                                .setMaxInactiveInterval(sessionTimeout);
2127:                                                                }
2128:                                                                return session;
2129:                                                            } else if (attributeListeners != null) {
2130:                                                                if (mn
2131:                                                                        .equals("setAttribute")) {
2132:                                                                    Object av = hreq
2133:                                                                            .getAttribute((String) args[0]);
2134:                                                                    hreq
2135:                                                                            .setAttribute(
2136:                                                                                    (String) args[0],
2137:                                                                                    args[1]);
2138:                                                                    if (av == null) {
2139:                                                                        ServletRequestAttributeEvent e = new ServletRequestAttributeEvent(
2140:                                                                                WebAppServlet.this ,
2141:                                                                                hreq,
2142:                                                                                (String) args[0],
2143:                                                                                args[1]);
2144:                                                                        for (ServletRequestAttributeListener sarl : attributeListeners)
2145:                                                                            sarl
2146:                                                                                    .attributeAdded(e);
2147:                                                                    } else {
2148:                                                                        ServletRequestAttributeEvent e = new ServletRequestAttributeEvent(
2149:                                                                                WebAppServlet.this ,
2150:                                                                                hreq,
2151:                                                                                (String) args[0],
2152:                                                                                av);
2153:                                                                        for (ServletRequestAttributeListener sarl : attributeListeners)
2154:                                                                            sarl
2155:                                                                                    .attributeReplaced(e);
2156:                                                                    }
2157:                                                                    return null;
2158:                                                                } else if (mn
2159:                                                                        .equals("removeAttribute")) {
2160:                                                                    Object av = hreq
2161:                                                                            .getAttribute((String) args[0]);
2162:                                                                    hreq
2163:                                                                            .removeAttribute((String) args[0]);
2164:                                                                    ServletRequestAttributeEvent e = new ServletRequestAttributeEvent(
2165:                                                                            WebAppServlet.this ,
2166:                                                                            hreq,
2167:                                                                            (String) args[0],
2168:                                                                            av);
2169:                                                                    for (ServletRequestAttributeListener sarl : attributeListeners)
2170:                                                                        sarl
2171:                                                                                .attributeRemoved(e);
2172:                                                                    return null;
2173:                                                                } else if (mn
2174:                                                                        .equals("getOrigin")) {
2175:                                                                    Object origin = hreq;
2176:                                                                    while (origin instanceof  Openable)
2177:                                                                        origin = ((Openable) origin)
2178:                                                                                .getOrigin();
2179:                                                                    return origin;
2180:                                                                }
2181:                                                            }
2182:                                                            try {
2183:                                                                return method
2184:                                                                        .invoke(
2185:                                                                                hreq,
2186:                                                                                args);
2187:                                                            } catch (InvocationTargetException ite) {
2188:                                                                throw ite
2189:                                                                        .getTargetException();
2190:                                                            }
2191:                                                        }
2192:                                                    }), // response);
2193:                                    (HttpServletResponse) Proxy
2194:                                            .newProxyInstance(
2195:                                                    javax.servlet.http.HttpServletResponse.class
2196:                                                            .getClassLoader(),
2197:                                                    new Class[] {
2198:                                                            javax.servlet.http.HttpServletResponse.class,
2199:                                                            Openable.class },
2200:                                                    new InvocationHandler() {
2201:                                                        public Object invoke(
2202:                                                                Object proxy,
2203:                                                                Method method,
2204:                                                                Object[] args)
2205:                                                                throws Throwable {
2206:                                                            String mn = method
2207:                                                                    .getName();
2208:                                                            if (mn
2209:                                                                    .equals("sendError")) {
2210:                                                                if (errorPages != null)
2211:                                                                    for (ErrorPageDescr epd : errorPages)
2212:                                                                        if (epd.errorCode == ((Integer) args[0])
2213:                                                                                .intValue()) {
2214:                                                                            setErrorAttributes(
2215:                                                                                    hreq,
2216:                                                                                    (Integer) args[0],
2217:                                                                                    args.length > 1 ? (String) args[1]
2218:                                                                                            : "",
2219:                                                                                    getServletName(),
2220:                                                                                    hreq
2221:                                                                                            .getRequestURI(),
2222:                                                                                    null,
2223:                                                                                    null);
2224:                                                                            // System.err.printf("Forwarding to %s for %d%n",epd.errorPage, args[0]);
2225:                                                                            getRequestDispatcher(
2226:                                                                                    epd.errorPage)
2227:                                                                                    .forward(
2228:                                                                                            hreq,
2229:                                                                                            hres);
2230:                                                                            return null;
2231:                                                                        }
2232:                                                            } else if (mn
2233:                                                                    .equals("getOrigin")) {
2234:                                                                Object origin = hres;
2235:                                                                while (origin instanceof  Openable)
2236:                                                                    origin = ((Openable) origin)
2237:                                                                            .getOrigin();
2238:                                                                return origin;
2239:
2240:                                                            } // else if (mn.equals("sendRedirect")) {
2241:                                                            // System.err.printf("Redirect to:%s%n",args[0]);
2242:                                                            // }
2243:                                                            return method
2244:                                                                    .invoke(
2245:                                                                            hres,
2246:                                                                            args);
2247:                                                        }
2248:                                                    }));
2249:                }
2250:
2251:                public void destroy() {
2252:                    // destroy context filter
2253:                }
2254:            }
2255:
2256:            static public String extractPath(String uri, String context,
2257:                    String servlet, boolean info) {
2258:                if (_DEBUG)
2259:                    System.err
2260:                            .printf(
2261:                                    "Extract path URI: %s, context: %s, servlet: %s, action %b\n",
2262:                                    uri, context, servlet, info);
2263:                int sp = uri.indexOf(servlet, context.length());
2264:                if (sp < 0) {
2265:                    sp = context.length();
2266:                    /*
2267:                     * if (_DEBUG) System.err.printf("servlet pos: -1 %n"); if (info) return null; // invalid URI or too short return uri.substring(context.length());
2268:                     */
2269:                }
2270:                int pp = uri.indexOf('?', sp);
2271:                int ip = servlet.endsWith("/") ? sp + servlet.length() - 1
2272:                        : uri.indexOf('/', sp + servlet.length());
2273:                if (_DEBUG)
2274:                    System.err.printf(
2275:                            "servlet pos %d, info pos: %d, param pos: %d %n",
2276:                            sp, ip, pp);
2277:                if (info == false) {
2278:                    if (servlet.equals("/") || ip < 0)
2279:                        if (pp > 0)
2280:                            return uri.substring(sp, pp);
2281:                        else
2282:                            return uri.substring(sp);
2283:                    if (pp < 0)
2284:                        return uri.substring(sp, ip);
2285:
2286:                    return uri.substring(sp, pp);
2287:                }
2288:                if (servlet.equals("/") || ip < 0 || (pp > 0 && ip > pp))
2289:                    return null;
2290:                if (pp < 0)
2291:                    return uri.substring(ip);
2292:                return uri.substring(ip, pp);
2293:            }
2294:
2295:            protected class SimpleFilterChain implements  FilterChain {
2296:                List<FilterAccessDescriptor> filters;
2297:
2298:                Iterator<FilterAccessDescriptor> iterator;
2299:
2300:                Servlet servlet;
2301:
2302:                Filter filter;
2303:
2304:                Filter nextFilter;
2305:
2306:                ServletAccessDescr sad;
2307:
2308:                SimpleFilterChain() {
2309:                    filters = new ArrayList<FilterAccessDescriptor>();
2310:                }
2311:
2312:                public void setFilter(Filter filter) {
2313:                    this .filter = filter;
2314:                }
2315:
2316:                public void doFilter(ServletRequest request,
2317:                        ServletResponse response) throws java.io.IOException,
2318:                        ServletException {
2319:
2320:                    if (nextFilter != null) {
2321:                        nextFilter = null;
2322:                        filter.doFilter(request, response, this );
2323:                    } else if (iterator.hasNext()) {
2324:                        FilterAccessDescriptor fad = iterator.next();
2325:                        try {
2326:                            fad.filterInstance
2327:                                    .doFilter(request, response, this );
2328:                        } catch (UnavailableException ue) {
2329:                            if (ue.isPermanent()) {
2330:                                synchronized (fad) {
2331:                                    if (fad.filterInstance != null) {
2332:                                        fad.filterInstance.destroy();
2333:                                        fad.filterInstance = null;
2334:                                    }
2335:                                }
2336:                            } else {
2337:                                fad.timeToReactivate = System
2338:                                        .currentTimeMillis()
2339:                                        + ue.getUnavailableSeconds() * 1000l;
2340:                            }
2341:                            doFilter(request, response);
2342:                            // iterator.remove();
2343:                        }
2344:                    } else
2345:                        // TODO figure out error handler needed for filters, it should also handle UnavailableException
2346:                        // call sevlet
2347:                        try {
2348:                            servlet.service(request, response);
2349:                        } catch (IOException ioe) {
2350:                            if (handleError(ioe, request, response) == false)
2351:                                throw ioe;
2352:                        } catch (UnavailableException ue) {
2353:                            // log("Servlet " + servlet + " asked to be unavailable", ue);
2354:                            if (sad != null) {
2355:                                if (ue.isPermanent()) {
2356:                                    synchronized (sad) {
2357:                                        if (sad.instance != null) {
2358:                                            sad.instance.destroy();
2359:                                            sad.instance = null;
2360:                                        }
2361:                                    }
2362:                                } else {
2363:                                    sad.timeToReactivate = System
2364:                                            .currentTimeMillis()
2365:                                            + ue.getUnavailableSeconds()
2366:                                            * 1000l;
2367:                                }
2368:                            }
2369:                            ((HttpServletResponse) response).sendError(
2370:                                    HttpServletResponse.SC_SERVICE_UNAVAILABLE,
2371:                                    ue.getMessage());
2372:                            // allowing custom handling?
2373:                            // eating an exception to avoid removing entire webapp servlet throw ue;
2374:                        } catch (ServletException se) {
2375:                            if (handleError(se, request, response) == false)
2376:                                throw se;
2377:                        } catch (Throwable re) {
2378:                            if (re instanceof  ThreadDeath)
2379:                                throw (ThreadDeath) re;
2380:                            if (handleError(re, request, response) == false)
2381:                                throw new RuntimeException(re);
2382:                        }
2383:                }
2384:
2385:                protected boolean handleError(Throwable t,
2386:                        ServletRequest request, ServletResponse response)
2387:                        throws java.io.IOException, ServletException {
2388:                    if (errorPages != null) {
2389:                        Class eclass = t.getClass();
2390:                        for (ErrorPageDescr epd : errorPages) {
2391:                            if (epd.exception != null
2392:                                    && eclass.equals(epd.exception)) {
2393:                                log("forward to " + epd.errorPage, t);
2394:                                ((HttpServletResponse) response)
2395:                                        .sendRedirect(epd.errorPage);
2396:                                setErrorAttributes(request, -1, t.getMessage(),
2397:                                        getServletName(),
2398:                                        ((HttpServletRequest) request)
2399:                                                .getRequestURI(), t, t
2400:                                                .getClass());
2401:                                getRequestDispatcher(epd.errorPage).forward(
2402:                                        request, response);
2403:                                return true;
2404:                            }
2405:                        }
2406:                        Class[] peclasses = eclass.getClasses();
2407:                        for (Class peclass : peclasses)
2408:                            for (ErrorPageDescr epd : errorPages) {
2409:                                if (epd.exception != null
2410:                                        && peclass.equals(epd.exception)) {
2411:                                    log("forward to " + epd.errorPage, t);
2412:                                    ((HttpServletResponse) response)
2413:                                            .sendRedirect(epd.errorPage);
2414:                                    setErrorAttributes(request, -1, t
2415:                                            .getMessage(), getServletName(),
2416:                                            ((HttpServletRequest) request)
2417:                                                    .getRequestURI(), t, t
2418:                                                    .getClass());
2419:                                    getRequestDispatcher(epd.errorPage)
2420:                                            .forward(request, response);
2421:                                    return true;
2422:                                }
2423:                            }
2424:
2425:                    }
2426:                    return false;
2427:                }
2428:
2429:                protected void reset() {
2430:                    iterator = filters.iterator();
2431:                    nextFilter = filter;
2432:                }
2433:
2434:                protected void add(FilterAccessDescriptor fad) {
2435:                    if (fad.timeToReactivate > 0
2436:                            && fad.timeToReactivate > System
2437:                                    .currentTimeMillis())
2438:                        return;
2439:                    if (filters.contains(fad) == false)
2440:                        filters.add(fad);
2441:                }
2442:
2443:                protected void setServlet(Servlet servlet) {
2444:                    this .servlet = servlet;
2445:                }
2446:
2447:                protected void setServlet(ServletAccessDescr sad) {
2448:                    this .servlet = sad.instance;
2449:                    this .sad = sad;
2450:                }
2451:            }
2452:
2453:            private final static boolean _DEBUG = false;
2454:
2455:            private final static boolean __DEBUG = "yes".equals(System
2456:                    .getProperty(DEF_DEBUG));
2457:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.