You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by gn...@apache.org on 2010/04/09 11:35:06 UTC

svn commit: r932315 - in /incubator/aries/trunk/subsystem: subsystem-api/src/main/java/org/apache/aries/subsystem/ subsystem-api/src/main/java/org/apache/aries/subsystem/spi/ subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ subsys...

Author: gnodet
Date: Fri Apr  9 09:35:05 2010
New Revision: 932315

URL: http://svn.apache.org/viewvc?rev=932315&view=rev
Log:
[subsystems] Various API changes:
  - remove the Subsystem#getScope() method and add a SubsystemAdmin#getSubsystem(String symbolicName, Version version) method
  - add a map of attributes on the Resource to be able to customize converters and processors
  - remove the SubsystemAdmin#uninstallForced() method
  - define a few attributes for resources of type bundle

Modified:
    incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/Subsystem.java
    incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemAdmin.java
    incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemConstants.java
    incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/spi/Resource.java
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceProcessor.java
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/NoOpResolver.java
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceImpl.java
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java
    incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java
    incubator/aries/trunk/subsystem/subsystem-install/src/main/java/org/apache/aries/subsystem/install/internal/SubsystemInstaller.java
    incubator/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemAdminTest.java

Modified: incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/Subsystem.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/Subsystem.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/Subsystem.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/Subsystem.java Fri Apr  9 09:35:05 2010
@@ -83,18 +83,6 @@ public interface Subsystem {
     Version getVersion();
 
     /**
-     * Retrieve the scope of the subsystem.
-     * The scope is computed as
-     *  <code>getSymbolicName() + "_" + getVersion().toString()</code>.
-     * It is guaranteed to be unique in the parent composite bundle
-     * or framework, but it not guaranteed to be unique in the whole
-     * OSGi framework, nor immutable as the value can change if
-     * the subsystem is updated. 
-     * @return
-     */
-    String getScope();
-
-    /**
      * Return the subsystem headers
      *
      * @return

Modified: incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemAdmin.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemAdmin.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemAdmin.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemAdmin.java Fri Apr  9 09:35:05 2010
@@ -17,6 +17,8 @@ import java.io.InputStream;
 import java.util.Collection;
 import java.util.Map;
 
+import org.osgi.framework.Version;
+
 /**
  * Subsystems administration interface.
  *
@@ -33,18 +35,30 @@ import java.util.Map;
 public interface SubsystemAdmin {
 
     /**
-     * Retrieve all subsystems managed by this service
+     * Retrieve all subsystems managed by this service.
+     * This includes all the top-level subsystems installed in the composite
+     * which this service has been retrieved from.
+     *
+     * @return
+     */
+    Collection<Subsystem> getSubsystems();
+
+    /**
+     * Retrieve a subsystem given its id.
+     *
+     * @param id
      * @return
      */
-    Map<Long, Subsystem> getSubsystems();
+    Subsystem getSubsystem(long id);
 
     /**
-     * Retrieve a subsystem given its scope.
+     * Retrieve a subsystem given its symbolic name and id
      *
-     * @param scope
+     * @param symbolicName
+     * @param version
      * @return
      */
-    Subsystem getSubsystem(String scope);
+    Subsystem getSubsystem(String symbolicName, Version version);
 
     /**
      * Install a new subsystem from the specified location identifier.
@@ -99,14 +113,6 @@ public interface SubsystemAdmin {
     void uninstall(Subsystem subsystem) throws SubsystemException;
 
     /**
-     * Force the uninstallation of a subsystem.
-     * Any errors will be ignored.
-     *
-     * @param subsystem
-     */
-    void uninstallForced(Subsystem subsystem);
-
-    /**
      * Abort the current operation.
      * The installing thread must throw a SubsystemException if the operation
      * has actually been canceled and rolled back before terminating.

Modified: incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemConstants.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemConstants.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemConstants.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/SubsystemConstants.java Fri Apr  9 09:35:05 2010
@@ -48,7 +48,6 @@ public class SubsystemConstants {
      */
     public static final String SUBSYSTEM_DESCRIPTION         = "Subsystem-Description";
 
-
     /**
      * Name of the resource to use for localized headers
      */
@@ -100,6 +99,21 @@ public class SubsystemConstants {
      */
     public static final String RESOURCE_LOCATION_ATTRIBUTE   = "location";
 
+    /**
+     * Attribute to indicate a bundle needs to be started, defaults to <code>true</code>
+     */
+    public static final String RESOURCE_START_ATTRIBUTE      = "start";
+
+    /**
+     * Attribute to indicate a bundle needs to be forced updated, even if the version is the same, defaults to <code>false</code>
+     */
+    public static final String RESOURCE_UPDATE_ATTRIBUTE     = "update";
+
+    /**
+     * Attribute to indicate the start level that must be associated to a constituent bundle or subsystem 
+     */
+    public static final String RESOURCE_START_LEVEL_ATTRIBUTE      = "start-level";
+
     /*
     String APPLICATION_SYMBOLICNAME = "Application-SymbolicName";
     String APPLICATION_VERSION = "Application-Version";

Modified: incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/spi/Resource.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/spi/Resource.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/spi/Resource.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-api/src/main/java/org/apache/aries/subsystem/spi/Resource.java Fri Apr  9 09:35:05 2010
@@ -15,6 +15,7 @@ package org.apache.aries.subsystem.spi;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Map;
 
 import org.osgi.framework.Version;
 
@@ -55,6 +56,14 @@ public interface Resource {
     String getLocation();
 
     /**
+     * Attributes associated to this resource.  Those may contain informations
+     * for {@link ResourceConverter}s or {@link ResourceProcessor}s.
+     *  
+     * @return
+     */
+    Map<String, String> getAttributes();
+
+    /**
      * Open the resource for reading.
      *
      * @return

Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceProcessor.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceProcessor.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceProcessor.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BundleResourceProcessor.java Fri Apr  9 09:35:05 2010
@@ -16,6 +16,7 @@ package org.apache.aries.subsystem.core.
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.aries.subsystem.SubsystemConstants;
 import org.apache.aries.subsystem.SubsystemException;
 import org.apache.aries.subsystem.spi.Resource;
 import org.apache.aries.subsystem.spi.ResourceProcessor;
@@ -39,7 +40,14 @@ public class BundleResourceProcessor imp
 
         public void process(Resource resource) throws SubsystemException {
             try {
+                // TODO: found bundle and update or do nothing if needed
                 Bundle bundle = context.installBundle(resource.getLocation(), resource.open());
+
+                if ("true".equals(resource.getAttributes().get(SubsystemConstants.RESOURCE_START_ATTRIBUTE))) {
+                    // This will only mark the bundle as persistently started as the composite is supposed
+                    // to be stoped
+                    bundle.start();
+                }
                 installed.add(bundle);
             } catch (SubsystemException e) {
                 throw e;
@@ -49,7 +57,7 @@ public class BundleResourceProcessor imp
         }
 
         public void dropped(Resource resource) throws SubsystemException {
-            //To change body of implemented methods use File | Settings | File Templates.
+            // TODO: uninstall bundle
         }
 
         public void prepare() throws SubsystemException {

Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/NoOpResolver.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/NoOpResolver.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/NoOpResolver.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/NoOpResolver.java Fri Apr  9 09:35:05 2010
@@ -14,13 +14,17 @@
 package org.apache.aries.subsystem.core.internal;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.aries.subsystem.SubsystemConstants;
 import org.apache.aries.subsystem.SubsystemException;
 import org.apache.aries.subsystem.spi.Resource;
 import org.apache.aries.subsystem.spi.ResourceResolver;
+import org.apache.felix.utils.manifest.Attribute;
 import org.apache.felix.utils.manifest.Clause;
+import org.apache.felix.utils.manifest.Directive;
 import org.apache.felix.utils.manifest.Parser;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
@@ -40,16 +44,27 @@ public class NoOpResolver implements Res
         if (loc == null) {
             throw new SubsystemException("Mandatory location missing on resource: " + resource);
         }
+        Map<String,String> attributes = new HashMap<String,String>();
+        for (Attribute a : clauses[0].getAttributes()) {
+            String name = a.getName();
+            if (!Constants.VERSION_ATTRIBUTE.equals(name)
+                    && !SubsystemConstants.RESOURCE_TYPE_ATTRIBUTE.equals(name)
+                    && !SubsystemConstants.RESOURCE_LOCATION_ATTRIBUTE.equals(name))
+            {
+                attributes.put(name, a.getValue());
+            }
+        }
         return new ResourceImpl(
                 bsn,
                 ver != null ? new Version(ver) : Version.emptyVersion,
                 typ != null ? typ : SubsystemConstants.RESOURCE_TYPE_BUNDLE,
-                loc
+                loc,
+                attributes
         );
     }
 
     public List<Resource> resolve(List<Resource> subsystemContent, List<Resource> subsystemResources) throws SubsystemException {
-        return Collections.emptyList();
+        return subsystemResources;
     }
 
 }

Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceImpl.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceImpl.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceImpl.java Fri Apr  9 09:35:05 2010
@@ -16,6 +16,7 @@ package org.apache.aries.subsystem.core.
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.Map;
 
 import org.apache.aries.subsystem.spi.Resource;
 import org.osgi.framework.Version;
@@ -26,12 +27,14 @@ public class ResourceImpl implements Res
     private final Version version;
     private final String type;
     private final String location;
+    private final Map<String,String> attributes;
 
-    public ResourceImpl(String symbolicName, Version version, String type, String location) {
+    public ResourceImpl(String symbolicName, Version version, String type, String location, Map<String,String> attributes) {
         this.symbolicName = symbolicName;
         this.version = version;
         this.type = type;
         this.location = location;
+        this.attributes = attributes;
     }
 
     public String getSymbolicName() {
@@ -50,6 +53,10 @@ public class ResourceImpl implements Res
         return location;
     }
 
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
     public InputStream open() throws IOException {
         return new URL(location).openStream();
     }

Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemAdminImpl.java Fri Apr  9 09:35:05 2010
@@ -15,15 +15,17 @@ package org.apache.aries.subsystem.core.
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.Semaphore;
 
 import org.apache.aries.subsystem.Subsystem;
 import org.apache.aries.subsystem.SubsystemAdmin;
 import org.apache.aries.subsystem.SubsystemConstants;
 import org.apache.aries.subsystem.SubsystemException;
+import org.apache.aries.subsystem.SubsystemListener;
 import org.apache.aries.subsystem.spi.Resource;
 import org.apache.aries.subsystem.spi.ResourceResolver;
 import org.apache.felix.utils.manifest.Clause;
@@ -31,7 +33,6 @@ import org.apache.felix.utils.manifest.P
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
 import org.osgi.framework.SynchronousBundleListener;
 import org.osgi.framework.Version;
@@ -45,12 +46,12 @@ public class SubsystemAdminImpl implemen
     private static final Logger LOGGER = LoggerFactory.getLogger(SubsystemAdminImpl.class);
     private static final Version SUBSYSTEM_MANIFEST_VERSION = new Version("1.0");
 
-    final Semaphore lock = new Semaphore(1);
     final BundleContext context;
     final Map<Long, Subsystem> subsystems = new HashMap<Long, Subsystem>();
     final ServiceTracker compositeAdminTracker;
     final ServiceTracker resourceResolverTracker;
     final SubsystemEventDispatcher eventDispatcher;
+    final ServiceTracker listenersTracker;
 
     public SubsystemAdminImpl(BundleContext context, SubsystemEventDispatcher eventDispatcher) {
         this.context = context;
@@ -59,6 +60,8 @@ public class SubsystemAdminImpl implemen
         this.compositeAdminTracker.open();
         this.resourceResolverTracker = new ServiceTracker(context, ResourceResolver.class.getName(), null);
         this.resourceResolverTracker.open();
+        this.listenersTracker = new ServiceTracker(context, SubsystemListener.class.getName(), null);
+        this.listenersTracker.open();
         // Track subsystems
         synchronized (subsystems) {
             this.context.addBundleListener(new SynchronousBundleListener() {
@@ -123,10 +126,10 @@ public class SubsystemAdminImpl implemen
         return null;
     }
 
-    public Subsystem getSubsystem(String scope) {
+    public Subsystem getSubsystem(long id) {
         synchronized (subsystems) {
             for (Subsystem s : subsystems.values()) {
-                if (s.getScope().equals(scope)) {
+                if (s.getSubsystemId() == id) {
                     return s;
                 }
             }
@@ -134,9 +137,20 @@ public class SubsystemAdminImpl implemen
         }
     }
 
-    public Map<Long, Subsystem> getSubsystems() {
+    public Subsystem getSubsystem(String symbolicName, Version version) {
         synchronized (subsystems) {
-            return Collections.unmodifiableMap(subsystems);
+            for (Subsystem s : subsystems.values()) {
+                if (s.getSymbolicName().equals(symbolicName) && s.getVersion().equals(version)) {
+                    return s;
+                }
+            }
+            return null;
+        }
+    }
+
+    public Collection<Subsystem> getSubsystems() {
+        synchronized (subsystems) {
+            return Collections.unmodifiableCollection(new ArrayList(subsystems.values()));
         }
     }
 
@@ -157,7 +171,7 @@ public class SubsystemAdminImpl implemen
             return toReturn;
         }
         
-        Resource subsystemResource = new ResourceImpl(null, null, SubsystemConstants.RESOURCE_TYPE_SUBSYSTEM, url) {
+        Resource subsystemResource = new ResourceImpl(null, null, SubsystemConstants.RESOURCE_TYPE_SUBSYSTEM, url, Collections.<String, String>emptyMap()) {
             @Override
             public InputStream open() throws IOException {
                 if (is != null) {
@@ -199,52 +213,56 @@ public class SubsystemAdminImpl implemen
         update(subsystem, null);
     }
 
-    public synchronized void update(Subsystem subsystem, InputStream content) {
-        // TODO: update
-    }
-
-    public synchronized void uninstall(Subsystem ss) {
-        if (!(ss instanceof SubsystemImpl)) {
-            throw new IllegalArgumentException("The given subsystem is not managed by the SubsystemAdmin instance");
-        }
-        if (ss.getState().equals(Subsystem.State.UNINSTALLED)) {
-            return;
-        }
-        SubsystemImpl subsystem = (SubsystemImpl) ss;
+    public void update(final Subsystem subsystem, final InputStream is) {
+        Resource subsystemResource = new ResourceImpl(subsystem.getSymbolicName(), subsystem.getVersion(), SubsystemConstants.RESOURCE_TYPE_SUBSYSTEM, subsystem.getLocation(), Collections.<String, String>emptyMap()) {
+            @Override
+            public InputStream open() throws IOException {
+                if (is != null) {
+                    return is;
+                }
+                // TODO: check update location first
+                return super.open();
+            }
+        };
+        SubsystemResourceProcessor processor = new SubsystemResourceProcessor();
+        SubsystemResourceProcessor.SubsystemSession session = processor.createSession(context);
+        boolean success = false;
         try {
-            subsystem.composite.uninstall();
-        } catch (BundleException e) {
-            // TODO: Rollback
-            throw new SubsystemException("Error while uninstalling the subsystem", e);
+            session.process(subsystemResource);
+            session.prepare();
+            session.commit();
+            success = true;
+        } finally {
+            if (!success) {
+                session.rollback();
+            }
         }
     }
 
-    public void uninstallForced(Subsystem ss) {
-        if (!(ss instanceof SubsystemImpl)) {
-            throw new IllegalArgumentException("The given subsystem is not managed by the SubsystemAdmin instance");
-        }
-        if (ss.getState().equals(Subsystem.State.UNINSTALLED)) {
-            return;
-        }
-        SubsystemImpl subsystem = (SubsystemImpl) ss;
+    public void uninstall(Subsystem subsystem) {
+        Resource subsystemResource = new ResourceImpl(subsystem.getSymbolicName(), subsystem.getVersion(), SubsystemConstants.RESOURCE_TYPE_SUBSYSTEM, subsystem.getLocation(), Collections.<String, String>emptyMap());
+        SubsystemResourceProcessor processor = new SubsystemResourceProcessor();
+        SubsystemResourceProcessor.SubsystemSession session = processor.createSession(context);
+        boolean success = false;
         try {
-            subsystem.composite.uninstall();
-        } catch (BundleException e) {
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug("Uninstalling subsystem scope {} is not successful.  Removing the subsystem from  subsystems map being tracked", ss.getScope());
-            }
+            session.dropped(subsystemResource);
+            session.prepare();
+            session.commit();
+            success = true;
         } finally {
-            this.subsystems.remove(subsystem.id);
+            if (!success) {
+                session.rollback();
+            }
         }
     }
 
-    public boolean cancel() {
+        public boolean cancel() {
         // TODO
         return false;
     }
 
     private Subsystem getInstalledSubsytem(String url) {
-        for (Subsystem ss : getSubsystems().values()) {
+        for (Subsystem ss : getSubsystems()) {
             if (url.equals(ss.getLocation())) {
                 return ss;
             }

Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEventDispatcher.java Fri Apr  9 09:35:05 2010
@@ -129,7 +129,8 @@ public class SubsystemEventDispatcher im
 
     @SuppressWarnings( { "ThrowableResultOfMethodCallIgnored" })
     private static String toString(SubsystemEvent event) {
-        return "SubsystemEvent[subsystem=" + event.getSubsystem().getScope()
+        return "SubsystemEvent[subsystem=" + event.getSubsystem().getSymbolicName() + "/"
+                + event.getSubsystem().getVersion()
                 + " type=" + event.getType() + "]";
     }
 

Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemImpl.java Fri Apr  9 09:35:05 2010
@@ -13,10 +13,7 @@
  */
 package org.apache.aries.subsystem.core.internal;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import org.apache.aries.subsystem.Subsystem;
 import org.apache.aries.subsystem.SubsystemException;
@@ -88,17 +85,13 @@ public class SubsystemImpl implements Su
         return composite.getVersion();
     }
 
-    public String getScope() {
-        return getSymbolicName() + "_" + getVersion().toString();
-    }
-
     public Map<String, String> getHeaders() {
         return getHeaders(null);
     }
 
     public Map<String, String> getHeaders(String locale) {
-        // TODO: retrieve headers
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        final Dictionary dict = composite.getHeaders(locale);
+        return new DictionaryAsMap(dict);
     }
 
     public Collection<Bundle> getConstituents() {
@@ -111,4 +104,41 @@ public class SubsystemImpl implements Su
         }
         return list;
     }
