FileDocCategorySizeDatePackage
StandardService.javaAPI DocApache Tomcat 6.0.1421779Fri Jul 20 04:20:34 BST 2007org.apache.catalina.core

StandardService

public class StandardService extends Object implements org.apache.catalina.Lifecycle, org.apache.catalina.Service, MBeanRegistration
Standard implementation of the Service interface. The associated Container is generally an instance of Engine, but this is not required.
author
Craig R. McClanahan

Fields Summary
private static org.apache.juli.logging.Log
log
private static final String
info
Descriptive information about this component implementation.
private String
name
The name of this service.
private org.apache.catalina.util.LifecycleSupport
lifecycle
The lifecycle event support for this component.
private static final org.apache.catalina.util.StringManager
sm
The string manager for this package.
private org.apache.catalina.Server
server
The Server that owns this Service, if any.
private boolean
started
Has this component been started?
protected PropertyChangeSupport
support
The property change support for this component.
protected org.apache.catalina.connector.Connector[]
connectors
The set of Connectors associated with this Service.
protected ArrayList
executors
protected org.apache.catalina.Container
container
The Container associated with this Service. (In the case of the org.apache.catalina.startup.Embedded subclass, this holds the most recently added Engine.)
protected boolean
initialized
Has this component been initialized?
protected String
type
protected String
domain
protected String
suffix
protected ObjectName
oname
protected ObjectName
controller
protected MBeanServer
mserver
Constructors Summary
Methods Summary
public voidaddConnector(org.apache.catalina.connector.Connector connector)
Add a new Connector to the set of defined Connectors, and associate it with this Service's Container.

param
connector The Connector to be added


        synchronized (connectors) {
            connector.setContainer(this.container);
            connector.setService(this);
            Connector results[] = new Connector[connectors.length + 1];
            System.arraycopy(connectors, 0, results, 0, connectors.length);
            results[connectors.length] = connector;
            connectors = results;

            if (initialized) {
                try {
                    connector.initialize();
                } catch (LifecycleException e) {
                    log.error("Connector.initialize", e);
                }
            }

            if (started && (connector instanceof Lifecycle)) {
                try {
                    ((Lifecycle) connector).start();
                } catch (LifecycleException e) {
                    log.error("Connector.start", e);
                }
            }

            // Report this property change to interested listeners
            support.firePropertyChange("connector", null, connector);
        }

    
public voidaddExecutor(org.apache.catalina.Executor ex)
Adds a named executor to the service

param
ex Executor

        synchronized (executors) {
            if (!executors.contains(ex)) {
                executors.add(ex);
                if (started)
                    try {
                        ex.start();
                    } catch (LifecycleException x) {
                        log.error("Executor.start", x);
                    }
            }
        }
    
public voidaddLifecycleListener(org.apache.catalina.LifecycleListener listener)
Add a LifecycleEvent listener to this component.

param
listener The listener to add


        lifecycle.addLifecycleListener(listener);

    
public voidaddPropertyChangeListener(java.beans.PropertyChangeListener listener)
Add a property change listener to this component.

param
listener The listener to add


        support.addPropertyChangeListener(listener);

    
public voiddestroy()

        if( started ) stop();
        // FIXME unregister should be here probably -- stop doing that ?
    
public org.apache.catalina.connector.Connector[]findConnectors()
Find and return the set of Connectors associated with this Service.


        return (connectors);

    
public org.apache.catalina.Executor[]findExecutors()
Retrieves all executors

return
Executor[]

        synchronized (executors) {
            Executor[] arr = new Executor[executors.size()];
            executors.toArray(arr);
            return arr;
        }
    
public org.apache.catalina.LifecycleListener[]findLifecycleListeners()
Get the lifecycle listeners associated with this lifecycle. If this Lifecycle has no listeners registered, a zero-length array is returned.


        return lifecycle.findLifecycleListeners();

    
public javax.management.ObjectName[]getConnectorNames()

        ObjectName results[] = new ObjectName[connectors.length];
        for (int i=0; i<results.length; i++) {
            results[i] = connectors[i].getObjectName();
        }
        return results;
    
public org.apache.catalina.ContainergetContainer()
Return the Container that handles requests for all Connectors associated with this Service.



    // ------------------------------------------------------------- Properties


                      
       

        return (this.container);

    
public javax.management.ObjectNamegetContainerName()

        if( container instanceof ContainerBase ) {
            return ((ContainerBase)container).getJmxName();
        }
        return null;
    
public java.lang.StringgetDomain()

        return domain;
    
