You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2009/03/02 11:24:40 UTC

svn commit: r749261 - in /servicemix/smx4/nmr/trunk: examples/ jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/ jbi/deployer/src/main/java/org/apache/servicem...

Author: gnodet
Date: Mon Mar  2 10:24:40 2009
New Revision: 749261

URL: http://svn.apache.org/viewvc?rev=749261&view=rev
Log:
SMX4NMR-109: When a component is stopped and restarted, service assemblies are stopped, but not restarted

Added:
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AssemblyReferencesListener.java
      - copied, changed from r748220, servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AssemblyReferencesListener.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleEvent.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleListener.java
Removed:
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AssemblyReferencesListener.java
Modified:
    servicemix/smx4/nmr/trunk/examples/   (props changed)
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AbstractLifecycleJbiArtifact.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ComponentImpl.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImpl.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceUnitImpl.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/handler/JBIDeploymentListener.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AbstractInstaller.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ComponentInstaller.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/Deployer.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ServiceAssemblyInstaller.java
    servicemix/smx4/nmr/trunk/jbi/deployer/src/main/resources/META-INF/spring/servicemix-jbi-deployer.xml
    servicemix/smx4/nmr/trunk/jbi/deployer/src/test/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImplTest.java
    servicemix/smx4/nmr/trunk/jbi/itests/src/test/java/org/apache/servicemix/jbi/itests/IntegrationTest.java
    servicemix/smx4/nmr/trunk/jbi/runtime/src/main/java/org/apache/servicemix/jbi/runtime/impl/AbstractComponentContext.java
    servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/event/Listener.java

Propchange: servicemix/smx4/nmr/trunk/examples/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Mar  2 10:24:40 2009
@@ -1 +1,4 @@
 target
+*.iml
+*.ipr
+*.iws

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AbstractLifecycleJbiArtifact.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AbstractLifecycleJbiArtifact.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AbstractLifecycleJbiArtifact.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AbstractLifecycleJbiArtifact.java Mon Mar  2 10:24:40 2009
@@ -17,13 +17,17 @@
 package org.apache.servicemix.jbi.deployer.artifacts;
 
 import javax.jbi.management.LifeCycleMBean;
+import javax.jbi.JBIException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.nmr.api.event.ListenerRegistry;
+import org.apache.servicemix.jbi.deployer.events.LifeCycleEvent;
+import org.apache.servicemix.jbi.deployer.events.LifeCycleListener;
 import org.osgi.service.prefs.BackingStoreException;
 import org.osgi.service.prefs.Preferences;
 
-public class AbstractLifecycleJbiArtifact {
+public abstract class AbstractLifecycleJbiArtifact implements LifeCycleMBean {
 
     public static final String STATE = "state";
 
@@ -39,11 +43,24 @@
     protected State state = State.Unknown;
     protected Preferences prefs;
     protected State runningState;
+    protected ListenerRegistry listenerRegistry;
 
     public State getState() {
         return state;
     }
 
+    public State getRunningState() {
+        return runningState;
+    }
+
+    public ListenerRegistry getListenerRegistry() {
+        return listenerRegistry;
+    }
+
+    public void setListenerRegistry(ListenerRegistry listenerRegistry) {
+        this.listenerRegistry = listenerRegistry;
+    }
+
     public String getCurrentState() {
         switch (state) {
             case Started:
@@ -57,6 +74,10 @@
         }
     }
 
+    protected State loadState(State def) {
+        return State.valueOf(this.prefs.get(STATE, def.name()));
+    }
+
     protected void saveState() {
         this.prefs.put(STATE, state.name());
         try {
@@ -64,6 +85,23 @@
         } catch (BackingStoreException e) {
             LOGGER.warn("Unable to persist state", e);
         }
+        this.runningState = state;
+    }
+
+    protected void fireEvent(LifeCycleEvent.LifeCycleEventType type) throws JBIException {
+        fireEvent(type, false);
+    }
+
+    protected void fireEvent(LifeCycleEvent.LifeCycleEventType type, boolean force) throws JBIException {
+        if (listenerRegistry != null) {
+            LifeCycleEvent event = null;
+            for (LifeCycleListener listener : listenerRegistry.getListeners(LifeCycleListener.class)) {
+                if (event == null) {
+                    event = new LifeCycleEvent(type, this, force);
+                }
+                listener.lifeCycleChanged(event);
+            }
+        }
     }
 
 }

Copied: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AssemblyReferencesListener.java (from r748220, servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AssemblyReferencesListener.java)
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AssemblyReferencesListener.java?p2=servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AssemblyReferencesListener.java&p1=servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AssemblyReferencesListener.java&r1=748220&r2=749261&rev=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AssemblyReferencesListener.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/AssemblyReferencesListener.java Mon Mar  2 10:24:40 2009
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicemix.jbi.deployer.impl;
+package org.apache.servicemix.jbi.deployer.artifacts;
 
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ComponentImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ComponentImpl.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ComponentImpl.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ComponentImpl.java Mon Mar  2 10:24:40 2009
@@ -17,9 +17,7 @@
 package org.apache.servicemix.jbi.deployer.artifacts;
 
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 import javax.jbi.JBIException;
@@ -36,6 +34,7 @@
 import org.apache.servicemix.jbi.deployer.Component;
 import org.apache.servicemix.jbi.deployer.ServiceUnit;
 import org.apache.servicemix.jbi.deployer.SharedLibrary;
+import org.apache.servicemix.jbi.deployer.events.LifeCycleEvent;
 import org.apache.servicemix.jbi.deployer.descriptor.ComponentDesc;
 import org.apache.servicemix.jbi.deployer.descriptor.DescriptorFactory;
 import org.apache.servicemix.jbi.runtime.ComponentWrapper;
@@ -49,8 +48,7 @@
     private Bundle bundle;
     private ComponentDesc componentDesc;
     private javax.jbi.component.Component component;
-    private List<ServiceUnitImpl> serviceUnits;
-    private Runnable callback;
+    private Set<ServiceUnitImpl> serviceUnits;
     private SharedLibrary[] sharedLibraries;
 
     public ComponentImpl(Bundle bundle,
@@ -58,15 +56,13 @@
                          javax.jbi.component.Component component,
                          Preferences prefs,
                          boolean autoStart,
-                         Runnable callback,
                          SharedLibrary[] sharedLibraries) {
         this.bundle = bundle;
         this.componentDesc = componentDesc;
         this.component = new ComponentWrapper(component);
         this.prefs = prefs;
-        this.runningState = State.valueOf(this.prefs.get(STATE, (autoStart ? State.Started : State.Shutdown).name()));
-        this.callback = callback;
-        this.serviceUnits = new ArrayList<ServiceUnitImpl>();
+        this.runningState = loadState(autoStart ? State.Started : State.Shutdown);
+        this.serviceUnits = new HashSet<ServiceUnitImpl>();
         this.sharedLibraries = sharedLibraries;
     }
 
@@ -121,11 +117,13 @@
             if (state == State.Shutdown) {
                 component.getLifeCycle().init(null);
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.Starting);
             component.getLifeCycle().start();
             state = State.Started;
             if (saveState) {
                 saveState();
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.Started);
         }
     }
 
