Author: [email protected]
Date: Thu Feb  2 14:20:29 2012
New Revision: 2049

Log:
Fix for AMDATU-550: we register *custom* Bundle/Framework listener's but never 
unregister them. 

Modified:
   
trunk/amdatu-core/tenant-adapter/src/main/java/org/amdatu/tenant/adapter/TenantAdapter.java
   
trunk/amdatu-core/tenant-adapter/src/main/java/org/amdatu/tenant/adapter/TenantAwareBundleContext.java

Modified: 
trunk/amdatu-core/tenant-adapter/src/main/java/org/amdatu/tenant/adapter/TenantAdapter.java
==============================================================================
--- 
trunk/amdatu-core/tenant-adapter/src/main/java/org/amdatu/tenant/adapter/TenantAdapter.java
 (original)
+++ 
trunk/amdatu-core/tenant-adapter/src/main/java/org/amdatu/tenant/adapter/TenantAdapter.java
 Thu Feb  2 14:20:29 2012
@@ -82,7 +82,9 @@
             m_log.log(LogService.LOG_ERROR, "Could not stop activator for 
tenant " + getTenantID(), e);
         }
         finally {
-            m_tenantAwareBundleContext.unregisterServices();
+            // Make sure we unregister all services that were registered using 
this bundle 
+            // context, and also remove any listeners that were installed! See 
AMDATU-550.
+            m_tenantAwareBundleContext.unregisterServicesAndListeners();
         }
     }
 

Modified: 
trunk/amdatu-core/tenant-adapter/src/main/java/org/amdatu/tenant/adapter/TenantAwareBundleContext.java
==============================================================================
--- 
trunk/amdatu-core/tenant-adapter/src/main/java/org/amdatu/tenant/adapter/TenantAwareBundleContext.java
      (original)
+++ 
trunk/amdatu-core/tenant-adapter/src/main/java/org/amdatu/tenant/adapter/TenantAwareBundleContext.java
      Thu Feb  2 14:20:29 2012
@@ -23,6 +23,7 @@
 import java.util.Dictionary;
 import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import org.amdatu.tenant.TenantConstants;
 import org.osgi.framework.Bundle;