+
+    private static class DictionaryAsMap extends AbstractMap<String,String> {
+        private Dictionary dict;
+
+        private DictionaryAsMap(Dictionary dict) {
+            this.dict = dict;
+        }
+
+        @Override
+        public Set<Entry<String, String>> entrySet() {
+            return new AbstractSet<Entry<String, String>>() {
+                @Override
+                public Iterator<Entry<String, String>> iterator() {
+                    final Enumeration e = dict.keys();
+                    return new Iterator<Entry<String,String>>() {
+                        public boolean hasNext() {
+                            return e.hasMoreElements();
+                        }
+
+                        public Entry<String, String> next() {
+                            Object key = e.nextElement();
+                            Object val = dict.get(key);
+                            return new SimpleImmutableEntry<String,String>(key != null ? key.toString() : null, val != null ? val.toString() : null);
+                        }
+
+                        public void remove() {
+                            throw new UnsupportedOperationException();
+                        }
+                    };
+                }
+                @Override
+                public int size() {
+                    return dict.size();
+                }
+            };
+        }
+    }
 }
\ No newline at end of file

Modified: incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceProcessor.java Fri Apr  9 09:35:05 2010
@@ -34,6 +34,7 @@ import org.apache.aries.subsystem.spi.Re
 import org.apache.aries.subsystem.spi.ResourceResolver;
 import org.apache.felix.utils.manifest.Clause;
 import org.apache.felix.utils.manifest.Parser;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