@@ -148,18 +146,14 @@
     public void stop(boolean saveState) throws JBIException {
         LOGGER.info("Stopping component " + getName());
         if (state == State.Started) {
-            // Stop deployed SAs
-            for (ServiceAssemblyImpl sa : getServiceAssemblies()) {
-                if (sa.getState() == ServiceAssemblyImpl.State.Started) {
-                    sa.stop(false);
-                }
-            }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.Stopping);
             // Stop component
             component.getLifeCycle().stop();
             state = State.Stopped;
             if (saveState) {
                 saveState();
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.Stopped);
         }
     }
 
@@ -177,18 +171,14 @@
             stop(saveState);
         }
         if (state == State.Stopped) {
-            // Shutdown deployed SAs
-            for (ServiceAssemblyImpl sa : getServiceAssemblies()) {
-                if (sa.getState() == ServiceAssemblyImpl.State.Stopped) {
-                    sa.shutDown(false, force);
-                }
-            }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.ShuttingDown, force);
             // Shutdown component
             component.getLifeCycle().shutDown();
             state = State.Shutdown;
             if (saveState) {
                 saveState();
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.ShutDown);
         }
     }
 
@@ -233,35 +223,39 @@
         }
 
         public void init(ComponentContext context) throws JBIException {
+            ComponentContext contextToUse = context;
             if (this.context == null) {
                 this.context = context;
             }
-            if (context == null) {
-                context = this.context;
+            if (contextToUse == null) {
+                contextToUse = this.context;
             }
             ClassLoader cl = Thread.currentThread().getContextClassLoader();
             try {
                 Thread.currentThread().setContextClassLoader(component.getClass().getClassLoader());
-                if (runningState != State.Unknown) {
-                    if (runningState == State.Started) {
-                        lifeCycle.init(context);
+                State stateToUse = context != null ? runningState : State.Shutdown;
+                switch (stateToUse) {
+                    case Started:
+                        fireEvent(LifeCycleEvent.LifeCycleEventType.Starting);
+                        lifeCycle.init(contextToUse);
                         start();
                         state = State.Started;
-                    } else if (runningState == State.Stopped) {
-                        lifeCycle.init(context);
+                        fireEvent(LifeCycleEvent.LifeCycleEventType.Started);
+                        break;
+                    case Stopped:
+                        fireEvent(LifeCycleEvent.LifeCycleEventType.Stopping);
+                        lifeCycle.init(contextToUse);
                         start();
                         stop();
                         state = State.Stopped;
-                    } else if (runningState == State.Shutdown) {
+                        fireEvent(LifeCycleEvent.LifeCycleEventType.Stopped);
+                        break;
+                    case Shutdown:
+                        fireEvent(LifeCycleEvent.LifeCycleEventType.ShuttingDown);
+                        lifeCycle.init(contextToUse);
                         state = State.Shutdown;
-                    }
-                    runningState = State.Unknown;
-                } else {
-                    lifeCycle.init(context);
-                    state = State.Shutdown;
-                }
-                if (callback != null) {
-                    callback.run();
+                        fireEvent(LifeCycleEvent.LifeCycleEventType.ShutDown);
+                        break;
                 }
             } finally {
                 Thread.currentThread().setContextClassLoader(cl);

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImpl.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImpl.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImpl.java Mon Mar  2 10:24:40 2009
@@ -27,11 +27,11 @@
 
 import org.apache.servicemix.jbi.deployer.ServiceAssembly;
 import org.apache.servicemix.jbi.deployer.ServiceUnit;
-import org.apache.servicemix.jbi.deployer.Component;
+import org.apache.servicemix.jbi.deployer.events.LifeCycleEvent;
 import org.apache.servicemix.jbi.deployer.descriptor.Connection;
 import org.apache.servicemix.jbi.deployer.descriptor.DescriptorFactory;
 import org.apache.servicemix.jbi.deployer.descriptor.ServiceAssemblyDesc;
-import org.apache.servicemix.jbi.deployer.impl.AssemblyReferencesListener;
+import org.apache.servicemix.jbi.deployer.artifacts.AssemblyReferencesListener;
 import org.apache.servicemix.nmr.api.Wire;
 import org.apache.servicemix.nmr.core.util.MapToDictionary;
 import org.osgi.framework.Bundle;
@@ -87,7 +87,7 @@
         this.serviceUnits = serviceUnits;
         this.prefs = prefs;
         this.listener = listener;
-        this.runningState = State.valueOf(this.prefs.get(STATE, (autoStart ? State.Started : State.Shutdown).name()));
+        this.runningState = loadState(autoStart ? State.Started : State.Shutdown);
         for (ServiceUnitImpl su : serviceUnits) {
             su.setServiceAssemblyImpl(this);
         }
@@ -114,6 +114,10 @@
         return serviceUnits.toArray(new ServiceUnit[serviceUnits.size()]);
     }
 
+    public List<ServiceUnitImpl> getServiceUnitsList() {
+        return serviceUnits;
+    }
+
     public synchronized void init() throws JBIException {
         checkComponentsStarted();
         listener.setAssembly(this);
@@ -124,6 +128,8 @@
             } else if (runningState == State.Stopped) {
                 transition(Action.Init, State.Stopped);
             } else if (runningState == State.Shutdown) {
+                transition(Action.Init, State.Stopped);
+                transition(Action.Shutdown, State.Shutdown);
                 state = State.Shutdown;
             }
         } finally {
@@ -145,11 +151,13 @@
             if (state == State.Shutdown) {
                 transition(Action.Init, State.Stopped);
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.Starting);
             startConnections();
             transition(Action.Start, State.Started);
             if (persist) {
                 saveState();
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.Started);
         } finally {
             listener.setAssembly(null);
         }
@@ -165,6 +173,7 @@
             if (state == State.Stopped) {
                 return;
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.Stopping);
             if (state == State.Shutdown) {
                 transition(Action.Init, State.Stopped);
             }
@@ -175,6 +184,7 @@
             if (persist) {
                 saveState();
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.Stopped);
         } finally {
             listener.setAssembly(null);
         }
@@ -197,6 +207,7 @@
             if (state == State.Started) {
                 transition(Action.Stop, State.Stopped);
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.ShuttingDown);
             if (!force) {
                 for (; ;) {
                     try {
@@ -210,6 +221,7 @@
             if (persist) {
                 saveState();
             }
+            fireEvent(LifeCycleEvent.LifeCycleEventType.ShutDown);
         } finally {
             listener.setAssembly(null);
             listener.forget(this);

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceUnitImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceUnitImpl.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceUnitImpl.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceUnitImpl.java Mon Mar  2 10:24:40 2009
@@ -85,6 +85,10 @@
         return component;
     }
 
+    public ComponentImpl getComponentImpl() {
+        return component;
+    }
+
     public File getRootDir() {
         return rootDir;
     }
@@ -108,6 +112,7 @@
         } finally {
             Thread.currentThread().setContextClassLoader(oldCl);
         }
+        component.addServiceUnit(this);
     }
 
     public void start() throws JBIException {

Added: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleEvent.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleEvent.java?rev=749261&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleEvent.java (added)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleEvent.java Mon Mar  2 10:24:40 2009
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.servicemix.jbi.deployer.events;
+
+import java.util.EventObject;
+
+import javax.jbi.management.LifeCycleMBean;
+
+/**
+ */
+public class LifeCycleEvent extends EventObject {
+
+    public enum LifeCycleEventType {
+        Starting,
+        Started,
+        Stopping,
+        Stopped,
+        ShuttingDown,
+        ShutDown
+    }
+
+    private final LifeCycleEventType type;
+    private final boolean forced;
+
+    public LifeCycleEvent(LifeCycleEventType type, LifeCycleMBean source, boolean forced) {
+        super(source);
+        this.type = type;
+        this.forced = forced;
+    }
+
+    public LifeCycleEventType getType() {
+        return type;
+    }
+
+    public LifeCycleMBean getLifeCycleMBean() {
+        return (LifeCycleMBean) getSource();
+    }
+
+    public boolean isForced() {
+        return forced;
+    }
+}

Added: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleListener.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleListener.java?rev=749261&view=auto
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleListener.java (added)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/events/LifeCycleListener.java Mon Mar  2 10:24:40 2009
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.servicemix.jbi.deployer.events;
+
+import javax.jbi.JBIException;
+
+import org.apache.servicemix.nmr.api.event.Listener;
+
+/**
+ */
+public interface LifeCycleListener extends Listener {
+
+    void lifeCycleChanged(LifeCycleEvent event) throws JBIException;
+
+}

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/handler/JBIDeploymentListener.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/handler/JBIDeploymentListener.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/handler/JBIDeploymentListener.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/handler/JBIDeploymentListener.java Mon Mar  2 10:24:40 2009
@@ -25,7 +25,6 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.servicemix.jbi.deployer.descriptor.DescriptorFactory;
-import org.apache.servicemix.jbi.deployer.impl.Deployer;
 import org.apache.servicemix.kernel.filemonitor.DeploymentListener;
 
 /**
@@ -37,8 +36,6 @@
 
     private static final Log Logger = LogFactory.getLog(JBIDeploymentListener.class);
 
-    private Deployer deployer;
-
     /**
      * Check if the file is a recognized JBI artifact that needs to be
      * processed.
@@ -99,14 +96,4 @@
     }
 
 
-    public void setDeployer(Deployer deployer) {
-        this.deployer = deployer;
-    }
-
-
-    public Deployer getDeployer() {
-        return deployer;
-    }
-
-
 }

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AbstractInstaller.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AbstractInstaller.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AbstractInstaller.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/AbstractInstaller.java Mon Mar  2 10:24:40 2009
@@ -39,8 +39,13 @@
 import org.osgi.framework.BundleException;
 import org.osgi.service.prefs.BackingStoreException;
 import org.osgi.service.prefs.Preferences;
-import org.osgi.service.prefs.PreferencesService;
 
+/**
+ * Installers are used to controll the installation / deployment process of JBI artifacts
+ * and manage the installed OSGi bundle.
+ *
+ * TODO: refactor the use of installRoot and reuse the Deployer#jbiRootDir
+ */
 public abstract class AbstractInstaller {
 
     public static final String LAST_INSTALL = "jbi.deployer.install";

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ComponentInstaller.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ComponentInstaller.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ComponentInstaller.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ComponentInstaller.java Mon Mar  2 10:24:40 2009
@@ -56,6 +56,7 @@
     private ObjectName extensionMBeanName;
     private boolean initialized;
     private Bootstrap bootstrap;
+    private javax.jbi.component.Component innerComponent;
 
 
     public ComponentInstaller(Deployer deployer, Descriptor descriptor, File jbiArtifact, boolean autoStart) throws Exception {
@@ -88,6 +89,14 @@
         return descriptor.getComponent().getIdentification().getName();
     }
 
+    public javax.jbi.component.Component getInnerComponent() {
+        return innerComponent;
+    }
+
+    public void setInnerComponent(javax.jbi.component.Component innerComponent) {
+        this.innerComponent = innerComponent;
+    }
+
     public void init() throws Exception {
         // Check requirements
         if (descriptor.getComponent().getSharedLibraries() != null) {
@@ -114,10 +123,10 @@
      */
     public ObjectName install() throws JBIException {
         try {
-            if (isInstalled()) {
-                throw new DeploymentException("Component is already installed");
-            }
             if (isModified) {
+                if (isInstalled()) {
+                    throw new DeploymentException("Component is already installed");
+                }
                 initBootstrap();
                 bootstrap.onInstall();
                 try {
@@ -186,22 +195,24 @@
         // Shutdown component
         stop(force);
         // Retrieve component
-        Component comp = deployer.getComponent(getName());
+        ComponentImpl comp = deployer.getComponent(getName());
         if (comp == null && !force) {
             throw ManagementSupport.failure("uninstallComponent", "Component '" + getName() + "' is not installed.");
         }
         // TODO: if there is any SA deployed onto this component, undeploy the SA and put it in a pending state
         // Bootstrap stuff
-        try {
-            initBootstrap();
-            bootstrap.init(this.installationContext);
-            bootstrap.getExtensionMBeanName();
-            bootstrap.onUninstall();
-            cleanUpBootstrap();
-            installationContext.setInstall(true);
-        } catch (Exception e) {
-            cleanUpBootstrap();
-            throw e;
+        if (hasBootstrap()) {
+            try {
+                initBootstrap();
+                bootstrap.init(this.installationContext);
+                bootstrap.getExtensionMBeanName();
+                bootstrap.onUninstall();
+                cleanUpBootstrap();
+                installationContext.setInstall(true);
+            } catch (Exception e) {
+                cleanUpBootstrap();
+                throw e;
+            }
         }
         // Unregister component
         deployer.unregisterComponent(comp);
@@ -283,6 +294,9 @@
     }
 
     private void initBootstrap() throws DeploymentException {
+        if (!hasBootstrap()) {
+            return;
+        }
         try {
             if (!initialized) {
                 // Unregister a previously registered extension mbean,
@@ -315,19 +329,26 @@
     }
 
     protected void cleanUpBootstrap() throws DeploymentException {
-        ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
-        try {
-            Thread.currentThread().setContextClassLoader(bootstrap.getClass().getClassLoader());
-            bootstrap.cleanUp();
-        } catch (JBIException e) {
-            LOGGER.error("Could not initialize bootstrap", e);
-            throw new DeploymentException(e);
-        } finally {
-            initialized = false;
-            Thread.currentThread().setContextClassLoader(oldCl);
+        if (bootstrap != null) {
+            ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
+            try {
+                Thread.currentThread().setContextClassLoader(bootstrap.getClass().getClassLoader());
+                bootstrap.cleanUp();
+            } catch (JBIException e) {
+                LOGGER.error("Could not initialize bootstrap", e);
+                throw new DeploymentException(e);
+            } finally {
+                initialized = false;
+                Thread.currentThread().setContextClassLoader(oldCl);
+            }
         }
     }
 
+    private boolean hasBootstrap() {
+        ComponentDesc descriptor = installationContext.getDescriptor();
+        return descriptor.getBootstrapClassName() != null;
+    }
+
     private Bootstrap createBootstrap() throws DeploymentException {
         ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
         ComponentDesc descriptor = installationContext.getDescriptor();
@@ -356,36 +377,38 @@
     }
 
     private ObjectName initComponent() throws Exception {
-        ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
-        try {
-            ComponentDesc componentDesc = installationContext.getDescriptor();
-            List<SharedLibrary> libs = new ArrayList<SharedLibrary>();
-            if (componentDesc.getSharedLibraries() != null) {
-                for (SharedLibraryList sll : componentDesc.getSharedLibraries()) {
-                    SharedLibrary lib = deployer.getSharedLibrary(sll.getName());
-                    if (lib == null) {
-                        // TODO: throw exception here ?
-                    } else {
-                        libs.add(lib);
-                    }
+        ComponentDesc componentDesc = installationContext.getDescriptor();
+        List<SharedLibrary> libs = new ArrayList<SharedLibrary>();
+        if (componentDesc.getSharedLibraries() != null) {
+            for (SharedLibraryList sll : componentDesc.getSharedLibraries()) {
+                SharedLibrary lib = deployer.getSharedLibrary(sll.getName());
+                if (lib == null) {
+                    // TODO: throw exception here ?
+                } else {
+                    libs.add(lib);
                 }
             }
-            SharedLibrary[] aLibs = libs.toArray(new SharedLibrary[libs.size()]);
+        }
+        SharedLibrary[] aLibs = libs.toArray(new SharedLibrary[libs.size()]);
 
+        if (innerComponent == null) {
             ClassLoader classLoader = createClassLoader(
                     getBundle(),
                     componentDesc.getIdentification().getName(),
                     (String[]) installationContext.getClassPathElements().toArray(new String[installationContext.getClassPathElements().size()]),
                     componentDesc.isComponentClassLoaderDelegationParentFirst(),
                     aLibs);
-            Thread.currentThread().setContextClassLoader(classLoader);
-            Class clazz = classLoader.loadClass(componentDesc.getComponentClassName());
-            javax.jbi.component.Component innerComponent = (javax.jbi.component.Component) clazz.newInstance();
-            Component component = deployer.registerComponent(getBundle(), componentDesc, innerComponent, aLibs);
-            return deployer.getNamingStrategy().getObjectName(component);
-        } finally {
-            Thread.currentThread().setContextClassLoader(oldCl);
+            ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
+            try {
+                Thread.currentThread().setContextClassLoader(classLoader);
+                Class clazz = classLoader.loadClass(componentDesc.getComponentClassName());
+                innerComponent = (javax.jbi.component.Component) clazz.newInstance();
+            } finally {
+                Thread.currentThread().setContextClassLoader(oldCl);
+            }
         }
+        Component component = deployer.registerComponent(getBundle(), componentDesc, innerComponent, aLibs);
+        return deployer.getNamingStrategy().getObjectName(component);
     }
 
     public void configure(Properties props) throws Exception {

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/Deployer.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/Deployer.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/Deployer.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/Deployer.java Mon Mar  2 10:24:40 2009
@@ -37,11 +37,15 @@
 import org.apache.servicemix.jbi.deployer.NamingStrategy;
 import org.apache.servicemix.jbi.deployer.ServiceAssembly;
 import org.apache.servicemix.jbi.deployer.SharedLibrary;
+import org.apache.servicemix.jbi.deployer.ServiceUnit;
+import org.apache.servicemix.jbi.deployer.events.LifeCycleListener;
+import org.apache.servicemix.jbi.deployer.events.LifeCycleEvent;
 import org.apache.servicemix.jbi.deployer.artifacts.AbstractLifecycleJbiArtifact;
 import org.apache.servicemix.jbi.deployer.artifacts.ComponentImpl;
 import org.apache.servicemix.jbi.deployer.artifacts.ServiceAssemblyImpl;
 import org.apache.servicemix.jbi.deployer.artifacts.ServiceUnitImpl;
 import org.apache.servicemix.jbi.deployer.artifacts.SharedLibraryImpl;
+import org.apache.servicemix.jbi.deployer.artifacts.AssemblyReferencesListener;
 import org.apache.servicemix.jbi.deployer.descriptor.ComponentDesc;
 import org.apache.servicemix.jbi.deployer.descriptor.Descriptor;
 import org.apache.servicemix.jbi.deployer.descriptor.DescriptorFactory;
@@ -52,6 +56,8 @@
 import org.apache.servicemix.jbi.deployer.descriptor.Target;
 import org.apache.servicemix.jbi.runtime.ComponentWrapper;
 import org.apache.servicemix.jbi.runtime.Environment;
+import org.apache.servicemix.nmr.api.event.ListenerRegistry;
+import org.apache.servicemix.nmr.core.ListenerRegistryImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -69,7 +75,7 @@
 /**
  * Deployer for JBI artifacts
  */
-public class Deployer implements BundleContextAware, InitializingBean, DisposableBean, SynchronousBundleListener {
+public class Deployer implements BundleContextAware, InitializingBean, DisposableBean, SynchronousBundleListener, LifeCycleListener {
 
     public static final String NAME = "NAME";
     public static final String TYPE = "TYPE";
@@ -93,7 +99,7 @@
 
     private final Map<Bundle, List<ServiceRegistration>> services = new ConcurrentHashMap<Bundle, List<ServiceRegistration>>();
 
-    private final List<Bundle> pendingBundles = new ArrayList<Bundle>();
+    private final Set<AbstractInstaller> pendingInstallers = new HashSet<AbstractInstaller>();
 
     private File jbiRootDir;
 
@@ -112,17 +118,15 @@
     private ManagementAgent managementAgent;
     private Environment environment;
 
-    private Runnable checkPendingBundlesCallback;
+    private ListenerRegistry listenerRegistry;
 
     public Deployer() throws JBIException {
-        checkPendingBundlesCallback = new Runnable() {
-            public void run() {
-                checkPendingBundles();
-            }
-        };
         // TODO: control that using properties
         jbiRootDir = new File(System.getProperty("servicemix.base"), "data/jbi");
         jbiRootDir.mkdirs();
+        // Create listener registry
+        listenerRegistry = new ListenerRegistryImpl();
+        listenerRegistry.register(this, null);
     }
 
     public BundleContext getBundleContext() {
@@ -309,28 +313,38 @@
             ClassLoader cl = Thread.currentThread().getContextClassLoader();
             try {
                 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-                URL url = bundle.getResource(DescriptorFactory.DESCRIPTOR_FILE);
-                Descriptor descriptor = DescriptorFactory.buildDescriptor(url);
-                DescriptorFactory.checkDescriptor(descriptor);
-                if (descriptor.getSharedLibrary() != null) {
-                    LOGGER.info("Deploying bundle '" + OsgiStringUtils.nullSafeNameAndSymName(bundle) + "' as a JBI shared library");
-                    installer = new SharedLibraryInstaller(this, descriptor, null, true);
-                } else if (descriptor.getComponent() != null) {
-                    LOGGER.info("Deploying bundle '" + OsgiStringUtils.nullSafeNameAndSymName(bundle) + "' as a JBI component");
-                    installer = new ComponentInstaller(this, descriptor, null, true);
-                } else if (descriptor.getServiceAssembly() != null) {
-                    LOGGER.info("Deploying bundle '" + OsgiStringUtils.nullSafeNameAndSymName(bundle) + "' as a JBI service assembly");
-                    installer = new ServiceAssemblyInstaller(this, descriptor, null, true);
-                } else {
-                    throw new IllegalStateException("Unrecognized JBI descriptor: " + url);
+
+                // Check if there is an already existing installer
+                // This is certainly the case when a bundle has been stopped and is restarted.
+                installer = installers.get(bundle);
+                if (installer == null) {
+                    URL url = bundle.getResource(DescriptorFactory.DESCRIPTOR_FILE);
+                    Descriptor descriptor = DescriptorFactory.buildDescriptor(url);
+                    DescriptorFactory.checkDescriptor(descriptor);
+                    if (descriptor.getSharedLibrary() != null) {
+                        LOGGER.info("Deploying bundle '" + OsgiStringUtils.nullSafeNameAndSymName(bundle) + "' as a JBI shared library");
+                        installer = new SharedLibraryInstaller(this, descriptor, null, true);
+                    } else if (descriptor.getComponent() != null) {
+                        LOGGER.info("Deploying bundle '" + OsgiStringUtils.nullSafeNameAndSymName(bundle) + "' as a JBI component");
+                        installer = new ComponentInstaller(this, descriptor, null, true);
+                    } else if (descriptor.getServiceAssembly() != null) {
+                        LOGGER.info("Deploying bundle '" + OsgiStringUtils.nullSafeNameAndSymName(bundle) + "' as a JBI service assembly");
+                        installer = new ServiceAssemblyInstaller(this, descriptor, null, true);
+                    } else {
+                        throw new IllegalStateException("Unrecognized JBI descriptor: " + url);
+                    }
+                    installer.setBundle(bundle);
+                    installers.put(bundle, installer);
+                }
+
+                // TODO: handle the case where the bundle is restarted: i.e. the artifact is already installed
+                try {
+                    installer.init();
+                    installer.install();
+                } catch (PendingException e) {
+                    pendingInstallers.add(installer);
+                    LOGGER.warn("Requirements not met for JBI artifact in bundle " + OsgiStringUtils.nullSafeNameAndSymName(bundle) + ". Installation pending. " + e);
                 }
-                installer.setBundle(bundle);
-                installer.init();
-                installer.install();
-                installers.put(bundle, installer);
-            } catch (PendingException e) {
-                pendingBundles.add(e.getBundle());
-                LOGGER.warn("Requirements not met for JBI artifact in bundle " + OsgiStringUtils.nullSafeNameAndSymName(bundle) + ". Installation pending. " + e);
             } catch (Exception e) {
                 LOGGER.error("Error handling bundle start event", e);
             } finally {
@@ -357,17 +371,20 @@
     protected void onBundleUninstalled(Bundle bundle) {
         AbstractInstaller installer = getJmxManaged();
         if (installer == null) {
-            installer = installers.get(bundle);
+            installer = installers.remove(bundle);
             if (installer != null) {
                 try {
+                    pendingInstallers.remove(installer);
                     installer.setUninstallFromOsgi(true);
                     installer.uninstall(true);
+
                 } catch (Exception e) {
                     LOGGER.warn("Error uninstalling JBI artifact", e);
                 }
             }
+        } else {
+            installers.remove(bundle);
         }
-        pendingBundles.remove(bundle);
     }
 
     public ServiceUnitImpl createServiceUnit(ServiceUnitDesc sud, File suRootDir, ComponentImpl component) {
@@ -385,30 +402,31 @@
         registerService(bundle, SharedLibrary.class.getName(), sl, props);
         getManagementAgent().register(new StandardMBean(sl, SharedLibrary.class), getNamingStrategy().getObjectName(sl));
         // Check pending bundles
-        checkPendingBundles();
+        checkPendingInstallers();
         return sl;
     }
 
     public Component registerComponent(Bundle bundle, ComponentDesc componentDesc, javax.jbi.component.Component innerComponent, SharedLibrary[] sharedLibraries) throws Exception {
         String name = componentDesc.getIdentification().getName();
         Preferences prefs = preferencesService.getUserPreferences(name);
-        ComponentImpl component = new ComponentImpl(bundle, componentDesc, innerComponent, prefs, autoStart, checkPendingBundlesCallback, sharedLibraries);
+        ComponentImpl component = new ComponentImpl(bundle, componentDesc, innerComponent, prefs, autoStart, sharedLibraries);
+        component.setListenerRegistry(listenerRegistry);
         // populate props from the component meta-data
         Dictionary<String, String> props = new Hashtable<String, String>();
         props.put(NAME, name);
         props.put(TYPE, componentDesc.getType());
+        for (SharedLibrary lib : sharedLibraries) {
+            ((SharedLibraryImpl) lib).addComponent(component);
+        }
+        components.put(name, component);
         // register the component in the OSGi registry
         LOGGER.debug("Registering JBI component");
         registerService(bundle, new String[] { Component.class.getName(), ComponentWrapper.class.getName() },
                         component, props);
-        components.put(name, component);
         // Now, register the inner component
         registerService(bundle, javax.jbi.component.Component.class.getName(), innerComponent, props);
         getManagementAgent().register(new StandardMBean(component, Component.class),
                                       getNamingStrategy().getObjectName(component));
-        for (SharedLibrary lib : sharedLibraries) {
-            ((SharedLibraryImpl) lib).addComponent(component);
-        }
         return component;
     }
 
@@ -416,6 +434,7 @@
         // Now create the SA and initialize it
         Preferences prefs = preferencesService.getUserPreferences(serviceAssemblyDesc.getIdentification().getName());
         ServiceAssemblyImpl sa = new ServiceAssemblyImpl(bundle, serviceAssemblyDesc, sus, prefs, endpointListener, autoStart);
+        sa.setListenerRegistry(listenerRegistry);
         sa.init();
         serviceAssemblies.put(sa.getName(), sa);
         // populate props from the component meta-data
@@ -428,8 +447,35 @@
         return sa;
     }
 
-    protected void unregisterComponent(Component component) {
+    protected void unregisterComponent(ComponentImpl component) {
         if (component != null) {
+            try {
+                component.stop(false);
+                component.shutDown(false, true);
+                // TODO: Undeploy SAs and put their bundles in the pending state
+                // Undeploy SAs
+                Set<ServiceAssemblyImpl> sas = new HashSet<ServiceAssemblyImpl>();
+                for (ServiceUnit su : component.getServiceUnits()) {
+                    sas.add((ServiceAssemblyImpl) su.getServiceAssembly());
+                }
+                for (ServiceAssemblyImpl sa : sas) {
+                    Bundle bundle = sa.getBundle();
+                    ServiceAssemblyInstaller installer = (ServiceAssemblyInstaller) installers.get(bundle);
+                    if (installer != null) {
+                        try {
+                            installer.stop(true);
+                            unregisterServiceAssembly(sa);
+                            pendingAssemblies.remove(sa);
+                            pendingInstallers.add(installer);
+                        } catch (Exception e) {
+                            LOGGER.warn("Error uninstalling service assembly", e);
+                        }
+                    }
+                }
+                unregisterServices(component.getBundle());
+            } catch (JBIException e) {
+                LOGGER.warn("Error when shutting down component", e);
+            }
             for (SharedLibrary lib : component.getSharedLibraries()) {
                 ((SharedLibraryImpl) lib).removeComponent(component);
             }
@@ -437,14 +483,19 @@
         }
     }
 
-    protected void unregisterServiceAssembly(ServiceAssembly assembly) {
+    protected void unregisterServiceAssembly(ServiceAssemblyImpl assembly) {
         if (assembly != null) {
             serviceAssemblies.remove(assembly.getName());
+            unregisterServices(assembly.getBundle());
+            for (ServiceUnitImpl su : assembly.getServiceUnitsList()) {
+                su.getComponentImpl().removeServiceUnit(su);
+            }
         }
     }
 
     protected void unregisterSharedLibrary(SharedLibrary library) {
         if (library != null) {
+            // TODO: shutdown all components
             sharedLibraries.remove(library.getName());
         }
     }
@@ -462,6 +513,79 @@
         return null;
     }
 
+    //===============================================================================
+    //
+    //   Pending artifacts support
+    //
+    //===============================================================================
+
+    protected void checkPendingInstallers() {
+        if (!pendingInstallers.isEmpty()) {
+            final List<AbstractInstaller> pending = new ArrayList<AbstractInstaller>(pendingInstallers);
+            pendingInstallers.clear();
+            // Synchronous call because if using a separate thread
+            // we run into deadlocks
+            for (AbstractInstaller installer : pending) {
+                try {
+                    installer.init();
+                    installer.install();
+                    installers.put(installer.getBundle(), installer);
+                } catch (PendingException e) {
+                    pendingInstallers.add(installer);
+                } catch (Exception e) {
+                    LOGGER.warn("Error installing JBI artifact", e);
+                }
+            }
+        }
+    }
+
+    private Set<ServiceAssemblyImpl> pendingAssemblies = new HashSet<ServiceAssemblyImpl>();
+
+    protected void checkPendingAssemblies() {
+        List<ServiceAssemblyImpl> sas = new ArrayList<ServiceAssemblyImpl>(pendingAssemblies);
+        pendingAssemblies.clear();
+        for (ServiceAssemblyImpl sa : sas) {
+            try {
+                sa.init();
+            } catch (JBIException e) {
+                pendingAssemblies.add(sa);
+            }
+        }
+    }
+
+    public void lifeCycleChanged(LifeCycleEvent event) throws JBIException {
+        if (event.getLifeCycleMBean() instanceof ComponentImpl) {
+            ComponentImpl comp = (ComponentImpl) event.getLifeCycleMBean();
+            switch (event.getType()) {
+                case Stopping:
+                    if (comp.getState() == AbstractLifecycleJbiArtifact.State.Started) {
+                        // Stop deployed SAs
+                        for (ServiceAssemblyImpl sa : comp.getServiceAssemblies()) {
+                            if (sa.getState() == ServiceAssemblyImpl.State.Started) {
+                                sa.stop(false);
+                                pendingAssemblies.add(sa);
+                            }
+                        }
+                    }
+                    break;
+                case ShuttingDown:
+                    if (comp.getState() == AbstractLifecycleJbiArtifact.State.Stopped) {
+                        // Shutdown deployed SAs
+                        for (ServiceAssemblyImpl sa : comp.getServiceAssemblies()) {
+                            if (sa.getState() == ServiceAssemblyImpl.State.Stopped) {
+                                sa.shutDown(false, event.isForced());
+                                pendingAssemblies.add(sa);
+                            }
+                        }
+                    }
+                    break;
+                case Started:
+                    checkPendingInstallers();
+                    checkPendingAssemblies();
+                    break;
+            }
+        }
+    }
 
     //===============================================================================
     //
@@ -484,40 +608,46 @@
         String name = (String) reference.getProperty(NAME);
         if (name != null && !components.containsKey(name)) {
             String type = (String) reference.getProperty(TYPE);
-            Preferences prefs = preferencesService.getUserPreferences(name);
+            Descriptor descriptor = new Descriptor();
             ComponentDesc componentDesc = new ComponentDesc();
             componentDesc.setIdentification(new Identification());
             componentDesc.getIdentification().setName(name);
             componentDesc.setType(type);
-            ComponentImpl wrapper = new ComponentImpl(reference.getBundle(), componentDesc, component, prefs, autoStart, checkPendingBundlesCallback, new SharedLibrary[0]);
-            wrappedComponents.put(name, true);
-            components.put(name, wrapper);
-            Dictionary<String, String> props = new Hashtable<String, String>();
-            props.put(NAME, name);
-            props.put(TYPE, componentDesc.getType());
-            registerService(reference.getBundle(), new String[] { Component.class.getName(), ComponentWrapper.class.getName() },
-                            wrapper, props);
+            descriptor.setComponent(componentDesc);
+
+            try {
+                ComponentInstaller installer = new ComponentInstaller(this, descriptor, null, autoStart);
+                installer.setBundle(reference.getBundle());
+                installer.setInnerComponent(component);
+                installer.init();
+                installer.install();
+                bundles.add(reference.getBundle());
+            } catch (Exception e) {
+                LOGGER.warn("Error registering deployed component", e);
+            }
+
+//            Preferences prefs = preferencesService.getUserPreferences(name);
+//            ComponentImpl wrapper = new ComponentImpl(reference.getBundle(), componentDesc, component, prefs, autoStart, new SharedLibrary[0]);
+//            wrapper.setListenerRegistry(listenerRegistry);
+//            wrappedComponents.put(name, true);
+//            components.put(name, wrapper);
+//            Dictionary<String, String> props = new Hashtable<String, String>();
+//            props.put(NAME, name);
+//            props.put(TYPE, componentDesc.getType());
+//            registerService(reference.getBundle(), new String[] { Component.class.getName(), ComponentWrapper.class.getName() },
+//                            wrapper, props);
         }
     }
 
     protected void unregisterDeployedComponent(ServiceReference reference, javax.jbi.component.Component component) {
         String name = (String) reference.getProperty(NAME);
-        if (name != null && Boolean.TRUE.equals(wrappedComponents.remove(name))) {
-            ComponentImpl ci = components.remove(name);
-            if (ci != null) {
-                try {
-                    ci.stop(false);
-                    ci.shutDown(false, false);
-                    pendingBundles.remove(reference.getBundle());
-                    unregisterServices(reference.getBundle());
-                } catch (JBIException e) {
-                    LOGGER.warn("Error when shutting down component", e);
-                }
-            }
+        if (name != null) {
+            wrappedComponents.remove(name);
+            unregisterComponent(getComponent(name));
         }
     }
 
-    public void registerDeployedServiceAssembly(ServiceReference serviceReference, DeployedAssembly assembly) {
+    public void registerDeployedServiceAssembly(ServiceReference reference, DeployedAssembly assembly) {
         try {
             assembly.deploy();
             ServiceAssemblyDesc desc = new ServiceAssemblyDesc();
@@ -533,13 +663,14 @@
                 ServiceUnitImpl su = createServiceUnit(suDesc, null, components.get(unit.getValue()));
                 sus.add(su);
             }
-            registerServiceAssembly(serviceReference.getBundle(), desc, sus);
+            registerServiceAssembly(reference.getBundle(), desc, sus);
+            bundles.add(reference.getBundle());
         } catch (Exception e) {
             LOGGER.error("Error registering deployed service assembly", e);
         }
     }
 
-    public void unregisterDeployedServiceAssembly(ServiceReference serviceReference, DeployedAssembly assembly) {
+    public void unregisterDeployedServiceAssembly(ServiceReference reference, DeployedAssembly assembly) {
         // TODO: what to do here ? we should not uninstall the bundle as it's managed externally
         // TODO: but we should maybe stop / shut it down
         ServiceAssemblyImpl sa = getServiceAssembly(assembly.getName());
@@ -559,18 +690,6 @@
         }
     }
 
-    protected void checkPendingBundles() {
-        if (!pendingBundles.isEmpty()) {
-            final List<Bundle> pending = new ArrayList<Bundle>(pendingBundles);
-            pendingBundles.clear();
-            // Synchronous call because if using a separate thread
-            // we run into deadlocks
-            for (Bundle bundle : pending) {
-                onBundleStarted(bundle);
-            }
-        }
-    }
-
     //===============================================================================
     //
     //   OSGi Services registrations
@@ -610,6 +729,7 @@
                 try {
                     reg.unregister();
                 } catch (IllegalStateException e) {
+                    // Ignore
                 }
             }
         }

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ServiceAssemblyInstaller.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ServiceAssemblyInstaller.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ServiceAssemblyInstaller.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/java/org/apache/servicemix/jbi/deployer/impl/ServiceAssemblyInstaller.java Mon Mar  2 10:24:40 2009
@@ -101,13 +101,13 @@
         // Shutdown SA
         stop(force);
         // Retrieve SA
-        ServiceAssembly assembly = deployer.getServiceAssembly(getName());
+        ServiceAssemblyImpl assembly = deployer.getServiceAssembly(getName());
         if (assembly == null && !force) {
             throw ManagementSupport.failure("undeployServiceAssembly", "ServiceAssembly '" + getName() + "' is not deployed.");
         }
         // Undeploy SUs
-        for (ServiceUnit su : assembly.getServiceUnits()) {
-            ((ServiceUnitImpl) su).undeploy();
+        for (ServiceUnitImpl su : assembly.getServiceUnitsList()) {
+            su.undeploy();
         }
         // Unregister assembly
         deployer.unregisterServiceAssembly(assembly);
@@ -137,9 +137,11 @@
             // Create directory for this SU
             File suRootDir = new File(saDir, sud.getIdentification().getName());
             // Unpack it
-            String zip = sud.getTarget().getArtifactsZip();
-            URL zipUrl = bundle.getResource(zip);
-            FileUtil.unpackArchive(zipUrl, suRootDir);
+            if (isModified) {
+                String zip = sud.getTarget().getArtifactsZip();
+                URL zipUrl = bundle.getResource(zip);
+                FileUtil.unpackArchive(zipUrl, suRootDir);
+            }
             // Find component
             String componentName = sud.getTarget().getComponentName();
             ComponentImpl component = deployer.getComponent(componentName);

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/main/resources/META-INF/spring/servicemix-jbi-deployer.xml
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/main/resources/META-INF/spring/servicemix-jbi-deployer.xml?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/main/resources/META-INF/spring/servicemix-jbi-deployer.xml (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/main/resources/META-INF/spring/servicemix-jbi-deployer.xml Mon Mar  2 10:24:40 2009
@@ -40,12 +40,10 @@
     </bean>
 
     <!-- Endpoint listener -->
-    <bean id="endpointListener" class="org.apache.servicemix.jbi.deployer.impl.AssemblyReferencesListener" />
+    <bean id="endpointListener" class="org.apache.servicemix.jbi.deployer.artifacts.AssemblyReferencesListener" />
 
     <!-- Deployment listener -->
-    <bean id="listener" class="org.apache.servicemix.jbi.deployer.handler.JBIDeploymentListener">
-        <property name="deployer" ref="deployer" />
-    </bean>
+    <bean id="listener" class="org.apache.servicemix.jbi.deployer.handler.JBIDeploymentListener" />
     
     <!-- JBI Handler -->
     <bean id="jbiHandler" class="org.apache.servicemix.jbi.deployer.handler.URLHandler" />

Modified: servicemix/smx4/nmr/trunk/jbi/deployer/src/test/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImplTest.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/deployer/src/test/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImplTest.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/deployer/src/test/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImplTest.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/deployer/src/test/java/org/apache/servicemix/jbi/deployer/artifacts/ServiceAssemblyImplTest.java Mon Mar  2 10:24:40 2009
@@ -26,12 +26,10 @@
 import javax.jbi.JBIException;
 
 import org.apache.servicemix.jbi.deployer.ServiceAssembly;
-import org.apache.servicemix.jbi.deployer.Component;
-import org.apache.servicemix.jbi.deployer.ServiceUnit;
 import org.apache.servicemix.jbi.deployer.artifacts.AbstractLifecycleJbiArtifact.State;
 import org.apache.servicemix.jbi.deployer.descriptor.DescriptorFactory;
 import org.apache.servicemix.jbi.deployer.descriptor.ServiceAssemblyDesc;
-import org.apache.servicemix.jbi.deployer.impl.AssemblyReferencesListener;
+import org.apache.servicemix.jbi.deployer.artifacts.AssemblyReferencesListener;
 import org.apache.servicemix.nmr.api.Wire;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.prefs.Preferences;
@@ -48,7 +46,7 @@
         expect(prefs.get("state", State.Shutdown.name())).andReturn(State.Shutdown.name()).anyTimes();
         replay(prefs);
 
-        ComponentImpl comp = new ComponentImpl(null, null, null, prefs, false, null, null);
+        ComponentImpl comp = new ComponentImpl(null, null, null, prefs, false, null);
         comp.state = State.Shutdown;
         ServiceUnitImpl su = new ServiceUnitImpl(descriptor.getServiceUnits()[0], null, comp);
         ServiceAssemblyImpl sa = new ServiceAssemblyImpl(null, descriptor, Collections.singletonList(su), prefs, new AssemblyReferencesListener(), false);

Modified: servicemix/smx4/nmr/trunk/jbi/itests/src/test/java/org/apache/servicemix/jbi/itests/IntegrationTest.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/itests/src/test/java/org/apache/servicemix/jbi/itests/IntegrationTest.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/itests/src/test/java/org/apache/servicemix/jbi/itests/IntegrationTest.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/itests/src/test/java/org/apache/servicemix/jbi/itests/IntegrationTest.java Mon Mar  2 10:24:40 2009
@@ -27,6 +27,7 @@
 import java.net.HttpURLConnection;
 
 import javax.jbi.component.Component;
+import javax.jbi.management.LifeCycleMBean;
 
 import org.apache.servicemix.nmr.api.NMR;
 import org.apache.servicemix.kernel.testing.support.AbstractIntegrationTest;
@@ -168,6 +169,39 @@
         //sa.shutDown();
     }
 
+    public void testJbiLifecycle() throws Exception {
+        Bundle smxShared = installJbiBundle("org.apache.servicemix", "servicemix-shared", "installer", "zip");
+        Bundle smxJsr181 = installJbiBundle("org.apache.servicemix", "servicemix-jsr181", "installer", "zip");
+        Bundle smxHttp = installJbiBundle("org.apache.servicemix", "servicemix-http", "installer", "zip");
+
+        Bundle saBundle = installJbiBundle("org.apache.servicemix.samples.wsdl-first", "wsdl-first-sa", null, "zip");
+        System.out.println("Waiting for JBI Service Assembly");
+        ServiceAssembly sa = getOsgiService(ServiceAssembly.class);
+        assertNotNull(sa);
+        assertEquals(LifeCycleMBean.STARTED, sa.getCurrentState());
+
+        saBundle.stop();
+
+        saBundle.start();
+        sa = getOsgiService(ServiceAssembly.class);
+        assertNotNull(sa);
+        assertEquals(LifeCycleMBean.STARTED, sa.getCurrentState());
+
+        smxHttp.stop();
+        try {
+            getOsgiService(ServiceAssembly.class, 1);
+            fail("ServiceAssembly OSGi service should have been unregistered");
+        } catch (RuntimeException e) {
+            // Ignore
+        }
+
+        smxHttp.start();
+        sa = getOsgiService(ServiceAssembly.class);
+        assertNotNull(sa);
+        assertEquals(LifeCycleMBean.STARTED, sa.getCurrentState());
+
+    }
+
     protected Bundle installJbiBundle(String groupId, String artifactId, String classifier, String type) throws BundleException {
         String version = getBundleVersion(groupId, artifactId);
         File loc = localMavenBundle(groupId, artifactId, version, classifier, type);

Modified: servicemix/smx4/nmr/trunk/jbi/runtime/src/main/java/org/apache/servicemix/jbi/runtime/impl/AbstractComponentContext.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/jbi/runtime/src/main/java/org/apache/servicemix/jbi/runtime/impl/AbstractComponentContext.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/jbi/runtime/src/main/java/org/apache/servicemix/jbi/runtime/impl/AbstractComponentContext.java (original)
+++ servicemix/smx4/nmr/trunk/jbi/runtime/src/main/java/org/apache/servicemix/jbi/runtime/impl/AbstractComponentContext.java Mon Mar  2 10:24:40 2009
@@ -63,8 +63,17 @@
     protected DeliveryChannel dc;
     protected ComponentRegistryImpl componentRegistry;
 
+    protected MBeanServer mbeanServer;
+    protected InitialContext initialContext;
+    protected Object transactionManager;
+
     public AbstractComponentContext(ComponentRegistryImpl componentRegistry) {
         this.componentRegistry = componentRegistry;
+        if (componentRegistry.getEnvironment() != null) {
+            this.mbeanServer = componentRegistry.getEnvironment().getMBeanServer();
+            this.initialContext = componentRegistry.getEnvironment().getNamingContext();
+            this.transactionManager = componentRegistry.getEnvironment().getTransactionManager();
+        }
     }
 
     public NMR getNmr() {
@@ -228,24 +237,15 @@
     }
 
     public MBeanServer getMBeanServer() {
-        if (componentRegistry.getEnvironment() != null) {
-            return componentRegistry.getEnvironment().getMBeanServer();
-        }
-        return null;
+        return mbeanServer;
     }
 
     public InitialContext getNamingContext() {
-        if (this.componentRegistry.getEnvironment() != null) {
-            return componentRegistry.getEnvironment().getNamingContext();
-        }
-        return null;
+        return initialContext;
     }
 
     public Object getTransactionManager() {
-        if (this.componentRegistry.getEnvironment() != null) {
-            return this.componentRegistry.getEnvironment().getTransactionManager();
-        }
-        return null;
+        return transactionManager;
     }
 
     public ObjectName createCustomComponentMBeanName(String customName) {

Modified: servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/event/Listener.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/event/Listener.java?rev=749261&r1=749260&r2=749261&view=diff
==============================================================================
--- servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/event/Listener.java (original)
+++ servicemix/smx4/nmr/trunk/nmr/api/src/main/java/org/apache/servicemix/nmr/api/event/Listener.java Mon Mar  2 10:24:40 2009
@@ -16,6 +16,8 @@
  */
 package org.apache.servicemix.nmr.api.event;
 
+import java.util.EventListener;
+
 /**
  *
  * Marker interface for all listeners that can be registered.
@@ -23,5 +25,5 @@
  * @version $Revision: $
  * @since 4.0
  */
-public interface Listener {
+public interface Listener extends EventListener {
 }