// ======================================================================== // $Id: Container.java,v 1.4 2005/08/13 08:49:59 gregwilkins Exp $ // Copyright 1999-2004 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // 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 net.lightbody.bmp.proxy.jetty.util; import net.lightbody.bmp.proxy.jetty.http.HttpContext; import net.lightbody.bmp.proxy.jetty.log.LogFactory; import org.apache.commons.logging.Log; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.EventListener; /* ------------------------------------------------------------ */ /** Abstract Container. * Provides base handling for LifeCycle and Component events. * * @version $Id: Container.java,v 1.4 2005/08/13 08:49:59 gregwilkins Exp $ * @author Greg Wilkins (gregw) */ public abstract class Container implements LifeCycle,EventProvider,Serializable { private static Log log = LogFactory.getLog(Container.class); private Object _eventListeners; private Object _components; private transient boolean _started; private transient boolean _starting; private transient boolean _stopping; /* ------------------------------------------------------------ */ /** Start the server. * Generate LifeCycleEvents for starting and started either side of a call to doStart */ public synchronized final void start() throws Exception { if (_started || _starting) return; _starting=true; if (log.isDebugEnabled()) log.debug("Starting "+this); LifeCycleEvent event = new LifeCycleEvent(this); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof LifeCycleListener) ((LifeCycleListener)listener).lifeCycleStarting(event); } try { doStart(); _started=true; log.info("Started "+this); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof LifeCycleListener) ((LifeCycleListener)listener).lifeCycleStarted(event); } } catch(Throwable e) { LifeCycleEvent failed = new LifeCycleEvent(this,e); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof LifeCycleListener) ((LifeCycleListener)listener).lifeCycleFailure(event); } if (e instanceof Exception) throw (Exception)e; if (e instanceof RuntimeException) throw (RuntimeException)e; if (e instanceof Error) throw (Error)e; log.warn(LogSupport.EXCEPTION, e); } finally { _starting=false; } } /* ------------------------------------------------------------ */ /** Do start operations. * This abstract method is called by start * to perform the actual start operations. */ protected abstract void doStart() throws Exception; /* ------------------------------------------------------------ */ public synchronized boolean isStarted() { return _started; } /* ------------------------------------------------------------ */ protected synchronized boolean isStarting() { return _starting; } /* ------------------------------------------------------------ */ protected synchronized boolean isStopping() { return _stopping; } /* ------------------------------------------------------------ */ /** Stop the container. * Generate LifeCycleEvents for stopping and stopped either side of a call to doStop */ public synchronized final void stop() throws InterruptedException { if (!_started || _stopping) return; _stopping=true; if (log.isDebugEnabled()) log.debug("Stopping "+this); LifeCycleEvent event = new LifeCycleEvent(this); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof LifeCycleListener) ((LifeCycleListener)listener).lifeCycleStopping(event); } try { doStop(); _started=false; log.info("Stopped "+this); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof LifeCycleListener) ((LifeCycleListener)listener).lifeCycleStopped(event); } } catch(Throwable e) { event = new LifeCycleEvent(this,e); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof LifeCycleListener) ((LifeCycleListener)listener).lifeCycleFailure(event); } if (e instanceof InterruptedException) throw (InterruptedException)e; if (e instanceof RuntimeException) throw (RuntimeException)e; if (e instanceof Error) throw (Error)e; log.warn(LogSupport.EXCEPTION, e); } finally { _stopping=false; } } /* ------------------------------------------------------------ */ /** Do stop operations. * This abstract method is called by stop * to perform the actual stop operations. */ protected abstract void doStop() throws Exception; /* ------------------------------------------------------------ */ protected void addComponent(Object o) { if (!LazyList.contains(_components,o)) { _components = LazyList.add(_components,o); if(log.isDebugEnabled())log.debug("add component: "+o); ComponentEvent event = new ComponentEvent(this,o); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof ComponentListener) ((ComponentListener)listener).addComponent(event); } } } /* ------------------------------------------------------------ */ protected void removeComponent(Object o) { if (LazyList.contains(_components,o)) { _components=LazyList.remove(_components, o); if(log.isDebugEnabled())log.debug("remove component: "+o); ComponentEvent event = new ComponentEvent(this,o); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof ComponentListener) ((ComponentListener)listener).removeComponent(event); } } } /* ------------------------------------------------------------ */ /** Add a server event listener. * @param listener ComponentEventListener or LifeCycleEventListener */ public void addEventListener(EventListener listener) throws IllegalArgumentException { if (_eventListeners==null) _eventListeners=new ArrayList(); if (listener instanceof ComponentListener || listener instanceof LifeCycleListener ) { if(log.isDebugEnabled())log.debug("addEventListener: "+listener); _eventListeners=LazyList.add(_eventListeners,listener); } } /* ------------------------------------------------------------ */ public void removeEventListener(EventListener listener) { if(log.isDebugEnabled())log.debug("removeEventListener: "+listener); _eventListeners=LazyList.remove(_eventListeners,listener); } /* ------------------------------------------------------------ */ /** Destroy a stopped server. * Remove all components and send notifications to all event * listeners. The HttpServer must be stopped before it can be destroyed. */ public void destroy() { if (isStarted()) throw new IllegalStateException("Started"); if (_components!=null && _eventListeners!=null) { for (int c=0;c<LazyList.size(_components);c++) { Object o=LazyList.get(_components,c); if (o instanceof HttpContext ) ((HttpContext)o).destroy(); ComponentEvent event = new ComponentEvent(this,o); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof ComponentListener) ((ComponentListener)listener).removeComponent(event); } } } _components=null; _eventListeners=null; } /* ------------------------------------------------------------ */ public Collection getComponents() { return LazyList.getList(_eventListeners, false); } /* ------------------------------------------------------------ */ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); for (int c=0;c<LazyList.size(_components);c++) { Object o = LazyList.get(_components,c); ComponentEvent event = new ComponentEvent(this,o); for(int i=0;i<LazyList.size(_eventListeners);i++) { EventListener listener=(EventListener)LazyList.get(_eventListeners,i); if (listener instanceof ComponentListener) ((ComponentListener)listener).addComponent(event); } } } }