@@ -64,7 +65,9 @@ public class SubsystemResourceProcessor 
 
         private final BundleContext context;
         private final Map<Resource, CompositeBundle> installed = new HashMap<Resource, CompositeBundle>();
+        private final Map<Resource, CompositeBundle> updated = new HashMap<Resource, CompositeBundle>();
         private final Map<Resource, CompositeBundle> removed = new HashMap<Resource, CompositeBundle>();
+        private final List<CompositeBundle> stopped = new ArrayList<CompositeBundle>();
         private final Map<String, ServiceTracker> trackers = new HashMap<String, ServiceTracker>();
         private final Map<BundleContext, Map<String, Session>> sessions = new HashMap<BundleContext, Map<String, Session>>();
 
@@ -74,8 +77,6 @@ public class SubsystemResourceProcessor 
         }
 
         public void process(Resource res) throws SubsystemException {
-            CompositeBundle composite = null;
-            boolean success = false;
             try {
 
                 CompositeAdmin admin = getService(CompositeAdmin.class);
@@ -112,6 +113,8 @@ public class SubsystemResourceProcessor 
                     content.add(r);
                 }
 
+                List<Resource> previous = new ArrayList<Resource>();
+
                 // TODO: convert resources before calling the resolver?
 
                 List<Resource> additional = resolver.resolve(content, resource);
@@ -158,43 +161,85 @@ public class SubsystemResourceProcessor 
                 // TODO: compute other composite manifest entries
                 // TODO: compute list of bundles
 
-                composite = admin.installCompositeBundle(
-                                            res.getLocation(),
-                                            headers,
-                                            Collections.<String, String>emptyMap());
-                installed.put(res, composite);
+                // Check existing bundles
+                CompositeBundle composite = findSubsystemComposite(res);
+                if (composite == null) {
+                    composite = admin.installCompositeBundle(
+                                                res.getLocation(),
+                                                headers,
+                                                Collections.<String, String>emptyMap());
+                    installed.put(res, composite);
+                } else {
+                    String previousContentHeader = (String) composite.getHeaders().get(SUBSYSTEM_CONTENT);
+                    Clause[] previousContentClauses = Parser.parseHeader(previousContentHeader);
+                    for (Clause c : previousContentClauses) {
+                        Resource r = resolver.find(c.toString());
+                        previous.add(r);
+                    }
+                    if (composite.getState() == Bundle.ACTIVE) {
+                        composite.stop();
+                        stopped.add(composite);
+                    }
+                    composite.update(headers);
+                    updated.put(res, composite);
+                }
                 composite.getSystemBundleContext().registerService(SubsystemAdmin.class.getName(), new Activator.SubsystemAdminFactory(), null);
 
+                for (Resource r : previous) {
+                    boolean stillHere = false;
+                    for (Resource r2 : content) {
+                        if (r2.getSymbolicName().equals(r.getSymbolicName()) && r2.getVersion().equals(r.getVersion())) {
+                            stillHere = true;
+                            break;
+                        }
+                    }
+                    if (!stillHere) {
+                        getSession(composite.getSystemBundleContext(), r.getType()).dropped(r);
+                    }
+                }
                 for (Resource r : additional) {
                     getSession(context, r.getType()).process(r);
                 }
                 for (Resource r : content) {
                     getSession(composite.getSystemBundleContext(), r.getType()).process(r);
                 }
-
-                success = true;
-
             } catch (SubsystemException e) {
                 throw e;
             } catch (Exception e) {
                 throw new SubsystemException("Unable to install subsystem", e);
-            } finally {
-                if (!success && composite != null) {
-                    try {
-                        composite.uninstall();
-                    } catch (Exception e) {
-                        // TODO: log error
-                    }
-                }
             }
         }
 
