alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  
* <td align=center>Container * <td>Child container added to this Container. * </tr> * <tr> * <td align=center>addValve * <td align=center>Valve * <td>Valve added to this Container. * </tr> * <tr> * <td align=center>removeChild * <td align=center>Container * <td>Child container removed from this Container. * </tr> * <tr> * <td align=center>removeValve * <td align=center>Valve * <td>Valve removed from this Container. * </tr> * <tr> * <td align=center>start * <td align=center>null * <td>Container was started. * </tr> * <tr> * <td align=center>stop * <td align=center>null * <td>Container was stopped. * </tr> * </table> * Subclasses that fire additional events should document them in the * class comments of the implementation class. * * @author Craig R. McClanahan */ public abstract class ContainerBase implements Container, Lifecycle, Pipeline, MBeanRegistration, Serializable { private static Logger log = Logger.getLogger( ContainerBase.class.getName()); /** * Perform addChild with the permissions of this class. * addChild can be called with the XML parser on the stack, * this allows the XML parser to have fewer privileges than * Tomcat. */ protected class PrivilegedAddChild implements PrivilegedAction { private Container child; PrivilegedAddChild(Container child) { this.child = child; } public Object run() { addChildInternal(child); return null; } } // ----------------------------------------------------- Instance Variables /** * The child Containers belonging to this Container, keyed by name. */ protected Map<String, Container> children = new LinkedHashMap(); /** * The debugging detail level for this component. */ protected int debug = 0; /** * The processor delay for this component. */ protected int backgroundProcessorDelay = -1; /** * Flag indicating whether a check to see if the request is secure is * required before adding Pragma and Cache-Control headers when proxy * caching has been disabled */ protected boolean checkIfRequestIsSecure = false; /** * The lifecycle event support for this component. */ protected LifecycleSupport lifecycle = new LifecycleSupport(this); /** * The container event listeners for this Container. */ protected ArrayList<ContainerListener> listeners = new ArrayList<ContainerListener>(); private ContainerListener[] listenersArray = new ContainerListener[0]; /** * The Loader implementation with which this Container is associated. */ protected Loader loader = null; private ReadWriteLock lock = new ReentrantReadWriteLock(); protected Lock readLock = lock.readLock(); protected Lock writeLock = lock.writeLock(); /** * The Logger implementation with which this Container is associated. */ protected org.apache.catalina.Logger logger = null; /** * The Manager implementation with which this Container is associated. */ protected Manager manager = null; /** * The human-readable name of this Container. */ protected String name = null; /** * The parent Container to which this Container is a child. */ protected Container parent = null; /** * The parent class loader to be configured when we install a Loader. */ protected ClassLoader parentClassLoader = null; /** * The Pipeline object with which this Container is associated. */ protected Pipeline pipeline = new StandardPipeline(this); protected boolean hasCustomPipeline = false; /** * The Realm with which this Container is associated. */ protected Realm realm = null; /** * The resources DirContext object with which this Container is associated. */ protected DirContext resources = null; /** * The string manager for this package. */ protected static final StringManager sm = StringManager.getManager(Constants.Package); /** * Has this component been started? */ protected boolean started = false; protected boolean initialized=false; /** * The property change support for this component. */ protected PropertyChangeSupport support = new PropertyChangeSupport(this); /** * The background thread. */ private Thread thread = null; /** * The background thread completion semaphore. */ private volatile boolean threadDone = false; /** * Indicates whether ContainerListener instances need to be notified * of a particular configuration event. */ protected boolean notifyContainerListeners = true; // ------------------------------------------------------------- Properties /** * @return true if ContainerListener instances need to be notified * of a particular configuration event, and false otherwise */ boolean isNotifyContainerListeners() { return notifyContainerListeners; } /** * Return the debugging detail level for this component. */ public int getDebug() { return (this.debug); } /** * Set the debugging detail level for this component. * * @param debug The new debugging detail level */ public void setDebug(int debug) { int oldDebug = this.debug; this.debug = debug; support.firePropertyChange("debug", Integer.valueOf(oldDebug), Integer.valueOf(this.debug)); } /** * Get the delay between the invocation of the backgroundProcess method on * this container and its children. Child containers will not be invoked * if their delay value is not negative (which would mean they are using * their own thread). Setting this to a positive value will cause * a thread to be spawn. After waiting the specified amount of time, * the thread will invoke the executePeriodic method on this container * and all its children. */ public int getBackgroundProcessorDelay() { return backgroundProcessorDelay; } /** * Set the delay between the invocation of the execute method on this * container and its children. * * @param delay The delay in seconds between the invocation of * backgroundProcess methods */ public void setBackgroundProcessorDelay(int delay) { backgroundProcessorDelay = delay; } /** * Return descriptive information about this Container implementation and * the corresponding version number, in the format * <code><description>/<version>. */ public String getInfo() { return this.getClass().getName(); } /** * Return the Loader with which this Container is associated. If there is * no associated Loader, return the Loader associated with our parent * Container (if any); otherwise, return <code>null. */ public Loader getLoader() { try { readLock.lock(); if (loader != null) return (loader); } finally { readLock.unlock(); } if (parent != null) return (parent.getLoader()); return (null); } /** * Set the Loader with which this Container is associated. * * @param loader The newly associated loader */ public void setLoader(Loader loader) { Loader oldLoader; try { writeLock.lock(); // Change components if necessary oldLoader = this.loader; if (oldLoader == loader) return; this.loader = loader; // Stop the old component if necessary if (started && (oldLoader != null) && (oldLoader instanceof Lifecycle)) { try { ((Lifecycle) oldLoader).stop(); } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.setLoader: stop: ", e); } } // Start the new component if necessary if (loader != null) loader.setContainer(this); if (started && (loader != null) && (loader instanceof Lifecycle)) { try { ((Lifecycle) loader).start(); } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.setLoader: start: ", e); } } } finally { writeLock.unlock(); } // Report this property change to interested listeners support.firePropertyChange("loader", oldLoader, this.loader); } /** * Return the Logger with which this Container is associated. If there is * no associated Logger, return the Logger associated with our parent * Container (if any); otherwise return <code>null. */ public org.apache.catalina.Logger getLogger() { try { readLock.lock(); if (logger != null) return (logger); } finally { readLock.unlock(); } if (parent != null) return (parent.getLogger()); return (null); } /** * Set the Logger with which this Container is associated. * * @param logger The newly associated Logger */ public void setLogger(org.apache.catalina.Logger logger) { org.apache.catalina.Logger oldLogger; try { writeLock.lock(); // Change components if necessary oldLogger = this.logger; if (oldLogger == logger) return; this.logger = logger; // Stop the old component if necessary if (started && (oldLogger != null) && (oldLogger instanceof Lifecycle)) { try { ((Lifecycle) oldLogger).stop(); } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.setLogger: stop: ", e); } } // Start the new component if necessary if (logger != null) logger.setContainer(this); if (started && (logger != null) && (logger instanceof Lifecycle)) { try { ((Lifecycle) logger).start(); } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.setLogger: start: ", e); } } } finally { writeLock.unlock(); } // Report this property change to interested listeners support.firePropertyChange("logger", oldLogger, this.logger); } /** * Return the Manager with which this Container is associated. If there is * no associated Manager, return the Manager associated with our parent * Container (if any); otherwise return <code>null. */ public Manager getManager() { try { readLock.lock(); if (manager != null) return (manager); } finally { readLock.unlock(); } if (parent != null) return (parent.getManager()); return (null); } /** * Set the Manager with which this Container is associated. * * @param manager The newly associated Manager */ public void setManager(Manager manager) { Manager oldManager; try { writeLock.lock(); // Change components if necessary oldManager = this.manager; if (oldManager == manager) return; this.manager = manager; // Stop the old component if necessary if (started && (oldManager != null) && (oldManager instanceof Lifecycle)) { try { ((Lifecycle) oldManager).stop(); } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.setManager: stop: ", e); } } // Start the new component if necessary if (manager != null) manager.setContainer(this); if (started && (manager != null) && (manager instanceof Lifecycle)) { try { ((Lifecycle) manager).start(); } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.setManager: start: ", e); } } } finally { writeLock.unlock(); } // Report this property change to interested listeners support.firePropertyChange("manager", oldManager, this.manager); } /** * Return an object which may be utilized for mapping to this component. */ public Object getMappingObject() { return this; } /** * Return a name string (suitable for use by humans) that describes this * Container. Within the set of child containers belonging to a particular * parent, Container names must be unique. */ public String getName() { return (name); } /** * Set a name string (suitable for use by humans) that describes this * Container. Within the set of child containers belonging to a particular * parent, Container names must be unique. * * @param name New name of this container * * @exception IllegalStateException if this Container has already been * added to the children of a parent Container (after which the name * may not be changed) */ public void setName(String name) { String oldName = this.name; this.name = name; support.firePropertyChange("name", oldName, this.name); } /** * Return the Container for which this Container is a child, if there is * one. If there is no defined parent, return <code>null. */ public Container getParent() { return (parent); } /** * Set the parent Container to which this Container is being added as a * child. This Container may refuse to become attached to the specified * Container by throwing an exception. * * @param container Container to which this Container is being added * as a child * * @exception IllegalArgumentException if this Container refuses to become * attached to the specified Container */ public void setParent(Container container) { Container oldParent = this.parent; this.parent = container; support.firePropertyChange("parent", oldParent, this.parent); } /** * Return the parent class loader (if any) for this web application. * This call is meaningful only <strong>after a Loader has * been configured. */ public ClassLoader getParentClassLoader() { if (parentClassLoader != null) return (parentClassLoader); if (parent != null) { return (parent.getParentClassLoader()); } return (ClassLoader.getSystemClassLoader()); } /** * Set the parent class loader (if any) for this web application. * This call is meaningful only <strong>before a Loader has * been configured, and the specified value (if non-null) should be * passed as an argument to the class loader constructor. * * * @param parent The new parent class loader */ public void setParentClassLoader(ClassLoader parent) { ClassLoader oldParentClassLoader = this.parentClassLoader; this.parentClassLoader = parent; support.firePropertyChange("parentClassLoader", oldParentClassLoader, this.parentClassLoader); } /** * Return the Pipeline object that manages the Valves associated with * this Container. */ public Pipeline getPipeline() { return (this.pipeline); } /** * @return true if this container was configured with a custom pipeline, * false otherwise */ public boolean hasCustomPipeline() { return hasCustomPipeline; } /** * Indicates whether the request will be checked to see if it is secure * before adding Pragma and Cache-control headers when proxy caching has * been disabled. * * @return true if the check is required; false otherwise. */ public boolean isCheckIfRequestIsSecure() { return checkIfRequestIsSecure; } /** * Sets the checkIfRequestIsSecure property of this Container. * * Setting this property to true will check if the request is secure * before adding Pragma and Cache-Control headers when proxy caching has * been disabled. * * @param checkIfRequestIsSecure true if check is required, false * otherwise */ public void setCheckIfRequestIsSecure(boolean checkIfRequestIsSecure) { this.checkIfRequestIsSecure = checkIfRequestIsSecure; } /** * Return the Realm with which this Container is associated. If there is * no associated Realm, return the Realm associated with our parent * Container (if any); otherwise return <code>null. */ public Realm getRealm() { try { readLock.lock(); if (realm != null) return (realm); } finally { readLock.unlock(); } if (parent != null) return (parent.getRealm()); return (null); } /** * Set the Realm with which this Container is associated. * * @param realm The newly associated Realm */ public void setRealm(Realm realm) { Realm oldRealm; try { writeLock.lock(); // Change components if necessary oldRealm = this.realm; if (oldRealm == realm) return; this.realm = realm; // Stop the old component if necessary if (started && (oldRealm != null) && (oldRealm instanceof Lifecycle)) { try { ((Lifecycle) oldRealm).stop(); } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.setRealm: stop: ", e); } } // Start the new component if necessary if (realm != null) realm.setContainer(this); if (started && (realm != null) && (realm instanceof Lifecycle)) { try { ((Lifecycle) realm).start(); } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.setRealm: start: ", e); } } } finally { writeLock.unlock(); } // Report this property change to interested listeners support.firePropertyChange("realm", oldRealm, this.realm); } /** * Return the resources DirContext object with which this Container is * associated. If there is no associated resources object, return the * resources associated with our parent Container (if any); otherwise * return <code>null. */ public DirContext getResources() { try { readLock.lock(); if (resources != null) return (resources); } finally { readLock.unlock(); } if (parent != null) return (parent.getResources()); return (null); } /** * Set the resources DirContext object with which this Container is * associated. * * @param resources The newly associated DirContext */ public void setResources(DirContext resources) throws Exception { // Called from StandardContext.setResources() // <- StandardContext.start() // <- ContainerBase.addChildInternal() // Change components if necessary DirContext oldResources; try { writeLock.lock(); oldResources = this.resources; if (oldResources == resources) return; Hashtable env = new Hashtable(); if (getParent() != null) env.put(ProxyDirContext.HOST, getParent().getName()); env.put(ProxyDirContext.CONTEXT, getName()); this.resources = new ProxyDirContext(env, resources); // Report this property change to interested listeners } finally { writeLock.unlock(); } support.firePropertyChange("resources", oldResources, this.resources); } // ------------------------------------------------------ Container Methods /** * Add a new child Container to those associated with this Container, * if supported. Prior to adding this Container to the set of children, * the child's <code>setParent() method must be called, with this * Container as an argument. This method may thrown an * <code>IllegalArgumentException if this Container chooses not * to be attached to the specified Container, in which case it is not added * * @param child New child Container to be added * * @exception IllegalArgumentException if this exception is thrown by * the <code>setParent() method of the child Container * @exception IllegalArgumentException if the new child does not have * a name unique from that of existing children of this Container * @exception IllegalStateException if this Container does not support * child Containers */ public void addChild(Container child) { if (Globals.IS_SECURITY_ENABLED) { PrivilegedAction dp = new PrivilegedAddChild(child); AccessController.doPrivileged(dp); } else { addChildInternal(child); } } private void addChildInternal(Container child) { if(log.isLoggable(Level.FINEST)) log.finest("Add child " + child + " " + this); synchronized(children) { if (children.get(child.getName()) != null) throw new IllegalArgumentException("addChild: Child name '" + child.getName() + "' is not unique"); child.setParent(this); // May throw IAE if (started && (child instanceof Lifecycle)) { try { ((Lifecycle) child).start(); } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.addChild: start: ", e); throw new IllegalStateException ("ContainerBase.addChild: start: " + e); } } children.put(child.getName(), child); if (notifyContainerListeners) { fireContainerEvent(ADD_CHILD_EVENT, child); } } } /** * Add a container event listener to this component. * * @param listener The listener to add */ public void addContainerListener(ContainerListener listener) { synchronized (listeners) { listeners.add(listener); listenersArray = listeners.toArray( new ContainerListener[listeners.size()]); } } /** * Add a property change listener to this component. * * @param listener The listener to add */ public void addPropertyChangeListener(PropertyChangeListener listener) { support.addPropertyChangeListener(listener); } /** * Return the child Container, associated with this Container, with * the specified name (if any); otherwise, return <code>null * * @param name Name of the child Container to be retrieved */ public Container findChild(String name) { if (name == null) return (null); synchronized (children) { // Required by post-start changes return children.get(name); } } /** * Return the set of children Containers associated with this Container. * If this Container has no children, a zero-length array is returned. */ public Container[] findChildren() { synchronized (children) { return children.values().toArray(new Container[children.size()]); } } /** * Return the set of container listeners associated with this Container. * If this Container has no registered container listeners, a zero-length * array is returned. */ public ContainerListener[] findContainerListeners() { synchronized (listeners) { return listenersArray; } } /** * Process the specified Request, to produce the corresponding Response, * by invoking the first Valve in our pipeline (if any), or the basic * Valve otherwise. * * @param request Request to be processed * @param response Response to be produced * * @exception IllegalStateException if neither a pipeline or a basic * Valve have been configured for this Container * @exception IOException if an input/output error occurred while * processing * @exception ServletException if a ServletException was thrown * while processing this request */ public void invoke(Request request, Response response) throws IOException, ServletException { pipeline.invoke(request, response); } /** * Remove an existing child Container from association with this parent * Container. * * @param child Existing child Container to be removed */ public void removeChild(Container child) { if (child == null) { return; } synchronized(children) { if (children.get(child.getName()) == null) return; children.remove(child.getName()); } if (started && (child instanceof Lifecycle)) { try { if( child instanceof ContainerBase ) { if( ((ContainerBase)child).started ) { ((Lifecycle) child).stop(); } } else { ((Lifecycle) child).stop(); } } catch (LifecycleException e) { log.log(Level.SEVERE, "ContainerBase.removeChild: stop: ", e); } } if (notifyContainerListeners) { fireContainerEvent(REMOVE_CHILD_EVENT, child); } // child.setParent(null); } /** * Remove a container event listener from this component. * * @param listener The listener to remove */ public void removeContainerListener(ContainerListener listener) { synchronized (listeners) { listeners.remove(listener); listenersArray = listeners.toArray( new ContainerListener[listeners.size()]); } } /** * Remove a property change listener from this component. * * @param listener The listener to remove */ public void removePropertyChangeListener(PropertyChangeListener listener) { support.removePropertyChangeListener(listener); } // ------------------------------------------------------ Lifecycle Methods /** * Add a lifecycle event listener to this component. * * @param listener The listener to add */ public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); } /** * Gets the (possibly empty) list of lifecycle listeners associated * with this Container. */ public List<LifecycleListener> findLifecycleListeners() { return lifecycle.findLifecycleListeners(); } /** * Removes the given lifecycle event listener from this Container. * * @param listener The listener to remove */ public void removeLifecycleListener(LifecycleListener listener) { lifecycle.removeLifecycleListener(listener); } /** * Removes any lifecycle event listeners from this Container. */ public void removeLifecycleListeners() { lifecycle.removeLifecycleListeners(); } /** * Prepare for active use of the public methods of this Component. * * @exception LifecycleException if this component detects a fatal error * that prevents it from being started */ public synchronized void start() throws LifecycleException { // Validate and update our current component state if (started) { if (log.isLoggable(Level.INFO)) { log.info(sm.getString("containerBase.alreadyStarted", logName())); } return; } if( logger instanceof LoggerBase ) { LoggerBase lb=(LoggerBase)logger; if( lb.getObjectName()==null ) { ObjectName lname=lb.createObjectName(); try { // Do not register unused tomcat mbeans //Registry.getRegistry(null, null).registerComponent(lb, lname, // null); } catch( Exception ex ) { log.log(Level.SEVERE, "Can't register logger " + lname, ex); } } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); started = true; // Start our subordinate components, if any if ((loader != null) && (loader instanceof Lifecycle)) ((Lifecycle) loader).start(); if ((logger != null) && (logger instanceof Lifecycle)) ((Lifecycle) logger).start(); if ((manager != null) && (manager instanceof Lifecycle)) ((Lifecycle) manager).start(); if ((realm != null) && (realm instanceof Lifecycle)) ((Lifecycle) realm).start(); if ((resources != null) && (resources instanceof Lifecycle)) ((Lifecycle) resources).start(); // Start our child containers, if any startChildren(); // Start the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) { ((Lifecycle) pipeline).start(); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(START_EVENT, null); // Start our thread threadStart(); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); } /** * Gracefully shut down active use of the public methods of this Component. * * @exception LifecycleException if this component detects a fatal error * that needs to be reported */ public synchronized void stop() throws LifecycleException { // Validate and update our current component state if (!started) { if (log.isLoggable(Level.INFO)) { log.info(sm.getString("containerBase.notStarted", logName())); } return; } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); // Stop our thread threadStop(); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; // Stop the Valves in our pipeline (including the basic), if any if (pipeline instanceof Lifecycle) { ((Lifecycle) pipeline).stop(); } // Stop our child containers, if any Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) { try { ((Lifecycle) children[i]).stop(); } catch (Throwable t) { log.log(Level.SEVERE, sm.getString("containerBase.errorStopping", children[i]), t); } } } // Remove children - so next start can work children = findChildren(); for (int i = 0; i < children.length; i++) { removeChild(children[i]); } // Stop our subordinate components, if any if ((resources != null) && (resources instanceof Lifecycle)) { ((Lifecycle) resources).stop(); } if ((realm != null) && (realm instanceof Lifecycle)) { ((Lifecycle) realm).stop(); } if ((manager != null) && (manager instanceof Lifecycle)) { ((Lifecycle) manager).stop(); } if ((logger != null) && (logger instanceof Lifecycle)) { ((Lifecycle) logger).stop(); } if ((loader != null) && (loader instanceof Lifecycle)) { ((Lifecycle) loader).stop(); } if( logger instanceof LoggerBase ) { LoggerBase lb=(LoggerBase)logger; if( lb.getObjectName()!=null ) { try { // Do not register unused tomcat mbeans //Registry.getRegistry(null, null).unregisterComponent(lb.getObjectName()); } catch( Exception ex ) { log.log(Level.SEVERE, "Can't unregister logger " + lb.getObjectName(), ex); } } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); } /** Init method, part of the MBean lifecycle. * If the container was added via JMX, it'll register itself with the * parent, using the ObjectName conventions to locate the parent. * * If the container was added directly and it doesn't have an ObjectName, * it'll create a name and register itself with the JMX console. On destroy(), * the object will unregister. * * @throws Exception */ public void init() throws Exception { if( this.getParent() == null ) { // "Life" update ObjectName parentName=getParentName(); //log.info("Register " + parentName ); if( parentName != null && mserver.isRegistered(parentName)) { mserver.invoke(parentName, "addChild", new Object[] { this }, new String[] {"org.apache.catalina.Container"}); } } initialized=true; } public ObjectName getParentName() throws MalformedObjectNameException { return null; } public void destroy() throws Exception { if( started ) { stop(); } initialized=false; // unregister this component if( oname != null ) { try { if( controller == oname ) { Registry.getRegistry(null, null).unregisterComponent(oname); if (log.isLoggable(Level.FINE)) { log.fine("unregistering " + oname); } } } catch( Throwable t ) { log.log(Level.SEVERE, "Error unregistering ", t); } } if (parent != null) { parent.removeChild(this); } // Stop our child containers, if any Container children[] = findChildren(); for(Container aChildren : children) { removeChild(aChildren); } // START SJSAS 6330332 // Remove LifecycleListeners removeLifecycleListeners(); // Release realm setRealm(null); // END SJSAS 6330332 } // ------------------------------------------------------- Pipeline Methods /** * Add a new Valve to the end of the pipeline associated with this * Container. Prior to adding the Valve, the Valve's * <code>setContainer method must be called, with this Container * as an argument. The method may throw an * <code>IllegalArgumentException if this Valve chooses not to * be associated with this Container, or <code>IllegalStateException * if it is already associated with a different Container. * * @param valve Valve to be added * * @exception IllegalArgumentException if this Container refused to * accept the specified Valve * @exception IllegalArgumentException if the specified Valve refuses to be * associated with this Container * @exception IllegalStateException if the specified Valve is already * associated with a different Container */ public synchronized void addValve(GlassFishValve valve) { pipeline.addValve(valve); if (notifyContainerListeners) { fireContainerEvent(ADD_VALVE_EVENT, valve); } } /** * Add Tomcat-style valve. */ public synchronized void addValve(Valve valve) { pipeline.addValve(valve); if (notifyContainerListeners) { fireContainerEvent(ADD_VALVE_EVENT, valve); } } public ObjectName[] getValveObjectNames() { return ((StandardPipeline)pipeline).getValveObjectNames(); } /** * <p>Return the Valve instance that has been distinguished as the basic * Valve for this Pipeline (if any). */ public GlassFishValve getBasic() { return (pipeline.getBasic()); } /** * Return the set of Valves in the pipeline associated with this * Container, including the basic Valve (if any). If there are no * such Valves, a zero-length array is returned. */ public GlassFishValve[] getValves() { return (pipeline.getValves()); } /** * @return true if this pipeline has any non basic valves, false * otherwise */ public boolean hasNonBasicValves() { return pipeline.hasNonBasicValves(); } /** * Remove the specified Valve from the pipeline associated with this * Container, if it is found; otherwise, do nothing. * * @param valve Valve to be removed */ public synchronized void removeValve(GlassFishValve valve) { pipeline.removeValve(valve); if (notifyContainerListeners) { fireContainerEvent(REMOVE_VALVE_EVENT, valve); } } /** * <p>Set the Valve instance that has been distinguished as the basic * Valve for this Pipeline (if any). Prior to setting the basic Valve, * the Valve's <code>setContainer() will be called, if it * implements <code>Contained, with the owning Container as an * argument. The method may throw an <code>IllegalArgumentException * if this Valve chooses not to be associated with this Container, or * <code>IllegalStateException if it is already associated with * a different Container.</p> * * @param valve Valve to be distinguished as the basic Valve */ public void setBasic(GlassFishValve valve) { pipeline.setBasic(valve); } /** * Execute a periodic task, such as reloading, etc. This method will be * invoked inside the classloading context of this container. Unexpected * throwables will be caught and logged. */ public void backgroundProcess() { } // ------------------------------------------------------ Protected Methods /** * Notify all container event listeners that a particular event has * occurred for this Container. The default implementation performs * this notification synchronously using the calling thread. * * @param type Event type * @param data Event data */ public void fireContainerEvent(String type, Object data) { ContainerListener[] list = null; synchronized (listeners) { if (listeners.isEmpty()) { return; } list = listenersArray; } ContainerEvent event = new ContainerEvent(this, type, data); for (int i = 0; i < list.length; i++) { list[i].containerEvent(event); } } /** * Starts the children of this container. */ protected void startChildren() { Container children[] = findChildren(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof Lifecycle) { try { ((Lifecycle) children[i]).start(); } catch (Throwable t) { log.log(Level.SEVERE, sm.getString("containerBase.notStarted", children[i]), t); if (children[i] instanceof Context) { ((Context) children[i]).setAvailable(false); } else if (children[i] instanceof Wrapper) { ((Wrapper) children[i]).setAvailable(Long.MAX_VALUE); } } } } } /** * Log the specified message to our current Logger (if any). * * @param message Message to be logged */ protected void log(String message) { // Logger logger = getLogger(); // if (logger != null) // logger.log(logName() + ": " + message); // else log.info(message); } /** * Log the specified message and exception to our current Logger * (if any). * * @param message Message to be logged * @param throwable Related exception */ protected void log(String message, Throwable throwable) { org.apache.catalina.Logger logger = getLogger(); if (logger != null) logger.log(logName() + ": " + message, throwable); else { log.log(Level.SEVERE, message, throwable); } } /** * Return the abbreviated name of this container for logging messages */ protected String logName() { String className = this.getClass().getName(); int period = className.lastIndexOf("."); if (period >= 0) className = className.substring(period + 1); return (className + "[" + getName() + "]"); } // -------------------- JMX and Registration -------------------- protected String type; protected String domain; protected String suffix; protected ObjectName oname; protected ObjectName controller; protected transient MBeanServer mserver; public ObjectName getJmxName() { return oname; } public String getObjectName() { if (oname != null) { return oname.toString(); } else return null; } public String getDomain() { if( domain==null ) { Container parent=this; while( parent != null && !( parent instanceof StandardEngine) ) { parent=parent.getParent(); } if( parent instanceof StandardEngine ) { domain=((StandardEngine)parent).getDomain(); } } return domain; } public void setDomain(String domain) { this.domain=domain; } public String getType() { return type; } protected String getJSR77Suffix() { return suffix; } public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { oname=name; mserver=server; if (name == null ){ return null; } domain=name.getDomain(); type=name.getKeyProperty("type"); if( type==null ) { type=name.getKeyProperty("j2eeType"); } String j2eeApp=name.getKeyProperty("J2EEApplication"); String j2eeServer=name.getKeyProperty("J2EEServer"); if( j2eeApp==null ) { j2eeApp="none"; } if( j2eeServer==null ) { j2eeServer="none"; } suffix=",J2EEApplication=" + j2eeApp + ",J2EEServer=" + j2eeServer; return name; } public void postRegister(Boolean registrationDone) { } public void preDeregister() throws Exception { } public void postDeregister() { } public ObjectName[] getChildren() { ObjectName result[]=new ObjectName[children.size()]; Iterator it=children.values().iterator(); int i=0; while( it.hasNext() ) { Object next=it.next(); if( next instanceof ContainerBase ) { result[i++]=((ContainerBase)next).getJmxName(); } } return result; } public ObjectName createObjectName(String domain, ObjectName parent) throws Exception { if (log.isLoggable(Level.FINE)) log.fine("Create ObjectName " + domain + " " + parent ); return null; } public String getContainerSuffix() { Container container=this; Container context=null; Container host=null; Container servlet=null; StringBuilder suffix=new StringBuilder(); if( container instanceof StandardHost ) { host=container; } else if( container instanceof StandardContext ) { host=container.getParent(); context=container; } else if( container instanceof StandardWrapper ) { context=container.getParent(); host=context.getParent(); servlet=container; } if( context!=null ) { String path=((StandardContext)context).getEncodedPath(); suffix.append(",path=").append((path.equals("")) ? "/" : path); } if( host!=null ) suffix.append(",host=").append( host.getName() ); if( servlet != null ) { String name=container.getName(); suffix.append(",servlet="); suffix.append((name=="") ? "/" : name); } return suffix.toString(); } /** * Start the background thread that will periodically check for * session timeouts. */ protected void threadStart() { if (thread != null) return; if (backgroundProcessorDelay <= 0) return; threadDone = false; String threadName = "ContainerBackgroundProcessor[" + toString() + "]"; thread = new Thread(new ContainerBackgroundProcessor(), threadName); thread.setDaemon(true); thread.start(); } /** * Stop the background thread that is periodically checking for * session timeouts. */ protected void threadStop() { if (thread == null) return; threadDone = true; thread.interrupt(); try { thread.join(); } catch (InterruptedException e) { ; } thread = null; } // -------------------------------------- ContainerExecuteDelay Inner Class /** * Private thread class to invoke the backgroundProcess method * of this container and its children after a fixed delay. */ protected class ContainerBackgroundProcessor implements Runnable { public void run() { while (!threadDone) { try { Thread.sleep(backgroundProcessorDelay * 1000L); } catch (InterruptedException e) { ; } if (!threadDone) { Container parent = (Container) getMappingObject(); ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (parent.getLoader() != null) { cl = parent.getLoader().getClassLoader(); } processChildren(parent, cl); } } } protected void processChildren(Container container, ClassLoader cl) { try { if (container.getLoader() != null) { Thread.currentThread().setContextClassLoader (container.getLoader().getClassLoader()); } container.backgroundProcess(); } catch (Throwable t) { log.log(Level.SEVERE, "Exception invoking periodic operation: ", t); } finally { Thread.currentThread().setContextClassLoader(cl); } Container[] children = container.findChildren(); for (int i = 0; i < children.length; i++) { if (children[i].getBackgroundProcessorDelay() <= 0) { processChildren(children[i], cl); } } } } }

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish ContainerBase.java source code file:

Glassfish example source code file (ContainerBase.java)

This example Glassfish source code file (ContainerBase.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

bean, classloader, container, container, exception, io, javabean, lifecycle, lifecycle, lifecycleexception, log, loggerbase, logging, management, object, objectname, objectname, string, string, throwable

The Glassfish ContainerBase.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 *
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 * Copyright 2004 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.catalina.core;

import org.apache.catalina.*;
import org.apache.catalina.logger.LoggerBase;
import org.apache.catalina.util.LifecycleSupport;
import org.apache.catalina.util.StringManager;
import org.apache.naming.resources.ProxyDirContext;
import org.apache.tomcat.util.modeler.Registry;
import org.glassfish.web.valve.GlassFishValve;

import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.naming.directory.DirContext;
import javax.servlet.ServletException;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Abstract implementation of the <b>Container interface, providing common
 * functionality required by nearly every implementation.  Classes extending
 * this base class must implement <code>getInfo(), and may implement
 * a replacement for <code>invoke().
 * <p>
 * All subclasses of this abstract base class will include support for a
 * Pipeline object that defines the processing to be performed for each request
 * received by the <code>invoke() method of this class, utilizing the
 * "Chain of Responsibility" design pattern.  A subclass should encapsulate its
 * own processing functionality as a <code>Valve, and configure this
 * Valve into the pipeline by calling <code>setBasic().
 * <p>
 * This implementation fires property change events, per the JavaBeans design
 * pattern, for changes in singleton properties.  In addition, it fires the
 * following <code>ContainerEvent events to listeners who register
 * themselves with <code>addContainerListener():
 * <table border=1>
 *   <tr>
 *     <th>Type
 *     <th>Data
 *     <th>Description
 *   </tr>
 *   <tr>
 *     <td align=center>addChild
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.