public org.apache.catalina.ExecutorgetExecutor(java.lang.String name)
Retrieves executor by name, null if not found

param
name String
return
Executor

        synchronized (executors) {
            for (int i = 0; i < executors.size(); i++) {
                if (name.equals(executors.get(i).getName()))
                    return executors.get(i);
            }
        }
        return null;
    
public java.lang.StringgetInfo()
Return descriptive information about this Service implementation and the corresponding version number, in the format <description>/<version>.


        return (info);

    
public java.lang.StringgetName()
Return the name of this Service.


        return (this.name);

    
public javax.management.ObjectNamegetObjectName()

        return oname;
    
public org.apache.catalina.ServergetServer()
Return the Server with which we are associated (if any).


        return (this.server);

    
public voidinit()

        try {
            initialize();
        } catch( Throwable t ) {
            log.error(sm.getString("standardService.initialize.failed",domain),t);
        }
    
public voidinitialize()
Invoke a pre-startup initialization. This is used to allow connectors to bind to restricted ports under Unix operating environments.

        // Service shouldn't be used with embeded, so it doesn't matter
        if (initialized) {
            if(log.isInfoEnabled())
                log.info(sm.getString("standardService.initialize.initialized"));
            return;
        }
        initialized = true;

        if( oname==null ) {
            try {
                // Hack - Server should be deprecated...
                Container engine=this.getContainer();
                domain=engine.getName();
                oname=new ObjectName(domain + ":type=Service,serviceName="+name);
                this.controller=oname;
                Registry.getRegistry(null, null)
                    .registerComponent(this, oname, null);
                
                Executor[] executors = findExecutors();
                for (int i = 0; i < executors.length; i++) {
                    ObjectName executorObjectName = 
                        new ObjectName(domain + ":type=Executor,name=" + executors[i].getName());
                    Registry.getRegistry(null, null)
                        .registerComponent(executors[i], executorObjectName, null);
                }
                
            } catch (Exception e) {
                log.error(sm.getString("standardService.register.failed",domain),e);
            }
            
            
        }
        if( server==null ) {
            // Register with the server 
            // HACK: ServerFactory should be removed...
            
            ServerFactory.getServer().addService(this);
        }
               

        // Initialize our defined Connectors
        synchronized (connectors) {
                for (int i = 0; i < connectors.length; i++) {
                    connectors[i].initialize();
                }
        }
    
public voidpostDeregister()

    
public voidpostRegister(java.lang.Boolean registrationDone)

    
public voidpreDeregister()

    
public javax.management.ObjectNamepreRegister(javax.management.MBeanServer server, javax.management.ObjectName name)

        oname=name;
        mserver=server;
        domain=name.getDomain();
        return name;
    
public voidremoveConnector(org.apache.catalina.connector.Connector connector)
Remove the specified Connector from the set associated from this Service. The removed Connector will also be disassociated from our Container.

param
connector The Connector to be removed


        synchronized (connectors) {
            int j = -1;
            for (int i = 0; i < connectors.length; i++) {
                if (connector == connectors[i]) {
                    j = i;
                    break;
                }
            }
            if (j < 0)
                return;
            if (started && (connectors[j] instanceof Lifecycle)) {
                try {
                    ((Lifecycle) connectors[j]).stop();
                } catch (LifecycleException e) {
                    log.error("Connector.stop", e);
                }
            }
            connectors[j].setContainer(null);
            connector.setService(null);
            int k = 0;
            Connector results[] = new Connector[connectors.length - 1];
            for (int i = 0; i < connectors.length; i++) {
                if (i != j)
                    results[k++] = connectors[i];
            }
            connectors = results;

            // Report this property change to interested listeners
            support.firePropertyChange("connector", connector, null);
        }

    
public voidremoveExecutor(org.apache.catalina.Executor ex)
Removes an executor from the service

param
ex Executor

        synchronized (executors) {
            if ( executors.remove(ex) && started ) {
                try {
                    ex.stop();
                } catch (LifecycleException e) {
                    log.error("Executor.stop", e);
                }
            }
        }
    
public voidremoveLifecycleListener(org.apache.catalina.LifecycleListener listener)
Remove a LifecycleEvent listener from this component.

param
listener The listener to remove


        lifecycle.removeLifecycleListener(listener);

    
public voidremovePropertyChangeListener(java.beans.PropertyChangeListener listener)
Remove a property change listener from this component.

param
listener The listener to remove


        support.removePropertyChangeListener(listener);

    
public voidsetContainer(org.apache.catalina.Container container)
Set the Container that handles requests for all Connectors associated with this Service.