@@ -45,104 +46,236 @@
  */
 public class TenantAwareBundleContext implements BundleContext {
 
-    private final ConcurrentHashMap<BundleListener, TenantAwareBundleListener> 
m_bundleListeners =
-        new ConcurrentHashMap<BundleListener, TenantAwareBundleListener>();
+    /**
+     * Provides a tenant-aware framework event.
+     */
+    private static class ScopedFrameworkEvent extends FrameworkEvent {
+
+        private static final long serialVersionUID = 1L;
+
+        private Bundle m_eventBundle;
+
+        public ScopedFrameworkEvent(FrameworkEvent event) {
+            super(event.getType(), event.getBundle(), event.getThrowable());
+            m_eventBundle = event.getBundle();
+        }
+
+        /**
+         * @see org.osgi.framework.FrameworkEvent#getBundle()
+         */
+        public Bundle getBundle() {
+            return new TenantAwareBundle(m_eventBundle);
+        }
+    }
 
-    private final ConcurrentHashMap<FrameworkListener, 
TenantAwareFrameworkListener> m_frameworkListeners =
-        new ConcurrentHashMap<FrameworkListener, 
TenantAwareFrameworkListener>();
+    /**
+     * Provides a tenant-aware service registration.
+     */
+    private static class ServiceRegistrationAdapter implements 
ServiceRegistration {
 
-    private final ConcurrentHashMap<ServiceRegistrationAdapter, 
ServiceRegistration> m_serviceRegistrations =
-        new ConcurrentHashMap<ServiceRegistrationAdapter, 
ServiceRegistration>();
+        private final TenantAwareBundleContext m_context;
+        private final ServiceRegistration m_registration;
 
-    private final BundleContext m_bundleContext;
+        public ServiceRegistrationAdapter(TenantAwareBundleContext context, 
ServiceRegistration registration) {
+            m_context = context;
+            m_registration = registration;
+        }
+
+        /**
+         * @see org.osgi.framework.ServiceRegistration#getReference()
+         */
+        public ServiceReference getReference() {
+            return m_registration.getReference();
+        }
+
+        /**
+         * @see 
org.osgi.framework.ServiceRegistration#setProperties(java.util.Dictionary)
+         */
+        public void setProperties(Dictionary properties) {
+            
m_registration.setProperties(m_context.getScopedProperties(properties));
+        }
+
+        /**
+         * @see org.osgi.framework.ServiceRegistration#unregister()
+         */
+        public void unregister() {
+            m_context.unregisterService(this);
+        }
+
+        /**
+         * @return the original service registration, never <code>null</code>.
+         */
+        public ServiceRegistration getRegistration() {
+            return m_registration;
+        }
+    }
+
+    /**
+     * Provides a tenant-aware bundle event wrapper.
+     */
+    private static class TenantAwareBundleEvent extends BundleEvent {
+
+        private static final long serialVersionUID = 1L;
+
+        private final Bundle m_eventBundle;
+
+        public TenantAwareBundleEvent(BundleEvent event) {
+            super(event.getType(), event.getBundle());
+            m_eventBundle = event.getBundle();
+        }
+
+        /**
+         * @see org.osgi.framework.BundleEvent#getBundle()
+         */
+        public Bundle getBundle() {
+            return new TenantAwareBundle(m_eventBundle);
+        }
+    }
+
+    /**
+     * Provides a tenant-aware bundle listener.
+     */
+    private static class TenantAwareBundleListener implements BundleListener {
+
+        private final BundleListener m_listener;
+
+        public TenantAwareBundleListener(BundleListener listener) {
+            m_listener = listener;
+        }
+
+        /**
+         * @see 
org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
+         */
+        public void bundleChanged(BundleEvent event) {
+            m_listener.bundleChanged(new TenantAwareBundleEvent(event));
+        }
+    }
+
+    /**
+     * Provides a tenant-aware framework listener.
+     */
+    private static class TenantAwareFrameworkListener implements 
FrameworkListener {
+
+        private final FrameworkListener m_listener;
+
+        public TenantAwareFrameworkListener(FrameworkListener listener) {
+            m_listener = listener;
+        }
+
+        /**
+         * @see 
org.osgi.framework.FrameworkListener#frameworkEvent(org.osgi.framework.FrameworkEvent)
+         */
+        public void frameworkEvent(FrameworkEvent event) {
+            m_listener.frameworkEvent(new ScopedFrameworkEvent(event));
+        }
+    }
+
+    private final ConcurrentMap<BundleListener, TenantAwareBundleListener> 
m_bundleListeners;
+    private final ConcurrentMap<FrameworkListener, 
TenantAwareFrameworkListener> m_frameworkListeners;
+    private final ConcurrentMap<ServiceRegistrationAdapter, 
ServiceRegistration> m_serviceRegistrations;
+    private final BundleContext m_parentBundleContext;
     private final String m_identifier;
     private final String m_filter;
 
+    /**
+     * Creates a new {@link TenantAwareBundleContext}.
+     * 
+     * @param bundleContext the original bundle context to wrap;
+     * @param identifier the tenant-identifier to use to partition the service 
space;
+     * @param filter the (optional) filter to use for this context.
+     */
     public TenantAwareBundleContext(BundleContext bundleContext, String 
identifier, String filter) {
+        if (bundleContext == null) {
+            throw new IllegalArgumentException("BundleContext cannot be 
null!");
+        }
+        m_parentBundleContext = bundleContext;
 
-        assert bundleContext != null;
-        m_bundleContext = bundleContext;
-
-        assert identifier != null;
-        assert "".equals(identifier);
+        if (identifier == null || identifier.trim().isEmpty()) {
+            throw new IllegalArgumentException("Identifier cannot be null or 
empty!");
+        }
         m_identifier = identifier;
 
         if (filter != null)
             m_filter = filter;
         else
             m_filter = "";
+
+        m_bundleListeners = new ConcurrentHashMap<BundleListener, 
TenantAwareBundleListener>();
+        m_frameworkListeners = new ConcurrentHashMap<FrameworkListener, 
TenantAwareFrameworkListener>();
+        m_serviceRegistrations = new 
ConcurrentHashMap<ServiceRegistrationAdapter, ServiceRegistration>();
     }
 
-    /*
-     * Public access
+    /**
+     * @see 
org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
      */
-
-    // FIXME protect?
-    public BundleContext getParent() {
-        return m_bundleContext;
+    public void addBundleListener(BundleListener listener) {
+        TenantAwareBundleListener scopedBundleListener = new 
TenantAwareBundleListener(listener);
+        if (m_bundleListeners.putIfAbsent(listener, scopedBundleListener) == 
null) {
+            m_parentBundleContext.addBundleListener(scopedBundleListener);
+        }
     }
 
-    // FIXME why do we need this?
-    public void unregisterServices() {
-        for (ServiceRegistration registration : 
m_serviceRegistrations.values()) {
-            registration.unregister();
+    /**
+     * @see 
org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void addFrameworkListener(FrameworkListener listener) {
+        TenantAwareFrameworkListener scopedFrameworkListener = new 
TenantAwareFrameworkListener(listener);
+        if (m_frameworkListeners.putIfAbsent(listener, 
scopedFrameworkListener) == null) {
+            
m_parentBundleContext.addFrameworkListener(scopedFrameworkListener);
         }
-        m_serviceRegistrations.clear();
     }
 
-    /*
-     * BundleContext interface
+    /**
+     * @see 
org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener)
      */
+    public void addServiceListener(ServiceListener listener) {
+        try {
+            m_parentBundleContext.addServiceListener(listener, 
getScopedFilter(null));
+        }
+        catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+    }
 
     /**
-     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
+     * @see 
org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener,
 java.lang.String)
      */
-    public String getProperty(String key) {
-        return m_bundleContext.getProperty(key);
+    public void addServiceListener(ServiceListener listener, String filter) 
throws InvalidSyntaxException {
+        m_parentBundleContext.addServiceListener(listener, 
getScopedFilter(filter));
     }
 
     /**
-     * @see org.osgi.framework.BundleContext#getBundle()
+     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
      */
-    public Bundle getBundle() {
-        return new TenantAwareBundle(this);
+    public Filter createFilter(String filter) throws InvalidSyntaxException {
+        return m_parentBundleContext.createFilter(filter);
     }
 
     /**
-     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, 
java.io.InputStream)
+     * @see 
org.osgi.framework.BundleContext#getAllServiceReferences(java.lang.String, 
java.lang.String)
      */
-    public Bundle installBundle(String location, InputStream input) throws 
BundleException {
-        // FIXME This does not do what we want... do we even want to allow it?
-        return m_bundleContext.installBundle(location, new 
MultiTenantBundleInputStream(input));
+    public ServiceReference[] getAllServiceReferences(String clazz, String 
filter) throws InvalidSyntaxException {
+        return m_parentBundleContext.getAllServiceReferences(clazz, 
getScopedFilter(filter));
     }
 
     /**
-     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
+     * @see org.osgi.framework.BundleContext#getBundle()
      */
-    public Bundle installBundle(String location) throws BundleException {
-        try {
-            // FIXME This does not do what we want... do we even want to allow 
it?
-            return m_bundleContext.installBundle(location,
-                new MultiTenantBundleInputStream((new 
URL(location)).openStream()));
-        }
-        catch (IOException e) {
-            throw new BundleException(
-                "Could not convert bundle location to an input stream, 
wrapping it failed.", e);
-        }
+    public Bundle getBundle() {
+        return new TenantAwareBundle(this);
     }
 
     /**
      * @see org.osgi.framework.BundleContext#getBundle(long)
      */
     public Bundle getBundle(long id) {
-        Bundle bundle = m_bundleContext.getBundle(id);
-        if (bundle == null)
+        Bundle bundle = m_parentBundleContext.getBundle(id);
+        if (bundle == null) {
             return null;
+        }
         BundleContext bundleContext = bundle.getBundleContext();
         if (bundleContext != null) {
-            // FIXME Do we even want to (always) provide access to foreign 
BundleContext?
-            TenantAwareBundleContext scopedBundleContext =
-                new TenantAwareBundleContext(bundleContext, m_identifier, 
m_filter);
+            TenantAwareBundleContext scopedBundleContext = 
createScopedBundleContext(bundleContext);
             return scopedBundleContext.getBundle();
         }
         return new TenantAwareBundle(bundle);
@@ -152,15 +285,14 @@
      * @see org.osgi.framework.BundleContext#getBundles()
      */
     public Bundle[] getBundles() {
-        Bundle[] bundles = m_bundleContext.getBundles();
-        if (bundles == null)
-            return new Bundle[] {};
+        Bundle[] bundles = m_parentBundleContext.getBundles();
+        if (bundles == null) {
+            return new Bundle[0];
+        }
         for (int i = 0; i < bundles.length; i++) {
             BundleContext bundleContext = bundles[i].getBundleContext();
             if (bundleContext != null) {
-                // FIXME Do we even want to (always) provide access to foreign 
BundleContext?
-                TenantAwareBundleContext scopedBundleContext =
-                    new TenantAwareBundleContext(bundleContext, m_identifier, 
m_filter);
+                TenantAwareBundleContext scopedBundleContext = 
createScopedBundleContext(bundleContext);
                 bundles[i] = scopedBundleContext.getBundle();
             }
             else {
@@ -171,121 +303,138 @@
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener,
 java.lang.String)
+     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
      */
-    public void addServiceListener(ServiceListener listener, String filter) 
throws InvalidSyntaxException {
-        m_bundleContext.addServiceListener(listener, getScopedFilter(filter));
+    public File getDataFile(String filename) {
+        File dataFile = getScopedDataFile(m_identifier);
+        if (dataFile == null) {
+            return null;
+        }
+        if (!dataFile.exists()) {
+            dataFile.mkdir();
+        }
+        if (filename == null || "".equals(filename)) {
+            return dataFile;
+        }
+        return new File(dataFile, filename);
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener)
+     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
      */
-    public void addServiceListener(ServiceListener listener) {
-        try {
-            m_bundleContext.addServiceListener(listener, 
getScopedFilter(null));
-        }
-        catch (InvalidSyntaxException e) {
-            e.printStackTrace();
-        }
+    public String getProperty(String key) {
+        return m_parentBundleContext.getProperty(key);
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#removeServiceListener(org.osgi.framework.ServiceListener)
+     * @see 
org.osgi.framework.BundleContext#getService(org.osgi.framework.ServiceReference)
      */
-    public void removeServiceListener(ServiceListener listener) {
-        m_bundleContext.removeServiceListener(listener);
+    public Object getService(ServiceReference reference) {
+        return m_parentBundleContext.getService(reference);
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
+     * @see 
org.osgi.framework.BundleContext#getServiceReference(java.lang.String)
      */
-    public void addBundleListener(BundleListener listener) {
-        TenantAwareBundleListener scopedBundleListener = new 
TenantAwareBundleListener(listener);
-        if (m_bundleListeners.putIfAbsent(listener, scopedBundleListener) == 
null)
-            m_bundleContext.addBundleListener(scopedBundleListener);
+    public ServiceReference getServiceReference(String clazz) {
+        try {
+            ServiceReference[] references = 
m_parentBundleContext.getServiceReferences(clazz, getScopedFilter(null));
+            if (references != null && references.length > 0) {
+                Arrays.sort(references);
+                return references[0];
+            }
+        }
+        catch (InvalidSyntaxException e) {
+            // Ignore...
+        }
+        return null;
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
+     * @see 
org.osgi.framework.BundleContext#getServiceReferences(java.lang.String, 
java.lang.String)
      */
-    public void removeBundleListener(BundleListener listener) {
-        TenantAwareBundleListener scopedBundleListener = 
m_bundleListeners.remove(listener);
-        if (scopedBundleListener != null)
-            m_bundleContext.removeBundleListener(scopedBundleListener);
+    public ServiceReference[] getServiceReferences(String clazz, String 
filter) throws InvalidSyntaxException {
+        return m_parentBundleContext.getServiceReferences(clazz, 
getScopedFilter(filter));
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
      */
-    public void addFrameworkListener(FrameworkListener listener) {
-        TenantAwareFrameworkListener scopedFrameworkListener = new 
TenantAwareFrameworkListener(listener);
-        if (m_frameworkListeners.putIfAbsent(listener, 
scopedFrameworkListener) == null)
-            m_bundleContext.addFrameworkListener(scopedFrameworkListener);
+    public Bundle installBundle(String location) throws BundleException {
+        try {
+            // FIXME This does not do what we want... do we even want to allow 
it?
+            return m_parentBundleContext.installBundle(location,
+                new MultiTenantBundleInputStream((new 
URL(location)).openStream()));
+        }
+        catch (IOException e) {
+            throw new BundleException(
+                "Could not convert bundle location to an input stream, 
wrapping it failed.", e);
+        }
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, 
java.io.InputStream)
      */
-    public void removeFrameworkListener(FrameworkListener listener) {
-        TenantAwareFrameworkListener scopedFrameworkListener = 
m_frameworkListeners.remove(listener);
-        if (scopedFrameworkListener != null)
-            m_bundleContext.removeFrameworkListener(scopedFrameworkListener);
+    public Bundle installBundle(String location, InputStream input) throws 
BundleException {
+        // FIXME This does not do what we want... do we even want to allow it?
+        return m_parentBundleContext.installBundle(location, new 
MultiTenantBundleInputStream(input));
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#registerService(java.lang.String[], 
java.lang.Object, java.util.Dictionary)
+     * @see org.osgi.framework.BundleContext#registerService(java.lang.String, 
java.lang.Object, java.util.Dictionary)
      */
-    public ServiceRegistration registerService(String[] clazzes, Object 
service, Dictionary properties) {
-        ServiceRegistration registration = 
m_bundleContext.registerService(clazzes, service, 
getScopedProperties(properties));
-        ServiceRegistrationAdapter adapter = new 
ServiceRegistrationAdapter(registration);
+    public ServiceRegistration registerService(String clazz, Object service, 
Dictionary properties) {
+        ServiceRegistration registration = 
m_parentBundleContext.registerService(clazz, service, 
getScopedProperties(properties));
+        
+        ServiceRegistrationAdapter adapter = new 
ServiceRegistrationAdapter(this, registration);
         m_serviceRegistrations.putIfAbsent(adapter, registration);
         return adapter;
     }
 
     /**
-     * @see org.osgi.framework.BundleContext#registerService(java.lang.String, 
java.lang.Object, java.util.Dictionary)
+     * @see 
org.osgi.framework.BundleContext#registerService(java.lang.String[], 
java.lang.Object, java.util.Dictionary)
      */
-    public ServiceRegistration registerService(String clazz, Object service, 
Dictionary properties) {
-        ServiceRegistration registration = 
m_bundleContext.registerService(clazz, service, 
getScopedProperties(properties));
-        ServiceRegistrationAdapter adapter = new 
ServiceRegistrationAdapter(registration);
+    public ServiceRegistration registerService(String[] clazzes, Object 
service, Dictionary properties) {
+        ServiceRegistration registration = 
m_parentBundleContext.registerService(clazzes, service, 
getScopedProperties(properties));
+        
+        ServiceRegistrationAdapter adapter = new 
ServiceRegistrationAdapter(this, registration);
         m_serviceRegistrations.putIfAbsent(adapter, registration);
         return adapter;
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#getServiceReferences(java.lang.String, 
java.lang.String)
+     * @see 
org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
      */
-    public ServiceReference[] getServiceReferences(String clazz, String 
filter) throws InvalidSyntaxException {
-        return m_bundleContext.getServiceReferences(clazz, 
getScopedFilter(filter));
+    public void removeBundleListener(BundleListener listener) {
+        TenantAwareBundleListener scopedBundleListener = 
m_bundleListeners.remove(listener);
+        if (scopedBundleListener != null) {
+            m_parentBundleContext.removeBundleListener(scopedBundleListener);
+        }
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#getAllServiceReferences(java.lang.String, 
java.lang.String)
+     * @see 
org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
      */
-    public ServiceReference[] getAllServiceReferences(String clazz, String 
filter) throws InvalidSyntaxException {
-        return m_bundleContext.getAllServiceReferences(clazz, 
getScopedFilter(filter));
+    public void removeFrameworkListener(FrameworkListener listener) {
+        TenantAwareFrameworkListener scopedFrameworkListener = 
m_frameworkListeners.remove(listener);
+        if (scopedFrameworkListener != null) {
+            
m_parentBundleContext.removeFrameworkListener(scopedFrameworkListener);
+        }
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#getServiceReference(java.lang.String)
+     * @see 
org.osgi.framework.BundleContext#removeServiceListener(org.osgi.framework.ServiceListener)
      */
-    public ServiceReference getServiceReference(String clazz) {
-        try {
-            ServiceReference[] references = 
m_bundleContext.getServiceReferences(clazz, getScopedFilter(null));
-            if (references != null && references.length > 0) {
-                Arrays.sort(references);
-                return references[0];
-            }
-        }
-        catch (Exception e) {}
-        return null;
+    public void removeServiceListener(ServiceListener listener) {
+        m_parentBundleContext.removeServiceListener(listener);
     }
 
     /**
-     * @see 
org.osgi.framework.BundleContext#getService(org.osgi.framework.ServiceReference)
+     * @see java.lang.Object#toString()
      */
-    public Object getService(ServiceReference reference) {
-        return m_bundleContext.getService(reference);
+    @Override
+    public String toString() {
+        return "TenantAwareBundleContext(" + m_identifier + ")";
     }
 
     /**
@@ -293,31 +442,60 @@
      */
     public boolean ungetService(ServiceReference reference) {
         try {
-            return m_bundleContext.ungetService(reference);
+            return m_parentBundleContext.ungetService(reference);
+        }
+        catch (Exception e) {
+            // Ignore...
         }
-        catch (Exception e) {}
         return false;
     }
 
     /**
-     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
+     * Returns the <em>original</em> (i.e., the one that was used to create 
the bundle) bundle context.
+     * <p>
+     * USE WITH CARE, THIS BUNDLE CONTEXT GOES OUTSIDE THE MULTI-TENANCY 
CONCEPT!
+     * </p>
+     * 
+     * @return the original bundle context, never <code>null</code>.
      */
-    public File getDataFile(String filename) {
-        File dataFile = m_bundleContext.getDataFile(m_identifier);
-        if (dataFile == null)
-            return null;
-        if (!dataFile.exists())
-            dataFile.mkdir();
-        if (filename == null || "".equals(filename))
-            return dataFile;
-        return new File(dataFile, filename);
+    final BundleContext getParent() {
+        return m_parentBundleContext;
     }
 
     /**
-     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
+     * Unregisters the given service registration adapter.
+     * 
+     * @param serviceReg the service registration adapter to unregister, 
cannot be <code>null</code>.
      */
-    public Filter createFilter(String filter) throws InvalidSyntaxException {
-        return m_bundleContext.createFilter(filter);
+    final void unregisterService(ServiceRegistrationAdapter serviceReg) {
+        m_serviceRegistrations.remove(serviceReg);
+        serviceReg.getRegistration().unregister();
+    }
+
+    /**
+     * Makes sure all remaining service registrations are cleaned up, and all 
bundle/framework listeners are deregistered as well.
+     */
+    final void unregisterServicesAndListeners() {
+        for (ServiceRegistration registration : 
m_serviceRegistrations.values()) {
+            registration.unregister();
+        }
+        m_serviceRegistrations.clear();
+
+        for (BundleListener bundleListener : m_bundleListeners.keySet()) {
+            removeBundleListener(bundleListener);
+        }
+
+        for (FrameworkListener fwListener : m_frameworkListeners.keySet()) {
+            removeFrameworkListener(fwListener);
+        }
+    }
+
+    /**
+     * @param scope
+     * @return
+     */
+    protected File getScopedDataFile(String scope) {
+        return m_parentBundleContext.getDataFile(scope);
     }
 
     /**
@@ -346,99 +524,12 @@
         return properties;
     }
 
-    protected File getScopedDataFile(String scope) {
-        return m_bundleContext.getDataFile(scope);
-    }
-
-    /*
-     * Private stuff
+    /**
+     * @param bundleContext
+     * @return
      */
-
-    private static class TenantAwareBundleListener implements BundleListener {
-
-        private final BundleListener m_listener;
-
-        public TenantAwareBundleListener(BundleListener listener) {
-            m_listener = listener;
-        }
-
-        public void bundleChanged(BundleEvent event) {
-            m_listener.bundleChanged(new TenantAwareBundleEvent(event));
-        }
-    }
-
-    private static class TenantAwareFrameworkListener implements 
FrameworkListener {
-
-        private final FrameworkListener m_listener;
-
-        public TenantAwareFrameworkListener(FrameworkListener listener) {
-            m_listener = listener;
-
-        }
-
-        public void frameworkEvent(FrameworkEvent event) {
-            m_listener.frameworkEvent(new ScopedFrameworkEvent(event));
-        }
-
-    }
-
-    private static class TenantAwareBundleEvent extends BundleEvent {
-
-        private static final long serialVersionUID = 1L;
-
-        private final BundleEvent m_event;
-
-        public TenantAwareBundleEvent(BundleEvent event) {
-            super(event.getType(), event.getBundle());
-            m_event = event;
-        }
-
-        public Bundle getBundle() {
-            // TODO this effectively hides the original BundleContext. Maybe
-            // we should be nice and make it available within scope?
-            return new TenantAwareBundle(m_event.getBundle());
-        }
-    }
-
-    private static class ScopedFrameworkEvent extends FrameworkEvent {
-
-        private static final long serialVersionUID = 1L;
-
-        private final FrameworkEvent m_event;
-
-        public ScopedFrameworkEvent(FrameworkEvent event) {
-            super(event.getType(), event.getBundle(), event.getThrowable());
-            m_event = event;
-        }
-
-        public Bundle getBundle() {
-            // TODO this effectively hides the original BundleContext. Maybe
-            // we should be nice and make it available within scope?
-            return new TenantAwareBundle(m_event.getBundle());
-        }
-    }
-
-    // FIXME I'd like this to be static
-    private class ServiceRegistrationAdapter implements ServiceRegistration {
-
-        private final ServiceRegistration m_registration;
-
-        public ServiceRegistrationAdapter(ServiceRegistration registration) {
-            m_registration = registration;
-
-        }
-
-        public ServiceReference getReference() {
-            return m_registration.getReference();
-        }
-
-        public void setProperties(Dictionary properties) {
-            m_registration.setProperties(getScopedProperties(properties));
-        }
-
-        public void unregister() {
-            m_serviceRegistrations.remove(this);
-            m_registration.unregister();
-        }
+    private TenantAwareBundleContext createScopedBundleContext(BundleContext 
bundleContext) {
+        // FIXME Do we even want to (always) provide access to foreign 
BundleContext?
+        return new TenantAwareBundleContext(bundleContext, m_identifier, 
m_filter);
     }
 }
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to