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


0001:        /*
0002:         * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v 1.39 2002/06/26 13:41:12 glenn Exp $
0003:         * $Revision: 1.39 $
0004:         * $Date: 2002/06/26 13:41:12 $
0005:         *
0006:         * ====================================================================
0007:         *
0008:         * The Apache Software License, Version 1.1
0009:         *
0010:         * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
0011:         * reserved.
0012:         *
0013:         * Redistribution and use in source and binary forms, with or without
0014:         * modification, are permitted provided that the following conditions
0015:         * are met:
0016:         *
0017:         * 1. Redistributions of source code must retain the above copyright
0018:         *    notice, this list of conditions and the following disclaimer.
0019:         *
0020:         * 2. Redistributions in binary form must reproduce the above copyright
0021:         *    notice, this list of conditions and the following disclaimer in
0022:         *    the documentation and/or other materials provided with the
0023:         *    distribution.
0024:         *
0025:         * 3. The end-user documentation included with the redistribution, if
0026:         *    any, must include the following acknowlegement:
0027:         *       "This product includes software developed by the
0028:         *        Apache Software Foundation (http://www.apache.org/)."
0029:         *    Alternately, this acknowlegement may appear in the software itself,
0030:         *    if and wherever such third-party acknowlegements normally appear.
0031:         *
0032:         * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
0033:         *    Foundation" must not be used to endorse or promote products derived
0034:         *    from this software without prior written permission. For written
0035:         *    permission, please contact apache@apache.org.
0036:         *
0037:         * 5. Products derived from this software may not be called "Apache"
0038:         *    nor may "Apache" appear in their names without prior written
0039:         *    permission of the Apache Group.
0040:         *
0041:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0042:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0043:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0044:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0045:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0046:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0047:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0048:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0049:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0050:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0051:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0052:         * SUCH DAMAGE.
0053:         * ====================================================================
0054:         *
0055:         * This software consists of voluntary contributions made by many
0056:         * individuals on behalf of the Apache Software Foundation.  For more
0057:         * information on the Apache Software Foundation, please see
0058:         * <http://www.apache.org/>.
0059:         *
0060:         * [Additional notices, if required by prior licensing conditions]
0061:         *
0062:         */
0063:
0064:        package org.apache.catalina.core;
0065:
0066:        import java.io.File;
0067:        import java.io.IOException;
0068:        import java.io.PrintStream;
0069:        import java.net.URL;
0070:        import java.util.Enumeration;
0071:        import java.util.HashMap;
0072:        import java.util.Stack;
0073:        import javax.servlet.Servlet;
0074:        import javax.servlet.ServletConfig;
0075:        import javax.servlet.ServletContext;
0076:        import javax.servlet.ServletException;
0077:        import javax.servlet.SingleThreadModel;
0078:        import javax.servlet.UnavailableException;
0079:        import javax.servlet.http.HttpServletResponse;
0080:        import org.apache.catalina.Container;
0081:        import org.apache.catalina.ContainerServlet;
0082:        import org.apache.catalina.Context;
0083:        import org.apache.catalina.InstanceEvent;
0084:        import org.apache.catalina.InstanceListener;
0085:        import org.apache.catalina.Lifecycle;
0086:        import org.apache.catalina.LifecycleException;
0087:        import org.apache.catalina.Loader;
0088:        import org.apache.catalina.Logger;
0089:        import org.apache.catalina.Request;
0090:        import org.apache.catalina.Response;
0091:        import org.apache.catalina.Wrapper;
0092:        import org.apache.catalina.connector.HttpRequestBase;
0093:        import org.apache.catalina.connector.HttpResponseBase;
0094:        import org.apache.catalina.loader.StandardClassLoader;
0095:        import org.apache.catalina.util.Enumerator;
0096:        import org.apache.catalina.util.InstanceSupport;
0097:        import org.apache.tomcat.util.log.SystemLogHandler;
0098:
0099:        /**
0100:         * Standard implementation of the <b>Wrapper</b> interface that represents
0101:         * an individual servlet definition.  No child Containers are allowed, and
0102:         * the parent Container must be a Context.
0103:         *
0104:         * @author Craig R. McClanahan
0105:         * @author Remy Maucherat
0106:         * @version $Revision: 1.39 $ $Date: 2002/06/26 13:41:12 $
0107:         */
0108:
0109:        public final class StandardWrapper extends ContainerBase implements 
0110:                ServletConfig, Wrapper {
0111:
0112:            // ----------------------------------------------------------- Constructors
0113:
0114:            /**
0115:             * Create a new StandardWrapper component with the default basic Valve.
0116:             */
0117:            public StandardWrapper() {
0118:
0119:                super ();
0120:                pipeline.setBasic(new StandardWrapperValve());
0121:
0122:            }
0123:
0124:            // ----------------------------------------------------- Instance Variables
0125:
0126:            /**
0127:             * The date and time at which this servlet will become available (in
0128:             * milliseconds since the epoch), or zero if the servlet is available.
0129:             * If this value equals Long.MAX_VALUE, the unavailability of this
0130:             * servlet is considered permanent.
0131:             */
0132:            private long available = 0L;
0133:
0134:            /**
0135:             * The count of allocations that are currently active (even if they
0136:             * are for the same instance, as will be true on a non-STM servlet).
0137:             */
0138:            private int countAllocated = 0;
0139:
0140:            /**
0141:             * The debugging detail level for this component.
0142:             */
0143:            private int debug = 0;
0144:
0145:            /**
0146:             * The facade associated with this wrapper.
0147:             */
0148:            private StandardWrapperFacade facade = new StandardWrapperFacade(
0149:                    this );
0150:
0151:            /**
0152:             * The descriptive information string for this implementation.
0153:             */
0154:            private static final String info = "org.apache.catalina.core.StandardWrapper/1.0";
0155:
0156:            /**
0157:             * The (single) initialized instance of this servlet.
0158:             */
0159:            private Servlet instance = null;
0160:
0161:            /**
0162:             * The support object for our instance listeners.
0163:             */
0164:            private InstanceSupport instanceSupport = new InstanceSupport(this );
0165:
0166:            /**
0167:             * The context-relative URI of the JSP file for this servlet.
0168:             */
0169:            private String jspFile = null;
0170:
0171:            /**
0172:             * The load-on-startup order value (negative value means load on
0173:             * first call) for this servlet.
0174:             */
0175:            private int loadOnStartup = -1;
0176:
0177:            /**
0178:             * The initialization parameters for this servlet, keyed by
0179:             * parameter name.
0180:             */
0181:            private HashMap parameters = new HashMap();
0182:
0183:            /**
0184:             * The security role references for this servlet, keyed by role name
0185:             * used in the servlet.  The corresponding value is the role name of
0186:             * the web application itself.
0187:             */
0188:            private HashMap references = new HashMap();
0189:
0190:            /**
0191:             * The run-as identity for this servlet.
0192:             */
0193:            private String runAs = null;
0194:
0195:            /**
0196:             * The fully qualified servlet class name for this servlet.
0197:             */
0198:            private String servletClass = null;
0199:
0200:            /**
0201:             * Does this servlet implement the SingleThreadModel interface?
0202:             */
0203:            private boolean singleThreadModel = false;
0204:
0205:            /**
0206:             * Are we unloading our servlet instance at the moment?
0207:             */
0208:            private boolean unloading = false;
0209:
0210:            /**
0211:             * Maximum number of STM instances.
0212:             */
0213:            private int maxInstances = 20;
0214:
0215:            /**
0216:             * Number of instances currently loaded for a STM servlet.
0217:             */
0218:            private int nInstances = 0;
0219:
0220:            /**
0221:             * Stack containing the STM instances.
0222:             */
0223:            private Stack instancePool = null;
0224:
0225:            // ------------------------------------------------------------- Properties
0226:
0227:            /**
0228:             * Return the available date/time for this servlet, in milliseconds since
0229:             * the epoch.  If this date/time is in the future, any request for this
0230:             * servlet will return an SC_SERVICE_UNAVAILABLE error.  If it is zero,
0231:             * the servlet is currently available.  A value equal to Long.MAX_VALUE
0232:             * is considered to mean that unavailability is permanent.
0233:             */
0234:            public long getAvailable() {
0235:
0236:                return (this .available);
0237:
0238:            }
0239:
0240:            /**
0241:             * Set the available date/time for this servlet, in milliseconds since the
0242:             * epoch.  If this date/time is in the future, any request for this servlet
0243:             * will return an SC_SERVICE_UNAVAILABLE error.
0244:             *
0245:             * @param available The new available date/time
0246:             */
0247:            public void setAvailable(long available) {
0248:
0249:                long oldAvailable = this .available;
0250:                if (available > System.currentTimeMillis())
0251:                    this .available = available;
0252:                else
0253:                    this .available = 0L;
0254:                support.firePropertyChange("available", new Long(oldAvailable),
0255:                        new Long(this .available));
0256:
0257:            }
0258:
0259:            /**
0260:             * Return the number of active allocations of this servlet, even if they
0261:             * are all for the same instance (as will be true for servlets that do
0262:             * not implement <code>SingleThreadModel</code>.
0263:             */
0264:            public int getCountAllocated() {
0265:
0266:                return (this .countAllocated);
0267:
0268:            }
0269:
0270:            /**
0271:             * Return the debugging detail level for this component.
0272:             */
0273:            public int getDebug() {
0274:
0275:                return (this .debug);
0276:
0277:            }
0278:
0279:            /**
0280:             * Set the debugging detail level for this component.
0281:             *
0282:             * @param debug The new debugging detail level
0283:             */
0284:            public void setDebug(int debug) {
0285:
0286:                int oldDebug = this .debug;
0287:                this .debug = debug;
0288:                support.firePropertyChange("debug", new Integer(oldDebug),
0289:                        new Long(this .debug));
0290:
0291:            }
0292:
0293:            /**
0294:             * Return descriptive information about this Container implementation and
0295:             * the corresponding version number, in the format
0296:             * <code>&lt;description&gt;/&lt;version&gt;</code>.
0297:             */
0298:            public String getInfo() {
0299:
0300:                return (info);
0301:
0302:            }
0303:
0304:            /**
0305:             * Return the InstanceSupport object for this Wrapper instance.
0306:             */
0307:            public InstanceSupport getInstanceSupport() {
0308:
0309:                return (this .instanceSupport);
0310:
0311:            }
0312:
0313:            /**
0314:             * Return the context-relative URI of the JSP file for this servlet.
0315:             */
0316:            public String getJspFile() {
0317:
0318:                return (this .jspFile);
0319:
0320:            }
0321:
0322:            /**
0323:             * Set the context-relative URI of the JSP file for this servlet.
0324:             *
0325:             * @param jspFile JSP file URI
0326:             */
0327:            public void setJspFile(String jspFile) {
0328:
0329:                //        if ((jspFile != null) && !jspFile.startsWith("/"))
0330:                //        throw new IllegalArgumentException
0331:                //                (sm.getString("standardWrapper.jspFile.format", jspFile));
0332:
0333:                String oldJspFile = this .jspFile;
0334:                this .jspFile = jspFile;
0335:                support.firePropertyChange("jspFile", oldJspFile, this .jspFile);
0336:
0337:            }
0338:
0339:            /**
0340:             * Return the load-on-startup order value (negative value means
0341:             * load on first call).
0342:             */
0343:            public int getLoadOnStartup() {
0344:
0345:                return (this .loadOnStartup);
0346:
0347:            }
0348:
0349:            /**
0350:             * Set the load-on-startup order value (negative value means
0351:             * load on first call).
0352:             *
0353:             * @param value New load-on-startup value
0354:             */
0355:            public void setLoadOnStartup(int value) {
0356:
0357:                int oldLoadOnStartup = this .loadOnStartup;
0358:                this .loadOnStartup = value;
0359:                support.firePropertyChange("loadOnStartup", new Integer(
0360:                        oldLoadOnStartup), new Integer(this .loadOnStartup));
0361:
0362:            }
0363:
0364:            /**
0365:             * Set the load-on-startup order value from a (possibly null) string.
0366:             * Per the specification, any missing or non-numeric value is converted
0367:             * to a zero, so that this servlet will still be loaded at startup
0368:             * time, but in an arbitrary order.
0369:             *
0370:             * @param value New load-on-startup value
0371:             */
0372:            public void setLoadOnStartupString(String value) {
0373:
0374:                try {
0375:                    setLoadOnStartup(Integer.parseInt(value));
0376:                } catch (NumberFormatException e) {
0377:                    setLoadOnStartup(0);
0378:                }
0379:
0380:            }
0381:
0382:            /**
0383:             * Return maximum number of instances that will be allocated when a single
0384:             * thread model servlet is used.
0385:             */
0386:            public int getMaxInstances() {
0387:
0388:                return (this .maxInstances);
0389:
0390:            }
0391:
0392:            /**
0393:             * Set the maximum number of instances that will be allocated when a single
0394:             * thread model servlet is used.
0395:             *
0396:             * @param maxInstnces New value of maxInstances
0397:             */
0398:            public void setMaxInstances(int maxInstances) {
0399:
0400:                int oldMaxInstances = this .maxInstances;
0401:                this .maxInstances = maxInstances;
0402:                support.firePropertyChange("maxInstances", oldMaxInstances,
0403:                        this .maxInstances);
0404:
0405:            }
0406:
0407:            /**
0408:             * Set the parent Container of this Wrapper, but only if it is a Context.
0409:             *
0410:             * @param container Proposed parent Container
0411:             */
0412:            public void setParent(Container container) {
0413:
0414:                if ((container != null) && !(container instanceof  Context))
0415:                    throw new IllegalArgumentException(sm
0416:                            .getString("standardWrapper.notContext"));
0417:                super .setParent(container);
0418:
0419:            }
0420:
0421:            /**
0422:             * Return the run-as identity for this servlet.
0423:             */
0424:            public String getRunAs() {
0425:
0426:                return (this .runAs);
0427:
0428:            }
0429:
0430:            /**
0431:             * Set the run-as identity for this servlet.
0432:             *
0433:             * @param value New run-as identity value
0434:             */
0435:            public void setRunAs(String runAs) {
0436:
0437:                String oldRunAs = this .runAs;
0438:                this .runAs = runAs;
0439:                support.firePropertyChange("runAs", oldRunAs, this .runAs);
0440:
0441:            }
0442:
0443:            /**
0444:             * Return the fully qualified servlet class name for this servlet.
0445:             */
0446:            public String getServletClass() {
0447:
0448:                return (this .servletClass);
0449:
0450:            }
0451:
0452:            /**
0453:             * Set the fully qualified servlet class name for this servlet.
0454:             *
0455:             * @param servletClass Servlet class name
0456:             */
0457:            public void setServletClass(String servletClass) {
0458:
0459:                String oldServletClass = this .servletClass;
0460:                this .servletClass = servletClass;
0461:                support.firePropertyChange("servletClass", oldServletClass,
0462:                        this .servletClass);
0463:
0464:            }
0465:
0466:            /**
0467:             * Set the name of this servlet.  This is an alias for the normal
0468:             * <code>Container.setName()</code> method, and complements the
0469:             * <code>getServletName()</code> method required by the
0470:             * <code>ServletConfig</code> interface.
0471:             *
0472:             * @param name The new name of this servlet
0473:             */
0474:            public void setServletName(String name) {
0475:
0476:                setName(name);
0477:
0478:            }
0479:
0480:            /**
0481:             * Return <code>true</code> if the servlet class represented by this
0482:             * component implements the <code>SingleThreadModel</code> interface.
0483:             */
0484:            public boolean isSingleThreadModel() {
0485:
0486:                try {
0487:                    loadServlet();
0488:                } catch (Throwable t) {
0489:                    ;
0490:                }
0491:                return (singleThreadModel);
0492:
0493:            }
0494:
0495:            /**
0496:             * Is this servlet currently unavailable?
0497:             */
0498:            public boolean isUnavailable() {
0499:
0500:                if (available == 0L)
0501:                    return (false);
0502:                else if (available <= System.currentTimeMillis()) {
0503:                    available = 0L;
0504:                    return (false);
0505:                } else
0506:                    return (true);
0507:
0508:            }
0509:
0510:            // --------------------------------------------------------- Public Methods
0511:
0512:            /**
0513:             * Refuse to add a child Container, because Wrappers are the lowest level
0514:             * of the Container hierarchy.
0515:             *
0516:             * @param child Child container to be added
0517:             */
0518:            public void addChild(Container child) {
0519:
0520:                throw new IllegalStateException(sm
0521:                        .getString("standardWrapper.notChild"));
0522:
0523:            }
0524:
0525:            /**
0526:             * Add a new servlet initialization parameter for this servlet.
0527:             *
0528:             * @param name Name of this initialization parameter to add
0529:             * @param value Value of this initialization parameter to add
0530:             */
0531:            public void addInitParameter(String name, String value) {
0532:
0533:                synchronized (parameters) {
0534:                    parameters.put(name, value);
0535:                }
0536:                fireContainerEvent("addInitParameter", name);
0537:
0538:            }
0539:
0540:            /**
0541:             * Add a new listener interested in InstanceEvents.
0542:             *
0543:             * @param listener The new listener
0544:             */
0545:            public void addInstanceListener(InstanceListener listener) {
0546:
0547:                instanceSupport.addInstanceListener(listener);
0548:
0549:            }
0550:
0551:            /**
0552:             * Add a new security role reference record to the set of records for
0553:             * this servlet.
0554:             *
0555:             * @param name Role name used within this servlet
0556:             * @param link Role name used within the web application
0557:             */
0558:            public void addSecurityReference(String name, String link) {
0559:
0560:                synchronized (references) {
0561:                    references.put(name, link);
0562:                }
0563:                fireContainerEvent("addSecurityReference", name);
0564:
0565:            }
0566:
0567:            /**
0568:             * Allocate an initialized instance of this Servlet that is ready to have
0569:             * its <code>service()</code> method called.  If the servlet class does
0570:             * not implement <code>SingleThreadModel</code>, the (only) initialized
0571:             * instance may be returned immediately.  If the servlet class implements
0572:             * <code>SingleThreadModel</code>, the Wrapper implementation must ensure
0573:             * that this instance is not allocated again until it is deallocated by a
0574:             * call to <code>deallocate()</code>.
0575:             *
0576:             * @exception ServletException if the servlet init() method threw
0577:             *  an exception
0578:             * @exception ServletException if a loading error occurs
0579:             */
0580:            public Servlet allocate() throws ServletException {
0581:
0582:                if (debug >= 1)
0583:                    log("Allocating an instance");
0584:
0585:                // If we are currently unloading this servlet, throw an exception
0586:                if (unloading)
0587:                    throw new ServletException(sm.getString(
0588:                            "standardWrapper.unloading", getName()));
0589:
0590:                // If not SingleThreadedModel, return the same instance every time
0591:                if (!singleThreadModel) {
0592:
0593:                    // Load and initialize our instance if necessary
0594:                    if (instance == null) {
0595:                        synchronized (this ) {
0596:                            if (instance == null) {
0597:                                try {
0598:                                    instance = loadServlet();
0599:                                } catch (ServletException e) {
0600:                                    throw e;
0601:                                } catch (Throwable e) {
0602:                                    throw new ServletException(
0603:                                            sm
0604:                                                    .getString("standardWrapper.allocate"),
0605:                                            e);
0606:                                }
0607:                            }
0608:                        }
0609:                    }
0610:
0611:                    if (!singleThreadModel) {
0612:                        if (debug >= 2)
0613:                            log("  Returning non-STM instance");
0614:                        countAllocated++;
0615:                        return (instance);
0616:                    }
0617:
0618:                }
0619:
0620:                synchronized (instancePool) {
0621:
0622:                    while (countAllocated >= nInstances) {
0623:                        // Allocate a new instance if possible, or else wait
0624:                        if (nInstances < maxInstances) {
0625:                            try {
0626:                                instancePool.push(loadServlet());
0627:                                nInstances++;
0628:                            } catch (ServletException e) {
0629:                                throw e;
0630:                            } catch (Throwable e) {
0631:                                throw new ServletException(sm
0632:                                        .getString("standardWrapper.allocate"),
0633:                                        e);
0634:                            }
0635:                        } else {
0636:                            try {
0637:                                instancePool.wait();
0638:                            } catch (InterruptedException e) {
0639:                                ;
0640:                            }
0641:                        }
0642:                    }
0643:                    if (debug >= 2)
0644:                        log("  Returning allocated STM instance");
0645:                    countAllocated++;
0646:                    return (Servlet) instancePool.pop();
0647:
0648:                }
0649:
0650:            }
0651:
0652:            /**
0653:             * Return this previously allocated servlet to the pool of available
0654:             * instances.  If this servlet class does not implement SingleThreadModel,
0655:             * no action is actually required.
0656:             *
0657:             * @param servlet The servlet to be returned
0658:             *
0659:             * @exception ServletException if a deallocation error occurs
0660:             */
0661:            public void deallocate(Servlet servlet) throws ServletException {
0662:
0663:                // If not SingleThreadModel, no action is required
0664:                if (!singleThreadModel) {
0665:                    countAllocated--;
0666:                    return;
0667:                }
0668:
0669:                // Unlock and free this instance
0670:                synchronized (instancePool) {
0671:                    countAllocated--;
0672:                    instancePool.push(servlet);
0673:                    instancePool.notify();
0674:                }
0675:
0676:            }
0677:
0678:            /**
0679:             * Return the value for the specified initialization parameter name,
0680:             * if any; otherwise return <code>null</code>.
0681:             *
0682:             * @param name Name of the requested initialization parameter
0683:             */
0684:            public String findInitParameter(String name) {
0685:
0686:                synchronized (parameters) {
0687:                    return ((String) parameters.get(name));
0688:                }
0689:
0690:            }
0691:
0692:            /**
0693:             * Return the names of all defined initialization parameters for this
0694:             * servlet.
0695:             */
0696:            public String[] findInitParameters() {
0697:
0698:                synchronized (parameters) {
0699:                    String results[] = new String[parameters.size()];
0700:                    return ((String[]) parameters.keySet().toArray(results));
0701:                }
0702:
0703:            }
0704:
0705:            /**
0706:             * Return the security role link for the specified security role
0707:             * reference name, if any; otherwise return <code>null</code>.
0708:             *
0709:             * @param name Security role reference used within this servlet
0710:             */
0711:            public String findSecurityReference(String name) {
0712:
0713:                synchronized (references) {
0714:                    return ((String) references.get(name));
0715:                }
0716:
0717:            }
0718:
0719:            /**
0720:             * Return the set of security role reference names associated with
0721:             * this servlet, if any; otherwise return a zero-length array.
0722:             */
0723:            public String[] findSecurityReferences() {
0724:
0725:                synchronized (references) {
0726:                    String results[] = new String[references.size()];
0727:                    return ((String[]) references.keySet().toArray(results));
0728:                }
0729:
0730:            }
0731:
0732:            /**
0733:             * Load and initialize an instance of this servlet, if there is not already
0734:             * at least one initialized instance.  This can be used, for example, to
0735:             * load servlets that are marked in the deployment descriptor to be loaded
0736:             * at server startup time.
0737:             * <p>
0738:             * <b>IMPLEMENTATION NOTE</b>:  Servlets whose classnames begin with
0739:             * <code>org.apache.catalina.</code> (so-called "container" servlets)
0740:             * are loaded by the same classloader that loaded this class, rather than
0741:             * the classloader for the current web application.
0742:             * This gives such classes access to Catalina internals, which are
0743:             * prevented for classes loaded for web applications.
0744:             *
0745:             * @exception ServletException if the servlet init() method threw
0746:             *  an exception
0747:             * @exception ServletException if some other loading problem occurs
0748:             */
0749:            public synchronized void load() throws ServletException {
0750:                instance = loadServlet();
0751:            }
0752:
0753:            /**
0754:             * Load and initialize an instance of this servlet, if there is not already
0755:             * at least one initialized instance.  This can be used, for example, to
0756:             * load servlets that are marked in the deployment descriptor to be loaded
0757:             * at server startup time.
0758:             */
0759:            public synchronized Servlet loadServlet() throws ServletException {
0760:
0761:                // Nothing to do if we already have an instance or an instance pool
0762:                if (!singleThreadModel && (instance != null))
0763:                    return instance;
0764:
0765:                PrintStream out = System.out;
0766:                SystemLogHandler.startCapture();
0767:                Servlet servlet = null;
0768:                try {
0769:                    // If this "servlet" is really a JSP file, get the right class.
0770:                    // HOLD YOUR NOSE - this is a kludge that avoids having to do special
0771:                    // case Catalina-specific code in Jasper - it also requires that the
0772:                    // servlet path be replaced by the <jsp-file> element content in
0773:                    // order to be completely effective
0774:                    String actualClass = servletClass;
0775:                    if ((actualClass == null) && (jspFile != null)) {
0776:                        Wrapper jspWrapper = (Wrapper) ((Context) getParent())
0777:                                .findChild(Constants.JSP_SERVLET_NAME);
0778:                        if (jspWrapper != null)
0779:                            actualClass = jspWrapper.getServletClass();
0780:                    }
0781:
0782:                    // Complain if no servlet class has been specified
0783:                    if (actualClass == null) {
0784:                        unavailable(null);
0785:                        throw new ServletException(sm.getString(
0786:                                "standardWrapper.notClass", getName()));
0787:                    }
0788:
0789:                    // Acquire an instance of the class loader to be used
0790:                    Loader loader = getLoader();
0791:                    if (loader == null) {
0792:                        unavailable(null);
0793:                        throw new ServletException(sm.getString(
0794:                                "standardWrapper.missingLoader", getName()));
0795:                    }
0796:
0797:                    ClassLoader classLoader = loader.getClassLoader();
0798:
0799:                    // Special case class loader for a container provided servlet
0800:                    if (isContainerProvidedServlet(actualClass)) {
0801:                        classLoader = this .getClass().getClassLoader();
0802:                        log(sm.getString("standardWrapper.containerServlet",
0803:                                getName()));
0804:                    }
0805:
0806:                    // Load the specified servlet class from the appropriate class loader
0807:                    Class classClass = null;
0808:                    try {
0809:                        if (classLoader != null) {
0810:                            classClass = classLoader.loadClass(actualClass);
0811:                        } else {
0812:                            classClass = Class.forName(actualClass);
0813:                        }
0814:                    } catch (ClassNotFoundException e) {
0815:                        unavailable(null);
0816:                        throw new ServletException(sm.getString(
0817:                                "standardWrapper.missingClass", actualClass), e);
0818:                    }
0819:                    if (classClass == null) {
0820:                        unavailable(null);
0821:                        throw new ServletException(sm.getString(
0822:                                "standardWrapper.missingClass", actualClass));
0823:                    }
0824:
0825:                    // Instantiate and initialize an instance of the servlet class itself
0826:                    try {
0827:                        servlet = (Servlet) classClass.newInstance();
0828:                    } catch (ClassCastException e) {
0829:                        unavailable(null);
0830:                        // Restore the context ClassLoader
0831:                        throw new ServletException(sm.getString(
0832:                                "standardWrapper.notServlet", actualClass), e);
0833:                    } catch (Throwable e) {
0834:                        unavailable(null);
0835:                        // Restore the context ClassLoader
0836:                        throw new ServletException(sm.getString(
0837:                                "standardWrapper.instantiate", actualClass), e);
0838:                    }
0839:
0840:                    // Check if loading the servlet in this web application should be 
0841:                    // allowed
0842:                    if (!isServletAllowed(servlet)) {
0843:                        throw new SecurityException(sm.getString(
0844:                                "standardWrapper.privilegedServlet",
0845:                                actualClass));
0846:                    }
0847:
0848:                    // Special handling for ContainerServlet instances
0849:                    if ((servlet instanceof  ContainerServlet)
0850:                            && isContainerProvidedServlet(actualClass)) {
0851:                        ((ContainerServlet) servlet).setWrapper(this );
0852:                    }
0853:
0854:                    // Call the initialization method of this servlet
0855:                    try {
0856:                        instanceSupport.fireInstanceEvent(
0857:                                InstanceEvent.BEFORE_INIT_EVENT, servlet);
0858:                        servlet.init(facade);
0859:                        // Invoke jspInit on JSP pages
0860:                        if ((loadOnStartup > 0) && (jspFile != null)) {
0861:                            // Invoking jspInit
0862:                            HttpRequestBase req = new HttpRequestBase();
0863:                            HttpResponseBase res = new HttpResponseBase();
0864:                            req.setServletPath(jspFile);
0865:                            req.setQueryString("jsp_precompile=true");
0866:                            servlet.service(req, res);
0867:                        }
0868:                        instanceSupport.fireInstanceEvent(
0869:                                InstanceEvent.AFTER_INIT_EVENT, servlet);
0870:                    } catch (UnavailableException f) {
0871:                        instanceSupport.fireInstanceEvent(
0872:                                InstanceEvent.AFTER_INIT_EVENT, servlet, f);
0873:                        unavailable(f);
0874:                        throw f;
0875:                    } catch (ServletException f) {
0876:                        instanceSupport.fireInstanceEvent(
0877:                                InstanceEvent.AFTER_INIT_EVENT, servlet, f);
0878:                        // If the servlet wanted to be unavailable it would have
0879:                        // said so, so do not call unavailable(null).
0880:                        throw f;
0881:                    } catch (Throwable f) {
0882:                        instanceSupport.fireInstanceEvent(
0883:                                InstanceEvent.AFTER_INIT_EVENT, servlet, f);
0884:                        // If the servlet wanted to be unavailable it would have
0885:                        // said so, so do not call unavailable(null).
0886:                        throw new ServletException(sm.getString(
0887:                                "standardWrapper.initException", getName()), f);
0888:                    }
0889:
0890:                    // Register our newly initialized instance
0891:                    singleThreadModel = servlet instanceof  SingleThreadModel;
0892:                    if (singleThreadModel) {
0893:                        if (instancePool == null)
0894:                            instancePool = new Stack();
0895:                    }
0896:                    fireContainerEvent("load", this );
0897:                } finally {
0898:                    String log = SystemLogHandler.stopCapture();
0899:                    if (log != null && log.length() > 0) {
0900:                        if (getServletContext() != null) {
0901:                            getServletContext().log(log);
0902:                        } else {
0903:                            out.println(log);
0904:                        }
0905:                    }
0906:                }
0907:                return servlet;
0908:
0909:            }
0910:
0911:            /**
0912:             * Remove the specified initialization parameter from this servlet.
0913:             *
0914:             * @param name Name of the initialization parameter to remove
0915:             */
0916:            public void removeInitParameter(String name) {
0917:
0918:                synchronized (parameters) {
0919:                    parameters.remove(name);
0920:                }
0921:                fireContainerEvent("removeInitParameter", name);
0922:
0923:            }
0924:
0925:            /**
0926:             * Remove a listener no longer interested in InstanceEvents.
0927:             *
0928:             * @param listener The listener to remove
0929:             */
0930:            public void removeInstanceListener(InstanceListener listener) {
0931:
0932:                instanceSupport.removeInstanceListener(listener);
0933:
0934:            }
0935:
0936:            /**
0937:             * Remove any security role reference for the specified role name.
0938:             *
0939:             * @param name Security role used within this servlet to be removed
0940:             */
0941:            public void removeSecurityReference(String name) {
0942:
0943:                synchronized (references) {
0944:                    references.remove(name);
0945:                }
0946:                fireContainerEvent("removeSecurityReference", name);
0947:
0948:            }
0949:
0950:            /**
0951:             * Return a String representation of this component.
0952:             */
0953:            public String toString() {
0954:
0955:                StringBuffer sb = new StringBuffer();
0956:                if (getParent() != null) {
0957:                    sb.append(getParent().toString());
0958:                    sb.append(".");
0959:                }
0960:                sb.append("StandardWrapper[");
0961:                sb.append(getName());
0962:                sb.append("]");
0963:                return (sb.toString());
0964:
0965:            }
0966:
0967:            /**
0968:             * Process an UnavailableException, marking this servlet as unavailable
0969:             * for the specified amount of time.
0970:             *
0971:             * @param unavailable The exception that occurred, or <code>null</code>
0972:             *  to mark this servlet as permanently unavailable
0973:             */
0974:            public void unavailable(UnavailableException unavailable) {
0975:                log(sm.getString("standardWrapper.unavailable", getName()));
0976:                if (unavailable == null)
0977:                    setAvailable(Long.MAX_VALUE);
0978:                else if (unavailable.isPermanent())
0979:                    setAvailable(Long.MAX_VALUE);
0980:                else {
0981:                    int unavailableSeconds = unavailable
0982:                            .getUnavailableSeconds();
0983:                    if (unavailableSeconds <= 0)
0984:                        unavailableSeconds = 60; // Arbitrary default
0985:                    setAvailable(System.currentTimeMillis()
0986:                            + (unavailableSeconds * 1000L));
0987:                }
0988:
0989:            }
0990:
0991:            /**
0992:             * Unload all initialized instances of this servlet, after calling the
0993:             * <code>destroy()</code> method for each instance.  This can be used,
0994:             * for example, prior to shutting down the entire servlet engine, or
0995:             * prior to reloading all of the classes from the Loader associated with
0996:             * our Loader's repository.
0997:             *
0998:             * @exception ServletException if an exception is thrown by the
0999:             *  destroy() method
1000:             */
1001:            public synchronized void unload() throws ServletException {
1002:
1003:                // Nothing to do if we have never loaded the instance
1004:                if (!singleThreadModel && (instance == null))
1005:                    return;
1006:                unloading = true;
1007:
1008:                // Loaf a while if the current instance is allocated
1009:                // (possibly more than once if non-STM)
1010:                if (countAllocated > 0) {
1011:                    int nRetries = 0;
1012:                    while (nRetries < 10) {
1013:                        if (nRetries == 0) {
1014:                            log("Waiting for " + countAllocated
1015:                                    + " instance(s) to be deallocated");
1016:                        }
1017:                        try {
1018:                            Thread.sleep(50);
1019:                        } catch (InterruptedException e) {
1020:                            ;
1021:                        }
1022:                        nRetries++;
1023:                    }
1024:                }
1025:
1026:                ClassLoader oldCtxClassLoader = Thread.currentThread()
1027:                        .getContextClassLoader();
1028:                ClassLoader classLoader = instance.getClass().getClassLoader();
1029:
1030:                // Call the servlet destroy() method
1031:                try {
1032:                    instanceSupport.fireInstanceEvent(
1033:                            InstanceEvent.BEFORE_DESTROY_EVENT, instance);
1034:                    Thread.currentThread().setContextClassLoader(classLoader);
1035:                    instance.destroy();
1036:                    instanceSupport.fireInstanceEvent(
1037:                            InstanceEvent.AFTER_DESTROY_EVENT, instance);
1038:                } catch (Throwable t) {
1039:                    instanceSupport.fireInstanceEvent(
1040:                            InstanceEvent.AFTER_DESTROY_EVENT, instance, t);
1041:                    instance = null;
1042:                    instancePool = null;
1043:                    nInstances = 0;
1044:                    fireContainerEvent("unload", this );
1045:                    unloading = false;
1046:                    throw new ServletException(sm.getString(
1047:                            "standardWrapper.destroyException", getName()), t);
1048:                } finally {
1049:                    // restore the context ClassLoader
1050:                    Thread.currentThread().setContextClassLoader(
1051:                            oldCtxClassLoader);
1052:                }
1053:
1054:                // Deregister the destroyed instance
1055:                instance = null;
1056:
1057:                if (singleThreadModel && (instancePool != null)) {
1058:                    try {
1059:                        Thread.currentThread().setContextClassLoader(
1060:                                classLoader);
1061:                        while (!instancePool.isEmpty()) {
1062:                            ((Servlet) instancePool.pop()).destroy();
1063:                        }
1064:                    } catch (Throwable t) {
1065:                        instancePool = null;
1066:                        nInstances = 0;
1067:                        unloading = false;
1068:                        fireContainerEvent("unload", this );
1069:                        throw new ServletException(sm.getString(
1070:                                "standardWrapper.destroyException", getName()),
1071:                                t);
1072:                    } finally {
1073:                        // restore the context ClassLoader
1074:                        Thread.currentThread().setContextClassLoader(
1075:                                oldCtxClassLoader);
1076:                    }
1077:                    instancePool = null;
1078:                    nInstances = 0;
1079:                }
1080:
1081:                unloading = false;
1082:                fireContainerEvent("unload", this );
1083:
1084:            }
1085:
1086:            // -------------------------------------------------- ServletConfig Methods
1087:
1088:            /**
1089:             * Return the initialization parameter value for the specified name,
1090:             * if any; otherwise return <code>null</code>.
1091:             *
1092:             * @param name Name of the initialization parameter to retrieve
1093:             */
1094:            public String getInitParameter(String name) {
1095:
1096:                return (findInitParameter(name));
1097:
1098:            }
1099:
1100:            /**
1101:             * Return the set of initialization parameter names defined for this
1102:             * servlet.  If none are defined, an empty Enumeration is returned.
1103:             */
1104:            public Enumeration getInitParameterNames() {
1105:
1106:                synchronized (parameters) {
1107:                    return (new Enumerator(parameters.keySet()));
1108:                }
1109:
1110:            }
1111:
1112:            /**
1113:             * Return the servlet context with which this servlet is associated.
1114:             */
1115:            public ServletContext getServletContext() {
1116:
1117:                if (parent == null)
1118:                    return (null);
1119:                else if (!(parent instanceof  Context))
1120:                    return (null);
1121:                else
1122:                    return (((Context) parent).getServletContext());
1123:
1124:            }
1125:
1126:            /**
1127:             * Return the name of this servlet.
1128:             */
1129:            public String getServletName() {
1130:
1131:                return (getName());
1132:
1133:            }
1134:
1135:            // -------------------------------------------------------- Package Methods
1136:
1137:            // -------------------------------------------------------- Private Methods
1138:
1139:            /**
1140:             * Add a default Mapper implementation if none have been configured
1141:             * explicitly.
1142:             *
1143:             * @param mapperClass Java class name of the default Mapper
1144:             */
1145:            protected void addDefaultMapper(String mapperClass) {
1146:
1147:                ; // No need for a default Mapper on a Wrapper
1148:
1149:            }
1150:
1151:            /**
1152:             * Return <code>true</code> if the specified class name represents a
1153:             * container provided servlet class that should be loaded by the
1154:             * server class loader.
1155:             *
1156:             * @param name Name of the class to be checked
1157:             */
1158:            private boolean isContainerProvidedServlet(String classname) {
1159:
1160:                if (classname.startsWith("org.apache.catalina.")) {
1161:                    return (true);
1162:                }
1163:                try {
1164:                    Class clazz = this .getClass().getClassLoader().loadClass(
1165:                            classname);
1166:                    return (ContainerServlet.class.isAssignableFrom(clazz));
1167:                } catch (Throwable t) {
1168:                    return (false);
1169:                }
1170:
1171:            }
1172:
1173:            /**
1174:             * Return <code>true</code> if loading this servlet is allowed.
1175:             */
1176:            private boolean isServletAllowed(Object servlet) {
1177:
1178:                if (servlet instanceof  ContainerServlet) {
1179:                    if (((Context) getParent()).getPrivileged()
1180:                            || (servlet.getClass().getName()
1181:                                    .equals("org.apache.catalina.servlets.InvokerServlet"))) {
1182:                        return (true);
1183:                    } else {
1184:                        return (false);
1185:                    }
1186:                }
1187:
1188:                return (true);
1189:
1190:            }
1191:
1192:            /**
1193:             * Log the abbreviated name of this Container for logging messages.
1194:             */
1195:            protected String logName() {
1196:
1197:                StringBuffer sb = new StringBuffer("StandardWrapper[");
1198:                if (getParent() != null)
1199:                    sb.append(getParent().getName());
1200:                else
1201:                    sb.append("null");
1202:                sb.append(':');
1203:                sb.append(getName());
1204:                sb.append(']');
1205:                return (sb.toString());
1206:
1207:            }
1208:
1209:            // ------------------------------------------------------ Lifecycle Methods
1210:
1211:            /**
1212:             * Start this component, pre-loading the servlet if the load-on-startup
1213:             * value is set appropriately.
1214:             *
1215:             * @exception LifecycleException if a fatal error occurs during startup
1216:             */
1217:            public void start() throws LifecycleException {
1218:
1219:                // Start up this component
1220:                super .start();
1221:
1222:                // Load and initialize an instance of this servlet if requested
1223:                // MOVED TO StandardContext START() METHOD
1224:
1225:            }
1226:
1227:            /**
1228:             * Stop this component, gracefully shutting down the servlet if it has
1229:             * been initialized.
1230:             *
1231:             * @exception LifecycleException if a fatal error occurs during shutdown
1232:             */
1233:            public void stop() throws LifecycleException {
1234:
1235:                // Shut down our servlet instance (if it has been initialized)
1236:                try {
1237:                    unload();
1238:                } catch (ServletException e) {
1239:                    log(sm.getString("standardWrapper.unloadException",
1240:                            getName()), e);
1241:                }
1242:
1243:                // Shut down this component
1244:                super.stop();
1245:
1246:            }
1247:
1248:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.