Source Code Cross Referenced for WebAppConfiguration.java in  » Web-Server » Winstone » winstone » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


0001:        /*
0002:         * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
0003:         * Distributed under the terms of either:
0004:         * - the common development and distribution license (CDDL), v1.0; or
0005:         * - the GNU Lesser General Public License, v2.1 or later
0006:         */
0007:        package winstone;
0008:
0009:        import java.io.File;
0010:        import java.io.IOException;
0011:        import java.io.InputStream;
0012:        import java.io.PrintWriter;
0013:        import java.io.StringWriter;
0014:        import java.lang.reflect.Constructor;
0015:        import java.net.MalformedURLException;
0016:        import java.net.URL;
0017:        import java.net.URLClassLoader;
0018:        import java.util.ArrayList;
0019:        import java.util.Arrays;
0020:        import java.util.Collection;
0021:        import java.util.Collections;
0022:        import java.util.Comparator;
0023:        import java.util.Enumeration;
0024:        import java.util.HashMap;
0025:        import java.util.HashSet;
0026:        import java.util.Hashtable;
0027:        import java.util.Iterator;
0028:        import java.util.List;
0029:        import java.util.Map;
0030:        import java.util.Set;
0031:        import java.util.StringTokenizer;
0032:
0033:        import javax.servlet.ServletContext;
0034:        import javax.servlet.ServletContextAttributeEvent;
0035:        import javax.servlet.ServletContextAttributeListener;
0036:        import javax.servlet.ServletContextEvent;
0037:        import javax.servlet.ServletContextListener;
0038:        import javax.servlet.ServletException;
0039:        import javax.servlet.ServletRequestAttributeListener;
0040:        import javax.servlet.ServletRequestListener;
0041:        import javax.servlet.http.HttpServletResponse;
0042:        import javax.servlet.http.HttpSessionActivationListener;
0043:        import javax.servlet.http.HttpSessionAttributeListener;
0044:        import javax.servlet.http.HttpSessionListener;
0045:
0046:        import org.w3c.dom.Node;
0047:        import org.w3c.dom.NodeList;
0048:
0049:        /**
0050:         * Models the web.xml file's details ... basically just a bunch of configuration
0051:         * details, plus the actual instances of mounted servlets.
0052:         * 
0053:         * @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
0054:         * @version $Id: WebAppConfiguration.java,v 1.55 2007/11/13 01:42:47 rickknowles Exp $
0055:         */
0056:        public class WebAppConfiguration implements  ServletContext, Comparator {
0057:            //    private static final String ELEM_DESCRIPTION = "description";
0058:            private static final String ELEM_DISPLAY_NAME = "display-name";
0059:            private static final String ELEM_SERVLET = "servlet";
0060:            private static final String ELEM_SERVLET_MAPPING = "servlet-mapping";
0061:            private static final String ELEM_SERVLET_NAME = "servlet-name";
0062:            private static final String ELEM_FILTER = "filter";
0063:            private static final String ELEM_FILTER_MAPPING = "filter-mapping";
0064:            private static final String ELEM_FILTER_NAME = "filter-name";
0065:            private static final String ELEM_DISPATCHER = "dispatcher";
0066:            private static final String ELEM_URL_PATTERN = "url-pattern";
0067:            private static final String ELEM_WELCOME_FILES = "welcome-file-list";
0068:            private static final String ELEM_WELCOME_FILE = "welcome-file";
0069:            private static final String ELEM_SESSION_CONFIG = "session-config";
0070:            private static final String ELEM_SESSION_TIMEOUT = "session-timeout";
0071:            private static final String ELEM_MIME_MAPPING = "mime-mapping";
0072:            private static final String ELEM_MIME_EXTENSION = "extension";
0073:            private static final String ELEM_MIME_TYPE = "mime-type";
0074:            private static final String ELEM_CONTEXT_PARAM = "context-param";
0075:            private static final String ELEM_PARAM_NAME = "param-name";
0076:            private static final String ELEM_PARAM_VALUE = "param-value";
0077:            private static final String ELEM_LISTENER = "listener";
0078:            private static final String ELEM_LISTENER_CLASS = "listener-class";
0079:            private static final String ELEM_DISTRIBUTABLE = "distributable";
0080:            private static final String ELEM_ERROR_PAGE = "error-page";
0081:            private static final String ELEM_EXCEPTION_TYPE = "exception-type";
0082:            private static final String ELEM_ERROR_CODE = "error-code";
0083:            private static final String ELEM_ERROR_LOCATION = "location";
0084:            private static final String ELEM_SECURITY_CONSTRAINT = "security-constraint";
0085:            private static final String ELEM_LOGIN_CONFIG = "login-config";
0086:            private static final String ELEM_SECURITY_ROLE = "security-role";
0087:            private static final String ELEM_ROLE_NAME = "role-name";
0088:            private static final String ELEM_ENV_ENTRY = "env-entry";
0089:            private static final String ELEM_LOCALE_ENC_MAP_LIST = "locale-encoding-mapping-list";
0090:            private static final String ELEM_LOCALE_ENC_MAPPING = "locale-encoding-mapping";
0091:            private static final String ELEM_LOCALE = "locale";
0092:            private static final String ELEM_ENCODING = "encoding";
0093:            private static final String ELEM_JSP_CONFIG = "jsp-config";
0094:            private static final String ELEM_JSP_PROPERTY_GROUP = "jsp-property-group";
0095:
0096:            private static final String DISPATCHER_REQUEST = "REQUEST";
0097:            private static final String DISPATCHER_FORWARD = "FORWARD";
0098:            private static final String DISPATCHER_INCLUDE = "INCLUDE";
0099:            private static final String DISPATCHER_ERROR = "ERROR";
0100:            private static final String JSP_SERVLET_NAME = "JspServlet";
0101:            private static final String JSP_SERVLET_MAPPING = "*.jsp";
0102:            private static final String JSPX_SERVLET_MAPPING = "*.jspx";
0103:            private static final String JSP_SERVLET_LOG_LEVEL = "WARNING";
0104:            private static final String INVOKER_SERVLET_NAME = "invoker";
0105:            private static final String INVOKER_SERVLET_CLASS = "winstone.invoker.InvokerServlet";
0106:            private static final String DEFAULT_INVOKER_PREFIX = "/servlet/";
0107:            private static final String DEFAULT_SERVLET_NAME = "default";
0108:            private static final String DEFAULT_SERVLET_CLASS = "winstone.StaticResourceServlet";
0109:            private static final String DEFAULT_REALM_CLASS = "winstone.realm.ArgumentsRealm";
0110:            private static final String DEFAULT_JNDI_MGR_CLASS = "winstone.jndi.WebAppJNDIManager";
0111:            private static final String RELOADING_CL_CLASS = "winstone.classLoader.ReloadingClassLoader";
0112:            private static final String WEBAPP_CL_CLASS = "winstone.classLoader.WebappClassLoader";
0113:            private static final String ERROR_SERVLET_NAME = "winstoneErrorServlet";
0114:            private static final String ERROR_SERVLET_CLASS = "winstone.ErrorServlet";
0115:
0116:            private static final String WEB_INF = "WEB-INF";
0117:            private static final String CLASSES = "classes/";
0118:            private static final String LIB = "lib";
0119:
0120:            static final String JSP_SERVLET_CLASS = "org.apache.jasper.servlet.JspServlet";
0121:
0122:            private HostConfiguration ownerHostConfig;
0123:            private Cluster cluster;
0124:            private String webRoot;
0125:            private String prefix;
0126:            private String contextName;
0127:            private ClassLoader loader;
0128:            private String displayName;
0129:            private Map attributes;
0130:            private Map initParameters;
0131:            private Map sessions;
0132:            private Map mimeTypes;
0133:            private Map servletInstances;
0134:            private Map filterInstances;
0135:            private ServletContextAttributeListener contextAttributeListeners[];
0136:            private ServletContextListener contextListeners[];
0137:            private ServletRequestListener requestListeners[];
0138:            private ServletRequestAttributeListener requestAttributeListeners[];
0139:            private HttpSessionActivationListener sessionActivationListeners[];
0140:            private HttpSessionAttributeListener sessionAttributeListeners[];
0141:            private HttpSessionListener sessionListeners[];
0142:            private Throwable contextStartupError;
0143:            private Map exactServletMatchMounts;
0144:            private Mapping patternMatches[];
0145:            private Mapping filterPatternsRequest[];
0146:            private Mapping filterPatternsForward[];
0147:            private Mapping filterPatternsInclude[];
0148:            private Mapping filterPatternsError[];
0149:            private AuthenticationHandler authenticationHandler;
0150:            private AuthenticationRealm authenticationRealm;
0151:            private String welcomeFiles[];
0152:            private Integer sessionTimeout;
0153:            private Class[] errorPagesByExceptionKeysSorted;
0154:            private Map errorPagesByException;
0155:            private Map errorPagesByCode;
0156:            private Map localeEncodingMap;
0157:            private String defaultServletName;
0158:            private String errorServletName;
0159:            private JNDIManager jndiManager;
0160:            private AccessLogger accessLogger;
0161:            private Map filterMatchCache;
0162:            private boolean useSavedSessions;
0163:
0164:            public static boolean booleanArg(Map args, String name,
0165:                    boolean defaultTrue) {
0166:                String value = (String) args.get(name);
0167:                if (defaultTrue)
0168:                    return (value == null)
0169:                            || (value.equalsIgnoreCase("true") || value
0170:                                    .equalsIgnoreCase("yes"));
0171:                else
0172:                    return (value != null)
0173:                            && (value.equalsIgnoreCase("true") || value
0174:                                    .equalsIgnoreCase("yes"));
0175:            }
0176:
0177:            public static String stringArg(Map args, String name,
0178:                    String defaultValue) {
0179:                return (String) (args.get(name) == null ? defaultValue : args
0180:                        .get(name));
0181:            }
0182:
0183:            public static int intArg(Map args, String name, int defaultValue) {
0184:                return Integer
0185:                        .parseInt(stringArg(args, name, "" + defaultValue));
0186:            }
0187:
0188:            public static String getTextFromNode(Node node) {
0189:                if (node == null) {
0190:                    return null;
0191:                }
0192:                Node child = node.getFirstChild();
0193:                if (child == null) {
0194:                    return "";
0195:                }
0196:                String textNode = child.getNodeValue();
0197:                if (textNode == null) {
0198:                    return "";
0199:                } else {
0200:                    return textNode.trim();
0201:                }
0202:            }
0203:
0204:            public static boolean useSavedSessions(Map args) {
0205:                return booleanArg(args, "useSavedSessions", false);
0206:            }
0207:
0208:            /**
0209:             * Constructor. This parses the xml and sets up for basic routing
0210:             */
0211:            public WebAppConfiguration(HostConfiguration ownerHostConfig,
0212:                    Cluster cluster, String webRoot, String prefix,
0213:                    ObjectPool objectPool, Map startupArgs, Node elm,
0214:                    ClassLoader parentClassLoader, File parentClassPaths[],
0215:                    String contextName) {
0216:                if (!prefix.equals("") && !prefix.startsWith("/")) {
0217:                    Logger.log(Logger.WARNING, Launcher.RESOURCES,
0218:                            "WebAppConfig.AddingLeadingSlash", prefix);
0219:                    prefix = "/" + prefix;
0220:                }
0221:                this .ownerHostConfig = ownerHostConfig;
0222:                this .webRoot = webRoot;
0223:                this .prefix = prefix;
0224:                this .contextName = contextName;
0225:
0226:                List localLoaderClassPathFiles = new ArrayList();
0227:                this .loader = buildWebAppClassLoader(startupArgs,
0228:                        parentClassLoader, webRoot, localLoaderClassPathFiles);
0229:
0230:                // Build switch values
0231:                boolean useJasper = booleanArg(startupArgs, "useJasper", true);
0232:                boolean useInvoker = booleanArg(startupArgs, "useInvoker",
0233:                        false);
0234:                boolean useJNDI = booleanArg(startupArgs, "useJNDI", false);
0235:                this .useSavedSessions = useSavedSessions(startupArgs);
0236:
0237:                // Check jasper is available - simple tests
0238:                if (useJasper) {
0239:                    try {
0240:                        Class.forName("javax.servlet.jsp.JspFactory", true,
0241:                                parentClassLoader);
0242:                        Class.forName(JSP_SERVLET_CLASS, true, this .loader);
0243:                    } catch (Throwable err) {
0244:                        if (booleanArg(startupArgs, "useJasper", false)) {
0245:                            Logger.log(Logger.WARNING, Launcher.RESOURCES,
0246:                                    "WebAppConfig.JasperNotFound");
0247:                            Logger.log(Logger.DEBUG, Launcher.RESOURCES,
0248:                                    "WebAppConfig.JasperLoadException", err);
0249:                        }
0250:                        useJasper = false;
0251:                    }
0252:                }
0253:                if (useInvoker) {
0254:                    try {
0255:                        Class
0256:                                .forName(INVOKER_SERVLET_CLASS, false,
0257:                                        this .loader);
0258:                    } catch (Throwable err) {
0259:                        Logger.log(Logger.WARNING, Launcher.RESOURCES,
0260:                                "WebAppConfig.InvokerNotFound");
0261:                        useInvoker = false;
0262:                    }
0263:                }
0264:
0265:                this .attributes = new Hashtable();
0266:                this .initParameters = new HashMap();
0267:                this .sessions = new Hashtable();
0268:
0269:                this .servletInstances = new HashMap();
0270:                this .filterInstances = new HashMap();
0271:                this .filterMatchCache = new HashMap();
0272:
0273:                List contextAttributeListeners = new ArrayList();
0274:                List contextListeners = new ArrayList();
0275:                List requestListeners = new ArrayList();
0276:                List requestAttributeListeners = new ArrayList();
0277:                List sessionActivationListeners = new ArrayList();
0278:                List sessionAttributeListeners = new ArrayList();
0279:                List sessionListeners = new ArrayList();
0280:
0281:                this .errorPagesByException = new HashMap();
0282:                this .errorPagesByCode = new HashMap();
0283:                boolean distributable = false;
0284:
0285:                this .exactServletMatchMounts = new Hashtable();
0286:                List localFolderPatterns = new ArrayList();
0287:                List localExtensionPatterns = new ArrayList();
0288:
0289:                List lfpRequest = new ArrayList();
0290:                List lfpForward = new ArrayList();
0291:                List lfpInclude = new ArrayList();
0292:                List lfpError = new ArrayList();
0293:
0294:                List localWelcomeFiles = new ArrayList();
0295:                List startupServlets = new ArrayList();
0296:
0297:                Set rolesAllowed = new HashSet();
0298:                List constraintNodes = new ArrayList();
0299:                List envEntryNodes = new ArrayList();
0300:                List localErrorPagesByExceptionList = new ArrayList();
0301:
0302:                Node loginConfigNode = null;
0303:
0304:                // Add the class loader as an implicit context listener if it implements the interface
0305:                addListenerInstance(this .loader, contextAttributeListeners,
0306:                        contextListeners, requestAttributeListeners,
0307:                        requestListeners, sessionActivationListeners,
0308:                        sessionAttributeListeners, sessionListeners);
0309:
0310:                // init mimeTypes set
0311:                this .mimeTypes = new Hashtable();
0312:                String allTypes = Launcher.RESOURCES
0313:                        .getString("WebAppConfig.DefaultMimeTypes");
0314:                StringTokenizer mappingST = new StringTokenizer(allTypes, ":",
0315:                        false);
0316:                for (; mappingST.hasMoreTokens();) {
0317:                    String mapping = mappingST.nextToken();
0318:                    int delimPos = mapping.indexOf('=');
0319:                    if (delimPos == -1)
0320:                        continue;
0321:                    String extension = mapping.substring(0, delimPos);
0322:                    String mimeType = mapping.substring(delimPos + 1);
0323:                    this .mimeTypes.put(extension.toLowerCase(), mimeType);
0324:                }
0325:
0326:                this .localeEncodingMap = new HashMap();
0327:                String encodingMapSet = Launcher.RESOURCES
0328:                        .getString("WebAppConfig.EncodingMap");
0329:                StringTokenizer st = new StringTokenizer(encodingMapSet, ";");
0330:                for (; st.hasMoreTokens();) {
0331:                    String token = st.nextToken();
0332:                    int delimPos = token.indexOf("=");
0333:                    if (delimPos == -1)
0334:                        continue;
0335:                    this .localeEncodingMap.put(token.substring(0, delimPos),
0336:                            token.substring(delimPos + 1));
0337:                }
0338:
0339:                // init jsp mappings set
0340:                List jspMappings = new ArrayList();
0341:                jspMappings.add(JSP_SERVLET_MAPPING);
0342:                jspMappings.add(JSPX_SERVLET_MAPPING);
0343:
0344:                // Add required context atttributes
0345:                File tmpDir = new File(new File(new File(System
0346:                        .getProperty("java.io.tmpdir"), "winstone.tmp"),
0347:                        ownerHostConfig.getHostname()), contextName);
0348:                tmpDir.mkdirs();
0349:                this .attributes.put("javax.servlet.context.tempdir", tmpDir);
0350:
0351:                // Parse the web.xml file
0352:                if (elm != null) {
0353:                    NodeList children = elm.getChildNodes();
0354:                    for (int n = 0; n < children.getLength(); n++) {
0355:                        Node child = children.item(n);
0356:                        if (child.getNodeType() != Node.ELEMENT_NODE)
0357:                            continue;
0358:                        String nodeName = child.getNodeName();
0359:
0360:                        if (nodeName.equals(ELEM_DISPLAY_NAME))
0361:                            this .displayName = getTextFromNode(child);
0362:
0363:                        else if (nodeName.equals(ELEM_DISTRIBUTABLE))
0364:                            distributable = true;
0365:
0366:                        else if (nodeName.equals(ELEM_SECURITY_CONSTRAINT))
0367:                            constraintNodes.add(child);
0368:
0369:                        else if (nodeName.equals(ELEM_ENV_ENTRY))
0370:                            envEntryNodes.add(child);
0371:
0372:                        else if (nodeName.equals(ELEM_LOGIN_CONFIG))
0373:                            loginConfigNode = child;
0374:
0375:                        // Session config elements
0376:                        else if (nodeName.equals(ELEM_SESSION_CONFIG)) {
0377:                            for (int m = 0; m < child.getChildNodes()
0378:                                    .getLength(); m++) {
0379:                                Node timeoutElm = child.getChildNodes().item(m);
0380:                                if ((timeoutElm.getNodeType() == Node.ELEMENT_NODE)
0381:                                        && (timeoutElm.getNodeName()
0382:                                                .equals(ELEM_SESSION_TIMEOUT))) {
0383:                                    String timeoutStr = getTextFromNode(timeoutElm);
0384:                                    if (!timeoutStr.equals("")) {
0385:                                        this .sessionTimeout = Integer
0386:                                                .valueOf(timeoutStr);
0387:                                    }
0388:                                }
0389:                            }
0390:                        }
0391:
0392:                        // Construct the security roles
0393:                        else if (child.getNodeName().equals(ELEM_SECURITY_ROLE)) {
0394:                            for (int m = 0; m < child.getChildNodes()
0395:                                    .getLength(); m++) {
0396:                                Node roleElm = child.getChildNodes().item(m);
0397:                                if ((roleElm.getNodeType() == Node.ELEMENT_NODE)
0398:                                        && (roleElm.getNodeName()
0399:                                                .equals(ELEM_ROLE_NAME)))
0400:                                    rolesAllowed.add(getTextFromNode(roleElm));
0401:                            }
0402:                        }
0403:
0404:                        // Construct the servlet instances
0405:                        else if (nodeName.equals(ELEM_SERVLET)) {
0406:                            ServletConfiguration instance = new ServletConfiguration(
0407:                                    this , child);
0408:                            this .servletInstances.put(
0409:                                    instance.getServletName(), instance);
0410:                            if (instance.getLoadOnStartup() >= 0)
0411:                                startupServlets.add(instance);
0412:                        }
0413:
0414:                        // Construct the servlet instances
0415:                        else if (nodeName.equals(ELEM_FILTER)) {
0416:                            FilterConfiguration instance = new FilterConfiguration(
0417:                                    this , this .loader, child);
0418:                            this .filterInstances.put(instance.getFilterName(),
0419:                                    instance);
0420:                        }
0421:
0422:                        // Construct the servlet instances
0423:                        else if (nodeName.equals(ELEM_LISTENER)) {
0424:                            String listenerClass = null;
0425:                            for (int m = 0; m < child.getChildNodes()
0426:                                    .getLength(); m++) {
0427:                                Node listenerElm = child.getChildNodes()
0428:                                        .item(m);
0429:                                if ((listenerElm.getNodeType() == Node.ELEMENT_NODE)
0430:                                        && (listenerElm.getNodeName()
0431:                                                .equals(ELEM_LISTENER_CLASS)))
0432:                                    listenerClass = getTextFromNode(listenerElm);
0433:                            }
0434:                            if (listenerClass != null)
0435:                                try {
0436:                                    Class listener = Class.forName(
0437:                                            listenerClass, true, this .loader);
0438:                                    Object listenerInstance = listener
0439:                                            .newInstance();
0440:                                    addListenerInstance(listenerInstance,
0441:                                            contextAttributeListeners,
0442:                                            contextListeners,
0443:                                            requestAttributeListeners,
0444:                                            requestListeners,
0445:                                            sessionActivationListeners,
0446:                                            sessionAttributeListeners,
0447:                                            sessionListeners);
0448:                                    Logger.log(Logger.DEBUG,
0449:                                            Launcher.RESOURCES,
0450:                                            "WebAppConfig.AddListener",
0451:                                            listenerClass);
0452:                                } catch (Throwable err) {
0453:                                    Logger.log(Logger.WARNING,
0454:                                            Launcher.RESOURCES,
0455:                                            "WebAppConfig.InvalidListener",
0456:                                            listenerClass);
0457:                                }
0458:                        }
0459:
0460:                        // Process the servlet mappings
0461:                        else if (nodeName.equals(ELEM_SERVLET_MAPPING)) {
0462:                            String name = null;
0463:                            List mappings = new ArrayList();
0464:
0465:                            // Parse the element and extract
0466:                            NodeList mappingChildren = child.getChildNodes();
0467:                            for (int k = 0; k < mappingChildren.getLength(); k++) {
0468:                                Node mapChild = mappingChildren.item(k);
0469:                                if (mapChild.getNodeType() != Node.ELEMENT_NODE)
0470:                                    continue;
0471:                                String mapNodeName = mapChild.getNodeName();
0472:                                if (mapNodeName.equals(ELEM_SERVLET_NAME)) {
0473:                                    name = getTextFromNode(mapChild);
0474:                                } else if (mapNodeName.equals(ELEM_URL_PATTERN)) {
0475:                                    mappings.add(getTextFromNode(mapChild));
0476:                                }
0477:                            }
0478:                            for (Iterator i = mappings.iterator(); i.hasNext();) {
0479:                                processMapping(name, (String) i.next(),
0480:                                        this .exactServletMatchMounts,
0481:                                        localFolderPatterns,
0482:                                        localExtensionPatterns);
0483:                            }
0484:                        }
0485:
0486:                        // Process the filter mappings
0487:                        else if (nodeName.equals(ELEM_FILTER_MAPPING)) {
0488:                            String filterName = null;
0489:                            List mappings = new ArrayList();
0490:                            boolean onRequest = false;
0491:                            boolean onForward = false;
0492:                            boolean onInclude = false;
0493:                            boolean onError = false;
0494:
0495:                            // Parse the element and extract
0496:                            for (int k = 0; k < child.getChildNodes()
0497:                                    .getLength(); k++) {
0498:                                Node mapChild = child.getChildNodes().item(k);
0499:                                if (mapChild.getNodeType() != Node.ELEMENT_NODE)
0500:                                    continue;
0501:                                String mapNodeName = mapChild.getNodeName();
0502:                                if (mapNodeName.equals(ELEM_FILTER_NAME)) {
0503:                                    filterName = getTextFromNode(mapChild);
0504:                                } else if (mapNodeName
0505:                                        .equals(ELEM_SERVLET_NAME)) {
0506:                                    mappings.add("srv:"
0507:                                            + getTextFromNode(mapChild));
0508:                                } else if (mapNodeName.equals(ELEM_URL_PATTERN)) {
0509:                                    mappings.add("url:"
0510:                                            + getTextFromNode(mapChild));
0511:                                } else if (mapNodeName.equals(ELEM_DISPATCHER)) {
0512:                                    String dispatcherValue = getTextFromNode(mapChild);
0513:                                    if (dispatcherValue
0514:                                            .equals(DISPATCHER_REQUEST))
0515:                                        onRequest = true;
0516:                                    else if (dispatcherValue
0517:                                            .equals(DISPATCHER_FORWARD))
0518:                                        onForward = true;
0519:                                    else if (dispatcherValue
0520:                                            .equals(DISPATCHER_INCLUDE))
0521:                                        onInclude = true;
0522:                                    else if (dispatcherValue
0523:                                            .equals(DISPATCHER_ERROR))
0524:                                        onError = true;
0525:                                }
0526:                            }
0527:                            if (!onRequest && !onInclude && !onForward
0528:                                    && !onError) {
0529:                                onRequest = true;
0530:                            }
0531:                            if (mappings.isEmpty()) {
0532:                                throw new WinstoneException(
0533:                                        Launcher.RESOURCES
0534:                                                .getString(
0535:                                                        "WebAppConfig.BadFilterMapping",
0536:                                                        filterName));
0537:                            }
0538:
0539:                            for (Iterator i = mappings.iterator(); i.hasNext();) {
0540:                                String item = (String) i.next();
0541:                                Mapping mapping = null;
0542:                                try {
0543:                                    if (item.startsWith("srv:")) {
0544:                                        mapping = Mapping.createFromLink(
0545:                                                filterName, item.substring(4));
0546:                                    } else {
0547:                                        mapping = Mapping.createFromURL(
0548:                                                filterName, item.substring(4));
0549:                                    }
0550:                                    if (onRequest)
0551:                                        lfpRequest.add(mapping);
0552:                                    if (onForward)
0553:                                        lfpForward.add(mapping);
0554:                                    if (onInclude)
0555:                                        lfpInclude.add(mapping);
0556:                                    if (onError)
0557:                                        lfpError.add(mapping);
0558:                                } catch (WinstoneException err) {
0559:                                    Logger.log(Logger.WARNING,
0560:                                            Launcher.RESOURCES,
0561:                                            "WebAppConfig.ErrorMapURL", err
0562:                                                    .getMessage());
0563:                                }
0564:                            }
0565:                        }
0566:
0567:                        // Process the list of welcome files
0568:                        else if (nodeName.equals(ELEM_WELCOME_FILES)) {
0569:                            for (int m = 0; m < child.getChildNodes()
0570:                                    .getLength(); m++) {
0571:                                Node welcomeFile = child.getChildNodes()
0572:                                        .item(m);
0573:                                if ((welcomeFile.getNodeType() == Node.ELEMENT_NODE)
0574:                                        && welcomeFile.getNodeName().equals(
0575:                                                ELEM_WELCOME_FILE)) {
0576:                                    String welcomeStr = getTextFromNode(welcomeFile);
0577:                                    if (!welcomeStr.equals("")) {
0578:                                        localWelcomeFiles.add(welcomeStr);
0579:                                    }
0580:                                }
0581:                            }
0582:                        }
0583:
0584:                        // Process the error pages
0585:                        else if (nodeName.equals(ELEM_ERROR_PAGE)) {
0586:                            String code = null;
0587:                            String exception = null;
0588:                            String location = null;
0589:
0590:                            // Parse the element and extract
0591:                            for (int k = 0; k < child.getChildNodes()
0592:                                    .getLength(); k++) {
0593:                                Node errorChild = child.getChildNodes().item(k);
0594:                                if (errorChild.getNodeType() != Node.ELEMENT_NODE)
0595:                                    continue;
0596:                                String errorChildName = errorChild
0597:                                        .getNodeName();
0598:                                if (errorChildName.equals(ELEM_ERROR_CODE))
0599:                                    code = getTextFromNode(errorChild);
0600:                                else if (errorChildName
0601:                                        .equals(ELEM_EXCEPTION_TYPE))
0602:                                    exception = getTextFromNode(errorChild);
0603:                                else if (errorChildName
0604:                                        .equals(ELEM_ERROR_LOCATION))
0605:                                    location = getTextFromNode(errorChild);
0606:                            }
0607:                            if ((code != null) && (location != null))
0608:                                this .errorPagesByCode.put(code.trim(), location
0609:                                        .trim());
0610:                            if ((exception != null) && (location != null))
0611:                                try {
0612:                                    Class exceptionClass = Class.forName(
0613:                                            exception.trim(), false,
0614:                                            this .loader);
0615:                                    localErrorPagesByExceptionList
0616:                                            .add(exceptionClass);
0617:                                    this .errorPagesByException.put(
0618:                                            exceptionClass, location.trim());
0619:                                } catch (ClassNotFoundException err) {
0620:                                    Logger.log(Logger.ERROR,
0621:                                            Launcher.RESOURCES,
0622:                                            "WebAppConfig.ExceptionNotFound",
0623:                                            exception);
0624:                                }
0625:                        }
0626:
0627:                        // Process the list of welcome files
0628:                        else if (nodeName.equals(ELEM_MIME_MAPPING)) {
0629:                            String extension = null;
0630:                            String mimeType = null;
0631:                            for (int m = 0; m < child.getChildNodes()
0632:                                    .getLength(); m++) {
0633:                                Node mimeTypeNode = child.getChildNodes().item(
0634:                                        m);
0635:                                if (mimeTypeNode.getNodeType() != Node.ELEMENT_NODE)
0636:                                    continue;
0637:                                else if (mimeTypeNode.getNodeName().equals(
0638:                                        ELEM_MIME_EXTENSION))
0639:                                    extension = getTextFromNode(mimeTypeNode);
0640:                                else if (mimeTypeNode.getNodeName().equals(
0641:                                        ELEM_MIME_TYPE))
0642:                                    mimeType = getTextFromNode(mimeTypeNode);
0643:                            }
0644:                            if ((extension != null) && (mimeType != null))
0645:                                this .mimeTypes.put(extension.toLowerCase(),
0646:                                        mimeType);
0647:                            else
0648:                                Logger.log(Logger.WARNING, Launcher.RESOURCES,
0649:                                        "WebAppConfig.InvalidMimeMapping",
0650:                                        new String[] { extension, mimeType });
0651:                        }
0652:
0653:                        // Process the list of welcome files
0654:                        else if (nodeName.equals(ELEM_CONTEXT_PARAM)) {
0655:                            String name = null;
0656:                            String value = null;
0657:                            for (int m = 0; m < child.getChildNodes()
0658:                                    .getLength(); m++) {
0659:                                Node contextParamNode = child.getChildNodes()
0660:                                        .item(m);
0661:                                if (contextParamNode.getNodeType() != Node.ELEMENT_NODE)
0662:                                    continue;
0663:                                else if (contextParamNode.getNodeName().equals(
0664:                                        ELEM_PARAM_NAME))
0665:                                    name = getTextFromNode(contextParamNode);
0666:                                else if (contextParamNode.getNodeName().equals(
0667:                                        ELEM_PARAM_VALUE))
0668:                                    value = getTextFromNode(contextParamNode);
0669:                            }
0670:                            if ((name != null) && (value != null))
0671:                                this .initParameters.put(name, value);
0672:                            else
0673:                                Logger.log(Logger.WARNING, Launcher.RESOURCES,
0674:                                        "WebAppConfig.InvalidInitParam",
0675:                                        new String[] { name, value });
0676:                        }
0677:
0678:                        // Process locale encoding mapping elements
0679:                        else if (nodeName.equals(ELEM_LOCALE_ENC_MAP_LIST)) {
0680:                            for (int m = 0; m < child.getChildNodes()
0681:                                    .getLength(); m++) {
0682:                                Node mappingNode = child.getChildNodes()
0683:                                        .item(m);
0684:                                if (mappingNode.getNodeType() != Node.ELEMENT_NODE)
0685:                                    continue;
0686:                                else if (mappingNode.getNodeName().equals(
0687:                                        ELEM_LOCALE_ENC_MAPPING)) {
0688:                                    String localeName = "";
0689:                                    String encoding = "";
0690:                                    for (int l = 0; l < mappingNode
0691:                                            .getChildNodes().getLength(); l++) {
0692:                                        Node mappingChildNode = mappingNode
0693:                                                .getChildNodes().item(l);
0694:                                        if (mappingChildNode.getNodeType() != Node.ELEMENT_NODE)
0695:                                            continue;
0696:                                        else if (mappingChildNode.getNodeName()
0697:                                                .equals(ELEM_LOCALE))
0698:                                            localeName = getTextFromNode(mappingChildNode);
0699:                                        else if (mappingChildNode.getNodeName()
0700:                                                .equals(ELEM_ENCODING))
0701:                                            encoding = getTextFromNode(mappingChildNode);
0702:                                    }
0703:                                    if (!encoding.equals("")
0704:                                            && !localeName.equals(""))
0705:                                        this .localeEncodingMap.put(localeName,
0706:                                                encoding);
0707:                                }
0708:                            }
0709:                        }
0710:
0711:                        // Record the url mappings for jsp files if set
0712:                        else if (nodeName.equals(ELEM_JSP_CONFIG)) {
0713:                            for (int m = 0; m < child.getChildNodes()
0714:                                    .getLength(); m++) {
0715:                                Node propertyGroupNode = child.getChildNodes()
0716:                                        .item(m);
0717:                                if ((propertyGroupNode.getNodeType() == Node.ELEMENT_NODE)
0718:                                        && propertyGroupNode
0719:                                                .getNodeName()
0720:                                                .equals(ELEM_JSP_PROPERTY_GROUP)) {
0721:                                    for (int l = 0; l < propertyGroupNode
0722:                                            .getChildNodes().getLength(); l++) {
0723:                                        Node urlPatternNode = propertyGroupNode
0724:                                                .getChildNodes().item(l);
0725:                                        if ((urlPatternNode.getNodeType() == Node.ELEMENT_NODE)
0726:                                                && urlPatternNode
0727:                                                        .getNodeName()
0728:                                                        .equals(
0729:                                                                ELEM_URL_PATTERN)) {
0730:                                            String jm = getTextFromNode(urlPatternNode);
0731:                                            if (!jm.equals("")) {
0732:                                                jspMappings.add(jm);
0733:                                            }
0734:                                        }
0735:                                    }
0736:                                }
0737:                            }
0738:                        }
0739:                    }
0740:                }
0741:
0742:                // If not distributable, remove the cluster reference
0743:                if (!distributable && (cluster != null)) {
0744:                    Logger.log(Logger.INFO, Launcher.RESOURCES,
0745:                            "WebAppConfig.ClusterOffNotDistributable",
0746:                            this .contextName);
0747:                } else {
0748:                    this .cluster = cluster;
0749:                }
0750:
0751:                // Build the login/security role instance
0752:                if (!constraintNodes.isEmpty() && (loginConfigNode != null)) {
0753:                    String authMethod = null;
0754:                    for (int n = 0; n < loginConfigNode.getChildNodes()
0755:                            .getLength(); n++) {
0756:                        if (loginConfigNode.getChildNodes().item(n)
0757:                                .getNodeName().equals("auth-method")) {
0758:                            authMethod = getTextFromNode(loginConfigNode
0759:                                    .getChildNodes().item(n));
0760:                        }
0761:                    }
0762:                    // Load the appropriate auth class
0763:                    if (authMethod == null) {
0764:                        authMethod = "BASIC";
0765:                    } else {
0766:                        authMethod = WinstoneResourceBundle.globalReplace(
0767:                                authMethod, "-", "");
0768:                    }
0769:                    String realmClassName = stringArg(startupArgs,
0770:                            "realmClassName", DEFAULT_REALM_CLASS).trim();
0771:                    String authClassName = "winstone.auth."
0772:                            + authMethod.substring(0, 1).toUpperCase()
0773:                            + authMethod.substring(1).toLowerCase()
0774:                            + "AuthenticationHandler";
0775:                    try {
0776:                        // Build the realm
0777:                        Class realmClass = Class.forName(realmClassName, true,
0778:                                parentClassLoader);
0779:                        Constructor realmConstr = realmClass
0780:                                .getConstructor(new Class[] { Set.class,
0781:                                        Map.class });
0782:                        this .authenticationRealm = (AuthenticationRealm) realmConstr
0783:                                .newInstance(new Object[] { rolesAllowed,
0784:                                        startupArgs });
0785:
0786:                        // Build the authentication handler
0787:                        Class authClass = Class.forName(authClassName);
0788:                        Constructor authConstr = authClass
0789:                                .getConstructor(new Class[] { Node.class,
0790:                                        List.class, Set.class,
0791:                                        AuthenticationRealm.class });
0792:                        this .authenticationHandler = (AuthenticationHandler) authConstr
0793:                                .newInstance(new Object[] { loginConfigNode,
0794:                                        constraintNodes, rolesAllowed,
0795:                                        authenticationRealm });
0796:                    } catch (ClassNotFoundException err) {
0797:                        Logger.log(Logger.DEBUG, Launcher.RESOURCES,
0798:                                "WebAppConfig.AuthDisabled", authMethod);
0799:                    } catch (Throwable err) {
0800:                        Logger.log(Logger.ERROR, Launcher.RESOURCES,
0801:                                "WebAppConfig.AuthError", new String[] {
0802:                                        authClassName, realmClassName }, err);
0803:                    }
0804:                } else if (!stringArg(startupArgs, "realmClassName", "").trim()
0805:                        .equals("")) {
0806:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
0807:                            "WebAppConfig.NoWebXMLSecurityDefs");
0808:                }
0809:
0810:                // Instantiate the JNDI manager
0811:                String jndiMgrClassName = stringArg(startupArgs,
0812:                        "webappJndiClassName", DEFAULT_JNDI_MGR_CLASS).trim();
0813:                if (useJNDI) {
0814:                    try {
0815:                        // Build the realm
0816:                        Class jndiMgrClass = Class.forName(jndiMgrClassName,
0817:                                true, parentClassLoader);
0818:                        Constructor jndiMgrConstr = jndiMgrClass
0819:                                .getConstructor(new Class[] { Map.class,
0820:                                        List.class, ClassLoader.class });
0821:                        this .jndiManager = (JNDIManager) jndiMgrConstr
0822:                                .newInstance(new Object[] { null,
0823:                                        envEntryNodes, this .loader });
0824:                        if (this .jndiManager != null)
0825:                            this .jndiManager.setup();
0826:                    } catch (ClassNotFoundException err) {
0827:                        Logger.log(Logger.DEBUG, Launcher.RESOURCES,
0828:                                "WebAppConfig.JNDIDisabled");
0829:                    } catch (Throwable err) {
0830:                        Logger
0831:                                .log(Logger.ERROR, Launcher.RESOURCES,
0832:                                        "WebAppConfig.JNDIError",
0833:                                        jndiMgrClassName, err);
0834:                    }
0835:                }
0836:
0837:                String loggerClassName = stringArg(startupArgs,
0838:                        "accessLoggerClassName", "").trim();
0839:                if (!loggerClassName.equals("")) {
0840:                    try {
0841:                        // Build the realm
0842:                        Class loggerClass = Class.forName(loggerClassName,
0843:                                true, parentClassLoader);
0844:                        Constructor loggerConstr = loggerClass
0845:                                .getConstructor(new Class[] {
0846:                                        WebAppConfiguration.class, Map.class });
0847:                        this .accessLogger = (AccessLogger) loggerConstr
0848:                                .newInstance(new Object[] { this , startupArgs });
0849:                    } catch (Throwable err) {
0850:                        Logger.log(Logger.ERROR, Launcher.RESOURCES,
0851:                                "WebAppConfig.LoggerError", loggerClassName,
0852:                                err);
0853:                    }
0854:                } else {
0855:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
0856:                            "WebAppConfig.LoggerDisabled");
0857:
0858:                }
0859:
0860:                // Add the default index.html welcomeFile if none are supplied
0861:                if (localWelcomeFiles.isEmpty()) {
0862:                    if (useJasper) {
0863:                        localWelcomeFiles.add("index.jsp");
0864:                    }
0865:                    localWelcomeFiles.add("index.html");
0866:                }
0867:
0868:                // Put the name filters after the url filters, then convert to string arrays
0869:                this .filterPatternsRequest = (Mapping[]) lfpRequest
0870:                        .toArray(new Mapping[0]);
0871:                this .filterPatternsForward = (Mapping[]) lfpForward
0872:                        .toArray(new Mapping[0]);
0873:                this .filterPatternsInclude = (Mapping[]) lfpInclude
0874:                        .toArray(new Mapping[0]);
0875:                this .filterPatternsError = (Mapping[]) lfpError
0876:                        .toArray(new Mapping[0]);
0877:
0878:                if (this .filterPatternsRequest.length > 0)
0879:                    Arrays.sort(this .filterPatternsRequest,
0880:                            this .filterPatternsRequest[0]);
0881:                if (this .filterPatternsForward.length > 0)
0882:                    Arrays.sort(this .filterPatternsForward,
0883:                            this .filterPatternsForward[0]);
0884:                if (this .filterPatternsInclude.length > 0)
0885:                    Arrays.sort(this .filterPatternsInclude,
0886:                            this .filterPatternsInclude[0]);
0887:                if (this .filterPatternsError.length > 0)
0888:                    Arrays.sort(this .filterPatternsError,
0889:                            this .filterPatternsError[0]);
0890:
0891:                this .welcomeFiles = (String[]) localWelcomeFiles
0892:                        .toArray(new String[0]);
0893:                this .errorPagesByExceptionKeysSorted = (Class[]) localErrorPagesByExceptionList
0894:                        .toArray(new Class[0]);
0895:                Arrays.sort(this .errorPagesByExceptionKeysSorted, this );
0896:
0897:                // Put the listeners into their arrays
0898:                this .contextAttributeListeners = (ServletContextAttributeListener[]) contextAttributeListeners
0899:                        .toArray(new ServletContextAttributeListener[0]);
0900:                this .contextListeners = (ServletContextListener[]) contextListeners
0901:                        .toArray(new ServletContextListener[0]);
0902:                this .requestListeners = (ServletRequestListener[]) requestListeners
0903:                        .toArray(new ServletRequestListener[0]);
0904:                this .requestAttributeListeners = (ServletRequestAttributeListener[]) requestAttributeListeners
0905:                        .toArray(new ServletRequestAttributeListener[0]);
0906:                this .sessionActivationListeners = (HttpSessionActivationListener[]) sessionActivationListeners
0907:                        .toArray(new HttpSessionActivationListener[0]);
0908:                this .sessionAttributeListeners = (HttpSessionAttributeListener[]) sessionAttributeListeners
0909:                        .toArray(new HttpSessionAttributeListener[0]);
0910:                this .sessionListeners = (HttpSessionListener[]) sessionListeners
0911:                        .toArray(new HttpSessionListener[0]);
0912:
0913:                // If we haven't explicitly mapped the default servlet, map it here
0914:                if (this .defaultServletName == null)
0915:                    this .defaultServletName = DEFAULT_SERVLET_NAME;
0916:                if (this .errorServletName == null)
0917:                    this .errorServletName = ERROR_SERVLET_NAME;
0918:
0919:                // If we don't have an instance of the default servlet, mount the inbuilt one
0920:                if (this .servletInstances.get(this .defaultServletName) == null) {
0921:                    boolean useDirLists = booleanArg(startupArgs,
0922:                            "directoryListings", true);
0923:
0924:                    Map staticParams = new Hashtable();
0925:                    staticParams.put("webRoot", webRoot);
0926:                    staticParams.put("prefix", this .prefix);
0927:                    staticParams.put("directoryList", "" + useDirLists);
0928:                    ServletConfiguration defaultServlet = new ServletConfiguration(
0929:                            this , this .defaultServletName,
0930:                            DEFAULT_SERVLET_CLASS, staticParams, 0);
0931:                    this .servletInstances.put(this .defaultServletName,
0932:                            defaultServlet);
0933:                    startupServlets.add(defaultServlet);
0934:                }
0935:
0936:                // If we don't have an instance of the default servlet, mount the inbuilt one
0937:                if (this .servletInstances.get(this .errorServletName) == null) {
0938:                    ServletConfiguration errorServlet = new ServletConfiguration(
0939:                            this , this .errorServletName, ERROR_SERVLET_CLASS,
0940:                            new HashMap(), 0);
0941:                    this .servletInstances.put(this .errorServletName,
0942:                            errorServlet);
0943:                    startupServlets.add(errorServlet);
0944:                }
0945:
0946:                // Initialise jasper servlet if requested
0947:                if (useJasper) {
0948:                    setAttribute("org.apache.catalina.classloader", this .loader);
0949:                    try {
0950:                        StringBuffer cp = new StringBuffer();
0951:                        for (Iterator i = localLoaderClassPathFiles.iterator(); i
0952:                                .hasNext();) {
0953:                            cp.append(((File) i.next()).getCanonicalPath())
0954:                                    .append(File.pathSeparatorChar);
0955:                        }
0956:                        for (int n = 0; n < parentClassPaths.length; n++) {
0957:                            cp.append(parentClassPaths[n].getCanonicalPath())
0958:                                    .append(File.pathSeparatorChar);
0959:                        }
0960:                        setAttribute("org.apache.catalina.jsp_classpath", (cp
0961:                                .length() > 0 ? cp
0962:                                .substring(0, cp.length() - 1) : ""));
0963:                    } catch (IOException err) {
0964:                        Logger.log(Logger.ERROR, Launcher.RESOURCES,
0965:                                "WebAppConfig.ErrorSettingJSPPaths", err);
0966:                    }
0967:
0968:                    Map jspParams = new HashMap();
0969:                    addJspServletParams(jspParams);
0970:                    ServletConfiguration sc = new ServletConfiguration(this ,
0971:                            JSP_SERVLET_NAME, JSP_SERVLET_CLASS, jspParams, 3);
0972:                    this .servletInstances.put(JSP_SERVLET_NAME, sc);
0973:                    startupServlets.add(sc);
0974:                    for (Iterator mapIt = jspMappings.iterator(); mapIt
0975:                            .hasNext();) {
0976:                        processMapping(JSP_SERVLET_NAME, (String) mapIt.next(),
0977:                                this .exactServletMatchMounts,
0978:                                localFolderPatterns, localExtensionPatterns);
0979:                    }
0980:                }
0981:
0982:                // Initialise invoker servlet if requested
0983:                if (useInvoker) {
0984:                    // Get generic options
0985:                    String invokerPrefix = stringArg(startupArgs,
0986:                            "invokerPrefix", DEFAULT_INVOKER_PREFIX);
0987:                    Map invokerParams = new HashMap();
0988:                    invokerParams.put("prefix", this .prefix);
0989:                    invokerParams.put("invokerPrefix", invokerPrefix);
0990:                    ServletConfiguration sc = new ServletConfiguration(this ,
0991:                            INVOKER_SERVLET_NAME, INVOKER_SERVLET_CLASS,
0992:                            invokerParams, 3);
0993:                    this .servletInstances.put(INVOKER_SERVLET_NAME, sc);
0994:                    processMapping(INVOKER_SERVLET_NAME, invokerPrefix
0995:                            + Mapping.STAR, this .exactServletMatchMounts,
0996:                            localFolderPatterns, localExtensionPatterns);
0997:                }
0998:
0999:                // Sort the folder patterns so the longest paths are first
1000:                localFolderPatterns.addAll(localExtensionPatterns);
1001:                this .patternMatches = (Mapping[]) localFolderPatterns
1002:                        .toArray(new Mapping[0]);
1003:                if (this .patternMatches.length > 0)
1004:                    Arrays.sort(this .patternMatches, this .patternMatches[0]);
1005:
1006:                // Send init notifies
1007:                try {
1008:                    for (int n = 0; n < this .contextListeners.length; n++) {
1009:                        ClassLoader cl = Thread.currentThread()
1010:                                .getContextClassLoader();
1011:                        Thread.currentThread().setContextClassLoader(
1012:                                this .loader);
1013:                        this .contextListeners[n]
1014:                                .contextInitialized(new ServletContextEvent(
1015:                                        this ));
1016:                        Thread.currentThread().setContextClassLoader(cl);
1017:                    }
1018:                } catch (Throwable err) {
1019:                    Logger.log(Logger.ERROR, Launcher.RESOURCES,
1020:                            "WebAppConfig.ContextStartupError",
1021:                            this .contextName, err);
1022:                    this .contextStartupError = err;
1023:                }
1024:
1025:                if (this .contextStartupError == null) {
1026:                    // Load sessions if enabled
1027:                    if (this .useSavedSessions) {
1028:                        WinstoneSession.loadSessions(this );
1029:                    }
1030:
1031:                    // Initialise all the filters
1032:                    for (Iterator i = this .filterInstances.values().iterator(); i
1033:                            .hasNext();) {
1034:                        FilterConfiguration config = (FilterConfiguration) i
1035:                                .next();
1036:                        try {
1037:                            config.getFilter();
1038:                        } catch (ServletException err) {
1039:                            Logger.log(Logger.ERROR, Launcher.RESOURCES,
1040:                                    "WebAppConfig.FilterStartupError", config
1041:                                            .getFilterName(), err);
1042:                        }
1043:                    }
1044:
1045:                    // Initialise load on startup servlets
1046:                    Object autoStarters[] = startupServlets.toArray();
1047:                    Arrays.sort(autoStarters);
1048:                    for (int n = 0; n < autoStarters.length; n++) {
1049:                        ((ServletConfiguration) autoStarters[n])
1050:                                .ensureInitialization();
1051:                    }
1052:                }
1053:            }
1054:
1055:            /**
1056:             * Build the web-app classloader. This tries to load the preferred classloader first, 
1057:             * but if it fails, falls back to a simple URLClassLoader.
1058:             */
1059:            private ClassLoader buildWebAppClassLoader(Map startupArgs,
1060:                    ClassLoader parentClassLoader, String webRoot,
1061:                    List classPathFileList) {
1062:                List urlList = new ArrayList();
1063:
1064:                try {
1065:                    // Web-inf folder
1066:                    File webInfFolder = new File(webRoot, WEB_INF);
1067:
1068:                    // Classes folder
1069:                    File classesFolder = new File(webInfFolder, CLASSES);
1070:                    if (classesFolder.exists()) {
1071:                        Logger.log(Logger.DEBUG, Launcher.RESOURCES,
1072:                                "WebAppConfig.WebAppClasses");
1073:                        String classesFolderURL = classesFolder
1074:                                .getCanonicalFile().toURL().toString();
1075:                        urlList
1076:                                .add(new URL(
1077:                                        classesFolderURL.endsWith("/") ? classesFolderURL
1078:                                                : classesFolderURL + "/"));
1079:                        classPathFileList.add(classesFolder);
1080:                    } else {
1081:                        Logger.log(Logger.WARNING, Launcher.RESOURCES,
1082:                                "WebAppConfig.NoWebAppClasses", classesFolder
1083:                                        .toString());
1084:                    }
1085:
1086:                    // Lib folder's jar files
1087:                    File libFolder = new File(webInfFolder, LIB);
1088:                    if (libFolder.exists()) {
1089:                        File jars[] = libFolder.listFiles();
1090:                        for (int n = 0; n < jars.length; n++) {
1091:                            String jarName = jars[n].getName().toLowerCase();
1092:                            if (jarName.endsWith(".jar")
1093:                                    || jarName.endsWith(".zip")) {
1094:                                Logger.log(Logger.DEBUG, Launcher.RESOURCES,
1095:                                        "WebAppConfig.WebAppLib", jars[n]
1096:                                                .getName());
1097:                                urlList.add(jars[n].toURL());
1098:                                classPathFileList.add(jars[n]);
1099:                            }
1100:                        }
1101:                    } else {
1102:                        Logger.log(Logger.WARNING, Launcher.RESOURCES,
1103:                                "WebAppConfig.NoWebAppLib", libFolder
1104:                                        .toString());
1105:                    }
1106:                } catch (MalformedURLException err) {
1107:                    throw new WinstoneException(Launcher.RESOURCES
1108:                            .getString("WebAppConfig.BadURL"), err);
1109:                } catch (IOException err) {
1110:                    throw new WinstoneException(Launcher.RESOURCES
1111:                            .getString("WebAppConfig.IOException"), err);
1112:                }
1113:
1114:                URL jarURLs[] = (URL[]) urlList
1115:                        .toArray(new URL[urlList.size()]);
1116:
1117:                String preferredClassLoader = stringArg(startupArgs,
1118:                        "preferredClassLoader", WEBAPP_CL_CLASS);
1119:                if (booleanArg(startupArgs, "useServletReloading", false)
1120:                        && stringArg(startupArgs, "preferredClassLoader", "")
1121:                                .equals("")) {
1122:                    preferredClassLoader = RELOADING_CL_CLASS;
1123:                }
1124:
1125:                // Try to set up the preferred class loader, and if we fail, use the normal one
1126:                ClassLoader outputCL = null;
1127:                if (!preferredClassLoader.equals("")) {
1128:                    try {
1129:                        Class preferredCL = Class.forName(preferredClassLoader,
1130:                                true, parentClassLoader);
1131:                        Constructor reloadConstr = preferredCL
1132:                                .getConstructor(new Class[] { URL[].class,
1133:                                        ClassLoader.class });
1134:                        outputCL = (ClassLoader) reloadConstr
1135:                                .newInstance(new Object[] { jarURLs,
1136:                                        parentClassLoader });
1137:                    } catch (Throwable err) {
1138:                        if (!stringArg(startupArgs, "preferredClassLoader", "")
1139:                                .equals("")
1140:                                || !preferredClassLoader
1141:                                        .equals(WEBAPP_CL_CLASS)) {
1142:                            Logger.log(Logger.ERROR, Launcher.RESOURCES,
1143:                                    "WebAppConfig.CLError", err);
1144:                        }
1145:                    }
1146:                }
1147:
1148:                if (outputCL == null) {
1149:                    outputCL = new URLClassLoader(jarURLs, parentClassLoader);
1150:                }
1151:
1152:                Logger.log(Logger.MAX, Launcher.RESOURCES,
1153:                        "WebAppConfig.WebInfClassLoader", outputCL.toString());
1154:                return outputCL;
1155:            }
1156:
1157:            private void addListenerInstance(Object listenerInstance,
1158:                    List contextAttributeListeners, List contextListeners,
1159:                    List requestAttributeListeners, List requestListeners,
1160:                    List sessionActivationListeners,
1161:                    List sessionAttributeListeners, List sessionListeners) {
1162:                if (listenerInstance instanceof  ServletContextAttributeListener)
1163:                    contextAttributeListeners.add(listenerInstance);
1164:                if (listenerInstance instanceof  ServletContextListener)
1165:                    contextListeners.add(listenerInstance);
1166:                if (listenerInstance instanceof  ServletRequestAttributeListener)
1167:                    requestAttributeListeners.add(listenerInstance);
1168:                if (listenerInstance instanceof  ServletRequestListener)
1169:                    requestListeners.add(listenerInstance);
1170:                if (listenerInstance instanceof  HttpSessionActivationListener)
1171:                    sessionActivationListeners.add(listenerInstance);
1172:                if (listenerInstance instanceof  HttpSessionAttributeListener)
1173:                    sessionAttributeListeners.add(listenerInstance);
1174:                if (listenerInstance instanceof  HttpSessionListener)
1175:                    sessionListeners.add(listenerInstance);
1176:            }
1177:
1178:            public String getContextPath() {
1179:                return this .prefix;
1180:            }
1181:
1182:            public String getWebroot() {
1183:                return this .webRoot;
1184:            }
1185:
1186:            public ClassLoader getLoader() {
1187:                return this .loader;
1188:            }
1189:
1190:            public AccessLogger getAccessLogger() {
1191:                return this .accessLogger;
1192:            }
1193:
1194:            public Map getFilters() {
1195:                return this .filterInstances;
1196:            }
1197:
1198:            public String getContextName() {
1199:                return this .contextName;
1200:            }
1201:
1202:            public Class[] getErrorPageExceptions() {
1203:                return this .errorPagesByExceptionKeysSorted;
1204:            }
1205:
1206:            public Map getErrorPagesByException() {
1207:                return this .errorPagesByException;
1208:            }
1209:
1210:            public Map getErrorPagesByCode() {
1211:                return this .errorPagesByCode;
1212:            }
1213:
1214:            public Map getLocaleEncodingMap() {
1215:                return this .localeEncodingMap;
1216:            }
1217:
1218:            public String[] getWelcomeFiles() {
1219:                return this .welcomeFiles;
1220:            }
1221:
1222:            public boolean isDistributable() {
1223:                return (this .cluster != null);
1224:            }
1225:
1226:            public Map getFilterMatchCache() {
1227:                return this .filterMatchCache;
1228:            }
1229:
1230:            public String getOwnerHostname() {
1231:                return this .ownerHostConfig.getHostname();
1232:            }
1233:
1234:            public ServletRequestListener[] getRequestListeners() {
1235:                return this .requestListeners;
1236:            }
1237:
1238:            public ServletRequestAttributeListener[] getRequestAttributeListeners() {
1239:                return this .requestAttributeListeners;
1240:            }
1241:
1242:            public static void addJspServletParams(Map jspParams) {
1243:                jspParams.put("logVerbosityLevel", JSP_SERVLET_LOG_LEVEL);
1244:                jspParams.put("fork", "false");
1245:            }
1246:
1247:            public int compare(Object one, Object two) {
1248:                if (!(one instanceof  Class) || !(two instanceof  Class))
1249:                    throw new IllegalArgumentException(
1250:                            "This comparator is only for sorting classes");
1251:                Class classOne = (Class) one;
1252:                Class classTwo = (Class) two;
1253:                if (classOne.isAssignableFrom(classTwo))
1254:                    return 1;
1255:                else if (classTwo.isAssignableFrom(classOne))
1256:                    return -1;
1257:                else
1258:                    return 0;
1259:            }
1260:
1261:            public String getServletURIFromRequestURI(String requestURI) {
1262:                if (prefix.equals("")) {
1263:                    return requestURI;
1264:                } else if (requestURI.startsWith(prefix)) {
1265:                    return requestURI.substring(prefix.length());
1266:                } else {
1267:                    throw new WinstoneException("This shouldn't happen, "
1268:                            + "since we aborted earlier if we didn't match");
1269:                }
1270:            }
1271:
1272:            /**
1273:             * Iterates through each of the servlets/filters and calls destroy on them
1274:             */
1275:            public void destroy() {
1276:                synchronized (this .filterMatchCache) {
1277:                    this .filterMatchCache.clear();
1278:                }
1279:
1280:                Collection filterInstances = new ArrayList(this .filterInstances
1281:                        .values());
1282:                for (Iterator i = filterInstances.iterator(); i.hasNext();) {
1283:                    try {
1284:                        ((FilterConfiguration) i.next()).destroy();
1285:                    } catch (Throwable err) {
1286:                        Logger.log(Logger.ERROR, Launcher.RESOURCES,
1287:                                "WebAppConfig.ShutdownError", err);
1288:                    }
1289:                }
1290:                this .filterInstances.clear();
1291:
1292:                Collection servletInstances = new ArrayList(
1293:                        this .servletInstances.values());
1294:                for (Iterator i = servletInstances.iterator(); i.hasNext();) {
1295:                    try {
1296:                        ((ServletConfiguration) i.next()).destroy();
1297:                    } catch (Throwable err) {
1298:                        Logger.log(Logger.ERROR, Launcher.RESOURCES,
1299:                                "WebAppConfig.ShutdownError", err);
1300:                    }
1301:                }
1302:                this .servletInstances.clear();
1303:
1304:                // Drop all sessions
1305:                Collection sessions = new ArrayList(this .sessions.values());
1306:                for (Iterator i = sessions.iterator(); i.hasNext();) {
1307:                    WinstoneSession session = (WinstoneSession) i.next();
1308:                    try {
1309:                        if (this .useSavedSessions) {
1310:                            session.saveToTemp();
1311:                        } else {
1312:                            session.invalidate();
1313:                        }
1314:                    } catch (Throwable err) {
1315:                        Logger.log(Logger.ERROR, Launcher.RESOURCES,
1316:                                "WebAppConfig.ShutdownError", err);
1317:                    }
1318:                }
1319:                this .sessions.clear();
1320:
1321:                // Send destroy notifies - backwards
1322:                for (int n = this .contextListeners.length - 1; n >= 0; n--) {
1323:                    try {
1324:                        ClassLoader cl = Thread.currentThread()
1325:                                .getContextClassLoader();
1326:                        Thread.currentThread().setContextClassLoader(
1327:                                this .loader);
1328:                        this .contextListeners[n]
1329:                                .contextDestroyed(new ServletContextEvent(this ));
1330:                        this .contextListeners[n] = null;
1331:                        Thread.currentThread().setContextClassLoader(cl);
1332:                    } catch (Throwable err) {
1333:                        Logger.log(Logger.ERROR, Launcher.RESOURCES,
1334:                                "WebAppConfig.ShutdownError", err);
1335:                    }
1336:                }
1337:                this .contextListeners = null;
1338:
1339:                // Terminate class loader reloading thread if running
1340:                if (this .loader != null) {
1341:                    // already shutdown/handled by the servlet context listeners
1342:                    //            try {
1343:                    //                Method methDestroy = this.loader.getClass().getMethod("destroy", new Class[0]);
1344:                    //                methDestroy.invoke(this.loader, new Object[0]);
1345:                    //            } catch (Throwable err) {
1346:                    //                Logger.log(Logger.ERROR, Launcher.RESOURCES, "WebAppConfig.ShutdownError", err);
1347:                    //            }
1348:                    this .loader = null;
1349:                }
1350:
1351:                // Kill JNDI manager if we have one
1352:                if (this .jndiManager != null) {
1353:                    this .jndiManager.tearDown();
1354:                    this .jndiManager = null;
1355:                }
1356:
1357:                // Kill JNDI manager if we have one
1358:                if (this .accessLogger != null) {
1359:                    this .accessLogger.destroy();
1360:                    this .accessLogger = null;
1361:                }
1362:            }
1363:
1364:            /**
1365:             * Triggered by the admin thread on the reloading class loader. This will
1366:             * cause a full shutdown and reinstantiation of the web app - not real
1367:             * graceful, but you shouldn't have reloading turned on in high load
1368:             * environments.
1369:             */
1370:            public void resetClassLoader() throws IOException {
1371:                this .ownerHostConfig.reloadWebApp(getContextPath());
1372:            }
1373:
1374:            /**
1375:             * Here we process url patterns into the exactMatch and patternMatch lists
1376:             */
1377:            private void processMapping(String name, String pattern,
1378:                    Map exactPatterns, List folderPatterns,
1379:                    List extensionPatterns) {
1380:
1381:                Mapping urlPattern = null;
1382:                try {
1383:                    urlPattern = Mapping.createFromURL(name, pattern);
1384:                } catch (WinstoneException err) {
1385:                    Logger.log(Logger.WARNING, Launcher.RESOURCES,
1386:                            "WebAppConfig.ErrorMapURL", err.getMessage());
1387:                    return;
1388:                }
1389:
1390:                // put the pattern in the correct list
1391:                if (urlPattern.getPatternType() == Mapping.EXACT_PATTERN) {
1392:                    exactPatterns.put(urlPattern.getUrlPattern(), name);
1393:                } else if (urlPattern.getPatternType() == Mapping.FOLDER_PATTERN) {
1394:                    folderPatterns.add(urlPattern);
1395:                } else if (urlPattern.getPatternType() == Mapping.EXTENSION_PATTERN) {
1396:                    extensionPatterns.add(urlPattern);
1397:                } else if (urlPattern.getPatternType() == Mapping.DEFAULT_SERVLET) {
1398:                    this .defaultServletName = name;
1399:                } else {
1400:                    Logger.log(Logger.WARNING, Launcher.RESOURCES,
1401:                            "WebAppConfig.InvalidMount", new String[] { name,
1402:                                    pattern });
1403:                }
1404:            }
1405:
1406:            /**
1407:             * Execute the pattern match, and try to return a servlet that matches this
1408:             * URL
1409:             */
1410:            private ServletConfiguration urlMatch(String path,
1411:                    StringBuffer servletPath, StringBuffer pathInfo) {
1412:                Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
1413:                        "WebAppConfig.URLMatch", path);
1414:
1415:                // Check exact matches first
1416:                String exact = (String) this .exactServletMatchMounts.get(path);
1417:                if (exact != null) {
1418:                    if (this .servletInstances.get(exact) != null) {
1419:                        servletPath
1420:                                .append(WinstoneRequest.decodeURLToken(path));
1421:                        // pathInfo.append(""); // a hack - empty becomes null later
1422:                        return (ServletConfiguration) this .servletInstances
1423:                                .get(exact);
1424:                    }
1425:                }
1426:
1427:                // Inexact mount check
1428:                for (int n = 0; n < this .patternMatches.length; n++) {
1429:                    Mapping urlPattern = this .patternMatches[n];
1430:                    if (urlPattern.match(path, servletPath, pathInfo)
1431:                            && (this .servletInstances.get(urlPattern
1432:                                    .getMappedTo()) != null)) {
1433:                        return (ServletConfiguration) this .servletInstances
1434:                                .get(urlPattern.getMappedTo());
1435:                    }
1436:                }
1437:
1438:                // return default servlet
1439:                // servletPath.append(""); // unneeded
1440:                if (this .servletInstances.get(this .defaultServletName) == null)
1441:                    throw new WinstoneException(Launcher.RESOURCES.getString(
1442:                            "WebAppConfig.MatchedNonExistServlet",
1443:                            this .defaultServletName));
1444:                //        pathInfo.append(path);
1445:                servletPath.append(WinstoneRequest.decodeURLToken(path));
1446:                return (ServletConfiguration) this .servletInstances
1447:                        .get(this .defaultServletName);
1448:            }
1449:
1450:            /**
1451:             * Constructs a session instance with the given sessionId
1452:             * 
1453:             * @param sessionId The sessionID for the new session
1454:             * @return A valid session object
1455:             */
1456:            public WinstoneSession makeNewSession(String sessionId) {
1457:                WinstoneSession ws = new WinstoneSession(sessionId);
1458:                ws.setWebAppConfiguration(this );
1459:                setSessionListeners(ws);
1460:                if ((this .sessionTimeout != null)
1461:                        && (this .sessionTimeout.intValue() > 0)) {
1462:                    ws
1463:                            .setMaxInactiveInterval(this .sessionTimeout
1464:                                    .intValue() * 60);
1465:                } else {
1466:                    ws.setMaxInactiveInterval(-1);
1467:                }
1468:                ws.setLastAccessedDate(System.currentTimeMillis());
1469:                ws.sendCreatedNotifies();
1470:                this .sessions.put(sessionId, ws);
1471:                return ws;
1472:            }
1473:
1474:            /**
1475:             * Retrieves the session by id. If the web app is distributable, it asks the
1476:             * other members of the cluster if it doesn't have it itself.
1477:             * 
1478:             * @param sessionId The id of the session we want
1479:             * @return A valid session instance
1480:             */
1481:            public WinstoneSession getSessionById(String sessionId,
1482:                    boolean localOnly) {
1483:                if (sessionId == null) {
1484:                    return null;
1485:                }
1486:                WinstoneSession session = (WinstoneSession) this .sessions
1487:                        .get(sessionId);
1488:                if (session != null) {
1489:                    return session;
1490:                }
1491:
1492:                // If I'm distributable ... check remotely
1493:                if ((this .cluster != null) && !localOnly) {
1494:                    session = this .cluster
1495:                            .askClusterForSession(sessionId, this );
1496:                    if (session != null) {
1497:                        this .sessions.put(sessionId, session);
1498:                    }
1499:                    return session;
1500:                } else {
1501:                    return null;
1502:                }
1503:            }
1504:
1505:            /**
1506:             * Add/Remove the session from the collection
1507:             */
1508:            void removeSessionById(String sessionId) {
1509:                this .sessions.remove(sessionId);
1510:            }
1511:
1512:            void addSession(String sessionId, WinstoneSession session) {
1513:                this .sessions.put(sessionId, session);
1514:            }
1515:
1516:            public void invalidateExpiredSessions() {
1517:                Object allSessions[] = this .sessions.values().toArray();
1518:                int expiredCount = 0;
1519:
1520:                for (int n = 0; n < allSessions.length; n++) {
1521:                    WinstoneSession session = (WinstoneSession) allSessions[n];
1522:                    if (!session.isNew() && session.isUnusedByRequests()
1523:                            && session.isExpired()) {
1524:                        session.invalidate();
1525:                        expiredCount++;
1526:                    }
1527:                }
1528:                if (expiredCount > 0) {
1529:                    Logger.log(Logger.DEBUG, Launcher.RESOURCES,
1530:                            "WebAppConfig.InvalidatedSessions", expiredCount
1531:                                    + "");
1532:                }
1533:            }
1534:
1535:            public void setSessionListeners(WinstoneSession session) {
1536:                session
1537:                        .setSessionActivationListeners(this .sessionActivationListeners);
1538:                session
1539:                        .setSessionAttributeListeners(this .sessionAttributeListeners);
1540:                session.setSessionListeners(this .sessionListeners);
1541:            }
1542:
1543:            public void removeServletConfigurationAndMappings(
1544:                    ServletConfiguration config) {
1545:                this .servletInstances.remove(config.getServletName());
1546:                // The urlMatch method will only match to non-null mappings, so we don't need
1547:                // to remove anything here
1548:            }
1549:
1550:            /***************************************************************************
1551:             * 
1552:             * OK ... from here to the end is the interface implementation methods for
1553:             * the servletContext interface.
1554:             * 
1555:             **************************************************************************/
1556:
1557:            // Application level attributes
1558:            public Object getAttribute(String name) {
1559:                return this .attributes.get(name);
1560:            }
1561:
1562:            public Enumeration getAttributeNames() {
1563:                return Collections.enumeration(this .attributes.keySet());
1564:            }
1565:
1566:            public void removeAttribute(String name) {
1567:                Object me = this .attributes.get(name);
1568:                this .attributes.remove(name);
1569:                if (me != null)
1570:                    for (int n = 0; n < this .contextAttributeListeners.length; n++) {
1571:                        ClassLoader cl = Thread.currentThread()
1572:                                .getContextClassLoader();
1573:                        Thread.currentThread().setContextClassLoader(
1574:                                getLoader());
1575:                        this .contextAttributeListeners[n]
1576:                                .attributeRemoved(new ServletContextAttributeEvent(
1577:                                        this , name, me));
1578:                        Thread.currentThread().setContextClassLoader(cl);
1579:                    }
1580:            }
1581:
1582:            public void setAttribute(String name, Object object) {
1583:                if (object == null) {
1584:                    removeAttribute(name);
1585:                } else {
1586:                    Object me = this .attributes.get(name);
1587:                    this .attributes.put(name, object);
1588:                    if (me != null) {
1589:                        for (int n = 0; n < this .contextAttributeListeners.length; n++) {
1590:                            ClassLoader cl = Thread.currentThread()
1591:                                    .getContextClassLoader();
1592:                            Thread.currentThread().setContextClassLoader(
1593:                                    getLoader());
1594:                            this .contextAttributeListeners[n]
1595:                                    .attributeReplaced(new ServletContextAttributeEvent(
1596:                                            this , name, me));
1597:                            Thread.currentThread().setContextClassLoader(cl);
1598:                        }
1599:                    } else {
1600:                        for (int n = 0; n < this .contextAttributeListeners.length; n++) {
1601:                            ClassLoader cl = Thread.currentThread()
1602:                                    .getContextClassLoader();
1603:                            Thread.currentThread().setContextClassLoader(
1604:                                    getLoader());
1605:                            this .contextAttributeListeners[n]
1606:                                    .attributeAdded(new ServletContextAttributeEvent(
1607:                                            this , name, object));
1608:                            Thread.currentThread().setContextClassLoader(cl);
1609:                        }
1610:                    }
1611:                }
1612:            }
1613:
1614:            // Application level init parameters
1615:            public String getInitParameter(String name) {
1616:                return (String) this .initParameters.get(name);
1617:            }
1618:
1619:            public Enumeration getInitParameterNames() {
1620:                return Collections.enumeration(this .initParameters.keySet());
1621:            }
1622:
1623:            // Server info
1624:            public String getServerInfo() {
1625:                return Launcher.RESOURCES.getString("ServerVersion");
1626:            }
1627:
1628:            public int getMajorVersion() {
1629:                return 2;
1630:            }
1631:
1632:            public int getMinorVersion() {
1633:                return 5;
1634:            }
1635:
1636:            // Weird mostly deprecated crap to do with getting servlet instances
1637:            public javax.servlet.ServletContext getContext(String uri) {
1638:                return this .ownerHostConfig.getWebAppByURI(uri);
1639:            }
1640:
1641:            public String getServletContextName() {
1642:                return this .displayName;
1643:            }
1644:
1645:            /**
1646:             * Look up the map of mimeType extensions, and return the type that matches
1647:             */
1648:            public String getMimeType(String fileName) {
1649:                int dotPos = fileName.lastIndexOf('.');
1650:                if ((dotPos != -1) && (dotPos != fileName.length() - 1)) {
1651:                    String extension = fileName.substring(dotPos + 1)
1652:                            .toLowerCase();
1653:                    String mimeType = (String) this .mimeTypes.get(extension);
1654:                    return mimeType;
1655:                } else
1656:                    return null;
1657:            }
1658:
1659:            // Context level log statements
1660:            public void log(String message) {
1661:                Logger.logDirectMessage(Logger.INFO, this .contextName, message,
1662:                        null);
1663:            }
1664:
1665:            public void log(String message, Throwable throwable) {
1666:                Logger.logDirectMessage(Logger.ERROR, this .contextName,
1667:                        message, throwable);
1668:            }
1669:
1670:            /**
1671:             * Named dispatcher - this basically gets us a simple exact dispatcher (no
1672:             * url matching, no request attributes and no security)
1673:             */
1674:            public javax.servlet.RequestDispatcher getNamedDispatcher(
1675:                    String name) {
1676:                ServletConfiguration servlet = (ServletConfiguration) this .servletInstances
1677:                        .get(name);
1678:                if (servlet != null) {
1679:                    RequestDispatcher rd = new RequestDispatcher(this , servlet);
1680:                    if (rd != null) {
1681:                        rd.setForNamedDispatcher(this .filterPatternsForward,
1682:                                this .filterPatternsInclude);
1683:                        return rd;
1684:                    }
1685:                }
1686:                return null;
1687:            }
1688:
1689:            /**
1690:             * Gets a dispatcher, which sets the request attributes, etc on a
1691:             * forward/include. Doesn't execute security though.
1692:             */
1693:            public javax.servlet.RequestDispatcher getRequestDispatcher(
1694:                    String uriInsideWebapp) {
1695:                if (uriInsideWebapp == null) {
1696:                    return null;
1697:                } else if (!uriInsideWebapp.startsWith("/")) {
1698:                    return null;
1699:                }
1700:
1701:                // Parse the url for query string, etc
1702:                String queryString = "";
1703:                int questionPos = uriInsideWebapp.indexOf('?');
1704:                if (questionPos != -1) {
1705:                    if (questionPos != uriInsideWebapp.length() - 1) {
1706:                        queryString = uriInsideWebapp
1707:                                .substring(questionPos + 1);
1708:                    }
1709:                    uriInsideWebapp = uriInsideWebapp.substring(0, questionPos);
1710:                }
1711:
1712:                // Return the dispatcher
1713:                StringBuffer servletPath = new StringBuffer();
1714:                StringBuffer pathInfo = new StringBuffer();
1715:                ServletConfiguration servlet = urlMatch(uriInsideWebapp,
1716:                        servletPath, pathInfo);
1717:                if (servlet != null) {
1718:                    RequestDispatcher rd = new RequestDispatcher(this , servlet);
1719:                    if (rd != null) {
1720:                        rd.setForURLDispatcher(servletPath.toString(), pathInfo
1721:                                .toString().equals("") ? null : pathInfo
1722:                                .toString(), queryString, uriInsideWebapp,
1723:                                this .filterPatternsForward,
1724:                                this .filterPatternsInclude);
1725:                        return rd;
1726:                    }
1727:                }
1728:                return null;
1729:            }
1730:
1731:            /**
1732:             * Creates the dispatcher that corresponds to a request level dispatch (ie
1733:             * the initial entry point). The difference here is that we need to set up
1734:             * the dispatcher so that on a forward, it executes the security checks and
1735:             * the request filters, while not setting any of the request attributes for
1736:             * a forward. Also, we can't return a null dispatcher in error case - instead 
1737:             * we have to return a dispatcher pre-init'd for showing an error page (eg 404).
1738:             * A null dispatcher is interpreted to mean a successful 302 has occurred. 
1739:             */
1740:            public RequestDispatcher getInitialDispatcher(
1741:                    String uriInsideWebapp, WinstoneRequest request,
1742:                    WinstoneResponse response) throws IOException {
1743:                if (!uriInsideWebapp.equals("")
1744:                        && !uriInsideWebapp.startsWith("/")) {
1745:                    return this 
1746:                            .getErrorDispatcherByCode(
1747:                                    HttpServletResponse.SC_BAD_REQUEST,
1748:                                    Launcher.RESOURCES.getString(
1749:                                            "WebAppConfig.InvalidURI",
1750:                                            uriInsideWebapp), null);
1751:                } else if (this .contextStartupError != null) {
1752:                    StringWriter sw = new StringWriter();
1753:                    PrintWriter pw = new PrintWriter(sw, true);
1754:                    this .contextStartupError.printStackTrace(pw);
1755:                    return this .getErrorDispatcherByCode(
1756:                            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1757:                            Launcher.RESOURCES.getString(
1758:                                    "WebAppConfig.ErrorDuringStartup", sw
1759:                                            .toString()),
1760:                            this .contextStartupError);
1761:                }
1762:
1763:                // Parse the url for query string, etc 
1764:                String queryString = "";
1765:                int questionPos = uriInsideWebapp.indexOf('?');
1766:                if (questionPos != -1) {
1767:                    if (questionPos != uriInsideWebapp.length() - 1)
1768:                        queryString = uriInsideWebapp
1769:                                .substring(questionPos + 1);
1770:                    uriInsideWebapp = uriInsideWebapp.substring(0, questionPos);
1771:                }
1772:
1773:                // Return the dispatcher
1774:                StringBuffer servletPath = new StringBuffer();
1775:                StringBuffer pathInfo = new StringBuffer();
1776:                ServletConfiguration servlet = urlMatch(uriInsideWebapp,
1777:                        servletPath, pathInfo);
1778:                if (servlet != null) {
1779:                    // If the default servlet was returned, we should check for welcome files
1780:                    if (servlet.getServletName()
1781:                            .equals(this .defaultServletName)) {
1782:                        // Is path a directory ?
1783:                        String directoryPath = servletPath.toString();
1784:                        if (directoryPath.endsWith("/")) {
1785:                            directoryPath = directoryPath.substring(0,
1786:                                    directoryPath.length() - 1);
1787:                        }
1788:                        if (directoryPath.startsWith("/")) {
1789:                            directoryPath = directoryPath.substring(1);
1790:                        }
1791:
1792:                        File res = new File(webRoot, directoryPath);
1793:                        if (res.exists()
1794:                                && res.isDirectory()
1795:                                && (request.getMethod().equals("GET") || request
1796:                                        .getMethod().equals("HEAD"))) {
1797:                            // Check for the send back with slash case
1798:                            if (!servletPath.toString().endsWith("/")) {
1799:                                Logger.log(Logger.FULL_DEBUG,
1800:                                        Launcher.RESOURCES,
1801:                                        "WebAppConfig.FoundNonSlashDirectory",
1802:                                        servletPath.toString());
1803:                                response.sendRedirect(this .prefix
1804:                                        + servletPath.toString()
1805:                                        + pathInfo.toString()
1806:                                        + "/"
1807:                                        + (queryString.equals("") ? "" : "?"
1808:                                                + queryString));
1809:                                return null;
1810:                            }
1811:
1812:                            // Check for welcome files
1813:                            Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
1814:                                    "WebAppConfig.CheckWelcomeFile",
1815:                                    servletPath.toString()
1816:                                            + pathInfo.toString());
1817:                            String welcomeFile = matchWelcomeFiles(servletPath
1818:                                    .toString()
1819:                                    + pathInfo.toString(), request, queryString);
1820:                            if (welcomeFile != null) {
1821:                                response
1822:                                        .sendRedirect(this .prefix + welcomeFile);
1823:                                //                                + servletPath.toString()
1824:                                //                                + pathInfo.toString()
1825:                                //                                + welcomeFile
1826:                                //                                + (queryString.equals("") ? "" : "?" + queryString));
1827:                                return null;
1828:                            }
1829:                        }
1830:                    }
1831:
1832:                    RequestDispatcher rd = new RequestDispatcher(this , servlet);
1833:                    rd.setForInitialDispatcher(servletPath.toString(),
1834:                            pathInfo.toString().equals("") ? null : pathInfo
1835:                                    .toString(), queryString, uriInsideWebapp,
1836:                            this .filterPatternsRequest,
1837:                            this .authenticationHandler);
1838:                    return rd;
1839:                }
1840:
1841:                // If we are here, return a 404
1842:                return this .getErrorDispatcherByCode(
1843:                        HttpServletResponse.SC_NOT_FOUND, Launcher.RESOURCES
1844:                                .getString(
1845:                                        "StaticResourceServlet.PathNotFound",
1846:                                        uriInsideWebapp), null);
1847:            }
1848:
1849:            /**
1850:             * Gets a dispatcher, set up for error dispatch.
1851:             */
1852:            public RequestDispatcher getErrorDispatcherByClass(
1853:                    Throwable exception) {
1854:
1855:                // Check for exception class match
1856:                Class exceptionClasses[] = this .errorPagesByExceptionKeysSorted;
1857:                Throwable errWrapper = new ServletException(exception);
1858:
1859:                while (errWrapper instanceof  ServletException) {
1860:                    errWrapper = ((ServletException) errWrapper).getRootCause();
1861:                    if (errWrapper == null) {
1862:                        break;
1863:                    }
1864:                    for (int n = 0; n < exceptionClasses.length; n++) {
1865:
1866:                        Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES,
1867:                                "WinstoneResponse.TestingException",
1868:                                new String[] {
1869:                                        this .errorPagesByExceptionKeysSorted[n]
1870:                                                .getName(),
1871:                                        errWrapper.getClass().getName() });
1872:                        if (exceptionClasses[n].isInstance(errWrapper)) {
1873:                            String errorURI = (String) this .errorPagesByException
1874:                                    .get(exceptionClasses[n]);
1875:                            if (errorURI != null) {
1876:                                RequestDispatcher rd = buildErrorDispatcher(
1877:                                        errorURI,
1878:                                        HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
1879:                                        null, errWrapper);
1880:                                if (rd != null) {
1881:                                    return rd;
1882:                                }
1883:                            } else {
1884:                                Logger
1885:                                        .log(
1886:                                                Logger.WARNING,
1887:                                                Launcher.RESOURCES,
1888:                                                "WinstoneResponse.SkippingException",
1889:                                                new String[] {
1890:                                                        exceptionClasses[n]
1891:                                                                .getName(),
1892:                                                        (String) this .errorPagesByException
1893:                                                                .get(exceptionClasses[n]) });
1894:                            }
1895:                        } else {
1896:                            Logger.log(Logger.WARNING, Launcher.RESOURCES,
1897:                                    "WinstoneResponse.ExceptionNotMatched",
1898:                                    exceptionClasses[n].getName());
1899:                        }
1900:                    }
1901:                }
1902:
1903:                // Otherwise throw a code error
1904:                Throwable errPassDown = exception;
1905:                while ((errPassDown instanceof  ServletException)
1906:                        && (((ServletException) errPassDown).getRootCause() != null)) {
1907:                    errPassDown = ((ServletException) errPassDown)
1908:                            .getRootCause();
1909:                }
1910:                return getErrorDispatcherByCode(
1911:                        HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null,
1912:                        errPassDown);
1913:            }
1914:
1915:            public RequestDispatcher getErrorDispatcherByCode(int statusCode,
1916:                    String summaryMessage, Throwable exception) {
1917:                // Check for status code match
1918:                String errorURI = (String) getErrorPagesByCode().get(
1919:                        "" + statusCode);
1920:                if (errorURI != null) {
1921:                    RequestDispatcher rd = buildErrorDispatcher(errorURI,
1922:                            statusCode, summaryMessage, exception);
1923:                    if (rd != null) {
1924:                        return rd;
1925:                    }
1926:                }
1927:
1928:                // If no dispatcher available, return a dispatcher to the default error formatter
1929:                ServletConfiguration errorServlet = (ServletConfiguration) this .servletInstances
1930:                        .get(this .errorServletName);
1931:                if (errorServlet != null) {
1932:                    RequestDispatcher rd = new RequestDispatcher(this ,
1933:                            errorServlet);
1934:                    if (rd != null) {
1935:                        rd.setForErrorDispatcher(null, null, null, statusCode,
1936:                                summaryMessage, exception, null,
1937:                                this .filterPatternsError);
1938:                        return rd;
1939:                    }
1940:                }
1941:
1942:                // Otherwise log and return null
1943:                Logger.log(Logger.ERROR, Launcher.RESOURCES,
1944:                        "WebAppConfig.NoErrorServlet", "" + statusCode,
1945:                        exception);
1946:                return null;
1947:            }
1948:
1949:            /**
1950:             * Build a dispatcher to the error handler if it's available. If it fails, return null.
1951:             */
1952:            private RequestDispatcher buildErrorDispatcher(String errorURI,
1953:                    int statusCode, String summaryMessage, Throwable exception) {
1954:                // Parse the url for query string, etc 
1955:                String queryString = "";
1956:                int questionPos = errorURI.indexOf('?');
1957:                if (questionPos != -1) {
1958:                    if (questionPos != errorURI.length() - 1) {
1959:                        queryString = errorURI.substring(questionPos + 1);
1960:                    }
1961:                    errorURI = errorURI.substring(0, questionPos);
1962:                }
1963:
1964:                // Get the message by recursing if none supplied
1965:                ServletException errIterator = new ServletException(exception);
1966:                while ((summaryMessage == null) && (errIterator != null)) {
1967:                    summaryMessage = errIterator.getMessage();
1968:                    if (errIterator.getRootCause() instanceof  ServletException) {
1969:                        errIterator = (ServletException) errIterator
1970:                                .getRootCause();
1971:                    } else {
1972:                        if (summaryMessage == null) {
1973:                            summaryMessage = errIterator.getRootCause()
1974:                                    .getMessage();
1975:                        }
1976:                        errIterator = null;
1977:                    }
1978:                }
1979:
1980:                // Return the dispatcher
1981:                StringBuffer servletPath = new StringBuffer();
1982:                StringBuffer pathInfo = new StringBuffer();
1983:                ServletConfiguration servlet = urlMatch(errorURI, servletPath,
1984:                        pathInfo);
1985:                if (servlet != null) {
1986:                    RequestDispatcher rd = new RequestDispatcher(this , servlet);
1987:                    if (rd != null) {
1988:                        rd.setForErrorDispatcher(servletPath.toString(),
1989:                                pathInfo.toString().equals("") ? null
1990:                                        : pathInfo.toString(), queryString,
1991:                                statusCode, summaryMessage, exception,
1992:                                errorURI, this .filterPatternsError);
1993:                        return rd;
1994:                    }
1995:                }
1996:                return null;
1997:            }
1998:
1999:            /**
2000:             * Check if any of the welcome files under this path are available. Returns the 
2001:             * name of the file if found, null otherwise. Returns the full internal webapp uri
2002:             */
2003:            private String matchWelcomeFiles(String path,
2004:                    WinstoneRequest request, String queryString) {
2005:                if (!path.endsWith("/")) {
2006:                    path = path + "/";
2007:                }
2008:
2009:                String qs = (queryString.equals("") ? "" : "?" + queryString);
2010:                for (int n = 0; n < this .welcomeFiles.length; n++) {
2011:                    String welcomeFile = this .welcomeFiles[n];
2012:                    while (welcomeFile.startsWith("/")) {
2013:                        welcomeFile = welcomeFile.substring(1);
2014:                    }
2015:                    welcomeFile = path + welcomeFile;
2016:
2017:                    String exact = (String) this .exactServletMatchMounts
2018:                            .get(welcomeFile);
2019:                    if (exact != null) {
2020:                        return welcomeFile + qs;
2021:                    }
2022:
2023:                    // Inexact folder mount check - note folder mounts only
2024:                    for (int j = 0; j < this .patternMatches.length; j++) {
2025:                        Mapping urlPattern = this .patternMatches[j];
2026:                        if ((urlPattern.getPatternType() == Mapping.FOLDER_PATTERN)
2027:                                && urlPattern.match(welcomeFile, null, null)) {
2028:                            return welcomeFile + qs;
2029:                        }
2030:                    }
2031:
2032:                    try {
2033:                        if (getResource(welcomeFile) != null) {
2034:                            return welcomeFile + qs;
2035:                        }
2036:                    } catch (MalformedURLException err) {
2037:                    }
2038:                }
2039:                return null;
2040:            }
2041:
2042:            // Getting resources via the classloader
2043:            public URL getResource(String path) throws MalformedURLException {
2044:                if (path == null) {
2045:                    return null;
2046:                } else if (!path.startsWith("/")) {
2047:                    throw new MalformedURLException(Launcher.RESOURCES
2048:                            .getString("WebAppConfig.BadResourcePath", path));
2049:                } else if (!path.equals("/") && path.endsWith("/")) {
2050:                    path = path.substring(0, path.length() - 1);
2051:                }
2052:                File res = new File(webRoot, path.substring(1));
2053:                return (res != null) && res.exists() ? res.toURL() : null;
2054:            }
2055:
2056:            public InputStream getResourceAsStream(String path) {
2057:                try {
2058:                    URL res = getResource(path);
2059:                    return res == null ? null : res.openStream();
2060:                } catch (IOException err) {
2061:                    throw new WinstoneException(Launcher.RESOURCES
2062:                            .getString("WebAppConfig.ErrorOpeningStream"), err);
2063:                }
2064:            }
2065:
2066:            public String getRealPath(String path) {
2067:                // Trim the prefix
2068:                if (path == null)
2069:                    return null;
2070:                else {
2071:                    try {
2072:                        File res = new File(this .webRoot, path);
2073:                        if (res.isDirectory())
2074:                            return res.getCanonicalPath() + "/";
2075:                        else
2076:                            return res.getCanonicalPath();
2077:                    } catch (IOException err) {
2078:                        return null;
2079:                    }
2080:                }
2081:            }
2082:
2083:            public Set getResourcePaths(String path) {
2084:                // Trim the prefix
2085:                if (path == null)
2086:                    return null;
2087:                else if (!path.startsWith("/"))
2088:                    throw new WinstoneException(Launcher.RESOURCES.getString(
2089:                            "WebAppConfig.BadResourcePath", path));
2090:                else {
2091:                    String workingPath = null;
2092:                    if (path.equals("/"))
2093:                        workingPath = "";
2094:                    else {
2095:                        boolean lastCharIsSlash = path
2096:                                .charAt(path.length() - 1) == '/';
2097:                        workingPath = path.substring(1, path.length()
2098:                                - (lastCharIsSlash ? 1 : 0));
2099:                    }
2100:                    File inPath = new File(this .webRoot,
2101:                            workingPath.equals("") ? "." : workingPath)
2102:                            .getAbsoluteFile();
2103:                    if (!inPath.exists())
2104:                        return null;
2105:                    else if (!inPath.isDirectory())
2106:                        return null;
2107:
2108:                    // Find all the files in this folder
2109:                    File children[] = inPath.listFiles();
2110:                    Set out = new HashSet();
2111:                    for (int n = 0; n < children.length; n++) {
2112:                        // Write the entry as subpath + child element
2113:                        String entry = //this.prefix + 
2114:                        "/"
2115:                                + (workingPath.length() != 0 ? workingPath
2116:                                        + "/" : "") + children[n].getName()
2117:                                + (children[n].isDirectory() ? "/" : "");
2118:                        out.add(entry);
2119:                    }
2120:                    return out;
2121:                }
2122:            }
2123:
2124:            /**
2125:             * @deprecated
2126:             */
2127:            public javax.servlet.Servlet getServlet(String name) {
2128:                return null;
2129:            }
2130:
2131:            /**
2132:             * @deprecated
2133:             */
2134:            public Enumeration getServletNames() {
2135:                return Collections.enumeration(new ArrayList());
2136:            }
2137:
2138:            /**
2139:             * @deprecated
2140:             */
2141:            public Enumeration getServlets() {
2142:                return Collections.enumeration(new ArrayList());
2143:            }
2144:
2145:            /**
2146:             * @deprecated
2147:             */
2148:            public void log(Exception exception, String msg) {
2149:                this.log(msg, exception);
2150:            }
2151:
2152:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.