-        public void dropped(Resource resource) throws SubsystemException {
-            // TODO: find corresponding subsystem
+        public void dropped(Resource res) throws SubsystemException {
+            CompositeBundle composite = findSubsystemComposite(res);
+            if (composite == null) {
+                throw new SubsystemException("Unable to find matching subsystem to uninstall");
+            }
+            try {
+                // TODO: iterate thorugh all resources and ask for a removal on each one
+                composite.uninstall();
+                removed.put(res, composite);
+            } catch (BundleException e) {
+                throw new SubsystemException("Unable to uninstall subsystem", e);
+            }
         }
 
-        protected Subsystem findSubsystem(Resource resource) {
-            // TODO
+        protected CompositeBundle findSubsystemComposite(Resource resource) {
+            for (Bundle bundle : context.getBundles()) {
+                if (resource.getLocation().equals(bundle.getLocation())) {
+                    if (bundle instanceof CompositeBundle) {
+                        CompositeBundle composite = (CompositeBundle) bundle;
+                        String bsn = (String) bundle.getHeaders().get(Constants.BUNDLE_SYMBOLICNAME);
+                        Clause[] bsnClauses = Parser.parseHeader(bsn);
+                        if ("true".equals(bsnClauses[0].getDirective(SubsystemConstants.SUBSYSTEM_DIRECTIVE))) {
+                            return composite;
+                        } else {
+                            throw new SubsystemException("A bundle with the same location already exists!");
+                        }
+
+                    }
+                }
+            }
             return null;
         }
 
@@ -204,6 +249,13 @@ public class SubsystemResourceProcessor 
                     s.prepare();
                 }
             }
