Source Code Cross Referenced for StandardWrapper.java in  » Sevlet-Container » apache-tomcat-6.0.14 » org » apache » catalina » core » 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 » Sevlet Container » apache tomcat 6.0.14 » org.apache.catalina.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        package org.apache.catalina.core;
0019:
0020:        import java.lang.reflect.Method;
0021:        import java.io.IOException;
0022:        import java.io.InputStream;
0023:        import java.io.PrintStream;
0024:        import java.util.ArrayList;
0025:        import java.util.Enumeration;
0026:        import java.util.HashMap;
0027:        import java.util.HashSet;
0028:        import java.util.Properties;
0029:        import java.util.Stack;
0030:        import java.security.AccessController;
0031:        import java.security.PrivilegedActionException;
0032:        import java.security.PrivilegedExceptionAction;
0033:        import javax.servlet.Servlet;
0034:        import javax.servlet.ServletConfig;
0035:        import javax.servlet.ServletContext;
0036:        import javax.servlet.ServletException;
0037:        import javax.servlet.ServletRequest;
0038:        import javax.servlet.ServletResponse;
0039:        import javax.servlet.SingleThreadModel;
0040:        import javax.servlet.UnavailableException;
0041:        import javax.management.ListenerNotFoundException;
0042:        import javax.management.MBeanNotificationInfo;
0043:        import javax.management.Notification;
0044:        import javax.management.NotificationBroadcasterSupport;
0045:        import javax.management.NotificationEmitter;
0046:        import javax.management.NotificationFilter;
0047:        import javax.management.NotificationListener;
0048:        import javax.management.ObjectName;
0049:
0050:        import org.apache.PeriodicEventListener;
0051:        import org.apache.catalina.Container;
0052:        import org.apache.catalina.ContainerServlet;
0053:        import org.apache.catalina.Context;
0054:        import org.apache.catalina.Globals;
0055:        import org.apache.catalina.InstanceEvent;
0056:        import org.apache.catalina.InstanceListener;
0057:        import org.apache.catalina.LifecycleException;
0058:        import org.apache.catalina.Loader;
0059:        import org.apache.catalina.Wrapper;
0060:        import org.apache.catalina.security.SecurityUtil;
0061:        import org.apache.catalina.util.Enumerator;
0062:        import org.apache.catalina.util.InstanceSupport;
0063:        import org.apache.tomcat.util.log.SystemLogHandler;
0064:        import org.apache.tomcat.util.modeler.Registry;
0065:
0066:        /**
0067:         * Standard implementation of the <b>Wrapper</b> interface that represents
0068:         * an individual servlet definition.  No child Containers are allowed, and
0069:         * the parent Container must be a Context.
0070:         *
0071:         * @author Craig R. McClanahan
0072:         * @author Remy Maucherat
0073:         * @version $Revision: 505593 $ $Date: 2007-02-10 01:54:56 +0100 (sam., 10 févr. 2007) $
0074:         */
0075:        public class StandardWrapper extends ContainerBase implements 
0076:                ServletConfig, Wrapper, NotificationEmitter {
0077:
0078:            protected static org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory
0079:                    .getLog(StandardWrapper.class);
0080:
0081:            protected static final String[] DEFAULT_SERVLET_METHODS = new String[] {
0082:                    "GET", "HEAD", "POST" };
0083:
0084:            // ----------------------------------------------------------- Constructors
0085:
0086:            /**
0087:             * Create a new StandardWrapper component with the default basic Valve.
0088:             */
0089:            public StandardWrapper() {
0090:
0091:                super ();
0092:                swValve = new StandardWrapperValve();
0093:                pipeline.setBasic(swValve);
0094:                broadcaster = new NotificationBroadcasterSupport();
0095:
0096:                if (restrictedServlets == null) {
0097:                    restrictedServlets = new Properties();
0098:                    try {
0099:                        InputStream is = this 
0100:                                .getClass()
0101:                                .getClassLoader()
0102:                                .getResourceAsStream(
0103:                                        "org/apache/catalina/core/RestrictedServlets.properties");
0104:                        if (is != null) {
0105:                            restrictedServlets.load(is);
0106:                        } else {
0107:                            log
0108:                                    .error(sm
0109:                                            .getString("standardWrapper.restrictedServletsResource"));
0110:                        }
0111:                    } catch (IOException e) {
0112:                        log
0113:                                .error(
0114:                                        sm
0115:                                                .getString("standardWrapper.restrictedServletsResource"),
0116:                                        e);
0117:                    }
0118:                }
0119:
0120:            }
0121:
0122:            // ----------------------------------------------------- Instance Variables
0123:
0124:            /**
0125:             * The date and time at which this servlet will become available (in
0126:             * milliseconds since the epoch), or zero if the servlet is available.
0127:             * If this value equals Long.MAX_VALUE, the unavailability of this
0128:             * servlet is considered permanent.
0129:             */
0130:            protected long available = 0L;
0131:
0132:            /**
0133:             * The broadcaster that sends j2ee notifications. 
0134:             */
0135:            protected NotificationBroadcasterSupport broadcaster = null;
0136:
0137:            /**
0138:             * The count of allocations that are currently active (even if they
0139:             * are for the same instance, as will be true on a non-STM servlet).
0140:             */
0141:            protected int countAllocated = 0;
0142:
0143:            /**
0144:             * The facade associated with this wrapper.
0145:             */
0146:            protected StandardWrapperFacade facade = new StandardWrapperFacade(
0147:                    this );
0148:
0149:            /**
0150:             * The descriptive information string for this implementation.
0151:             */
0152:            protected static final String info = "org.apache.catalina.core.StandardWrapper/1.0";
0153:
0154:            /**
0155:             * The (single) initialized instance of this servlet.
0156:             */
0157:            protected Servlet instance = null;
0158:
0159:            /**
0160:             * The support object for our instance listeners.
0161:             */
0162:            protected InstanceSupport instanceSupport = new InstanceSupport(
0163:                    this );
0164:
0165:            /**
0166:             * The context-relative URI of the JSP file for this servlet.
0167:             */
0168:            protected String jspFile = null;
0169:
0170:            /**
0171:             * The load-on-startup order value (negative value means load on
0172:             * first call) for this servlet.
0173:             */
0174:            protected int loadOnStartup = -1;
0175:
0176:            /**
0177:             * Mappings associated with the wrapper.
0178:             */
0179:            protected ArrayList mappings = new ArrayList();
0180:
0181:            /**
0182:             * The initialization parameters for this servlet, keyed by
0183:             * parameter name.
0184:             */
0185:            protected HashMap parameters = new HashMap();
0186:
0187:            /**
0188:             * The security role references for this servlet, keyed by role name
0189:             * used in the servlet.  The corresponding value is the role name of
0190:             * the web application itself.
0191:             */
0192:            protected HashMap references = new HashMap();
0193:
0194:            /**
0195:             * The run-as identity for this servlet.
0196:             */
0197:            protected String runAs = null;
0198:
0199:            /**
0200:             * The notification sequence number.
0201:             */
0202:            protected long sequenceNumber = 0;
0203:
0204:            /**
0205:             * The fully qualified servlet class name for this servlet.
0206:             */
0207:            protected String servletClass = null;
0208:
0209:            /**
0210:             * Does this servlet implement the SingleThreadModel interface?
0211:             */
0212:            protected boolean singleThreadModel = false;
0213:
0214:            /**
0215:             * Are we unloading our servlet instance at the moment?
0216:             */
0217:            protected boolean unloading = false;
0218:
0219:            /**
0220:             * Maximum number of STM instances.
0221:             */
0222:            protected int maxInstances = 20;
0223:
0224:            /**
0225:             * Number of instances currently loaded for a STM servlet.
0226:             */
0227:            protected int nInstances = 0;
0228:
0229:            /**
0230:             * Stack containing the STM instances.
0231:             */
0232:            protected Stack instancePool = null;
0233:
0234:            /**
0235:             * Wait time for servlet unload in ms.
0236:             */
0237:            protected long unloadDelay = 2000;
0238:
0239:            /**
0240:             * True if this StandardWrapper is for the JspServlet
0241:             */
0242:            protected boolean isJspServlet;
0243:
0244:            /**
0245:             * The ObjectName of the JSP monitoring mbean
0246:             */
0247:            protected ObjectName jspMonitorON;
0248:
0249:            /**
0250:             * Should we swallow System.out
0251:             */
0252:            protected boolean swallowOutput = false;
0253:
0254:            // To support jmx attributes
0255:            protected StandardWrapperValve swValve;
0256:            protected long loadTime = 0;
0257:            protected int classLoadTime = 0;
0258:
0259:            /**
0260:             * Static class array used when the SecurityManager is turned on and 
0261:             * <code>Servlet.init</code> is invoked.
0262:             */
0263:            protected static Class[] classType = new Class[] { ServletConfig.class };
0264:
0265:            /**
0266:             * Static class array used when the SecurityManager is turned on and 
0267:             * <code>Servlet.service</code>  is invoked.
0268:             */
0269:            protected static Class[] classTypeUsedInService = new Class[] {
0270:                    ServletRequest.class, ServletResponse.class };
0271:
0272:            /**
0273:             * Restricted servlets (which can only be loaded by a privileged webapp).
0274:             */
0275:            protected static Properties restrictedServlets = null;
0276:
0277:            // ------------------------------------------------------------- Properties
0278:
0279:            /**
0280:             * Return the available date/time for this servlet, in milliseconds since
0281:             * the epoch.  If this date/time is Long.MAX_VALUE, it is considered to mean
0282:             * that unavailability is permanent and any request for this servlet will return
0283:             * an SC_NOT_FOUND error.  If this date/time is in the future, any request for
0284:             * this servlet will return an SC_SERVICE_UNAVAILABLE error.  If it is zero,
0285:             * the servlet is currently available.
0286:             */
0287:            public long getAvailable() {
0288:
0289:                return (this .available);
0290:
0291:            }
0292:
0293:            /**
0294:             * Set the available date/time for this servlet, in milliseconds since the
0295:             * epoch.  If this date/time is Long.MAX_VALUE, it is considered to mean
0296:             * that unavailability is permanent and any request for this servlet will return
0297:             * an SC_NOT_FOUND error. If this date/time is in the future, any request for
0298:             * this servlet will return an SC_SERVICE_UNAVAILABLE error.
0299:             *
0300:             * @param available The new available date/time
0301:             */
0302:            public void setAvailable(long available) {
0303:
0304:                long oldAvailable = this .available;
0305:                if (available > System.currentTimeMillis())
0306:                    this .available = available;
0307:                else
0308:                    this .available = 0L;
0309:                support.firePropertyChange("available", new Long(oldAvailable),
0310:                        new Long(this .available));
0311:
0312:            }
0313:
0314:            /**
0315:             * Return the number of active allocations of this servlet, even if they
0316:             * are all for the same instance (as will be true for servlets that do
0317:             * not implement <code>SingleThreadModel</code>.
0318:             */
0319:            public int getCountAllocated() {
0320:
0321:                return (this .countAllocated);
0322:
0323:            }
0324:
0325:            public String getEngineName() {
0326:                return ((StandardContext) getParent()).getEngineName();
0327:            }
0328:
0329:            /**
0330:             * Return descriptive information about this Container implementation and
0331:             * the corresponding version number, in the format
0332:             * <code>&lt;description&gt;/&lt;version&gt;</code>.
0333:             */
0334:            public String getInfo() {
0335:
0336:                return (info);
0337:
0338:            }
0339:
0340:            /**
0341:             * Return the InstanceSupport object for this Wrapper instance.
0342:             */
0343:            public InstanceSupport getInstanceSupport() {
0344:
0345:                return (this .instanceSupport);
0346:
0347:            }
0348:
0349:            /**
0350:             * Return the context-relative URI of the JSP file for this servlet.
0351:             */
0352:            public String getJspFile() {
0353:
0354:                return (this .jspFile);
0355:
0356:            }
0357:
0358:            /**
0359:             * Set the context-relative URI of the JSP file for this servlet.
0360:             *
0361:             * @param jspFile JSP file URI
0362:             */
0363:            public void setJspFile(String jspFile) {
0364:
0365:                String oldJspFile = this .jspFile;
0366:                this .jspFile = jspFile;
0367:                support.firePropertyChange("jspFile", oldJspFile, this .jspFile);
0368:
0369:                // Each jsp-file needs to be represented by its own JspServlet and
0370:                // corresponding JspMonitoring mbean, because it may be initialized
0371:                // with its own init params
0372:                isJspServlet = true;
0373:
0374:            }
0375:
0376:            /**
0377:             * Return the load-on-startup order value (negative value means
0378:             * load on first call).
0379:             */
0380:            public int getLoadOnStartup() {
0381:
0382:                if (isJspServlet && loadOnStartup < 0) {
0383:                    /*
0384:                     * JspServlet must always be preloaded, because its instance is
0385:                     * used during registerJMX (when registering the JSP
0386:                     * monitoring mbean)
0387:                     */
0388:                    return Integer.MAX_VALUE;
0389:                } else {
0390:                    return (this .loadOnStartup);
0391:                }
0392:            }
0393:
0394:            /**
0395:             * Set the load-on-startup order value (negative value means
0396:             * load on first call).
0397:             *
0398:             * @param value New load-on-startup value
0399:             */
0400:            public void setLoadOnStartup(int value) {
0401:
0402:                int oldLoadOnStartup = this .loadOnStartup;
0403:                this .loadOnStartup = value;
0404:                support.firePropertyChange("loadOnStartup", new Integer(
0405:                        oldLoadOnStartup), new Integer(this .loadOnStartup));
0406:
0407:            }
0408:
0409:            /**
0410:             * Set the load-on-startup order value from a (possibly null) string.
0411:             * Per the specification, any missing or non-numeric value is converted
0412:             * to a zero, so that this servlet will still be loaded at startup
0413:             * time, but in an arbitrary order.
0414:             *
0415:             * @param value New load-on-startup value
0416:             */
0417:            public void setLoadOnStartupString(String value) {
0418:
0419:                try {
0420:                    setLoadOnStartup(Integer.parseInt(value));
0421:                } catch (NumberFormatException e) {
0422:                    setLoadOnStartup(0);
0423:                }
0424:            }
0425:
0426:            public String getLoadOnStartupString() {
0427:                return Integer.toString(getLoadOnStartup());
0428:            }
0429:
0430:            /**
0431:             * Return maximum number of instances that will be allocated when a single
0432:             * thread model servlet is used.
0433:             */
0434:            public int getMaxInstances() {
0435:
0436:                return (this .maxInstances);
0437:
0438:            }
0439:
0440:            /**
0441:             * Set the maximum number of instances that will be allocated when a single
0442:             * thread model servlet is used.
0443:             *
0444:             * @param maxInstances New value of maxInstances
0445:             */
0446:            public void setMaxInstances(int maxInstances) {
0447:
0448:                int oldMaxInstances = this .maxInstances;
0449:                this .maxInstances = maxInstances;
0450:                support.firePropertyChange("maxInstances", oldMaxInstances,
0451:                        this .maxInstances);
0452:
0453:            }
0454:
0455:            /**
0456:             * Set the parent Container of this Wrapper, but only if it is a Context.
0457:             *
0458:             * @param container Proposed parent Container
0459:             */
0460:            public void setParent(Container container) {
0461:
0462:                if ((container != null) && !(container instanceof  Context))
0463:                    throw new IllegalArgumentException(sm
0464:                            .getString("standardWrapper.notContext"));
0465:                if (container instanceof  StandardContext) {
0466:                    swallowOutput = ((StandardContext) container)
0467:                            .getSwallowOutput();
0468:                    unloadDelay = ((StandardContext) container)
0469:                            .getUnloadDelay();
0470:                }
0471:                super .setParent(container);
0472:
0473:            }
0474:
0475:            /**
0476:             * Return the run-as identity for this servlet.
0477:             */
0478:            public String getRunAs() {
0479:
0480:                return (this .runAs);
0481:
0482:            }
0483:
0484:            /**
0485:             * Set the run-as identity for this servlet.
0486:             *
0487:             * @param runAs New run-as identity value
0488:             */
0489:            public void setRunAs(String runAs) {
0490:
0491:                String oldRunAs = this .runAs;
0492:                this .runAs = runAs;
0493:                support.firePropertyChange("runAs", oldRunAs, this .runAs);
0494:
0495:            }
0496:
0497:            /**
0498:             * Return the fully qualified servlet class name for this servlet.
0499:             */
0500:            public String getServletClass() {
0501:
0502:                return (this .servletClass);
0503:
0504:            }
0505:
0506:            /**
0507:             * Set the fully qualified servlet class name for this servlet.
0508:             *
0509:             * @param servletClass Servlet class name
0510:             */
0511:            public void setServletClass(String servletClass) {
0512:
0513:                String oldServletClass = this .servletClass;
0514:                this .servletClass = servletClass;
0515:                support.firePropertyChange("servletClass", oldServletClass,
0516:                        this .servletClass);
0517:                if (Constants.JSP_SERVLET_CLASS.equals(servletClass)) {
0518:                    isJspServlet = true;
0519:                }
0520:            }
0521:
0522:            /**
0523:             * Set the name of this servlet.  This is an alias for the normal
0524:             * <code>Container.setName()</code> method, and complements the
0525:             * <code>getServletName()</code> method required by the
0526:             * <code>ServletConfig</code> interface.
0527:             *
0528:             * @param name The new name of this servlet
0529:             */
0530:            public void setServletName(String name) {
0531:
0532:                setName(name);
0533:
0534:            }
0535:
0536:            /**
0537:             * Return <code>true</code> if the servlet class represented by this
0538:             * component implements the <code>SingleThreadModel</code> interface.
0539:             */
0540:            public boolean isSingleThreadModel() {
0541:
0542:                try {
0543:                    loadServlet();
0544:                } catch (Throwable t) {
0545:                    ;
0546:                }
0547:                return (singleThreadModel);
0548:
0549:            }
0550:
0551:            /**
0552:             * Is this servlet currently unavailable?
0553:             */
0554:            public boolean isUnavailable() {
0555:
0556:                if (available == 0L)
0557:                    return (false);
0558:                else if (available <= System.currentTimeMillis()) {
0559:                    available = 0L;
0560:                    return (false);
0561:                } else
0562:                    return (true);
0563:
0564:            }
0565:
0566:            /**
0567:             * Gets the names of the methods supported by the underlying servlet.
0568:             *
0569:             * This is the same set of methods included in the Allow response header
0570:             * in response to an OPTIONS request method processed by the underlying
0571:             * servlet.
0572:             *
0573:             * @return Array of names of the methods supported by the underlying
0574:             * servlet
0575:             */
0576:            public String[] getServletMethods() throws ServletException {
0577:
0578:                Class servletClazz = loadServlet().getClass();
0579:                if (!javax.servlet.http.HttpServlet.class
0580:                        .isAssignableFrom(servletClazz)) {
0581:                    return DEFAULT_SERVLET_METHODS;
0582:                }
0583:
0584:                HashSet allow = new HashSet();
0585:                allow.add("TRACE");
0586:                allow.add("OPTIONS");
0587:
0588:                Method[] methods = getAllDeclaredMethods(servletClazz);
0589:                for (int i = 0; methods != null && i < methods.length; i++) {
0590:                    Method m = methods[i];
0591:
0592:                    if (m.getName().equals("doGet")) {
0593:                        allow.add("GET");
0594:                        allow.add("HEAD");
0595:                    } else if (m.getName().equals("doPost")) {
0596:                        allow.add("POST");
0597:                    } else if (m.getName().equals("doPut")) {
0598:                        allow.add("PUT");
0599:                    } else if (m.getName().equals("doDelete")) {
0600:                        allow.add("DELETE");
0601:                    }
0602:                }
0603:
0604:                String[] methodNames = new String[allow.size()];
0605:                return (String[]) allow.toArray(methodNames);
0606:
0607:            }
0608:
0609:            // --------------------------------------------------------- Public Methods
0610:
0611:            /**
0612:             * Execute a periodic task, such as reloading, etc. This method will be
0613:             * invoked inside the classloading context of this container. Unexpected
0614:             * throwables will be caught and logged.
0615:             */
0616:            public void backgroundProcess() {
0617:                super .backgroundProcess();
0618:
0619:                if (!started)
0620:                    return;
0621:
0622:                if (getServlet() != null
0623:                        && (getServlet() instanceof  PeriodicEventListener)) {
0624:                    ((PeriodicEventListener) getServlet()).periodicEvent();
0625:                }
0626:            }
0627:
0628:            /**
0629:             * Extract the root cause from a servlet exception.
0630:             * 
0631:             * @param e The servlet exception
0632:             */
0633:            public static Throwable getRootCause(ServletException e) {
0634:                Throwable rootCause = e;
0635:                Throwable rootCauseCheck = null;
0636:                // Extra aggressive rootCause finding
0637:                int loops = 0;
0638:                do {
0639:                    loops++;
0640:                    rootCauseCheck = rootCause.getCause();
0641:                    if (rootCauseCheck != null)
0642:                        rootCause = rootCauseCheck;
0643:                } while (rootCauseCheck != null && (loops < 20));
0644:                return rootCause;
0645:            }
0646:
0647:            /**
0648:             * Refuse to add a child Container, because Wrappers are the lowest level
0649:             * of the Container hierarchy.
0650:             *
0651:             * @param child Child container to be added
0652:             */
0653:            public void addChild(Container child) {
0654:
0655:                throw new IllegalStateException(sm
0656:                        .getString("standardWrapper.notChild"));
0657:
0658:            }
0659:
0660:            /**
0661:             * Add a new servlet initialization parameter for this servlet.
0662:             *
0663:             * @param name Name of this initialization parameter to add
0664:             * @param value Value of this initialization parameter to add
0665:             */
0666:            public void addInitParameter(String name, String value) {
0667:
0668:                synchronized (parameters) {
0669:                    parameters.put(name, value);
0670:                }
0671:                fireContainerEvent("addInitParameter", name);
0672:
0673:            }
0674:
0675:            /**
0676:             * Add a new listener interested in InstanceEvents.
0677:             *
0678:             * @param listener The new listener
0679:             */
0680:            public void addInstanceListener(InstanceListener listener) {
0681:
0682:                instanceSupport.addInstanceListener(listener);
0683:
0684:            }
0685:
0686:            /**
0687:             * Add a mapping associated with the Wrapper.
0688:             *
0689:             * @param mapping The new wrapper mapping
0690:             */
0691:            public void addMapping(String mapping) {
0692:
0693:                synchronized (mappings) {
0694:                    mappings.add(mapping);
0695:                }
0696:                fireContainerEvent("addMapping", mapping);
0697:
0698:            }
0699:
0700:            /**
0701:             * Add a new security role reference record to the set of records for
0702:             * this servlet.
0703:             *
0704:             * @param name Role name used within this servlet
0705:             * @param link Role name used within the web application
0706:             */
0707:            public void addSecurityReference(String name, String link) {
0708:
0709:                synchronized (references) {
0710:                    references.put(name, link);
0711:                }
0712:                fireContainerEvent("addSecurityReference", name);
0713:
0714:            }
0715:
0716:            /**
0717:             * Return the associated servlet instance.
0718:             */
0719:            public Servlet getServlet() {
0720:                return instance;
0721:            }
0722:
0723:            /**
0724:             * Allocate an initialized instance of this Servlet that is ready to have
0725:             * its <code>service()</code> method called.  If the servlet class does
0726:             * not implement <code>SingleThreadModel</code>, the (only) initialized
0727:             * instance may be returned immediately.  If the servlet class implements
0728:             * <code>SingleThreadModel</code>, the Wrapper implementation must ensure
0729:             * that this instance is not allocated again until it is deallocated by a
0730:             * call to <code>deallocate()</code>.
0731:             *
0732:             * @exception ServletException if the servlet init() method threw
0733:             *  an exception
0734:             * @exception ServletException if a loading error occurs
0735:             */
0736:            public Servlet allocate() throws ServletException {
0737:
0738:                // If we are currently unloading this servlet, throw an exception
0739:                if (unloading)
0740:                    throw new ServletException(sm.getString(
0741:                            "standardWrapper.unloading", getName()));
0742:
0743:                // If not SingleThreadedModel, return the same instance every time
0744:                if (!singleThreadModel) {
0745:
0746:                    // Load and initialize our instance if necessary
0747:                    if (instance == null) {
0748:                        synchronized (this ) {
0749:                            if (instance == null) {
0750:                                try {
0751:                                    if (log.isDebugEnabled())
0752:                                        log
0753:                                                .debug("Allocating non-STM instance");
0754:
0755:                                    instance = loadServlet();
0756:                                } catch (ServletException e) {
0757:                                    throw e;
0758:                                } catch (Throwable e) {
0759:                                    throw new ServletException(
0760:                                            sm
0761:                                                    .getString("standardWrapper.allocate"),
0762:                                            e);
0763:                                }
0764:                            }
0765:                        }
0766:                    }
0767:
0768:                    if (!singleThreadModel) {
0769:                        if (log.isTraceEnabled())
0770:                            log.trace("  Returning non-STM instance");
0771:                        countAllocated++;
0772:                        return (instance);
0773:                    }
0774:
0775:                }
0776:
0777:                synchronized (instancePool) {
0778:
0779:                    while (countAllocated >= nInstances) {
0780:                        // Allocate a new instance if possible, or else wait
0781:                        if (nInstances < maxInstances) {
0782:                            try {
0783:                                instancePool.push(loadServlet());
0784:                                nInstances++;
0785:                            } catch (ServletException e) {
0786:                                throw e;
0787:                            } catch (Throwable e) {
0788:                                throw new ServletException(sm
0789:                                        .getString("standardWrapper.allocate"),
0790:                                        e);
0791:                            }
0792:                        } else {
0793:                            try {
0794:                                instancePool.wait();
0795:                            } catch (InterruptedException e) {
0796:                                ;
0797:                            }
0798:                        }
0799:                    }
0800:                    if (log.isTraceEnabled())
0801:                        log.trace("  Returning allocated STM instance");
0802:                    countAllocated++;
0803:                    return (Servlet) instancePool.pop();
0804:
0805:                }
0806:
0807:            }
0808:
0809:            /**
0810:             * Return this previously allocated servlet to the pool of available
0811:             * instances.  If this servlet class does not implement SingleThreadModel,
0812:             * no action is actually required.
0813:             *
0814:             * @param servlet The servlet to be returned
0815:             *
0816:             * @exception ServletException if a deallocation error occurs
0817:             */
0818:            public void deallocate(Servlet servlet) throws ServletException {
0819:
0820:                // If not SingleThreadModel, no action is required
0821:                if (!singleThreadModel) {
0822:                    countAllocated--;
0823:                    return;
0824:                }
0825:
0826:                // Unlock and free this instance
0827:                synchronized (instancePool) {
0828:                    countAllocated--;
0829:                    instancePool.push(servlet);
0830:                    instancePool.notify();
0831:                }
0832:
0833:            }
0834:
0835:            /**
0836:             * Return the value for the specified initialization parameter name,
0837:             * if any; otherwise return <code>null</code>.
0838:             *
0839:             * @param name Name of the requested initialization parameter
0840:             */
0841:            public String findInitParameter(String name) {
0842:
0843:                synchronized (parameters) {
0844:                    return ((String) parameters.get(name));
0845:                }
0846:
0847:            }
0848:
0849:            /**
0850:             * Return the names of all defined initialization parameters for this
0851:             * servlet.
0852:             */
0853:            public String[] findInitParameters() {
0854:
0855:                synchronized (parameters) {
0856:                    String results[] = new String[parameters.size()];
0857:                    return ((String[]) parameters.keySet().toArray(results));
0858:                }
0859:
0860:            }
0861:
0862:            /**
0863:             * Return the mappings associated with this wrapper.
0864:             */
0865:            public String[] findMappings() {
0866:
0867:                synchronized (mappings) {
0868:                    return (String[]) mappings.toArray(new String[mappings
0869:                            .size()]);
0870:                }
0871:
0872:            }
0873:
0874:            /**
0875:             * Return the security role link for the specified security role
0876:             * reference name, if any; otherwise return <code>null</code>.
0877:             *
0878:             * @param name Security role reference used within this servlet
0879:             */
0880:            public String findSecurityReference(String name) {
0881:
0882:                synchronized (references) {
0883:                    return ((String) references.get(name));
0884:                }
0885:
0886:            }
0887:
0888:            /**
0889:             * Return the set of security role reference names associated with
0890:             * this servlet, if any; otherwise return a zero-length array.
0891:             */
0892:            public String[] findSecurityReferences() {
0893:
0894:                synchronized (references) {
0895:                    String results[] = new String[references.size()];
0896:                    return ((String[]) references.keySet().toArray(results));
0897:                }
0898:
0899:            }
0900:
0901:            /**
0902:             * FIXME: Fooling introspection ...
0903:             */
0904:            public Wrapper findMappingObject() {
0905:                return (Wrapper) getMappingObject();
0906:            }
0907:
0908:            /**
0909:             * Load and initialize an instance of this servlet, if there is not already
0910:             * at least one initialized instance.  This can be used, for example, to
0911:             * load servlets that are marked in the deployment descriptor to be loaded
0912:             * at server startup time.
0913:             * <p>
0914:             * <b>IMPLEMENTATION NOTE</b>:  Servlets whose classnames begin with
0915:             * <code>org.apache.catalina.</code> (so-called "container" servlets)
0916:             * are loaded by the same classloader that loaded this class, rather than
0917:             * the classloader for the current web application.
0918:             * This gives such classes access to Catalina internals, which are
0919:             * prevented for classes loaded for web applications.
0920:             *
0921:             * @exception ServletException if the servlet init() method threw
0922:             *  an exception
0923:             * @exception ServletException if some other loading problem occurs
0924:             */
0925:            public synchronized void load() throws ServletException {
0926:                instance = loadServlet();
0927:            }
0928:
0929:            /**
0930:             * Load and initialize an instance of this servlet, if there is not already
0931:             * at least one initialized instance.  This can be used, for example, to
0932:             * load servlets that are marked in the deployment descriptor to be loaded
0933:             * at server startup time.
0934:             */
0935:            public synchronized Servlet loadServlet() throws ServletException {
0936:
0937:                // Nothing to do if we already have an instance or an instance pool
0938:                if (!singleThreadModel && (instance != null))
0939:                    return instance;
0940:
0941:                PrintStream out = System.out;
0942:                if (swallowOutput) {
0943:                    SystemLogHandler.startCapture();
0944:                }
0945:
0946:                Servlet servlet;
0947:                try {
0948:                    long t1 = System.currentTimeMillis();
0949:                    // If this "servlet" is really a JSP file, get the right class.
0950:                    // HOLD YOUR NOSE - this is a kludge that avoids having to do special
0951:                    // case Catalina-specific code in Jasper - it also requires that the
0952:                    // servlet path be replaced by the <jsp-file> element content in
0953:                    // order to be completely effective
0954:                    String actualClass = servletClass;
0955:                    if ((actualClass == null) && (jspFile != null)) {
0956:                        Wrapper jspWrapper = (Wrapper) ((Context) getParent())
0957:                                .findChild(Constants.JSP_SERVLET_NAME);
0958:                        if (jspWrapper != null) {
0959:                            actualClass = jspWrapper.getServletClass();
0960:                            // Merge init parameters
0961:                            String paramNames[] = jspWrapper
0962:                                    .findInitParameters();
0963:                            for (int i = 0; i < paramNames.length; i++) {
0964:                                if (parameters.get(paramNames[i]) == null) {
0965:                                    parameters.put(paramNames[i], jspWrapper
0966:                                            .findInitParameter(paramNames[i]));
0967:                                }
0968:                            }
0969:                        }
0970:                    }
0971:
0972:                    // Complain if no servlet class has been specified
0973:                    if (actualClass == null) {
0974:                        unavailable(null);
0975:                        throw new ServletException(sm.getString(
0976:                                "standardWrapper.notClass", getName()));
0977:                    }
0978:
0979:                    // Acquire an instance of the class loader to be used
0980:                    Loader loader = getLoader();
0981:                    if (loader == null) {
0982:                        unavailable(null);
0983:                        throw new ServletException(sm.getString(
0984:                                "standardWrapper.missingLoader", getName()));
0985:                    }
0986:
0987:                    ClassLoader classLoader = loader.getClassLoader();
0988:
0989:                    // Special case class loader for a container provided servlet
0990:                    //  
0991:                    if (isContainerProvidedServlet(actualClass)
0992:                            && !((Context) getParent()).getPrivileged()) {
0993:                        // If it is a priviledged context - using its own
0994:                        // class loader will work, since it's a child of the container
0995:                        // loader
0996:                        classLoader = this .getClass().getClassLoader();
0997:                    }
0998:
0999:                    // Load the specified servlet class from the appropriate class loader
1000:                    Class classClass = null;
1001:                    try {
1002:                        if (SecurityUtil.isPackageProtectionEnabled()) {
1003:                            final ClassLoader fclassLoader = classLoader;
1004:                            final String factualClass = actualClass;
1005:                            try {
1006:                                classClass = (Class) AccessController
1007:                                        .doPrivileged(new PrivilegedExceptionAction() {
1008:                                            public Object run()
1009:                                                    throws Exception {
1010:                                                if (fclassLoader != null) {
1011:                                                    return fclassLoader
1012:                                                            .loadClass(factualClass);
1013:                                                } else {
1014:                                                    return Class
1015:                                                            .forName(factualClass);
1016:                                                }
1017:                                            }
1018:                                        });
1019:                            } catch (PrivilegedActionException pax) {
1020:                                Exception ex = pax.getException();
1021:                                if (ex instanceof  ClassNotFoundException) {
1022:                                    throw (ClassNotFoundException) ex;
1023:                                } else {
1024:                                    getServletContext().log(
1025:                                            "Error loading " + fclassLoader
1026:                                                    + " " + factualClass, ex);
1027:                                }
1028:                            }
1029:                        } else {
1030:                            if (classLoader != null) {
1031:                                classClass = classLoader.loadClass(actualClass);
1032:                            } else {
1033:                                classClass = Class.forName(actualClass);
1034:                            }
1035:                        }
1036:                    } catch (ClassNotFoundException e) {
1037:                        unavailable(null);
1038:                        getServletContext().log(
1039:                                "Error loading " + classLoader + " "
1040:                                        + actualClass, e);
1041:                        throw new ServletException(sm.getString(
1042:                                "standardWrapper.missingClass", actualClass), e);
1043:                    }
1044:
1045:                    if (classClass == null) {
1046:                        unavailable(null);
1047:                        throw new ServletException(sm.getString(
1048:                                "standardWrapper.missingClass", actualClass));
1049:                    }
1050:
1051:                    // Instantiate and initialize an instance of the servlet class itself
1052:                    try {
1053:                        servlet = (Servlet) classClass.newInstance();
1054:                        // Annotation processing
1055:                        if (!((Context) getParent()).getIgnoreAnnotations()) {
1056:                            if (getParent() instanceof  StandardContext) {
1057:                                ((StandardContext) getParent())
1058:                                        .getAnnotationProcessor()
1059:                                        .processAnnotations(servlet);
1060:                                ((StandardContext) getParent())
1061:                                        .getAnnotationProcessor()
1062:                                        .postConstruct(servlet);
1063:                            }
1064:                        }
1065:                    } catch (ClassCastException e) {
1066:                        unavailable(null);
1067:                        // Restore the context ClassLoader
1068:                        throw new ServletException(sm.getString(
1069:                                "standardWrapper.notServlet", actualClass), e);
1070:                    } catch (Throwable e) {
1071:                        unavailable(null);
1072:
1073:                        // Added extra log statement for Bugzilla 36630:
1074:                        // http://issues.apache.org/bugzilla/show_bug.cgi?id=36630
1075:                        if (log.isDebugEnabled()) {
1076:                            log.debug(
1077:                                    sm.getString("standardWrapper.instantiate",
1078:                                            actualClass), e);
1079:                        }
1080:
1081:                        // Restore the context ClassLoader
1082:                        throw new ServletException(sm.getString(
1083:                                "standardWrapper.instantiate", actualClass), e);
1084:                    }
1085:
1086:                    // Check if loading the servlet in this web application should be
1087:                    // allowed
1088:                    if (!isServletAllowed(servlet)) {
1089:                        throw new SecurityException(sm.getString(
1090:                                "standardWrapper.privilegedServlet",
1091:                                actualClass));
1092:                    }
1093:
1094:                    // Special handling for ContainerServlet instances
1095:                    if ((servlet instanceof  ContainerServlet)
1096:                            && (isContainerProvidedServlet(actualClass) || ((Context) getParent())
1097:                                    .getPrivileged())) {
1098:                        ((ContainerServlet) servlet).setWrapper(this );
1099:                    }
1100:
1101:                    classLoadTime = (int) (System.currentTimeMillis() - t1);
1102:                    // Call the initialization method of this servlet
1103:                    try {
1104:                        instanceSupport.fireInstanceEvent(
1105:                                InstanceEvent.BEFORE_INIT_EVENT, servlet);
1106:
1107:                        if (Globals.IS_SECURITY_ENABLED) {
1108:
1109:                            Object[] args = new Object[] { ((ServletConfig) facade) };
1110:                            SecurityUtil.doAsPrivilege("init", servlet,
1111:                                    classType, args);
1112:                            args = null;
1113:                        } else {
1114:                            servlet.init(facade);
1115:                        }
1116:
1117:                        // Invoke jspInit on JSP pages
1118:                        if ((loadOnStartup >= 0) && (jspFile != null)) {
1119:                            // Invoking jspInit
1120:                            DummyRequest req = new DummyRequest();
1121:                            req.setServletPath(jspFile);
1122:                            req.setQueryString("jsp_precompile=true");
1123:                            DummyResponse res = new DummyResponse();
1124:
1125:                            if (Globals.IS_SECURITY_ENABLED) {
1126:                                Object[] args = new Object[] { req, res };
1127:                                SecurityUtil.doAsPrivilege("service", servlet,
1128:                                        classTypeUsedInService, args);
1129:                                args = null;
1130:                            } else {
1131:                                servlet.service(req, res);
1132:                            }
1133:                        }
1134:                        instanceSupport.fireInstanceEvent(
1135:                                InstanceEvent.AFTER_INIT_EVENT, servlet);
1136:                    } catch (UnavailableException f) {
1137:                        instanceSupport.fireInstanceEvent(
1138:                                InstanceEvent.AFTER_INIT_EVENT, servlet, f);
1139:                        unavailable(f);
1140:                        throw f;
1141:                    } catch (ServletException f) {
1142:                        instanceSupport.fireInstanceEvent(
1143:                                InstanceEvent.AFTER_INIT_EVENT, servlet, f);
1144:                        // If the servlet wanted to be unavailable it would have
1145:                        // said so, so do not call unavailable(null).
1146:                        throw f;
1147:                    } catch (Throwable f) {
1148:                        getServletContext().log("StandardWrapper.Throwable", f);
1149:                        instanceSupport.fireInstanceEvent(
1150:                                InstanceEvent.AFTER_INIT_EVENT, servlet, f);
1151:                        // If the servlet wanted to be unavailable it would have
1152:                        // said so, so do not call unavailable(null).
1153:                        throw new ServletException(sm.getString(
1154:                                "standardWrapper.initException", getName()), f);
1155:                    }
1156:
1157:                    // Register our newly initialized instance
1158:                    singleThreadModel = servlet instanceof  SingleThreadModel;
1159:                    if (singleThreadModel) {
1160:                        if (instancePool == null)
1161:                            instancePool = new Stack();
1162:                    }
1163:                    fireContainerEvent("load", this );
1164:
1165:                    loadTime = System.currentTimeMillis() - t1;
1166:                } finally {
1167:                    if (swallowOutput) {
1168:                        String log = SystemLogHandler.stopCapture();
1169:                        if (log != null && log.length() > 0) {
1170:                            if (getServletContext() != null) {
1171:                                getServletContext().log(log);
1172:                            } else {
1173:                                out.println(log);
1174:                            }
1175:                        }
1176:                    }
1177:                }
1178:                return servlet;
1179:
1180:            }
1181:
1182:            /**
1183:             * Remove the specified initialization parameter from this servlet.
1184:             *
1185:             * @param name Name of the initialization parameter to remove
1186:             */
1187:            public void removeInitParameter(String name) {
1188:
1189:                synchronized (parameters) {
1190:                    parameters.remove(name);
1191:                }
1192:                fireContainerEvent("removeInitParameter", name);
1193:
1194:            }
1195:
1196:            /**
1197:             * Remove a listener no longer interested in InstanceEvents.
1198:             *
1199:             * @param listener The listener to remove
1200:             */
1201:            public void removeInstanceListener(InstanceListener listener) {
1202:
1203:                instanceSupport.removeInstanceListener(listener);
1204:
1205:            }
1206:
1207:            /**
1208:             * Remove a mapping associated with the wrapper.
1209:             *
1210:             * @param mapping The pattern to remove
1211:             */
1212:            public void removeMapping(String mapping) {
1213:
1214:                synchronized (mappings) {
1215:                    mappings.remove(mapping);
1216:                }
1217:                fireContainerEvent("removeMapping", mapping);
1218:
1219:            }
1220:
1221:            /**
1222:             * Remove any security role reference for the specified role name.
1223:             *
1224:             * @param name Security role used within this servlet to be removed
1225:             */
1226:            public void removeSecurityReference(String name) {
1227:
1228:                synchronized (references) {
1229:                    references.remove(name);
1230:                }
1231:                fireContainerEvent("removeSecurityReference", name);
1232:
1233:            }
1234:
1235:            /**
1236:             * Return a String representation of this component.
1237:             */
1238:            public String toString() {
1239:
1240:                StringBuffer sb = new StringBuffer();
1241:                if (getParent() != null) {
1242:                    sb.append(getParent().toString());
1243:                    sb.append(".");
1244:                }
1245:                sb.append("StandardWrapper[");
1246:                sb.append(getName());
1247:                sb.append("]");
1248:                return (sb.toString());
1249:
1250:            }
1251:
1252:            /**
1253:             * Process an UnavailableException, marking this servlet as unavailable
1254:             * for the specified amount of time.
1255:             *
1256:             * @param unavailable The exception that occurred, or <code>null</code>
1257:             *  to mark this servlet as permanently unavailable
1258:             */
1259:            public void unavailable(UnavailableException unavailable) {
1260:                getServletContext().log(
1261:                        sm.getString("standardWrapper.unavailable", getName()));
1262:                if (unavailable == null)
1263:                    setAvailable(Long.MAX_VALUE);
1264:                else if (unavailable.isPermanent())
1265:                    setAvailable(Long.MAX_VALUE);
1266:                else {
1267:                    int unavailableSeconds = unavailable
1268:                            .getUnavailableSeconds();
1269:                    if (unavailableSeconds <= 0)
1270:                        unavailableSeconds = 60; // Arbitrary default
1271:                    setAvailable(System.currentTimeMillis()
1272:                            + (unavailableSeconds * 1000L));
1273:                }
1274:
1275:            }
1276:
1277:            /**
1278:             * Unload all initialized instances of this servlet, after calling the
1279:             * <code>destroy()</code> method for each instance.  This can be used,
1280:             * for example, prior to shutting down the entire servlet engine, or
1281:             * prior to reloading all of the classes from the Loader associated with
1282:             * our Loader's repository.
1283:             *
1284:             * @exception ServletException if an exception is thrown by the
1285:             *  destroy() method
1286:             */
1287:            public synchronized void unload() throws ServletException {
1288:
1289:                // Nothing to do if we have never loaded the instance
1290:                if (!singleThreadModel && (instance == null))
1291:                    return;
1292:                unloading = true;
1293:
1294:                // Loaf a while if the current instance is allocated
1295:                // (possibly more than once if non-STM)
1296:                if (countAllocated > 0) {
1297:                    int nRetries = 0;
1298:                    long delay = unloadDelay / 20;
1299:                    while ((nRetries < 21) && (countAllocated > 0)) {
1300:                        if ((nRetries % 10) == 0) {
1301:                            log.info(sm.getString("standardWrapper.waiting",
1302:                                    new Integer(countAllocated)));
1303:                        }
1304:                        try {
1305:                            Thread.sleep(delay);
1306:                        } catch (InterruptedException e) {
1307:                            ;
1308:                        }
1309:                        nRetries++;
1310:                    }
1311:                }
1312:
1313:                PrintStream out = System.out;
1314:                if (swallowOutput) {
1315:                    SystemLogHandler.startCapture();
1316:                }
1317:
1318:                // Call the servlet destroy() method
1319:                try {
1320:                    instanceSupport.fireInstanceEvent(
1321:                            InstanceEvent.BEFORE_DESTROY_EVENT, instance);
1322:
1323:                    if (Globals.IS_SECURITY_ENABLED) {
1324:                        SecurityUtil.doAsPrivilege("destroy", instance);
1325:                        SecurityUtil.remove(instance);
1326:                    } else {
1327:                        instance.destroy();
1328:                    }
1329:
1330:                    instanceSupport.fireInstanceEvent(
1331:                            InstanceEvent.AFTER_DESTROY_EVENT, instance);
1332:
1333:                    // Annotation processing
1334:                    if (!((Context) getParent()).getIgnoreAnnotations()) {
1335:                        ((StandardContext) getParent())
1336:                                .getAnnotationProcessor().preDestroy(instance);
1337:                    }
1338:
1339:                } catch (Throwable t) {
1340:                    instanceSupport.fireInstanceEvent(
1341:                            InstanceEvent.AFTER_DESTROY_EVENT, instance, t);
1342:                    instance = null;
1343:                    instancePool = null;
1344:                    nInstances = 0;
1345:                    fireContainerEvent("unload", this );
1346:                    unloading = false;
1347:                    throw new ServletException(sm.getString(
1348:                            "standardWrapper.destroyException", getName()), t);
1349:                } finally {
1350:                    // Write captured output
1351:                    if (swallowOutput) {
1352:                        String log = SystemLogHandler.stopCapture();
1353:                        if (log != null && log.length() > 0) {
1354:                            if (getServletContext() != null) {
1355:                                getServletContext().log(log);
1356:                            } else {
1357:                                out.println(log);
1358:                            }
1359:                        }
1360:                    }
1361:                }
1362:
1363:                // Deregister the destroyed instance
1364:                instance = null;
1365:
1366:                if (singleThreadModel && (instancePool != null)) {
1367:                    try {
1368:                        while (!instancePool.isEmpty()) {
1369:                            Servlet s = (Servlet) instancePool.pop();
1370:                            if (Globals.IS_SECURITY_ENABLED) {
1371:                                SecurityUtil.doAsPrivilege("destroy", s);
1372:                                SecurityUtil.remove(instance);
1373:                            } else {
1374:                                s.destroy();
1375:                            }
1376:                            // Annotation processing
1377:                            if (!((Context) getParent()).getIgnoreAnnotations()) {
1378:                                ((StandardContext) getParent())
1379:                                        .getAnnotationProcessor().preDestroy(s);
1380:                            }
1381:                        }
1382:                    } catch (Throwable t) {
1383:                        instancePool = null;
1384:                        nInstances = 0;
1385:                        unloading = false;
1386:                        fireContainerEvent("unload", this );
1387:                        throw new ServletException(sm.getString(
1388:                                "standardWrapper.destroyException", getName()),
1389:                                t);
1390:                    }
1391:                    instancePool = null;
1392:                    nInstances = 0;
1393:                }
1394:
1395:                singleThreadModel = false;
1396:
1397:                unloading = false;
1398:                fireContainerEvent("unload", this );
1399:
1400:            }
1401:
1402:            // -------------------------------------------------- ServletConfig Methods
1403:
1404:            /**
1405:             * Return the initialization parameter value for the specified name,
1406:             * if any; otherwise return <code>null</code>.
1407:             *
1408:             * @param name Name of the initialization parameter to retrieve
1409:             */
1410:            public String getInitParameter(String name) {
1411:
1412:                return (findInitParameter(name));
1413:
1414:            }
1415:
1416:            /**
1417:             * Return the set of initialization parameter names defined for this
1418:             * servlet.  If none are defined, an empty Enumeration is returned.
1419:             */
1420:            public Enumeration getInitParameterNames() {
1421:
1422:                synchronized (parameters) {
1423:                    return (new Enumerator(parameters.keySet()));
1424:                }
1425:
1426:            }
1427:
1428:            /**
1429:             * Return the servlet context with which this servlet is associated.
1430:             */
1431:            public ServletContext getServletContext() {
1432:
1433:                if (parent == null)
1434:                    return (null);
1435:                else if (!(parent instanceof  Context))
1436:                    return (null);
1437:                else
1438:                    return (((Context) parent).getServletContext());
1439:
1440:            }
1441:
1442:            /**
1443:             * Return the name of this servlet.
1444:             */
1445:            public String getServletName() {
1446:
1447:                return (getName());
1448:
1449:            }
1450:
1451:            public long getProcessingTime() {
1452:                return swValve.getProcessingTime();
1453:            }
1454:
1455:            public void setProcessingTime(long processingTime) {
1456:                swValve.setProcessingTime(processingTime);
1457:            }
1458:
1459:            public long getMaxTime() {
1460:                return swValve.getMaxTime();
1461:            }
1462:
1463:            public void setMaxTime(long maxTime) {
1464:                swValve.setMaxTime(maxTime);
1465:            }
1466:
1467:            public long getMinTime() {
1468:                return swValve.getMinTime();
1469:            }
1470:
1471:            public void setMinTime(long minTime) {
1472:                swValve.setMinTime(minTime);
1473:            }
1474:
1475:            public int getRequestCount() {
1476:                return swValve.getRequestCount();
1477:            }
1478:
1479:            public void setRequestCount(int requestCount) {
1480:                swValve.setRequestCount(requestCount);
1481:            }
1482:
1483:            public int getErrorCount() {
1484:                return swValve.getErrorCount();
1485:            }
1486:
1487:            public void setErrorCount(int errorCount) {
1488:                swValve.setErrorCount(errorCount);
1489:            }
1490:
1491:            /**
1492:             * Increment the error count used for monitoring.
1493:             */
1494:            public void incrementErrorCount() {
1495:                swValve.setErrorCount(swValve.getErrorCount() + 1);
1496:            }
1497:
1498:            public long getLoadTime() {
1499:                return loadTime;
1500:            }
1501:
1502:            public void setLoadTime(long loadTime) {
1503:                this .loadTime = loadTime;
1504:            }
1505:
1506:            public int getClassLoadTime() {
1507:                return classLoadTime;
1508:            }
1509:
1510:            // -------------------------------------------------------- Package Methods
1511:
1512:            // -------------------------------------------------------- protected Methods
1513:
1514:            /**
1515:             * Add a default Mapper implementation if none have been configured
1516:             * explicitly.
1517:             *
1518:             * @param mapperClass Java class name of the default Mapper
1519:             */
1520:            protected void addDefaultMapper(String mapperClass) {
1521:
1522:                ; // No need for a default Mapper on a Wrapper
1523:
1524:            }
1525:
1526:            /**
1527:             * Return <code>true</code> if the specified class name represents a
1528:             * container provided servlet class that should be loaded by the
1529:             * server class loader.
1530:             *
1531:             * @param classname Name of the class to be checked
1532:             */
1533:            protected boolean isContainerProvidedServlet(String classname) {
1534:
1535:                if (classname.startsWith("org.apache.catalina.")) {
1536:                    return (true);
1537:                }
1538:                try {
1539:                    Class clazz = this .getClass().getClassLoader().loadClass(
1540:                            classname);
1541:                    return (ContainerServlet.class.isAssignableFrom(clazz));
1542:                } catch (Throwable t) {
1543:                    return (false);
1544:                }
1545:
1546:            }
1547:
1548:            /**
1549:             * Return <code>true</code> if loading this servlet is allowed.
1550:             */
1551:            protected boolean isServletAllowed(Object servlet) {
1552:
1553:                // Privileged webapps may load all servlets without restriction
1554:                if (((Context) getParent()).getPrivileged()) {
1555:                    return true;
1556:                }
1557:
1558:                if (servlet instanceof  ContainerServlet) {
1559:                    return (false);
1560:                }
1561:
1562:                Class clazz = servlet.getClass();
1563:                while (clazz != null
1564:                        && !clazz.getName().equals(
1565:                                "javax.servlet.http.HttpServlet")) {
1566:                    if ("restricted".equals(restrictedServlets
1567:                            .getProperty(clazz.getName()))) {
1568:                        return (false);
1569:                    }
1570:                    clazz = clazz.getSuperclass();
1571:                }
1572:
1573:                return (true);
1574:
1575:            }
1576:
1577:            protected Method[] getAllDeclaredMethods(Class c) {
1578:
1579:                if (c.equals(javax.servlet.http.HttpServlet.class)) {
1580:                    return null;
1581:                }
1582:
1583:                Method[] parentMethods = getAllDeclaredMethods(c
1584:                        .getSuperclass());
1585:
1586:                Method[] this Methods = c.getDeclaredMethods();
1587:                if (this Methods == null) {
1588:                    return parentMethods;
1589:                }
1590:
1591:                if ((parentMethods != null) && (parentMethods.length > 0)) {
1592:                    Method[] allMethods = new Method[parentMethods.length
1593:                            + this Methods.length];
1594:                    System.arraycopy(parentMethods, 0, allMethods, 0,
1595:                            parentMethods.length);
1596:                    System.arraycopy(this Methods, 0, allMethods,
1597:                            parentMethods.length, this Methods.length);
1598:
1599:                    this Methods = allMethods;
1600:                }
1601:
1602:                return this Methods;
1603:            }
1604:
1605:            // ------------------------------------------------------ Lifecycle Methods
1606:
1607:            /**
1608:             * Start this component, pre-loading the servlet if the load-on-startup
1609:             * value is set appropriately.
1610:             *
1611:             * @exception LifecycleException if a fatal error occurs during startup
1612:             */
1613:            public void start() throws LifecycleException {
1614:
1615:                // Send j2ee.state.starting notification 
1616:                if (this .getObjectName() != null) {
1617:                    Notification notification = new Notification(
1618:                            "j2ee.state.starting", this .getObjectName(),
1619:                            sequenceNumber++);
1620:                    broadcaster.sendNotification(notification);
1621:                }
1622:
1623:                // Start up this component
1624:                super .start();
1625:
1626:                if (oname != null)
1627:                    registerJMX((StandardContext) getParent());
1628:
1629:                // Load and initialize an instance of this servlet if requested
1630:                // MOVED TO StandardContext START() METHOD
1631:
1632:                setAvailable(0L);
1633:
1634:                // Send j2ee.state.running notification 
1635:                if (this .getObjectName() != null) {
1636:                    Notification notification = new Notification(
1637:                            "j2ee.state.running", this .getObjectName(),
1638:                            sequenceNumber++);
1639:                    broadcaster.sendNotification(notification);
1640:                }
1641:
1642:            }
1643:
1644:            /**
1645:             * Stop this component, gracefully shutting down the servlet if it has
1646:             * been initialized.
1647:             *
1648:             * @exception LifecycleException if a fatal error occurs during shutdown
1649:             */
1650:            public void stop() throws LifecycleException {
1651:
1652:                setAvailable(Long.MAX_VALUE);
1653:
1654:                // Send j2ee.state.stopping notification 
1655:                if (this .getObjectName() != null) {
1656:                    Notification notification = new Notification(
1657:                            "j2ee.state.stopping", this .getObjectName(),
1658:                            sequenceNumber++);
1659:                    broadcaster.sendNotification(notification);
1660:                }
1661:
1662:                // Shut down our servlet instance (if it has been initialized)
1663:                try {
1664:                    unload();
1665:                } catch (ServletException e) {
1666:                    getServletContext().log(
1667:                            sm.getString("standardWrapper.unloadException",
1668:                                    getName()), e);
1669:                }
1670:
1671:                // Shut down this component
1672:                super .stop();
1673:
1674:                // Send j2ee.state.stoppped notification 
1675:                if (this .getObjectName() != null) {
1676:                    Notification notification = new Notification(
1677:                            "j2ee.state.stopped", this .getObjectName(),
1678:                            sequenceNumber++);
1679:                    broadcaster.sendNotification(notification);
1680:                }
1681:
1682:                if (oname != null) {
1683:                    Registry.getRegistry(null, null).unregisterComponent(oname);
1684:
1685:                    // Send j2ee.object.deleted notification 
1686:                    Notification notification = new Notification(
1687:                            "j2ee.object.deleted", this .getObjectName(),
1688:                            sequenceNumber++);
1689:                    broadcaster.sendNotification(notification);
1690:                }
1691:
1692:                if (isJspServlet && jspMonitorON != null) {
1693:                    Registry.getRegistry(null, null).unregisterComponent(
1694:                            jspMonitorON);
1695:                }
1696:
1697:            }
1698:
1699:            protected void registerJMX(StandardContext ctx) {
1700:
1701:                String parentName = ctx.getName();
1702:                parentName = ("".equals(parentName)) ? "/" : parentName;
1703:
1704:                String hostName = ctx.getParent().getName();
1705:                hostName = (hostName == null) ? "DEFAULT" : hostName;
1706:
1707:                String domain = ctx.getDomain();
1708:
1709:                String webMod = "//" + hostName + parentName;
1710:                String onameStr = domain + ":j2eeType=Servlet,name="
1711:                        + getName() + ",WebModule=" + webMod
1712:                        + ",J2EEApplication=" + ctx.getJ2EEApplication()
1713:                        + ",J2EEServer=" + ctx.getJ2EEServer();
1714:                try {
1715:                    oname = new ObjectName(onameStr);
1716:                    controller = oname;
1717:                    Registry.getRegistry(null, null).registerComponent(this ,
1718:                            oname, null);
1719:
1720:                    // Send j2ee.object.created notification 
1721:                    if (this .getObjectName() != null) {
1722:                        Notification notification = new Notification(
1723:                                "j2ee.object.created", this .getObjectName(),
1724:                                sequenceNumber++);
1725:                        broadcaster.sendNotification(notification);
1726:                    }
1727:                } catch (Exception ex) {
1728:                    log.info("Error registering servlet with jmx " + this );
1729:                }
1730:
1731:                if (isJspServlet) {
1732:                    // Register JSP monitoring mbean
1733:                    onameStr = domain + ":type=JspMonitor,name=" + getName()
1734:                            + ",WebModule=" + webMod + ",J2EEApplication="
1735:                            + ctx.getJ2EEApplication() + ",J2EEServer="
1736:                            + ctx.getJ2EEServer();
1737:                    try {
1738:                        jspMonitorON = new ObjectName(onameStr);
1739:                        Registry.getRegistry(null, null).registerComponent(
1740:                                instance, jspMonitorON, null);
1741:                    } catch (Exception ex) {
1742:                        log.info("Error registering JSP monitoring with jmx "
1743:                                + instance);
1744:                    }
1745:                }
1746:            }
1747:
1748:            /* Remove a JMX notficationListener 
1749:             * @see javax.management.NotificationEmitter#removeNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
1750:             */
1751:            public void removeNotificationListener(
1752:                    NotificationListener listener, NotificationFilter filter,
1753:                    Object object) throws ListenerNotFoundException {
1754:                broadcaster
1755:                        .removeNotificationListener(listener, filter, object);
1756:
1757:            }
1758:
1759:            protected MBeanNotificationInfo[] notificationInfo;
1760:
1761:            /* Get JMX Broadcaster Info
1762:             * @TODO use StringManager for international support!
1763:             * @TODO This two events we not send j2ee.state.failed and j2ee.attribute.changed!
1764:             * @see javax.management.NotificationBroadcaster#getNotificationInfo()
1765:             */
1766:            public MBeanNotificationInfo[] getNotificationInfo() {
1767:
1768:                if (notificationInfo == null) {
1769:                    notificationInfo = new MBeanNotificationInfo[] {
1770:                            new MBeanNotificationInfo(
1771:                                    new String[] { "j2ee.object.created" },
1772:                                    Notification.class.getName(),
1773:                                    "servlet is created"),
1774:                            new MBeanNotificationInfo(
1775:                                    new String[] { "j2ee.state.starting" },
1776:                                    Notification.class.getName(),
1777:                                    "servlet is starting"),
1778:                            new MBeanNotificationInfo(
1779:                                    new String[] { "j2ee.state.running" },
1780:                                    Notification.class.getName(),
1781:                                    "servlet is running"),
1782:                            new MBeanNotificationInfo(
1783:                                    new String[] { "j2ee.state.stopped" },
1784:                                    Notification.class.getName(),
1785:                                    "servlet start to stopped"),
1786:                            new MBeanNotificationInfo(
1787:                                    new String[] { "j2ee.object.stopped" },
1788:                                    Notification.class.getName(),
1789:                                    "servlet is stopped"),
1790:                            new MBeanNotificationInfo(
1791:                                    new String[] { "j2ee.object.deleted" },
1792:                                    Notification.class.getName(),
1793:                                    "servlet is deleted") };
1794:
1795:                }
1796:
1797:                return notificationInfo;
1798:            }
1799:
1800:            /* Add a JMX-NotificationListener
1801:             * @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object)
1802:             */
1803:            public void addNotificationListener(NotificationListener listener,
1804:                    NotificationFilter filter, Object object)
1805:                    throws IllegalArgumentException {
1806:                broadcaster.addNotificationListener(listener, filter, object);
1807:            }
1808:
1809:            /**
1810:             * Remove a JMX-NotificationListener 
1811:             * @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener)
1812:             */
1813:            public void removeNotificationListener(NotificationListener listener)
1814:                    throws ListenerNotFoundException {
1815:                broadcaster.removeNotificationListener(listener);
1816:            }
1817:
1818:            // ------------------------------------------------------------- Attributes
1819:
1820:            public boolean isEventProvider() {
1821:                return false;
1822:            }
1823:
1824:            public boolean isStateManageable() {
1825:                return false;
1826:            }
1827:
1828:            public boolean isStatisticsProvider() {
1829:                return false;
1830:            }
1831:
1832:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.