Jetty LifeCycle

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/sandbox/trunk@1061 7e9141cc-0065-0410-87d8-b60c137991c4
diff --git a/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/AppProvider.java b/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/AppProvider.java
index 76ca1e6..cee3b2a 100644
--- a/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/AppProvider.java
+++ b/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/AppProvider.java
@@ -15,12 +15,19 @@
 // ========================================================================
 package org.eclipse.jetty.deploy;
 
+import org.eclipse.jetty.util.component.LifeCycle;
+
 /**
  * Object responsible for providing {@link App}s to the {@link DeploymentManager}
  */
-public interface AppProvider
+public interface AppProvider extends LifeCycle
 {
-    void startProvider(DeploymentManager deploymentManager) throws Exception;
-
-    void stopProvider() throws Exception;
+    /* ------------------------------------------------------------ */
+    /**
+     * Set the deployment manager
+     * @param deploymentManager
+     * @throws IllegalStateException if the provider {@link #isRunning()}.
+     */
+    public void setDeploymentManager(DeploymentManager deploymentManager);
+    
 }
diff --git a/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java b/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java
index 8a4ff5e..4ade66c 100644
--- a/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java
+++ b/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java
@@ -30,6 +30,7 @@
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
 import org.eclipse.jetty.util.AttributesMap;
+import org.eclipse.jetty.util.MultiException;
 import org.eclipse.jetty.util.component.AbstractLifeCycle;
 import org.eclipse.jetty.util.log.Log;
 
@@ -227,11 +228,14 @@
     public void addAppProvider(AppProvider provider)
     {
         providers.add(provider);
-        if (isStarted() || isStarting())
+        provider.setDeploymentManager(this);
+        if (getServer()!=null)
+            getServer().getContainer().addBean(provider);
+        if (isRunning())
         {
             try
             {
-                provider.startProvider(this);
+                provider.start();
             }
             catch (Exception e)
             {
@@ -245,17 +249,19 @@
     {
         Log.info("Starting all Providers: " + providers.size());
         // Start all of the AppProviders
+        MultiException mex = new MultiException();
         for (AppProvider provider : providers)
         {
             try
             {
-                provider.startProvider(this);
+                provider.start();
             }
             catch (Exception e)
             {
-                Log.warn("Unable to start AppProvider",e);
+                mex.add(e);
             }
         }
+        mex.ifExceptionThrow();
         super.doStart();
     }
 
@@ -269,7 +275,7 @@
         {
             try
             {
-                provider.stopProvider();
+                provider.stop();
             }
             catch (Exception e)
             {
@@ -327,11 +333,37 @@
         return Collections.unmodifiableList(this.lifecycleListeners);
     }
 
-    public Collection<AppProvider> getAppProviders()
+    public List<AppProvider> getAppProviders()
     {
         return providers;
     }
 
+    public void setAppProviders(List<AppProvider> providers)
+    {
+        Object[] old = this.providers==null?new Object[0]:this.providers.toArray();
+        this.providers=providers;
+        if (getServer()!=null)
+            getServer().getContainer().update(this, old, providers.toArray(), "provider");
+        if (isRunning())
+        {
+            MultiException mex=new MultiException();
+            
+            for (AppProvider provider : this.providers)
+            {
+                try
+                {
+                    provider.start();
+                }
+                catch(Exception e)
+                {
+                    mex.add(e);
+                }
+            }
+            
+            mex.ifExceptionThrowRuntime();
+        }
+    }
+
     public Collection<App> getApps()
     {
         List<App> ret = new ArrayList<App>();
@@ -412,12 +444,18 @@
         providers.remove(provider);
         try
         {
-            provider.stopProvider();
+            provider.stop();
         }
         catch (Exception e)
         {
             Log.warn("Unable to stop Provider",e);
         }
+        finally
+        {
+            provider.setDeploymentManager(null);
+            if (getServer()!=null)
+                getServer().getContainer().removeBean(provider);
+        }
     }
 
     /**
@@ -454,6 +492,12 @@
     public void setContexts(ContextHandlerCollection contexts)
     {
         this.contexts = contexts;
+        
+        if (contexts!=null)
+        {
+            for (AppProvider provider : this.providers)
+                getServer().getContainer().addBean(provider);
+        }
     }
 
     public void setDefaultLifeCycleState(AppLifeCycle.State defaultLifeCycleState)
diff --git a/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java b/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java
index 52fccd1..e8dcd59 100644
--- a/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java
+++ b/jetty-deploy-manager/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java
@@ -23,6 +23,7 @@
 import org.eclipse.jetty.deploy.AppProvider;
 import org.eclipse.jetty.deploy.DeploymentManager;
 import org.eclipse.jetty.util.Scanner;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.resource.Resource;
 
@@ -31,7 +32,7 @@
  * 
  * Similar in scope to the original org.eclipse.jetty.deploy.ContextDeployer
  */
-public class MonitoredDirAppProvider implements AppProvider, Scanner.DiscreteListener
+public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppProvider, Scanner.DiscreteListener
 {
     class ExtensionFilenameFilter implements FilenameFilter
     {
@@ -189,15 +190,25 @@
         this.scanInterval = scanInterval;
     }
 
-    public void startProvider(DeploymentManager deploymentManager) throws Exception
+    public void setDeploymentManager(DeploymentManager deploymentManager)
     {
-        Log.info(this.getClass().getSimpleName() + ".startProvider(" + deploymentManager + ")");
+        if (isRunning())
+            throw new IllegalStateException("Running");
+        this.deploymgr = deploymentManager;
+    }
+    
+    public void doStart() throws Exception
+    {
+        if (deploymgr == null)
+        {
+            throw new IllegalStateException("No Deployment manager specified");
+        }
         if (monitoredDir == null)
         {
             throw new IllegalStateException("No configuration dir specified");
         }
 
-        this.deploymgr = deploymentManager;
+        Log.info(this.getClass().getSimpleName() + ".startProvider(" + deploymgr + ")");
 
         File scandir = monitoredDir.getFile();
         Log.info("ScanDir: " + scandir);
diff --git a/jetty-deploy-manager/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java b/jetty-deploy-manager/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java
index 2e49846..6eec7a0 100644
--- a/jetty-deploy-manager/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java
+++ b/jetty-deploy-manager/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java
@@ -18,16 +18,16 @@
 import java.io.File;
 
 import org.eclipse.jetty.deploy.test.MavenTestingUtils;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
 
-public class MockAppProvider implements AppProvider
+public class MockAppProvider extends AbstractLifeCycle implements AppProvider 
 {
     private DeploymentManager deployMan;
     private File webappsDir;
 
-    public void startProvider(DeploymentManager deploymentManager) throws Exception
+    public void setDeploymentManager(DeploymentManager deploymentManager)
     {
-        this.deployMan = deploymentManager;
-        this.webappsDir = MavenTestingUtils.getTestResourceDir("webapps");
+        deployMan=deploymentManager;
     }
 
     public void findWebapp(String name)
@@ -37,7 +37,14 @@
         this.deployMan.addApp(app);
     }
 
-    public void stopProvider() throws Exception
+    @Override
+    public void doStart() throws Exception
+    {
+        this.webappsDir = MavenTestingUtils.getTestResourceDir("webapps");
+    }
+    
+    @Override
+    public void doStop() throws Exception
     {
         /* ignore */
     }