+            for (CompositeBundle composite : stopped) {
+                try {
+                    composite.start();
+                } catch (BundleException e) {
+                    throw new SubsystemException(e);
+                }
+            }
         }
 
         public void commit() {
@@ -213,6 +265,8 @@ public class SubsystemResourceProcessor 
                 }
             }
             installed.clear();
+            updated.clear();
+            removed.clear();
             closeTrackers();
         }
 
@@ -230,6 +284,7 @@ public class SubsystemResourceProcessor 
                 }
             }
             installed.clear();
+            // TODO: Handle updated and uninstalled subsystems
             closeTrackers();
         }
 

Modified: incubator/aries/trunk/subsystem/subsystem-install/src/main/java/org/apache/aries/subsystem/install/internal/SubsystemInstaller.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-install/src/main/java/org/apache/aries/subsystem/install/internal/SubsystemInstaller.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-install/src/main/java/org/apache/aries/subsystem/install/internal/SubsystemInstaller.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-install/src/main/java/org/apache/aries/subsystem/install/internal/SubsystemInstaller.java Fri Apr  9 09:35:05 2010
@@ -15,10 +15,12 @@ package org.apache.aries.subsystem.insta
 
 import java.io.File;
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.util.jar.Attributes;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 
+import org.apache.aries.subsystem.Subsystem;
 import org.apache.aries.subsystem.SubsystemAdmin;
 import org.apache.aries.subsystem.SubsystemConstants;
 import org.apache.felix.fileinstall.ArtifactInstaller;
