[jboss-osgi-commits] JBoss-OSGI SVN: r97112 - in projects/jboss-osgi/trunk/reactor/framework: src/etc/osgitck and 2 other directories.

jboss-osgi-commits at lists.jboss.org jboss-osgi-commits at lists.jboss.org
Fri Nov 27 10:38:15 EST 2009


Author: alesj
Date: 2009-11-27 10:38:13 -0500 (Fri, 27 Nov 2009)
New Revision: 97112

Added:
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/ControllerContextHandle.java
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/GenericServiceReferenceWrapper.java
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceState.java
Removed:
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceState.java
Modified:
   projects/jboss-osgi/trunk/reactor/framework/pom.xml
   projects/jboss-osgi/trunk/reactor/framework/src/etc/osgitck/jboss-osgi-bootstrap.xml
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/AbstractBundleState.java
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/ContextRegistryAction.java
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleManager.java
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleState.java
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceAction.java
   projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceReferenceWrapper.java
   projects/jboss-osgi/trunk/reactor/framework/src/test/resources/bootstrap/jboss-osgi-bootstrap.xml
Log:
[JBOSGI-141]; abstract osgi service usage to plain MC core.

Modified: projects/jboss-osgi/trunk/reactor/framework/pom.xml
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/pom.xml	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/pom.xml	2009-11-27 15:38:13 UTC (rev 97112)
@@ -42,7 +42,7 @@
     <version.drools>5.0.1</version.drools>
     <version.jboss.aop>2.1.0.CR3</version.jboss.aop>
     <version.jboss.classloading>2.0.8.GA</version.jboss.classloading>
-    <version.jboss.deployers>2.0.9.GA</version.jboss.deployers>
+    <version.jboss.deployers>2.2.0-SNAPSHOT</version.jboss.deployers>
     <version.jboss.kernel>2.2.0-SNAPSHOT</version.jboss.kernel>
     <version.jboss.osgi.apache.xerces>2.9.1.SP2</version.jboss.osgi.apache.xerces>
     <version.jboss.osgi.common>1.0.3</version.jboss.osgi.common>

Modified: projects/jboss-osgi/trunk/reactor/framework/src/etc/osgitck/jboss-osgi-bootstrap.xml
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/etc/osgitck/jboss-osgi-bootstrap.xml	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/src/etc/osgitck/jboss-osgi-bootstrap.xml	2009-11-27 15:38:13 UTC (rev 97112)
@@ -12,6 +12,7 @@
     <constructor>
       <parameter><inject bean="jboss.kernel:service=Kernel" /></parameter>
       <parameter><inject bean="MainDeployer" /></parameter>
+      <parameter><inject bean="DeploymentRegistry" /></parameter>
     </constructor>
     <property name="properties">
       <map keyClass="java.lang.String" valueClass="java.lang.String">
@@ -95,6 +96,9 @@
     <property name="deployers"><inject bean="Deployers" /></property>
   </bean>
 
+  <!-- The deployment registry -->
+  <bean name="DeploymentRegistry" class="org.jboss.deployers.structure.spi.helpers.AbstractDeploymentRegistry"/>
+
   <!-- The holder for deployers that determine structure -->
   <bean name="StructuralDeployers" class="org.jboss.deployers.vfs.plugins.structure.VFSStructuralDeployersImpl">
     <property name="structureBuilder">

Modified: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/AbstractBundleState.java
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/AbstractBundleState.java	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/AbstractBundleState.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -35,6 +35,8 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.jboss.dependency.plugins.tracker.AbstractContextTracker;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.tracker.ContextTracking;
 import org.jboss.osgi.framework.metadata.OSGiMetaData;
 import org.jboss.osgi.framework.plugins.BundleStoragePlugin;
 import org.jboss.osgi.framework.plugins.FrameworkEventsPlugin;
@@ -299,36 +301,37 @@
    /**
     * Add a registered service
     * 
-    * @param serviceState the service
+    * @param context the context
     */
-   void addRegisteredService(OSGiServiceState serviceState)
+   void addRegisteredService(org.jboss.dependency.spi.ControllerContext context)
    {
-      addUsedBy(serviceState, this);
+      addUsedBy(context, this);
    }
 
    /**
     * Remove a registered service
     * 
-    * @param serviceState the service
+    * @param context the context
     */
-   void removeRegisteredService(OSGiServiceState serviceState)
+   void removeRegisteredService(OSGiServiceState context)
    {
-      removeUsedBy(serviceState, this);
+      removeUsedBy(context, this);
    }
 
    public ServiceReference[] getRegisteredServices()
    {
       checkInstalled();
 
-      Set<OSGiServiceState> contexts = getUsedContexts(OSGiServiceState.class);
+      Set<org.jboss.dependency.spi.ControllerContext> contexts = getUsedContexts(null);
       if (contexts.isEmpty())
          return null;
 
       Set<ServiceReference> result = new HashSet<ServiceReference>();
-      for (OSGiServiceState service : contexts)
+      for (org.jboss.dependency.spi.ControllerContext context : contexts)
       {
-         if (service.hasPermission())
-            result.add(service.getReferenceInternal());
+         ServiceReference ref = getBundleManager().getServiceReferenceForContext(context);
+         if (ref != null)
+            result.add(ref);
       }
       if (result.isEmpty())
          return null;
@@ -336,51 +339,49 @@
    }
 
    /**
-    * True if the use count of a service for this bundle is grater that 0.
+    * Increment the use count of a context for this bundle
     * 
-    * @param serviceState the service
-    * @return true if counter is bigger than zero, false otherwise
+    * @param context the context
     */
-   boolean isServiceInUse(OSGiServiceState serviceState)
+   void addContextInUse(ControllerContext context)
    {
-      return isContextInUse(serviceState);
+      if (context instanceof ContextTracking)
+      {
+         ContextTracking ct = (ContextTracking)context;
+         ct.getTarget(this);
+      }
    }
 
    /**
-    * Increment the use count of a service for this bundle
+    * Decrement the use count of a context for this bundle
     * 
-    * @param serviceState the service
-    */
-   void addServiceInUse(OSGiServiceState serviceState)
-   {
-      serviceState.getTarget(this);
-   }
-
-   /**
-    * Decrement the use count of a service for this bundle
-    * 
-    * @param serviceState the service
+    * @param context the context
     * @return true when the service is still in use by the bundle
     */
-   boolean removeServiceInUse(OSGiServiceState serviceState)
+   boolean removeContextInUse(ControllerContext context)
    {
-      serviceState.ungetTarget(this);
-      return isContextInUse(serviceState);
+      if (context instanceof ContextTracking)
+      {
+         ContextTracking ct = (ContextTracking)context;
+         ct.ungetTarget(this);
+      }
+      return isContextInUse(context);
    }
 
    public ServiceReference[] getServicesInUse()
    {
-      Set<OSGiServiceState> contexts = getUsedContexts(OSGiServiceState.class);
+      Set<org.jboss.dependency.spi.ControllerContext> contexts = getUsedContexts(null);
       if (contexts == null || contexts.isEmpty())
          return null;
 
       List<ServiceReference> references = new ArrayList<ServiceReference>();
-      for (OSGiServiceState service : contexts)
+      for (org.jboss.dependency.spi.ControllerContext context : contexts)
       {
-         if (getUsedByCount(service, this) > 0)
+         if (getUsedByCount(context, this) > 0)
          {
-            if (service.hasPermission())
-               references.add(service.getReferenceInternal());
+            ServiceReference ref = getBundleManager().getServiceReferenceForContext(context);
+            if (ref != null)
+               references.add(ref);
          }
       }
 
@@ -407,7 +408,7 @@
 
    Object getService(OSGiServiceState serviceState)
    {
-      return getBundleManager().getService(this, serviceState);  
+      return getBundleManager().getService(this, serviceState);
    }
 
    public ServiceReference getServiceReference(String clazz)
@@ -457,18 +458,19 @@
          throw new IllegalArgumentException("Null reference");
 
       // Check if the service is still in use by this bundle
-      OSGiServiceState serviceState = ((OSGiServiceReferenceWrapper)reference).getServiceState();
-      if (isServiceInUse(serviceState) == false)
+      ControllerContextHandle handle = (ControllerContextHandle)reference;
+      ControllerContext context = handle.getContext();
+      if (isContextInUse(context) == false)
          return false;
 
       checkValidBundleContext();
 
-      return getBundleManager().ungetService(this, reference);
+      return getBundleManager().ungetContext(this, context);
    }
 
-   boolean ungetService(OSGiServiceState state)
+   boolean ungetContex(ControllerContext state)
    {
-      return getBundleManager().ungetService(this, state);
+      return getBundleManager().ungetContext(this, state);
    }
 
    public void addBundleListener(BundleListener listener)

Modified: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/ContextRegistryAction.java
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/ContextRegistryAction.java	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/ContextRegistryAction.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -22,7 +22,6 @@
 package org.jboss.osgi.framework.bundle;
 
 import org.jboss.dependency.spi.Controller;
-import org.jboss.dependency.spi.ControllerContext;
 import org.jboss.dependency.spi.tracker.ContextRegistry;
 
 /**
@@ -38,7 +37,7 @@
     * @param context the context
     * @return context registry or null if cannot be applied
     */