param
container The new Container


        Container oldContainer = this.container;
        if ((oldContainer != null) && (oldContainer instanceof Engine))
            ((Engine) oldContainer).setService(null);
        this.container = container;
        if ((this.container != null) && (this.container instanceof Engine))
            ((Engine) this.container).setService(this);
        if (started && (this.container != null) &&
            (this.container instanceof Lifecycle)) {
            try {
                ((Lifecycle) this.container).start();
            } catch (LifecycleException e) {
                ;
            }
        }
        synchronized (connectors) {
            for (int i = 0; i < connectors.length; i++)
                connectors[i].setContainer(this.container);
        }
        if (started && (oldContainer != null) &&
            (oldContainer instanceof Lifecycle)) {
            try {
                ((Lifecycle) oldContainer).stop();
            } catch (LifecycleException e) {
                ;
            }
        }

        // Report this property change to interested listeners
        support.firePropertyChange("container", oldContainer, this.container);

    
public voidsetName(java.lang.String name)
Set the name of this Service.

param
name The new service name


        this.name = name;

    
public voidsetServer(org.apache.catalina.Server server)
Set the Server with which we are associated (if any).

param
server The server that owns this Service


        this.server = server;

    
public voidstart()
Prepare for the beginning of active use of the public methods of this component. This method should be called before any of the public methods of this component are utilized. It should also send a LifecycleEvent of type START_EVENT to any registered listeners.

exception
LifecycleException if this component detects a fatal error that prevents this component from being used


        // Validate and update our current component state
        if (log.isInfoEnabled() && started) {
            log.info(sm.getString("standardService.start.started"));
        }
        
        if( ! initialized )
            init(); 

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
        if(log.isInfoEnabled())
            log.info(sm.getString("standardService.start.name", this.name));
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;

        // Start our defined Container first
        if (container != null) {
            synchronized (container) {
                if (container instanceof Lifecycle) {
                    ((Lifecycle) container).start();
                }
            }
        }

        synchronized (executors) {
            for ( int i=0; i<executors.size(); i++ ) {
                executors.get(i).start();
            }
        }

        // Start our defined Connectors second
        synchronized (connectors) {
            for (int i = 0; i < connectors.length; i++) {
                if (connectors[i] instanceof Lifecycle)
                    ((Lifecycle) connectors[i]).start();
            }
        }
        
        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

    
public voidstop()
Gracefully terminate the active use of the public methods of this component. This method should be the last one called on a given instance of this component. It should also send a LifecycleEvent of type STOP_EVENT to any registered listeners.

exception
LifecycleException if this component detects a fatal error that needs to be reported


        // Validate and update our current component state
        if (!started) {
            return;
        }

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);

        // Stop our defined Connectors first
        synchronized (connectors) {
            for (int i = 0; i < connectors.length; i++) {
                connectors[i].pause();
            }
        }

        // Heuristic: Sleep for a while to ensure pause of the connector
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // Ignore
        }

        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        if(log.isInfoEnabled())
            log.info
                (sm.getString("standardService.stop.name", this.name));
        started = false;

        // Stop our defined Container second
        if (container != null) {
            synchronized (container) {
                if (container instanceof Lifecycle) {
                    ((Lifecycle) container).stop();
                }
            }
        }
        // FIXME pero -- Why container stop first? KeepAlive connetions can send request! 
        // Stop our defined Connectors first
        synchronized (connectors) {
            for (int i = 0; i < connectors.length; i++) {
                if (connectors[i] instanceof Lifecycle)
                    ((Lifecycle) connectors[i]).stop();
            }
        }

        synchronized (executors) {
            for ( int i=0; i<executors.size(); i++ ) {
                executors.get(i).stop();
            }
        }

        if( oname==controller ) {
            // we registered ourself on init().
            // That should be the typical case - this object is just for
            // backward compat, nobody should bother to load it explicitely
            Registry.getRegistry(null, null).unregisterComponent(oname);
            Executor[] executors = findExecutors();
            for (int i = 0; i < executors.length; i++) {
                try {
                    ObjectName executorObjectName = 
                        new ObjectName(domain + ":type=Executor,name=" + executors[i].getName());
                    Registry.getRegistry(null, null).unregisterComponent(executorObjectName);
                } catch (Exception e) {
                    // Ignore (invalid ON, which cannot happen)
                }
            }
        }
        

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);

    
public java.lang.StringtoString()
Return a String representation of this component.


        StringBuffer sb = new StringBuffer("StandardService[");
        sb.append(getName());
        sb.append("]");
        return (sb.toString());