@@ -36,19 +38,32 @@ public class SubsystemInstaller implemen
     }
 
     public void install(File file) throws Exception {
-        if (file.isDirectory()) {
-            subsystemAdmin.install("jardir:" + file.getPath());
-        } else {
-            subsystemAdmin.install(file.toURI().toURL().toExternalForm());
-        }
+        subsystemAdmin.install(getLocation(file));
     }
 
     public void update(File file) throws Exception {
-        //To change body of implemented methods use File | Settings | File Templates.
+        subsystemAdmin.update(getSubsystem(getLocation(file)));
     }
 
     public void uninstall(File file) throws Exception {
-        //To change body of implemented methods use File | Settings | File Templates.
+        subsystemAdmin.uninstall(getSubsystem(getLocation(file)));
+    }
+
+    protected Subsystem getSubsystem(String location) {
+        for (Subsystem s : subsystemAdmin.getSubsystems()) {
+            if (s.getLocation().equals(location)) {
+                return s;
+            }
+        }
+        return null;
+    }
+
+    protected String getLocation(File file) throws MalformedURLException {
+        if (file.isDirectory()) {
+            return "jardir:" + file.getPath();
+        } else {
+            return file.toURI().toURL().toExternalForm();
+        }
     }
 
     public boolean canHandle(File artifact)

Modified: incubator/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemAdminTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemAdminTest.java?rev=932315&r1=932314&r2=932315&view=diff
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemAdminTest.java (original)
+++ incubator/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemAdminTest.java Fri Apr  9 09:35:05 2010
@@ -95,7 +95,7 @@ public class SubsystemAdminTest extends 
         System.out.println("able to get subsytem admin service");
         
         File f = new File("test.eba");
-        Subsystem subsystem = sa.install(f.toURL().toExternalForm());
+        Subsystem subsystem = sa.install(f.toURI().toURL().toExternalForm());
         assertNotNull("subsystem should not be null", subsystem);
         
         assertTrue("subsystem should have a unique id", subsystem.getSubsystemId() > 0);
@@ -125,7 +125,6 @@ public class SubsystemAdminTest extends 
             // Bundles
             mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.api"),
             mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.core"),
-            mavenBundle("org.osgi", "org.osgi.compendium"),
             mavenBundle("org.apache.aries.testsupport", "org.apache.aries.testsupport.unit"),
             //org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"),