-   protected ContextRegistry getContextRegistry(ControllerContext context)
+   protected ContextRegistry getContextRegistry(org.jboss.dependency.spi.ControllerContext context)
    {
       Controller controller = context.getController();
       return (controller instanceof ContextRegistry) ?  ContextRegistry.class.cast(controller) : null;

Copied: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/ControllerContextHandle.java (from rev 96803, projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceReferenceWrapper.java)
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/ControllerContextHandle.java	                        (rev 0)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/ControllerContextHandle.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -0,0 +1,40 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.osgi.framework.bundle;
+
+import org.jboss.dependency.spi.ControllerContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * ControllerContext handle.
+ *
+ * @author <a href="ales.justin at jboss.org">Ales Justin</a>
+ */
+abstract class ControllerContextHandle implements ServiceReference
+{
+   /**
+    * Get a hold of underlying controller context.
+    *
+    * @return the controller context
+    */
+   abstract ControllerContext getContext();
+}
\ No newline at end of file

Copied: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/GenericServiceReferenceWrapper.java (from rev 96803, projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceReferenceWrapper.java)
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/GenericServiceReferenceWrapper.java	                        (rev 0)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/GenericServiceReferenceWrapper.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -0,0 +1,126 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.osgi.framework.bundle;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.tracker.ContextTracker;
+import org.jboss.dependency.spi.tracker.ContextTracking;
+import org.osgi.framework.Bundle;
+
+/**
+ * GenericServiceReferenceWrapper.
+ *
+ * @author <a href="ales.justin at jboss.org">Ales Justin</a>
+ */
+class GenericServiceReferenceWrapper extends ControllerContextHandle
+{
+   private ControllerContext context;
+   private AbstractBundleState bundleState;
+
+   public GenericServiceReferenceWrapper(ControllerContext context, AbstractBundleState bundleState)
+   {
+      if (context == null)
+         throw new IllegalArgumentException("Null context");
+      if (bundleState == null)
+         throw new IllegalArgumentException("Null bundle state");
+
+      this.context = context;
+      this.bundleState = bundleState;
+   }
+
+   ControllerContext getContext()
+   {
+      return context;
+   }
+
+   public Object getProperty(String s)
+   {
+      return null;  // TODO
+   }
+
+   public String[] getPropertyKeys()
+   {
+      return null; // TODO
+   }
+
+   public Bundle getBundle()
+   {
+      return bundleState.getBundleInternal();
+   }
+
+   public Bundle[] getUsingBundles()
+   {
+      if (context instanceof ContextTracking)
+      {
+         ContextTracking tracking = (ContextTracking)context;
+         ContextTracker ct = tracking.getContextTracker();
+         if (ct == null)
+            return null;
+
+         Set<Object> users = ct.getUsers(context);
+         Set<Bundle> bundles = new HashSet<Bundle>();
+         for (Object user : users)
+         {
+            if (ct.getUsedByCount(context, user) > 0)
+            {
+               OSGiBundleManager manager = bundleState.getBundleManager();
+               AbstractBundleState abs = manager.getBundleForUser(user);
+               bundles.add(abs.getBundleInternal());
+            }
+         }
+         return bundles.toArray(new Bundle[bundles.size()]);
+      }
+      return null;
+   }
+
+   public boolean isAssignableTo(Bundle bundle, String s)
+   {
+      return false; // TODO
+   }
+
+   public int compareTo(Object o)
+   {
+      return 0; // TODO
+   }
+
+   public int hashCode()
+   {
+      return context.hashCode();
+   }
+
+   public boolean equals(Object obj)
+   {
+      if (obj instanceof GenericServiceReferenceWrapper == false)
+         return false;
+
+      GenericServiceReferenceWrapper other = (GenericServiceReferenceWrapper)obj;
+      return context == other.context;
+   }
+
+   public String toString()
+   {
+      return context.toString();
+   }
+}
\ No newline at end of file

Modified: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleManager.java
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleManager.java	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleManager.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -52,11 +52,13 @@
 import org.jboss.dependency.spi.Controller;
 import org.jboss.dependency.spi.ControllerContext;
 import org.jboss.dependency.spi.ControllerState;
+import org.jboss.dependency.spi.tracker.ContextTracker;
 import org.jboss.deployers.client.spi.DeployerClient;
 import org.jboss.deployers.spi.DeploymentException;
 import org.jboss.deployers.spi.attachments.MutableAttachments;
 import org.jboss.deployers.spi.deployer.DeploymentStage;
 import org.jboss.deployers.spi.deployer.DeploymentStages;
+import org.jboss.deployers.structure.spi.DeploymentRegistry;
 import org.jboss.deployers.structure.spi.DeploymentUnit;
 import org.jboss.deployers.structure.spi.main.MainDeployerStructure;
 import org.jboss.deployers.vfs.spi.client.VFSDeployment;
@@ -64,6 +66,11 @@
 import org.jboss.kernel.Kernel;
 import org.jboss.kernel.spi.dependency.KernelController;
 import org.jboss.logging.Logger;
+import org.jboss.metadata.plugins.loader.memory.MemoryMetaDataLoader;
+import org.jboss.metadata.spi.loader.MutableMetaDataLoader;
+import org.jboss.metadata.spi.repository.MutableMetaDataRepository;
+import org.jboss.metadata.spi.retrieval.MetaDataRetrieval;
+import org.jboss.metadata.spi.scope.ScopeKey;
 import org.jboss.osgi.deployment.deployer.Deployment;
 import org.jboss.osgi.framework.metadata.OSGiMetaData;
 import org.jboss.osgi.framework.metadata.PackageAttribute;
@@ -142,6 +149,9 @@
    /** The deployment structure */
    private MainDeployerStructure deployerStructure;
 
+   /** The deployment registry */
+   private DeploymentRegistry registry;
+
    /** The executor */
    private Executor executor;
 
@@ -175,11 +185,12 @@
     * 
     * @param kernel the kernel
     * @param deployerClient the deployer client
+    * @param registry the deployment registry
     * @throws IllegalArgumentException for a null parameter
     */
-   public OSGiBundleManager(Kernel kernel, DeployerClient deployerClient)
+   public OSGiBundleManager(Kernel kernel, DeployerClient deployerClient, DeploymentRegistry registry)
    {
-      this(kernel, deployerClient, null);
+      this(kernel, deployerClient, registry, null);
    }
 
    /**
@@ -187,10 +198,11 @@
     * 
     * @param kernel the kernel
     * @param deployerClient the deployer client
+    * @param registry the deployment registry
     * @param executor the executor
     * @throws IllegalArgumentException for a null parameter
     */
-   public OSGiBundleManager(Kernel kernel, DeployerClient deployerClient, Executor executor)
+   public OSGiBundleManager(Kernel kernel, DeployerClient deployerClient, DeploymentRegistry registry, Executor executor)
    {
       if (kernel == null)
          throw new IllegalArgumentException("Null kernel");
@@ -198,10 +210,13 @@
          throw new IllegalArgumentException("Null deployerClient");
       if (deployerClient instanceof MainDeployerStructure == false)
          throw new IllegalArgumentException("Deployer client does not implement " + MainDeployerStructure.class.getName());
+      if (registry == null)
+         throw new IllegalArgumentException("Null deployment registry");
 
       this.kernel = kernel;
       this.deployerClient = deployerClient;
       this.deployerStructure = (MainDeployerStructure)deployerClient;
+      this.registry = registry;
 
       // TODO thread factory
       if (executor == null)
@@ -220,11 +235,107 @@
       OSGiMetaData systemMetaData = new AbstractOSGiMetaData(manifest);
       systemBundle = new OSGiSystemState(systemMetaData);
       addBundle(systemBundle);
+
+      applySystemContextTracker(true);
    }
 
+   public void stop()
+   {
+      applySystemContextTracker(false);
+   }
+
    /**
+    * Add system bundle as default context tracker.
+    *
+    * @param register do we register or unregister
+    */
+   protected void applySystemContextTracker(boolean register)
+   {
+      MutableMetaDataRepository repository = kernel.getMetaDataRepository().getMetaDataRepository();
+      MetaDataRetrieval retrieval = repository.getMetaDataRetrieval(ScopeKey.DEFAULT_SCOPE);
+      if (register && retrieval == null)
+      {
+         retrieval = new MemoryMetaDataLoader(ScopeKey.DEFAULT_SCOPE);
+         repository.addMetaDataRetrieval(retrieval);
+      }
+      if (retrieval != null && retrieval instanceof MutableMetaDataLoader)
+      {
+         MutableMetaDataLoader mmdl = (MutableMetaDataLoader)retrieval;
+         if (register)
+         {
+            mmdl.addMetaData(systemBundle, ContextTracker.class);
+         }
+         else
+         {
+            mmdl.removeMetaData(ContextTracker.class);
+            if (mmdl.isEmpty())
+               repository.removeMetaDataRetrieval(mmdl.getScope());
+         }
+      }
+   }
+
+   /**
+    * Get bundle for user tracker.
+    *
+    * @param user the user tracker object
+    * @return bundle state
+    */
+   AbstractBundleState getBundleForUser(Object user)
+   {
+      if (user instanceof AbstractBundleState)
+         return (AbstractBundleState)user;
+      else if (user instanceof org.jboss.dependency.spi.ControllerContext)
+         return getBundleForContext((org.jboss.dependency.spi.ControllerContext)user);
+      else
+         throw new IllegalArgumentException("Unknown tracker type: " + user);
+   }
+
+   /**
+    * Get bundle for context.
+    *
+    * @param context the context
+    * @return bundle state
+    */
+   AbstractBundleState getBundleForContext(ControllerContext context)
+   {
+      if (context instanceof OSGiServiceState)
+      {
+         OSGiServiceState service = (OSGiServiceState)context;
+         return service.getBundleState();
+      }
+
+      DeploymentUnit unit = registry.getDeployment(context);
+      if (unit != null)
+      {
+         OSGiBundleState bundleState = unit.getAttachment(OSGiBundleState.class);
+         if (bundleState != null)
+            return bundleState;
+      }
+
+      return systemBundle;
+   }
+
+   /**
+    * Get service reference for context.
+    *
+    * @param context the context
+    * @return service reference
+    */
+   ServiceReference getServiceReferenceForContext(ControllerContext context)
+   {
+      if (context instanceof OSGiServiceState)
+      {
+         OSGiServiceState service = (OSGiServiceState)context;
+         return service.hasPermission() ? service.getReferenceInternal() : null;
+      }
+
+      AbstractBundleState bundleState = getBundleForContext(context);
+      return new GenericServiceReferenceWrapper(context, bundleState);
+   }
+
+   /**
     * Get the kernel
-    * 
+    *
     * @return the kernel
     */
    public Kernel getKernel()
@@ -234,7 +345,7 @@
 
    /**
     * Get the deployerClient.
-    * 
+    *
     * @return the deployerClient.
     */
    public DeployerClient getDeployerClient()
@@ -244,7 +355,7 @@
 
    /**
     * Set the framework properties
-    * 
+    *
     * @param properties the properties
     */
    public void setProperties(Map<String, Object> properties)
@@ -268,7 +379,7 @@
 
    /**
     * Get a property
-    * 
+    *
     * @param key the property key
     * @return the property
     * @throws SecurityException if the caller doesn't have the relevant property permission
@@ -967,7 +1078,7 @@
          return true;
 
       DeploymentUnit unit = bundleState.getDeploymentUnit();
-      ControllerContext context = unit.getAttachment(ControllerContext.class);
+      org.jboss.dependency.spi.ControllerContext context = unit.getAttachment(org.jboss.dependency.spi.ControllerContext.class);
 
       ControllerState requiredState = context.getRequiredState();
       DeploymentStage requiredStage = unit.getRequiredStage();
@@ -1053,7 +1164,7 @@
     */
    Collection<OSGiServiceState> getServices(AbstractBundleState bundle, String clazz, Filter filter, boolean checkAssignable)
    {
-      Set<ControllerContext> contexts;
+      Set<org.jboss.dependency.spi.ControllerContext> contexts;
       KernelController controller = kernel.getController();
 
       // Don't check assignabilty for the system bundle
@@ -1084,8 +1195,9 @@
       // review: optimise this, e.g. index by class
       // Use a sorted set to order services according to spec
       Set<OSGiServiceState> result = new TreeSet<OSGiServiceState>(ServiceComparator.INSTANCE);
-      for (ControllerContext context : contexts)
+      for (org.jboss.dependency.spi.ControllerContext context : contexts)
       {
+         // TODO - fix filtering
          if (context instanceof OSGiServiceState)
          {
             OSGiServiceState service = OSGiServiceState.class.cast(context);
@@ -1260,9 +1372,19 @@
     */
    Object getService(AbstractBundleState bundleState, ServiceReference reference)
    {
-      OSGiServiceReferenceWrapper serviceReference = (OSGiServiceReferenceWrapper)reference;
-      OSGiServiceState serviceState = serviceReference.getServiceState();
-      return getService(bundleState, serviceState);
+      if (reference instanceof OSGiServiceReferenceWrapper)
+      {
+         OSGiServiceReferenceWrapper serviceReference = (OSGiServiceReferenceWrapper)reference;
+         OSGiServiceState serviceState = serviceReference.getServiceState();
+         return getService(bundleState, serviceState);
+      }
+      else
+      {
+         ControllerContextHandle handle = (ControllerContextHandle)reference;
+         ControllerContext context = handle.getContext();
+         Object target = context.getTarget();
+         return getResult(bundleState, context, target);
+      }
    }
 
    /**
@@ -1275,8 +1397,21 @@
    Object getService(AbstractBundleState bundleState, OSGiServiceState serviceState)
    {
       Object result = serviceState.getService(bundleState);
+      return getResult(bundleState, serviceState, result);
+   }
+
+   /**
+    * Get result.
+    *
+    * @param bundleState the bundle state
+    * @param context the context
+    * @param result the result
+    * @return result
+    */
+   private Object getResult(AbstractBundleState bundleState, ControllerContext context, Object result)
+   {
       if (result != null)
-         bundleState.addServiceInUse(serviceState);
+         bundleState.addContextInUse(context);
       return result;
    }
 
@@ -1291,21 +1426,22 @@
    {
       if (reference == null)
          throw new IllegalArgumentException("Null reference");
-      OSGiServiceReferenceWrapper serviceReference = (OSGiServiceReferenceWrapper)reference;
-      OSGiServiceState serviceState = serviceReference.getServiceState();
-      return ungetService(bundleState, serviceState);
+
+      ControllerContextHandle serviceReference = (ControllerContextHandle)reference;
+      ControllerContext context = serviceReference.getContext();
+      return ungetContext(bundleState, context);
    }
 
    /**
-    * Unget a service
+    * Unget a context
     * 
     * @param bundleState the bundle state
-    * @param service the service
-    * @return true when the service is still in use by the bundle
+    * @param context the context
+    * @return true when the context is still in use by the bundle
     */
-   boolean ungetService(AbstractBundleState bundleState, OSGiServiceState service)
+   boolean ungetContext(AbstractBundleState bundleState, org.jboss.dependency.spi.ControllerContext context)
    {
-      return bundleState.removeServiceInUse(service);
+      return bundleState.removeContextInUse(context);
    }
 
    /**

Modified: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleState.java
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleState.java	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleState.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -343,6 +343,7 @@
             }
          }
 
+         // TODO - I guess we need to unget them all, but only OSGi will have a real "unget" notion
          for (OSGiServiceState service : getUsedContexts(OSGiServiceState.class))
          {
             int count = getUsedByCount(service, this);

Modified: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceAction.java
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceAction.java	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceAction.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -22,7 +22,6 @@
 package org.jboss.osgi.framework.bundle;
 
 import org.jboss.dependency.plugins.action.SimpleControllerContextAction;
-import org.jboss.dependency.spi.ControllerContext;
 import org.jboss.logging.Logger;
 
 /**
@@ -34,12 +33,12 @@
 {
    protected Logger log = Logger.getLogger(getClass());
    
-   protected OSGiServiceState contextCast(ControllerContext context)
+   protected OSGiServiceState contextCast(org.jboss.dependency.spi.ControllerContext context)
    {
       return OSGiServiceState.class.cast(context);
    }
 
-   protected boolean validateContext(ControllerContext context)
+   protected boolean validateContext(org.jboss.dependency.spi.ControllerContext context)
    {
       return (context instanceof OSGiServiceState);
    }

Modified: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceReferenceWrapper.java
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceReferenceWrapper.java	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceReferenceWrapper.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -21,16 +21,17 @@
 */
 package org.jboss.osgi.framework.bundle;
 
+import org.jboss.dependency.spi.ControllerContext;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
 
 /**
  * OSGiServiceReferenceWrapper.
  * 
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="ales.justin at jboss.org">Ales Justin</a>
  * @version $Revision: 1.1 $
  */
-public class OSGiServiceReferenceWrapper implements ServiceReference
+public class OSGiServiceReferenceWrapper extends ControllerContextHandle
 {
    /** The service state */
    private OSGiServiceState serviceState;
@@ -48,6 +49,11 @@
       this.serviceState = serviceState;
    }
 
+   ControllerContext getContext()
+   {
+      return getServiceState();
+   }
+
    public Bundle getBundle()
    {
       return serviceState.getBundle();

Deleted: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceState.java
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceState.java	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceState.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -1,833 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2009, Red Hat Middleware LLC, and individual contributors
-* as indicated by the @author tags. See the copyright.txt file in the
-* distribution for a full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.osgi.framework.bundle;
-
-import java.security.AccessControlContext;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.jboss.beans.info.spi.BeanInfo;
-import org.jboss.dependency.plugins.AbstractControllerContext;
-import org.jboss.dependency.spi.ScopeInfo;
-import org.jboss.dependency.spi.dispatch.InvokeDispatchContext;
-import org.jboss.dependency.spi.tracker.ContextTracker;
-import org.jboss.deployers.structure.spi.DeploymentUnit;
-import org.jboss.kernel.Kernel;
-import org.jboss.kernel.spi.config.KernelConfigurator;
-import org.jboss.metadata.spi.scope.CommonLevels;
-import org.jboss.metadata.spi.scope.Scope;
-import org.jboss.metadata.spi.scope.ScopeKey;
-import org.jboss.osgi.framework.plugins.FrameworkEventsPlugin;
-import org.jboss.osgi.framework.util.CaseInsensitiveDictionary;
-import org.jboss.osgi.spi.util.BundleClassLoader;
-import org.jboss.util.id.GUID;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServicePermission;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * OSGiServiceState.
- * 
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author <a href="ales.justin at jboss.org">Ales Justin</a>
- * @version $Revision: 1.1 $
- */
-public class OSGiServiceState extends AbstractControllerContext implements ServiceReference, ServiceRegistration, InvokeDispatchContext
-{
-   /** The get classloader permission */
-   private static final RuntimePermission GET_CLASSLOADER_PERMISSION = new RuntimePermission("getClassLoader");
-
-   /** Used to generate a unique id */
-   private static final AtomicLong serviceIDGenerator = new AtomicLong();
-
-   /** The bundle that registered the service */
-   private AbstractBundleState bundleState;
-
-   /** The service reference */
-   private OSGiServiceReferenceWrapper serviceReference;
-
-   /** The service registration */
-   private OSGiServiceRegistrationWrapper serviceRegistration;
-
-   /** The service id */
-   private long serviceId = serviceIDGenerator.incrementAndGet();
-
-   /** The service interfaces */
-   private String[] clazzes;
-
-   /** The service or service factory */
-   private Object serviceOrFactory;
-
-   /** The service factory provided service cache */
-   private Map<AbstractBundleState, Object> serviceCache;
-
-   /** The properties */
-   private CaseInsensitiveDictionary properties;
-
-   /** The bean info */
-   private BeanInfo beanInfo;
-
-   /**
-    * Create a new OSGiServiceState.
-    * 
-    * @param bundleState the bundle state
-    * @param clazzes the interfaces
-    * @param service the services
-    * @param properties the properties
-    * @throws IllegalArgumentException for a null parameter
-    */
-   @SuppressWarnings("unchecked")
-   public OSGiServiceState(AbstractBundleState bundleState, String[] clazzes, Object service, Dictionary properties)
-   {
-      // name is random / unique, we use aliases
-      super(GUID.asString(), OSGiControllerContextActions.ACTIONS, null, service);
-
-      if (bundleState == null)
-         throw new IllegalArgumentException("Null bundle state");
-      if (clazzes == null || clazzes.length == 0)
-         throw new IllegalArgumentException("Null or empty clazzes");
-
-      for (String clazz : clazzes)
-      {
-         if (clazz == null)
-            throw new IllegalArgumentException("Null class in: " + Arrays.toString(clazzes));
-      }
-      if (service == null)
-         throw new IllegalArgumentException("Null service");
-
-      this.bundleState = bundleState;
-      this.clazzes = clazzes;
-      this.serviceOrFactory = service;
-
-      if (service instanceof ServiceFactory == false)
-         checkObjClass(service);
-
-      if (properties != null)
-         this.properties = new CaseInsensitiveDictionary(properties);
-
-      serviceRegistration = new OSGiServiceRegistrationWrapper(this);
-
-      initOSGiScopeInfo();
-   }
-
-   /**
-    * Get the serviceId.
-    * 
-    * @return the serviceId.
-    */
-   public long getServiceId()
-   {
-      return serviceId;
-   }
-
-   /**
-    * Get the service ranking.
-    * 
-    * @return the service rankin.
-    */
-   public int getServiceRanking()
-   {
-      Object ranking = getProperty(Constants.SERVICE_RANKING);
-      if (ranking != null && ranking instanceof Integer)
-         return (Integer)ranking;
-      return 0;
-   }
-
-   /**
-    * Get the classes.
-    * 
-    * @return the classes.
-    */
-   public String[] getClasses()
-   {
-      return clazzes;
-   }
-
-   @Override
-   protected void initScopeInfo()
-   {
-      // nothing
-   }
-
-   protected void initOSGiScopeInfo()
-   {
-      String className = null;
-      Class<?> clazz = null;
-
-      Object target = serviceOrFactory;
-      if (target != null && target instanceof ServiceFactory == false)
-         clazz = target.getClass();
-      else if (clazzes.length == 1)
-         className = clazzes[0];
-
-      ScopeInfo info = OSGiScopeInfo.createScopeInfo(getName(), className, clazz, this);
-      setScopeInfo(info);
-
-      ScopeKey scope;
-      ScopeKey mutableScope;
-      if (bundleState instanceof OSGiBundleState)
-      {
-         OSGiBundleState obs = (OSGiBundleState)bundleState;
-         DeploymentUnit unit = obs.getDeploymentUnit();
-         scope = unit.getScope();
-         mutableScope = unit.getMutableScope();
-      }
-      else
-      {
-         // TODO - what to do for system bundle?
-         scope = new ScopeKey(CommonLevels.SERVER, "JBoss");
-         mutableScope = null;
-      }
-      mergeScopes(info.getScope(), scope);
-      mergeScopes(info.getMutableScope(), mutableScope);
-   }
-
-   /**
-    * Merge scope keys.
-    *
-    * @param contextKey the context key
-    * @param unitKey the unit key
-    */
-   protected static void mergeScopes(ScopeKey contextKey, ScopeKey unitKey)
-   {
-      if (contextKey == null)
-         return;
-      if (unitKey == null)
-         return;
-
-      Collection<Scope> unitScopes = unitKey.getScopes();
-      if (unitScopes == null || unitScopes.isEmpty())
-         return;
-
-      for (Scope scope : unitScopes)
-         contextKey.addScope(scope);
-   }
-
-   @Override
-   public Object getTarget()
-   {
-      // get service directly
-      return getService(bundleState);
-   }
-
-   public Object invoke(String name, Object[] parameters, String[] signature) throws Throwable
-   {
-      return getBeanInfo().invoke(getTarget(), name, signature, parameters);
-   }
-
-   public ClassLoader getClassLoader() throws Throwable
-   {
-      SecurityManager sm = System.getSecurityManager();
-      if (sm != null)
-         sm.checkPermission(GET_CLASSLOADER_PERMISSION);
-
-      return BundleClassLoader.createClassLoader(getBundle());
-   }
-
-   public Object get(String name) throws Throwable
-   {
-      return getBeanInfo().getProperty(getTarget(), name);
-   }
-
-   public void set(String name, Object value) throws Throwable
-   {
-      getBeanInfo().setProperty(getTarget(), name, value);
-   }
-
-   /**
-    * Get bean info.
-    *
-    * @return the bean info
-    */
-   protected BeanInfo getBeanInfo()
-   {
-      if (isUnregistered())
-         return null;
-
-      if (beanInfo == null)
-      {
-         try
-         {
-            Kernel kernel = bundleState.getBundleManager().getKernel();
-            KernelConfigurator configurator = kernel.getConfigurator();
-            Object service = getTarget(); // should not be null, we're not unregistered
-            beanInfo = configurator.getBeanInfo(service.getClass());
-         }
-         catch (Throwable t)
-         {
-            throw new RuntimeException(t);
-         }
-      }
-      return beanInfo;
-   }
-
-   /**
-    * Get the service.
-    * 
-    * @param bundleState the bundle that requested the service
-    * @return the service.
-    */
-   Object getService(AbstractBundleState bundleState)
-   {
-      // [TODO] fix race condition with unregistration
-      if (isUnregistered())
-         return null;
-
-      checkPermission("get", false);
-
-      Object service = serviceOrFactory;
-      if (serviceOrFactory instanceof ServiceFactory)
-      {
-         if (serviceCache == null)
-            serviceCache = new ConcurrentHashMap<AbstractBundleState, Object>();
-
-         service = serviceCache.get(bundleState);
-         if (service == null)
-         {
-            ServiceFactory serviceFactory = (ServiceFactory)serviceOrFactory;
-            try
-            {
-               service = checkObjClass(serviceFactory.getService(bundleState.getBundle(), getRegistration()));
-               serviceCache.put(bundleState, service);
-            }
-            catch (Throwable t)
-            {
-               log.error("Error from getService for " + this, t);
-               FrameworkEventsPlugin plugin = bundleState.getBundleManager().getPlugin(FrameworkEventsPlugin.class);
-               plugin.fireFrameworkEvent(bundleState, FrameworkEvent.ERROR, new BundleException("Error using service factory:" + serviceFactory, t));
-               return null;
-            }
-         }
-      }
-      return service;
-   }
-
-   /**
-    * Get the service registration
-    * 
-    * @return the service registration
-    */
-   public ServiceRegistration getRegistration()
-   {
-      return serviceRegistration;
-   }
-
-   public ServiceReference getReference()
-   {
-      checkUnregistered();
-      return getReferenceInternal();
-   }
-
-   public ServiceReference getReferenceInternal()
-   {
-      if (serviceReference == null)
-         serviceReference = new OSGiServiceReferenceWrapper(this);
-      return serviceReference;
-   }
-
-   public Bundle getBundle()
-   {
-      if (isUnregistered())
-         return null;
-      return bundleState.getBundleInternal();
-   }
-
-   /**
-    * Get the bundleState.
-    * 
-    * @return the bundleState.
-    */
-   public AbstractBundleState getBundleState()
-   {
-      return bundleState;
-   }
-
-   public Object getProperty(String key)
-   {
-      if (key == null)
-         return null;
-      if (Constants.SERVICE_ID.equalsIgnoreCase(key))
-         return getServiceId();
-      if (Constants.OBJECTCLASS.equalsIgnoreCase(key))
-         return getClasses();
-      if (properties == null)
-         return null;
-      return properties.get(key);
-   }
-
-   public String[] getPropertyKeys()
-   {
-      ArrayList<String> result = new ArrayList<String>();
-      if (properties != null)
-      {
-         Enumeration<String> keys = properties.keys();
-         while (keys.hasMoreElements())
-            result.add(keys.nextElement());
-      }
-      result.add(Constants.SERVICE_ID);
-      result.add(Constants.OBJECTCLASS);
-      return result.toArray(new String[result.size()]);
-   }
-
-   @SuppressWarnings("unchecked")
-   public void setProperties(Dictionary properties)
-   {
-      checkUnregistered();
-
-      if (properties == null)
-         this.properties = null;
-      else
-         this.properties = new CaseInsensitiveDictionary(properties);
-
-      FrameworkEventsPlugin plugin = bundleState.getBundleManager().getPlugin(FrameworkEventsPlugin.class);
-      plugin.fireServiceEvent(bundleState, ServiceEvent.MODIFIED, this);
-   }
-
-   public Bundle[] getUsingBundles()
-   {
-      ContextTracker ct = getContextTracker();
-      if (ct == null)
-         return null;
-
-      Set<Object> users = ct.getUsers(this);
-      List<Bundle> bundles = new ArrayList<Bundle>();
-      for (Object user : users)
-      {
-         if (user instanceof AbstractBundleState && ct.getUsedByCount(this, user) > 0)
-         {
-            AbstractBundleState abs = (AbstractBundleState)user;
-            bundles.add(abs.getBundleInternal());
-         }
-      }
-      return bundles.toArray(new Bundle[bundles.size()]);
-   }
-
-   public boolean isAssignableTo(Bundle bundle, String className)
-   {
-      if (bundle == null)
-         throw new IllegalArgumentException("Null bundle");
-      if (className == null)
-         throw new IllegalArgumentException("Null class name");
-
-      if (bundle instanceof OSGiBundleWrapper == false)
-         throw new IllegalArgumentException("Unknown bundle: " + bundle);
-
-      OSGiBundleWrapper wrapper = (OSGiBundleWrapper)bundle;
-      AbstractBundleState bundleState = wrapper.getBundleState();
-      return isAssignableTo(bundleState, className);
-   }
-
-   /**
-    * Check the isAssignableTo
-    * 
-    * @param other the bundle state
-    * @param className the class name
-    * @return true when assignable
-    */
-   boolean isAssignableTo(AbstractBundleState other, String className)
-   {
-      if (className == null)
-         throw new IllegalArgumentException("Null class name");
-
-      if (other == bundleState)
-         return true;
-
-      if (isUnregistered())
-         return false;
-
-      Class<?> source = (Class<?>)bundleState.getSource(className);
-      if (source == null)
-         throw new IllegalStateException("Cannot load '" + className + "' from: " + bundleState);
-
-      Class<?> otherSource = (Class<?>)other.getSource(className);
-      if (otherSource == null)
-      {
-         log.debug("Cannot load '" + className + "' from: " + other);
-         return false;
-      }
-
-      boolean equals = source.equals(otherSource);
-      if (equals == false)
-      {
-         ClassLoader otherLoader = otherSource.getClassLoader();
-         ClassLoader sourceLoader = source.getClassLoader();
-         StringBuffer buffer = new StringBuffer("Cannot assign '" + className + "' comming from different exporters");
-         buffer.append("\n  service: ").append(sourceLoader);
-         buffer.append("\n  request: ").append(otherLoader);
-         log.warn(buffer.toString());
-      }
-      return equals;
-   }
-
-   /**
-    * Check the isAssignable
-    * 
-    * @param bundle the bundle state
-    * @return true when assignable
-    */
-   boolean isAssignable(AbstractBundleState bundle)
-   {
-      if (bundle == bundleState)
-         return true;
-
-      if (isUnregistered())
-         return false;
-
-      for (String clazz : getClasses())
-      {
-         if (isAssignableTo(bundle, clazz) == false)
-            return false;
-      }
-      return true;
-   }
-
-   /**
-    * Match the class
-    * 
-    * @param className the class name
-    * @return true when the class name matches
-    */
-   boolean matchClass(String className)
-   {
-      if (clazzes == null || clazzes.length == 0)
-         return false;
-
-      for (String clazz : clazzes)
-      {
-         if (className.equals(clazz))
-            return true;
-      }
-      return false;
-   }
-
-   public void unregister()
-   {
-      checkUnregistered();
-
-      try
-      {
-         bundleState.unregisterService(this);
-      }
-      finally
-      {
-         synchronized (this)
-         {
-            serviceRegistration = null;
-         }
-      }
-   }
-
-   public int compareTo(Object reference)
-   {
-      if (reference == null)
-         throw new IllegalArgumentException("Null reference");
-
-      OSGiServiceState other;
-      if (reference instanceof OSGiServiceState)
-         other = (OSGiServiceState)reference;
-      else if (reference instanceof OSGiServiceReferenceWrapper)
-         other = ((OSGiServiceReferenceWrapper)reference).getServiceState();
-      else
-         throw new IllegalArgumentException(reference + " is not a service reference");
-
-      long thisServiceId = this.getServiceId();
-      long otherServiceId = other.getServiceId();
-      if (thisServiceId == otherServiceId)
-         return 0;
-
-      int thisRanking = this.getServiceRanking();
-      int otherRanking = other.getServiceRanking();
-      int ranking = thisRanking - otherRanking;
-      if (ranking != 0)
-         return ranking;
-
-      if (thisServiceId > otherServiceId)
-         return -1;
-      else
-         return +1;
-   }
-
-   @Override
-   public boolean equals(Object obj)
-   {
-      if (obj == null)
-         return false;
-
-      OSGiServiceState other;
-      if (obj instanceof OSGiServiceState)
-         other = (OSGiServiceState)obj;
-      else if (obj instanceof OSGiServiceReferenceWrapper)
-         other = ((OSGiServiceReferenceWrapper)obj).getServiceState();
-      else
-         return false;
-      return this == other;
-   }
-
-   @Override
-   public int hashCode()
-   {
-      return toString().hashCode();
-   }
-
-   @Override
-   public String toString()
-   {
-      StringBuilder builder = new StringBuilder();
-      builder.append("Service{");
-      builder.append("id=").append(getServiceId());
-      builder.append(" classes=").append(Arrays.asList(getClasses()));
-      builder.append("}");
-      return builder.toString();
-   }
-
-   public String toLongString()
-   {
-      StringBuilder builder = new StringBuilder();
-      builder.append("Service{");
-      builder.append("id=").append(getServiceId());
-      builder.append(" bundle=").append(getBundleState().getCanonicalName());
-      builder.append(" classes=").append(Arrays.asList(getClasses()));
-      builder.append(serviceOrFactory instanceof ServiceFactory ? " factory=" : " service=").append(serviceOrFactory);
-      if (properties != null)
-         builder.append(" properties=").append(properties);
-      builder.append("}");
-      return builder.toString();
-   }
-
-   /**
-    * Register the service
-    */
-   void internalRegister()
-   {
-      checkPermission("register", true);
-      getBundleState().addRegisteredService(this);
-   }
-
-   /**
-    * Unregister the service
-    */
-   void internalUnregister()
-   {
-      ContextTracker ct = getContextTracker();
-      if (ct != null) // nobody used us?
-      {
-         Set<Object> users = ct.getUsers(this);
-         if (users.isEmpty() == false)
-         {
-            for (Object user : users)
-            {
-               if (user instanceof AbstractBundleState)
-               {
-                  AbstractBundleState using = (AbstractBundleState)user;
-                  if (using.ungetService(this) == false)
-                  {
-                     if (serviceOrFactory instanceof ServiceFactory)
-                     {
-                        ServiceFactory serviceFactory = (ServiceFactory)serviceOrFactory;
-                        try
-                        {
-                           Object service = serviceCache.remove(using);
-                           serviceFactory.ungetService(using.getBundle(), getRegistration(), service);
-                        }
-                        catch (Throwable t)
-                        {
-                           log.warn("Error from ungetService for " + this, t);
-                           FrameworkEventsPlugin plugin = bundleState.getBundleManager().getPlugin(FrameworkEventsPlugin.class);
-                           plugin.fireFrameworkEvent(bundleState, FrameworkEvent.WARNING, new BundleException("Error using service factory:" + serviceFactory, t));
-                        }
-                     }
-                  }
-               }
-            }
-         }
-      }
-
-      getBundleState().removeRegisteredService(this);
-      serviceOrFactory = null;
-   }
-
-   /**
-    * Check an object matches the specified classes
-    * 
-    * @param object the object
-    * @return the object if all is ok
-    */
-   private Object checkObjClass(Object object)
-   {
-      if (object == null)
-         throw new IllegalArgumentException("Null object");
-
-      for (String className : getClasses())
-      {
-         try
-         {
-            Class<?> clazz = getBundleState().loadClass(className);
-            // [TODO] show classloader information all interfaces for debugging purposes
-            if (clazz.isInstance(object) == false)
-               throw new IllegalArgumentException(object.getClass().getName() + " does not implement " + className);
-         }
-         catch (ClassNotFoundException e)
-         {
-            throw new IllegalArgumentException(object.getClass().getName() + " cannot load class: " + className, e);
-         }
-      }
-      return object;
-   }
-
-   /**
-    * Check whether the caller has permission
-    * 
-    * @param action the action to check
-    * @param all whether all permissions are required
-    */
-   void checkPermission(String action, boolean all)
-   {
-      SecurityManager sm = System.getSecurityManager();
-      if (sm == null)
-         return;
-
-      String[] clazzes = getClasses();
-      SecurityException se = null;
-      for (String clazz : clazzes)
-      {
-         try
-         {
-            ServicePermission permission = new ServicePermission(clazz, action);
-            sm.checkPermission(permission);
-            if (all == false)
-               return;
-         }
-         catch (SecurityException e)
-         {
-            if (all)
-               throw e;
-            se = e;
-         }
-      }
-      if (se != null)
-         throw se;
-   }
-
-   /**
-    * Check whether the caller has permission
-    * 
-    * @param accessControlContext access control context
-    * @param action the action to check
-    * @param all whether all permissions are required
-    */
-   void checkPermission(AccessControlContext accessControlContext, String action, boolean all)
-   {
-      if (System.getSecurityManager() == null)
-         return;
-
-      String[] clazzes = getClasses();
-      SecurityException se = null;
-      for (String clazz : clazzes)
-      {
-         try
-         {
-            ServicePermission permission = new ServicePermission(clazz, action);
-            accessControlContext.checkPermission(permission);
-            if (all == false)
-               return;
-         }
-         catch (SecurityException e)
-         {
-            if (all)
-               throw e;
-            se = e;
-         }
-      }
-      if (se != null)
-         throw se;
-   }
-
-   /**
-    * Check whether the caller has permission to this object
-    * 
-    * @return true when the caller has permission
-    */
-   boolean hasPermission()
-   {
-      try
-      {
-         checkPermission("get", false);
-         return true;
-      }
-      catch (SecurityException ignored)
-      {
-      }
-      return false;
-   }
-
-   /**
-    * Check whether the caller has permission to this object
-    * 
-    * @param accessControlContext access control context
-    * @return true when the caller has permission
-    */
-   public boolean hasPermission(AccessControlContext accessControlContext)
-   {
-      try
-      {
-         checkPermission(accessControlContext, "get", false);
-         return true;
-      }
-      catch (SecurityException ignored)
-      {
-      }
-      return false;
-   }
-
-   /**
-    * Check if the service is unregistered
-    * 
-    * @throws IllegalStateException if unregistered
-    */
-   private void checkUnregistered()
-   {
-      if (isUnregistered())
-         throw new IllegalStateException("Service is unregistered: " + this);
-   }
-
-   /**
-    * @return true when the service is unregistered
-    */
-   synchronized boolean isUnregistered()
-   {
-      return serviceRegistration == null;
-   }
-}

Added: projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceState.java
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceState.java	                        (rev 0)
+++ projects/jboss-osgi/trunk/reactor/framework/src/main/java/org/jboss/osgi/framework/bundle/OSGiServiceState.java	2009-11-27 15:38:13 UTC (rev 97112)
@@ -0,0 +1,838 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.osgi.framework.bundle;
+
+import java.security.AccessControlContext;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.jboss.beans.info.spi.BeanInfo;
+import org.jboss.dependency.plugins.AbstractControllerContext;
+import org.jboss.dependency.spi.ScopeInfo;
+import org.jboss.dependency.spi.dispatch.InvokeDispatchContext;
+import org.jboss.dependency.spi.tracker.ContextTracker;
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+import org.jboss.kernel.Kernel;
+import org.jboss.kernel.spi.config.KernelConfigurator;
+import org.jboss.metadata.spi.scope.CommonLevels;
+import org.jboss.metadata.spi.scope.Scope;
+import org.jboss.metadata.spi.scope.ScopeKey;
+import org.jboss.osgi.framework.plugins.FrameworkEventsPlugin;
+import org.jboss.osgi.framework.util.CaseInsensitiveDictionary;
+import org.jboss.osgi.spi.util.BundleClassLoader;
+import org.jboss.util.id.GUID;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServicePermission;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * OSGiServiceState.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="ales.justin at jboss.org">Ales Justin</a>
+ * @version $Revision: 1.1 $
+ */
+public class OSGiServiceState extends AbstractControllerContext implements ServiceReference, ServiceRegistration, InvokeDispatchContext
+{
+   /** The get classloader permission */
+   private static final RuntimePermission GET_CLASSLOADER_PERMISSION = new RuntimePermission("getClassLoader");
+
+   /** Used to generate a unique id */
+   private static final AtomicLong serviceIDGenerator = new AtomicLong();
+
+   /** The bundle that registered the service */
+   private AbstractBundleState bundleState;
+
+   /** The service reference */
+   private OSGiServiceReferenceWrapper serviceReference;
+
+   /** The service registration */
+   private OSGiServiceRegistrationWrapper serviceRegistration;
+
+   /** The service id */
+   private long serviceId = serviceIDGenerator.incrementAndGet();
+
+   /** The service interfaces */
+   private String[] clazzes;
+
+   /** The service or service factory */
+   private Object serviceOrFactory;
+
+   /** The service factory provided service cache */
+   private Map<AbstractBundleState, Object> serviceCache;
+
+   /** The properties */
+   private CaseInsensitiveDictionary properties;
+
+   /** The bean info */
+   private BeanInfo beanInfo;
+
+   /**
+    * Create a new OSGiServiceState.
+    * 
+    * @param bundleState the bundle state
+    * @param clazzes the interfaces
+    * @param service the services
+    * @param properties the properties
+    * @throws IllegalArgumentException for a null parameter
+    */
+   @SuppressWarnings("unchecked")
+   public OSGiServiceState(AbstractBundleState bundleState, String[] clazzes, Object service, Dictionary properties)
+   {
+      // name is random / unique, we use aliases
+      super(GUID.asString(), OSGiControllerContextActions.ACTIONS, null, service);
+
+      if (bundleState == null)
+         throw new IllegalArgumentException("Null bundle state");
+      if (clazzes == null || clazzes.length == 0)
+         throw new IllegalArgumentException("Null or empty clazzes");
+
+      for (String clazz : clazzes)
+      {
+         if (clazz == null)
+            throw new IllegalArgumentException("Null class in: " + Arrays.toString(clazzes));
+      }
+      if (service == null)
+         throw new IllegalArgumentException("Null service");
+
+      this.bundleState = bundleState;
+      this.clazzes = clazzes;
+      this.serviceOrFactory = service;
+
+      if (service instanceof ServiceFactory == false)
+         checkObjClass(service);
+
+      if (properties != null)
+         this.properties = new CaseInsensitiveDictionary(properties);
+
+      serviceRegistration = new OSGiServiceRegistrationWrapper(this);
+
+      initOSGiScopeInfo();
+   }
+
+   /**
+    * Get the serviceId.
+    * 
+    * @return the serviceId.
+    */
+   public long getServiceId()
+   {
+      return serviceId;
+   }
+
+   /**
+    * Get the service ranking.
+    * 
+    * @return the service rankin.
+    */
+   public int getServiceRanking()
+   {
+      Object ranking = getProperty(Constants.SERVICE_RANKING);
+      if (ranking != null && ranking instanceof Integer)
+         return (Integer)ranking;
+      return 0;
+   }
+
+   /**
+    * Get the classes.
+    * 
+    * @return the classes.
+    */
+   public String[] getClasses()
+   {
+      return clazzes;
+   }
+
+   @Override
+   protected void initScopeInfo()
+   {
+      // nothing
+   }
+
+   protected void initOSGiScopeInfo()
+   {
+      String className = null;
+      Class<?> clazz = null;
+
+      Object target = serviceOrFactory;
+      if (target != null && target instanceof ServiceFactory == false)
+         clazz = target.getClass();
+      else if (clazzes.length == 1)
+         className = clazzes[0];
+
+      ScopeInfo info = OSGiScopeInfo.createScopeInfo(getName(), className, clazz, this);
+      setScopeInfo(info);
+
+      ScopeKey scope;
+      ScopeKey mutableScope;
+      if (bundleState instanceof OSGiBundleState)
+      {
+         OSGiBundleState obs = (OSGiBundleState)bundleState;
+         DeploymentUnit unit = obs.getDeploymentUnit();
+         scope = unit.getScope();
+         mutableScope = unit.getMutableScope();
+      }
+      else
+      {
+         // TODO - what to do for system bundle?
+         scope = new ScopeKey(CommonLevels.SERVER, "JBoss");
+         mutableScope = null;
+      }
+      mergeScopes(info.getScope(), scope);
+      mergeScopes(info.getMutableScope(), mutableScope);
+   }
+
+   /**
+    * Merge scope keys.
+    *
+    * @param contextKey the context key
+    * @param unitKey the unit key
+    */
+   protected static void mergeScopes(ScopeKey contextKey, ScopeKey unitKey)
+   {
+      if (contextKey == null)
+         return;
+      if (unitKey == null)
+         return;
+
+      Collection<Scope> unitScopes = unitKey.getScopes();
+      if (unitScopes == null || unitScopes.isEmpty())
+         return;
+
+      for (Scope scope : unitScopes)
+         contextKey.addScope(scope);
+   }
+
+   @Override
+   public Object getTarget()
+   {
+      // get service directly
+      return getService(bundleState);
+   }
+
+   public Object invoke(String name, Object[] parameters, String[] signature) throws Throwable
+   {
+      return getBeanInfo().invoke(getTarget(), name, signature, parameters);
+   }
+
+   public ClassLoader getClassLoader() throws Throwable
+   {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm != null)
+         sm.checkPermission(GET_CLASSLOADER_PERMISSION);
+
+      return BundleClassLoader.createClassLoader(getBundle());
+   }
+
+   public Object get(String name) throws Throwable
+   {
+      return getBeanInfo().getProperty(getTarget(), name);
+   }
+
+   public void set(String name, Object value) throws Throwable
+   {
+      getBeanInfo().setProperty(getTarget(), name, value);
+   }
+
+   /**
+    * Get bean info.
+    *
+    * @return the bean info
+    */
+   protected BeanInfo getBeanInfo()
+   {
+      if (isUnregistered())
+         return null;
+
+      if (beanInfo == null)
+      {
+         try
+         {
+            Kernel kernel = bundleState.getBundleManager().getKernel();
+            KernelConfigurator configurator = kernel.getConfigurator();
+            Object service = getTarget(); // should not be null, we're not unregistered
+            beanInfo = configurator.getBeanInfo(service.getClass());
+         }
+         catch (Throwable t)
+         {
+            throw new RuntimeException(t);
+         }
+      }
+      return beanInfo;
+   }
+
+   /**
+    * Get the service.
+    * 
+    * @param bundleState the bundle that requested the service
+    * @return the service.
+    */
+   Object getService(AbstractBundleState bundleState)
+   {
+      // [TODO] fix race condition with unregistration
+      if (isUnregistered())
+         return null;
+
+      checkPermission("get", false);
+
+      Object service = serviceOrFactory;
+      if (serviceOrFactory instanceof ServiceFactory)
+      {
+         if (serviceCache == null)
+            serviceCache = new ConcurrentHashMap<AbstractBundleState, Object>();
+
+         service = serviceCache.get(bundleState);
+         if (service == null)
+         {
+            ServiceFactory serviceFactory = (ServiceFactory)serviceOrFactory;
+            try
+            {
+               service = checkObjClass(serviceFactory.getService(bundleState.getBundle(), getRegistration()));
+               serviceCache.put(bundleState, service);
+            }
+            catch (Throwable t)
+            {
+               log.error("Error from getService for " + this, t);
+               FrameworkEventsPlugin plugin = bundleState.getBundleManager().getPlugin(FrameworkEventsPlugin.class);
+               plugin.fireFrameworkEvent(bundleState, FrameworkEvent.ERROR, new BundleException("Error using service factory:" + serviceFactory, t));
+               return null;
+            }
+         }
+      }
+      return service;
+   }
+
+   /**
+    * Get the service registration
+    * 
+    * @return the service registration
+    */
+   public ServiceRegistration getRegistration()
+   {
+      return serviceRegistration;
+   }
+
+   public ServiceReference getReference()
+   {
+      checkUnregistered();
+      return getReferenceInternal();
+   }
+
+   public ServiceReference getReferenceInternal()
+   {
+      if (serviceReference == null)
+         serviceReference = new OSGiServiceReferenceWrapper(this);
+      return serviceReference;
+   }
+
+   public Bundle getBundle()
+   {
+      if (isUnregistered())
+         return null;
+      return bundleState.getBundleInternal();
+   }
+
+   /**
+    * Get the bundleState.
+    * 
+    * @return the bundleState.
+    */
+   public AbstractBundleState getBundleState()
+   {
+      return bundleState;
+   }
+
+   public Object getProperty(String key)
+   {
+      if (key == null)
+         return null;
+      if (Constants.SERVICE_ID.equalsIgnoreCase(key))
+         return getServiceId();
+      if (Constants.OBJECTCLASS.equalsIgnoreCase(key))
+         return getClasses();
+      if (properties == null)
+         return null;
+      return properties.get(key);
+   }
+
+   public String[] getPropertyKeys()
+   {
+      ArrayList<String> result = new ArrayList<String>();
+      if (properties != null)
+      {
+         Enumeration<String> keys = properties.keys();
+         while (keys.hasMoreElements())
+            result.add(keys.nextElement());
+      }
+      result.add(Constants.SERVICE_ID);
+      result.add(Constants.OBJECTCLASS);
+      return result.toArray(new String[result.size()]);
+   }
+
+   @SuppressWarnings("unchecked")
+   public void setProperties(Dictionary properties)
+   {
+      checkUnregistered();
+
+      if (properties == null)
+         this.properties = null;
+      else
+         this.properties = new CaseInsensitiveDictionary(properties);
+
+      FrameworkEventsPlugin plugin = bundleState.getBundleManager().getPlugin(FrameworkEventsPlugin.class);
+      plugin.fireServiceEvent(bundleState, ServiceEvent.MODIFIED, this);
+   }
+
+   public Bundle[] getUsingBundles()
+   {
+      ContextTracker ct = getContextTracker();
+      if (ct == null)
+         return null;
+
+      Set<Object> users = ct.getUsers(this);
+      Set<Bundle> bundles = new HashSet<Bundle>();
+      for (Object user : users)
+      {
+         if (ct.getUsedByCount(this, user) > 0)
+         {
+            OSGiBundleManager manager = bundleState.getBundleManager();
+            AbstractBundleState abs = manager.getBundleForUser(user);
+            bundles.add(abs.getBundleInternal());
+         }
+      }
+      return bundles.toArray(new Bundle[bundles.size()]);
+   }
+
+   public boolean isAssignableTo(Bundle bundle, String className)
+   {
+      if (bundle == null)
+         throw new IllegalArgumentException("Null bundle");
+      if (className == null)
+         throw new IllegalArgumentException("Null class name");
+
+      if (bundle instanceof OSGiBundleWrapper == false)
+         throw new IllegalArgumentException("Unknown bundle: " + bundle);
+
+      OSGiBundleWrapper wrapper = (OSGiBundleWrapper)bundle;
+      AbstractBundleState bundleState = wrapper.getBundleState();
+      return isAssignableTo(bundleState, className);
+   }
+
+   /**
+    * Check the isAssignableTo
+    * 
+    * @param other the bundle state
+    * @param className the class name
+    * @return true when assignable
+    */
+   boolean isAssignableTo(AbstractBundleState other, String className)
+   {
+      if (className == null)
+         throw new IllegalArgumentException("Null class name");
+
+      if (other == bundleState)
+         return true;
+
+      if (isUnregistered())
+         return false;
+
+      Class<?> source = (Class<?>)bundleState.getSource(className);
+      if (source == null)
+         throw new IllegalStateException("Cannot load '" + className + "' from: " + bundleState);
+
+      Class<?> otherSource = (Class<?>)other.getSource(className);
+      if (otherSource == null)
+      {
+         log.debug("Cannot load '" + className + "' from: " + other);
+         return false;
+      }
+
+      boolean equals = source.equals(otherSource);
+      if (equals == false)
+      {
+         ClassLoader otherLoader = otherSource.getClassLoader();
+         ClassLoader sourceLoader = source.getClassLoader();
+         StringBuffer buffer = new StringBuffer("Cannot assign '" + className + "' comming from different exporters");
+         buffer.append("\n  service: ").append(sourceLoader);
+         buffer.append("\n  request: ").append(otherLoader);
+         log.warn(buffer.toString());
+      }
+      return equals;
+   }
+
+   /**
+    * Check the isAssignable
+    * 
+    * @param bundle the bundle state
+    * @return true when assignable
+    */
+   boolean isAssignable(AbstractBundleState bundle)
+   {
+      if (bundle == bundleState)
+         return true;
+
+      if (isUnregistered())
+         return false;
+
+      for (String clazz : getClasses())
+      {
+         if (isAssignableTo(bundle, clazz) == false)
+            return false;
+      }
+      return true;
+   }
+
+   /**
+    * Match the class
+    * 
+    * @param className the class name
+    * @return true when the class name matches
+    */
+   boolean matchClass(String className)
+   {
+      if (clazzes == null || clazzes.length == 0)
+         return false;
+
+      for (String clazz : clazzes)
+      {
+         if (className.equals(clazz))
+            return true;
+      }
+      return false;
+   }
+
+   public void unregister()
+   {
+      checkUnregistered();
+
+      try
+      {
+         bundleState.unregisterService(this);
+      }
+      finally
+      {
+         synchronized (this)
+         {
+            serviceRegistration = null;
+         }
+      }
+   }
+
+   public int compareTo(Object reference)
+   {
+      if (reference == null)
+         throw new IllegalArgumentException("Null reference");
+
+      OSGiServiceState other;
+      if (reference instanceof OSGiServiceState)
+         other = (OSGiServiceState)reference;
+      else if (reference instanceof OSGiServiceReferenceWrapper)
+         other = ((OSGiServiceReferenceWrapper)reference).getServiceState();
+      else
+         throw new IllegalArgumentException(reference + " is not a service reference");
+
+      long thisServiceId = this.getServiceId();
+      long otherServiceId = other.getServiceId();
+      if (thisServiceId == otherServiceId)
+         return 0;
+
+      int thisRanking = this.getServiceRanking();
+      int otherRanking = other.getServiceRanking();
+      int ranking = thisRanking - otherRanking;
+      if (ranking != 0)
+         return ranking;
+
+      if (thisServiceId > otherServiceId)
+         return -1;
+      else
+         return +1;
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj == null)
+         return false;
+
+      OSGiServiceState other;
+      if (obj instanceof OSGiServiceState)
+         other = (OSGiServiceState)obj;
+      else if (obj instanceof OSGiServiceReferenceWrapper)
+         other = ((OSGiServiceReferenceWrapper)obj).getServiceState();
+      else
+         return false;
+      return this == other;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return toString().hashCode();
+   }
+
+   @Override
+   public String toString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append("Service{");
+      builder.append("id=").append(getServiceId());
+      builder.append(" classes=").append(Arrays.asList(getClasses()));
+      builder.append("}");
+      return builder.toString();
+   }
+
+   public String toLongString()
+   {
+      StringBuilder builder = new StringBuilder();
+      builder.append("Service{");
+      builder.append("id=").append(getServiceId());
+      builder.append(" bundle=").append(getBundleState().getCanonicalName());
+      builder.append(" classes=").append(Arrays.asList(getClasses()));
+      builder.append(serviceOrFactory instanceof ServiceFactory ? " factory=" : " service=").append(serviceOrFactory);
+      if (properties != null)
+         builder.append(" properties=").append(properties);
+      builder.append("}");
+      return builder.toString();
+   }
+
+   /**
+    * Register the service
+    */
+   void internalRegister()
+   {
+      checkPermission("register", true);
+      getBundleState().addRegisteredService(this);
+   }
+
+   /**
+    * Unregister the service
+    */
+   void internalUnregister()
+   {
+      ContextTracker ct = getContextTracker();
+      if (ct != null) // nobody used us?
+      {
+         Set<Object> users = ct.getUsers(this);
+         if (users.isEmpty() == false)
+         {
+            OSGiBundleManager manager = bundleState.getBundleManager();
+            Set<AbstractBundleState> used = new HashSet<AbstractBundleState>();
+            for (Object user : users)
+            {
+               AbstractBundleState using = manager.getBundleForUser(user);
+               if (used.contains(using) == false)
+               {
+                  used.add(using); // add so we don't remove duplicates
+
+                  if (using.ungetContex(this) == false)
+                  {
+                     if (serviceOrFactory instanceof ServiceFactory)
+                     {
+                        ServiceFactory serviceFactory = (ServiceFactory)serviceOrFactory;
+                        try
+                        {
+                           Object service = serviceCache.remove(using);
+                           serviceFactory.ungetService(using.getBundle(), getRegistration(), service);
+                        }
+                        catch (Throwable t)
+                        {
+                           log.warn("Error from ungetService for " + this, t);
+                           FrameworkEventsPlugin plugin = bundleState.getBundleManager().getPlugin(FrameworkEventsPlugin.class);
+                           plugin.fireFrameworkEvent(bundleState, FrameworkEvent.WARNING, new BundleException("Error using service factory:" + serviceFactory, t));
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+      getBundleState().removeRegisteredService(this);
+      serviceOrFactory = null;
+   }
+
+   /**
+    * Check an object matches the specified classes
+    * 
+    * @param object the object
+    * @return the object if all is ok
+    */
+   private Object checkObjClass(Object object)
+   {
+      if (object == null)
+         throw new IllegalArgumentException("Null object");
+
+      for (String className : getClasses())
+      {
+         try
+         {
+            Class<?> clazz = getBundleState().loadClass(className);
+            // [TODO] show classloader information all interfaces for debugging purposes
+            if (clazz.isInstance(object) == false)
+               throw new IllegalArgumentException(object.getClass().getName() + " does not implement " + className);
+         }
+         catch (ClassNotFoundException e)
+         {
+            throw new IllegalArgumentException(object.getClass().getName() + " cannot load class: " + className, e);
+         }
+      }
+      return object;
+   }
+
+   /**
+    * Check whether the caller has permission
+    * 
+    * @param action the action to check
+    * @param all whether all permissions are required
+    */
+   void checkPermission(String action, boolean all)
+   {
+      SecurityManager sm = System.getSecurityManager();
+      if (sm == null)
+         return;
+
+      String[] clazzes = getClasses();
+      SecurityException se = null;
+      for (String clazz : clazzes)
+      {
+         try
+         {
+            ServicePermission permission = new ServicePermission(clazz, action);
+            sm.checkPermission(permission);
+            if (all == false)
+               return;
+         }
+         catch (SecurityException e)
+         {
+            if (all)
+               throw e;
+            se = e;
+         }
+      }
+      if (se != null)
+         throw se;
+   }
+
+   /**
+    * Check whether the caller has permission
+    * 
+    * @param accessControlContext access control context
+    * @param action the action to check
+    * @param all whether all permissions are required
+    */
+   void checkPermission(AccessControlContext accessControlContext, String action, boolean all)
+   {
+      if (System.getSecurityManager() == null)
+         return;
+
+      String[] clazzes = getClasses();
+      SecurityException se = null;
+      for (String clazz : clazzes)
+      {
+         try
+         {
+            ServicePermission permission = new ServicePermission(clazz, action);
+            accessControlContext.checkPermission(permission);
+            if (all == false)
+               return;
+         }
+         catch (SecurityException e)
+         {
+            if (all)
+               throw e;
+            se = e;
+         }
+      }
+      if (se != null)
+         throw se;
+   }
+
+   /**
+    * Check whether the caller has permission to this object
+    * 
+    * @return true when the caller has permission
+    */
+   boolean hasPermission()
+   {
+      try
+      {
+         checkPermission("get", false);
+         return true;
+      }
+      catch (SecurityException ignored)
+      {
+      }
+      return false;
+   }
+
+   /**
+    * Check whether the caller has permission to this object
+    * 
+    * @param accessControlContext access control context
+    * @return true when the caller has permission
+    */
+   public boolean hasPermission(AccessControlContext accessControlContext)
+   {
+      try
+      {
+         checkPermission(accessControlContext, "get", false);
+         return true;
+      }
+      catch (SecurityException ignored)
+      {
+      }
+      return false;
+   }
+
+   /**
+    * Check if the service is unregistered
+    * 
+    * @throws IllegalStateException if unregistered
+    */
+   private void checkUnregistered()
+   {
+      if (isUnregistered())
+         throw new IllegalStateException("Service is unregistered: " + this);
+   }
+
+   /**
+    * @return true when the service is unregistered
+    */
+   synchronized boolean isUnregistered()
+   {
+      return serviceRegistration == null;
+   }
+}

Modified: projects/jboss-osgi/trunk/reactor/framework/src/test/resources/bootstrap/jboss-osgi-bootstrap.xml
===================================================================
--- projects/jboss-osgi/trunk/reactor/framework/src/test/resources/bootstrap/jboss-osgi-bootstrap.xml	2009-11-27 15:12:58 UTC (rev 97111)
+++ projects/jboss-osgi/trunk/reactor/framework/src/test/resources/bootstrap/jboss-osgi-bootstrap.xml	2009-11-27 15:38:13 UTC (rev 97112)
@@ -12,6 +12,7 @@
     <constructor>
       <parameter><inject bean="jboss.kernel:service=Kernel" /></parameter>
       <parameter><inject bean="MainDeployer" /></parameter>
+      <parameter><inject bean="DeploymentRegistry" /></parameter>
     </constructor>
     <property name="properties">
       <map keyClass="java.lang.String" valueClass="java.lang.String">
@@ -94,6 +95,9 @@
     <property name="deployers"><inject bean="Deployers" /></property>
   </bean>
 
+  <!-- The deployment registry -->
+  <bean name="DeploymentRegistry" class="org.jboss.deployers.structure.spi.helpers.AbstractDeploymentRegistry"/>
+
   <!-- The holder for deployers that determine structure -->
   <bean name="StructuralDeployers" class="org.jboss.deployers.vfs.plugins.structure.VFSStructuralDeployersImpl">
     <property name="structureBuilder">
@@ -127,6 +131,7 @@
     <constructor>
       <parameter class="org.jboss.dependency.spi.Controller"><inject bean="jboss.kernel:service=KernelController" /></parameter>
     </constructor>
+    <property name="deploymentRegistry"><inject bean="DeploymentRegistry"/></property>
   </bean>
 
   <!-- OSGI Deployment -->



More information about the jboss-osgi-commits mailing list