Author: [email protected]
Date: Wed Oct 19 21:58:54 2011
New Revision: 1552

Log:
Transferring raw code and pom.xml

Added:
   sandbox/marrs/amdatu-core/tenant/pom.xml
   sandbox/marrs/amdatu-core/tenant/src/
   sandbox/marrs/amdatu-core/tenant/src/main/
   sandbox/marrs/amdatu-core/tenant/src/main/java/
   sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/
   
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/MultiTenantBundleActivator.java
   
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/MultiTenantBundleInputStream.java
   sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/Tenant.java
   sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/TenantConstants.java
   sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/
   sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/TenantAdapter.java
   
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/TenantAwareBundle.java
   
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/TenantAwareBundleContext.java
   sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/packageinfo

Added: sandbox/marrs/amdatu-core/tenant/pom.xml
==============================================================================
--- (empty file)
+++ sandbox/marrs/amdatu-core/tenant/pom.xml    Wed Oct 19 21:58:54 2011
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2010, 2011 The Amdatu Foundation
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.verning permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.amdatu.core</groupId>
+    <artifactId>org.amdatu.core</artifactId>
+    <version>0.2.1-SNAPSHOT</version>
+  </parent>
+  <artifactId>org.amdatu.core.tenant</artifactId>
+  <packaging>bundle</packaging>
+  <name>Amdatu Core - Tenant</name>
+  <description>Provides a transparant mechanism for adding multi-tenancy to an 
OSGi application</description>
+
+  <dependencies> 
+    <dependency>
+      <groupId>org.amdatu.libraries</groupId>
+      <artifactId>org.amdatu.libraries.utilities</artifactId>
+      <version>${org.amdatu.libraries.version}</version>
+      <scope>test</scope>
+    </dependency>    
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Bundle-SymbolicName>org.amdatu.core.tenant</Bundle-SymbolicName>
+            <Export-Package>
+              org.amdatu.core.tenant;version=2.0.0
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build> 
+</project>

Added: 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/MultiTenantBundleActivator.java
==============================================================================
--- (empty file)
+++ 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/MultiTenantBundleActivator.java
       Wed Oct 19 21:58:54 2011
@@ -0,0 +1,32 @@
+package tenant;
+
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+
+import tenant.impl.TenantAdapter;
+
+/**
+ * Generic bundle activator that can be used to convert a normal bundle into a 
multi tenant one.
+ * The process of converting a normal bundle starts with replacing the 
existing bundle activator
+ * with this one. Via a set of extra manifest entries the normal bundle 
activator can be specified.
+ * 
+ * @see TenantConstants
+ */
+public class MultiTenantBundleActivator extends DependencyActivatorBase {
+       @Override
+       public void init(BundleContext context, DependencyManager manager) 
throws Exception {
+               manager.add(createAdapterService(Tenant.class, null)
+                       .setImplementation(TenantAdapter.class)
+                       .add(createServiceDependency()
+                               .setService(LogService.class)
+                               .setRequired(false)
+                       )
+               );
+       }
+
+       @Override
+       public void destroy(BundleContext context, DependencyManager manager) 
throws Exception {
+       }
+}

Added: 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/MultiTenantBundleInputStream.java
==============================================================================
--- (empty file)
+++ 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/MultiTenantBundleInputStream.java
     Wed Oct 19 21:58:54 2011
@@ -0,0 +1,142 @@
+package tenant;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.jar.Attributes;
+import java.util.jar.Attributes.Name;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.osgi.framework.Constants;
+
+/**
+ * Wrapper that modifies an input stream that points to a bundle. The 
resulting input stream represents that
+ * same bundle, but makes it multi tenant aware. It does this by replacing the 
original bundle activator with
+ * one that will create an instance of the original bundle activator for each 
tenant in the system. This
+ * tenant specific instance will receive an adapter to the real bundle context 
when its start() and stop()
+ * life cycle methods are invoked. The adapter in turn does some magic to make 
the bundle work in a 
+ * multi tenant environment by:
+ * <ul>
+ * <li>Adding a tenant ID to every service that is registered, to make it 
tenant specific.</li>
+ * <li>Filtering out any service that has a tenant ID property that is 
different from the current
+ * tenant when the bundle queries for services or registers as a listener.</li>
+ * <li>Providing each tenant with a data area that can be exclusively used by 
that tenant.</li>
+ * </ul>
+ */
+public class MultiTenantBundleInputStream extends InputStream {
+       private static final Name MULTITENANT_VERSION_NAME = new 
Attributes.Name(TenantConstants.MULTITENANT_VERSION_KEY);
+       private static final Name BUNDLE_ACTIVATOR_NAME = new 
Attributes.Name(Constants.BUNDLE_ACTIVATOR);
+       private static final String TENANT_IMPORT_PACKAGE = 
MultiTenantBundleActivator.class.getPackage().getName() + 
";version=\"[1.0,2)\"";
+       private static final int MAX_MANIFEST_SIZE = 65536;
+       private final InputStream m_inputStream;
+       
+       public MultiTenantBundleInputStream(InputStream original) {
+               try {
+                       original = new BufferedInputStream(original);
+                       original.mark(MAX_MANIFEST_SIZE);
+                       JarInputStream jis = new JarInputStream(original);
+                       Manifest manifest = jis.getManifest();
+                       Attributes attributes = manifest.getMainAttributes();
+                       // do not process the bundle if it already has a tenant 
bundle activator (somebody already preprocessed it)
+                       // or it has no bundle activator at all (there's 
nothing to make tenant aware)
+                       if ((attributes.containsKey(MULTITENANT_VERSION_NAME) 
&& 
(attributes.getValue(MULTITENANT_VERSION_NAME).equals(TenantConstants.MULTITENANT_VERSION_VALUE)))
 || !attributes.containsKey(BUNDLE_ACTIVATOR_NAME)) {
+                               original.reset();
+                               m_inputStream = original;
+                       }
+                       else {
+                               String originalBundleActivator = 
attributes.getValue(Constants.BUNDLE_ACTIVATOR);
+                               attributes.putValue(Constants.BUNDLE_ACTIVATOR, 
MultiTenantBundleActivator.class.getName());
+                               
attributes.putValue(TenantConstants.MULTITENANT_BUNDLE_ACTIVATOR_KEY, 
originalBundleActivator);
+                               
attributes.putValue(TenantConstants.MULTITENANT_VERSION_KEY, 
TenantConstants.MULTITENANT_VERSION_VALUE);
+
+                               String originalImportPackage = 
attributes.getValue(Constants.IMPORT_PACKAGE);
+                               if (originalImportPackage == null) {
+                                       
attributes.putValue(Constants.IMPORT_PACKAGE, TENANT_IMPORT_PACKAGE);
+                               }
+                               else {
+                                       
attributes.putValue(Constants.IMPORT_PACKAGE, TENANT_IMPORT_PACKAGE + "," + 
originalImportPackage);
+                               }
+                               
+                               String originalBundleName = 
attributes.getValue(Constants.BUNDLE_NAME);
+                               attributes.putValue(Constants.BUNDLE_NAME, 
originalBundleName + " (MT)");
+                               
+                               ByteArrayOutputStream baos = new 
ByteArrayOutputStream();
+                               JarOutputStream jos = new JarOutputStream(baos, 
manifest);
+                               JarEntry entry = jis.getNextJarEntry();
+                               byte[] buffer = new byte[4096];
+                               while (entry != null) {
+                                       jos.putNextEntry(new 
JarEntry(entry.getName()));
+                                       int bytes = jis.read(buffer);
+                                       while (bytes != -1) {
+                                               jos.write(buffer, 0, bytes);
+                                               bytes = jis.read(buffer);
+                                       }
+                                       jos.closeEntry();
+                                       jis.closeEntry();
+                                       entry = jis.getNextJarEntry();
+                               }
+                               jos.flush();
+                               jos.close();
+                               baos.close();
+                               jis.close();
+                               m_inputStream = new 
ByteArrayInputStream(baos.toByteArray());
+                       }
+               }
+               catch (Exception e) {
+                       throw new RuntimeException("Could not wrap bundle to 
preprocess it.", e);
+               }
+       }
+
+       public int available() throws IOException {
+               return m_inputStream.available();
+       }
+
+       public void close() throws IOException {
+               m_inputStream.close();
+       }
+
+       public boolean equals(Object other) {
+               return m_inputStream.equals(other);
+       }
+
+       public int hashCode() {
+               return m_inputStream.hashCode();
+       }
+
+       public void mark(int readlimit) {
+               m_inputStream.mark(readlimit);
+       }
+
+       public boolean markSupported() {
+               return m_inputStream.markSupported();
+       }
+
+       public int read() throws IOException {
+               return m_inputStream.read();
+       }
+
+       public int read(byte[] b, int off, int len) throws IOException {
+               return m_inputStream.read(b, off, len);
+       }
+
+       public int read(byte[] b) throws IOException {
+               return m_inputStream.read(b);
+       }
+
+       public void reset() throws IOException {
+               m_inputStream.reset();
+       }
+
+       public long skip(long n) throws IOException {
+               return m_inputStream.skip(n);
+       }
+
+       public String toString() {
+               return m_inputStream.toString();
+       }
+}

Added: sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/Tenant.java
==============================================================================
--- (empty file)
+++ sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/Tenant.java   Wed Oct 
19 21:58:54 2011
@@ -0,0 +1,10 @@
+package tenant;
+
+/**
+ * Tenant interface.
+ */
+public interface Tenant {
+       public static final String ID_KEY = "tenant.id";
+       
+       public int getID();
+}

Added: 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/TenantConstants.java
==============================================================================
--- (empty file)
+++ sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/TenantConstants.java  
Wed Oct 19 21:58:54 2011
@@ -0,0 +1,10 @@
+package tenant;
+
+/**
+ * Compile time constants for multi tenancy.
+ */
+public interface TenantConstants {
+       public static final String MULTITENANT_BUNDLE_ACTIVATOR_KEY = 
"MultiTenant-Bundle-Activator";
+       public static final String MULTITENANT_VERSION_KEY = 
"MultiTenant-Version";
+       public static final String MULTITENANT_VERSION_VALUE = "1";
+}

Added: 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/TenantAdapter.java
==============================================================================
--- (empty file)
+++ 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/TenantAdapter.java   
    Wed Oct 19 21:58:54 2011
@@ -0,0 +1,49 @@
+package tenant.impl;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+
+import tenant.Tenant;
+import tenant.TenantConstants;
+
+/**
+ * Adapter that instantiates a bundle activator and makes that instance tenant 
specific
+ * by intercepting the bundle context.
+ */
+public class TenantAdapter {
+       private volatile BundleContext m_context;
+       private volatile Tenant m_tenant;
+       private volatile LogService m_log;
+       private String m_bundleActivatorClass;
+       private BundleActivator m_tenantBundleActivator;
+       private TenantAwareBundleContext m_tenantAwareBundleContext;
+       
+       public void start() {
+               try {
+                       m_bundleActivatorClass = (String) 
m_context.getBundle().getHeaders().get(TenantConstants.MULTITENANT_BUNDLE_ACTIVATOR_KEY);
+                       if (m_bundleActivatorClass == null) {
+                               m_log.log(LogService.LOG_ERROR, "Missing 
manifest header " + TenantConstants.MULTITENANT_BUNDLE_ACTIVATOR_KEY);
+                               return;
+                       }
+                       m_tenantBundleActivator = (BundleActivator) 
m_context.getBundle().loadClass(m_bundleActivatorClass).newInstance();
+                       m_tenantAwareBundleContext = new 
TenantAwareBundleContext(m_context, m_tenant.getID());
+                       
m_tenantBundleActivator.start(m_tenantAwareBundleContext);
+               }
+               catch (Exception e) {
+                       m_log.log(LogService.LOG_ERROR, "Could not start 
activator for tenant " + m_tenant.getID(), e);
+               }
+       }
+       
+       public void stop() {
+               try {
+                       if (m_tenantBundleActivator != null) {
+                               
m_tenantBundleActivator.stop(m_tenantAwareBundleContext);
+                               m_tenantAwareBundleContext.unregisterServices();
+                       }
+               }
+               catch (Exception e) {
+                       m_log.log(LogService.LOG_ERROR, "Could not stop 
activator for tenant " + m_tenant.getID(), e);
+               }
+       }
+}

Added: 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/TenantAwareBundle.java
==============================================================================
--- (empty file)
+++ 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/TenantAwareBundle.java
   Wed Oct 19 21:58:54 2011
@@ -0,0 +1,135 @@
+package tenant.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Map;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+
+/**
+ * Wrapper class for the bundle interface to make it tenant aware.
+ */
+public class TenantAwareBundle implements Bundle {
+       private final Bundle m_bundle;
+       private final int m_tenantId;
+       
+       public TenantAwareBundle(Bundle bundle, int tenantId) {
+               m_bundle = bundle;
+               m_tenantId = tenantId;
+       }
+
+       public int getState() {
+               return m_bundle.getState();
+       }
+
+       public void start(int options) throws BundleException {
+               m_bundle.start(options);
+       }
+
+       public void start() throws BundleException {
+               m_bundle.start();
+       }
+
+       public void stop(int options) throws BundleException {
+               m_bundle.stop(options);
+       }
+
+       public void stop() throws BundleException {
+               m_bundle.stop();
+       }
+
+       public void update(InputStream input) throws BundleException {
+               m_bundle.update(input);
+       }
+
+       public void update() throws BundleException {
+               m_bundle.update();
+       }
+
+       public void uninstall() throws BundleException {
+               m_bundle.uninstall();
+       }
+
+       public Dictionary getHeaders() {
+               return m_bundle.getHeaders();
+       }
+
+       public long getBundleId() {
+               return m_bundle.getBundleId();
+       }
+
+       public String getLocation() {
+               return m_bundle.getLocation();
+       }
+
+       public ServiceReference[] getRegisteredServices() {
+               return m_bundle.getRegisteredServices();
+       }
+
+       public ServiceReference[] getServicesInUse() {
+               return m_bundle.getServicesInUse();
+       }
+
+       public boolean hasPermission(Object permission) {
+               return m_bundle.hasPermission(permission);
+       }
+
+       public URL getResource(String name) {
+               return m_bundle.getResource(name);
+       }
+
+       public Dictionary getHeaders(String locale) {
+               return m_bundle.getHeaders(locale);
+       }
+
+       public String getSymbolicName() {
+               return m_bundle.getSymbolicName();
+       }
+
+       public Class loadClass(String name) throws ClassNotFoundException {
+               return m_bundle.loadClass(name);
+       }
+
+       public Enumeration getResources(String name) throws IOException {
+               return m_bundle.getResources(name);
+       }
+
+       public Enumeration getEntryPaths(String path) {
+               return m_bundle.getEntryPaths(path);
+       }
+
+       public URL getEntry(String path) {
+               return m_bundle.getEntry(path);
+       }
+
+       public long getLastModified() {
+               return m_bundle.getLastModified();
+       }
+
+       public Enumeration findEntries(String path, String filePattern, boolean 
recurse) {
+               return m_bundle.findEntries(path, filePattern, recurse);
+       }
+
+       public BundleContext getBundleContext() {
+               BundleContext bundleContext = m_bundle.getBundleContext();
+               if (bundleContext != null) {
+                       return new TenantAwareBundleContext(bundleContext, 
m_tenantId);
+               }
+               return null;
+       }
+
+       public Map getSignerCertificates(int signersType) {
+               return m_bundle.getSignerCertificates(signersType);
+       }
+
+       public Version getVersion() {
+               return m_bundle.getVersion();
+       }
+}

Added: 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/TenantAwareBundleContext.java
==============================================================================
--- (empty file)
+++ 
sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/impl/TenantAwareBundleContext.java
    Wed Oct 19 21:58:54 2011
@@ -0,0 +1,343 @@
+package tenant.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import tenant.MultiTenantBundleInputStream;
+import tenant.Tenant;
+
+/**
+ * Wrapper class for the bundle context interface to make it tenant aware.
+ */
+public class TenantAwareBundleContext implements BundleContext {
+       private static final String TENANT_DATAFILE_PREFIX = "tenant-";
+       private final BundleContext m_bundleContext;
+       private final Bundle m_bundle;
+       private final int m_tenantId;
+       private File m_dataFile;
+       private final ConcurrentHashMap<BundleListener, 
TenantAwareBundleListener> m_bundleListeners = new 
ConcurrentHashMap<BundleListener, TenantAwareBundleListener>();
+       private final ConcurrentHashMap<FrameworkListener, 
TenantAwareFrameworkListener> m_frameworkListeners = new 
ConcurrentHashMap<FrameworkListener, TenantAwareFrameworkListener>();
+       private final ConcurrentHashMap<ServiceRegistrationAdapter, 
ServiceRegistration> m_serviceRegistrations = new 
ConcurrentHashMap<ServiceRegistrationAdapter, ServiceRegistration>();
+
+       public TenantAwareBundleContext(BundleContext bc, int tenantId) {
+               m_bundleContext = bc;
+               m_tenantId = tenantId;
+               m_bundle = new TenantAwareBundle(bc.getBundle(), m_tenantId);
+       }
+       
+       public void unregisterServices() {
+               for (ServiceRegistration registration : 
m_serviceRegistrations.values()) {
+                       registration.unregister();
+               }
+               m_serviceRegistrations.clear();
+       }
+
+       @Override
+       public String getProperty(String key) {
+               return m_bundleContext.getProperty(key);
+       }
+
+       @Override
+       public Bundle getBundle() {
+               return m_bundle;
+       }
+
+       @Override
+       public Bundle installBundle(String location, InputStream input) throws 
BundleException {
+               return m_bundleContext.installBundle(location, new 
MultiTenantBundleInputStream(input));
+       }
+
+       @Override
+       public Bundle installBundle(String location) throws BundleException {
+               try {
+                       return m_bundleContext.installBundle(location, new 
MultiTenantBundleInputStream(bundleLocationToInputStream(location)));
+               }
+               catch (IOException e) {
+                       throw new BundleException("Could not convert bundle 
location to an input stream, wrapping it failed.", e);
+               }
+       }
+
+       private InputStream bundleLocationToInputStream(String location) throws 
IOException {
+               return (new URL(location)).openStream();
+       }
+
+       @Override
+       public Bundle getBundle(long id) {
+               Bundle bundle = m_bundleContext.getBundle(id);
+               return new TenantAwareBundle(bundle, m_tenantId);
+       }
+
+       @Override
+       public Bundle[] getBundles() {
+               Bundle[] bundles = m_bundleContext.getBundles();
+               for (int i = 0; i < bundles.length; i++) {
+                       Bundle bundle = bundles[i];
+                       bundles[i] = new TenantAwareBundle(bundle, m_tenantId);
+               }
+               return bundles;
+       }
+
+       @Override
+       public void addServiceListener(ServiceListener listener, String filter) 
throws InvalidSyntaxException {
+               m_bundleContext.addServiceListener(listener, 
getCompleteFilter(filter));
+       }
+
+       @Override
+       public void addServiceListener(ServiceListener listener) {
+               try {
+                       m_bundleContext.addServiceListener(listener, 
getCompleteFilter(null));
+               }
+               catch (InvalidSyntaxException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public void removeServiceListener(ServiceListener listener) {
+               m_bundleContext.removeServiceListener(listener);
+       }
+
+       @Override
+       public void addBundleListener(BundleListener listener) {
+               TenantAwareBundleListener tenantAwareBundleListener = new 
TenantAwareBundleListener(listener);
+               if (m_bundleListeners.putIfAbsent(listener, 
tenantAwareBundleListener) == null) {
+                       
m_bundleContext.addBundleListener(tenantAwareBundleListener);
+               }
+       }
+
+       @Override
+       public void removeBundleListener(BundleListener listener) {
+               TenantAwareBundleListener tenantAwareBundleListener = 
m_bundleListeners.remove(listener);
+               if (tenantAwareBundleListener != null) {
+                       
m_bundleContext.removeBundleListener(tenantAwareBundleListener);
+               }
+       }
+
+       @Override
+       public void addFrameworkListener(FrameworkListener listener) {
+               TenantAwareFrameworkListener tenantAwareFrameworkListener = new 
TenantAwareFrameworkListener(listener);
+               if (m_frameworkListeners.putIfAbsent(listener, 
tenantAwareFrameworkListener) == null) {
+                       
m_bundleContext.addFrameworkListener(tenantAwareFrameworkListener);
+               }
+       }
+
+       @Override
+       public void removeFrameworkListener(FrameworkListener listener) {
+               TenantAwareFrameworkListener tenantAwareFrameworkListener = 
m_frameworkListeners.remove(listener);
+               if (tenantAwareFrameworkListener != null) {
+                       
m_bundleContext.removeFrameworkListener(tenantAwareFrameworkListener);
+               }
+       }
+
+       @Override
+       public ServiceRegistration registerService(String[] clazzes, Object 
service, Dictionary properties) {
+               if (properties == null) {
+                       properties = new Properties();
+               }
+               properties.put(Tenant.ID_KEY, Integer.valueOf(m_tenantId));
+               ServiceRegistration registration = 
m_bundleContext.registerService(clazzes, service, properties);
+               ServiceRegistrationAdapter adapter = new 
ServiceRegistrationAdapter(registration);
+               m_serviceRegistrations.put(adapter, registration);
+               return adapter;
+       }
+
+       @Override
+       public ServiceRegistration registerService(String clazz, Object 
service, Dictionary properties) {
+               if (properties == null) {
+                       properties = new Properties();
+               }
+               properties.put(Tenant.ID_KEY, Integer.valueOf(m_tenantId));
+               ServiceRegistration registration = 
m_bundleContext.registerService(clazz, service, properties);
+               ServiceRegistrationAdapter adapter = new 
ServiceRegistrationAdapter(registration);
+               m_serviceRegistrations.put(adapter, registration);
+               return adapter;
+       }
+
+       @Override
+       public ServiceReference[] getServiceReferences(String clazz, String 
filter) throws InvalidSyntaxException {
+               try {
+                       return m_bundleContext.getServiceReferences(clazz, 
getCompleteFilter(filter));
+               }
+               catch (InvalidSyntaxException e) {
+                       e.printStackTrace();
+               }
+               return null;
+       }
+       
+       public String getCompleteFilter(String filter) {
+               String result = (filter == null) ? "(|(" + Tenant.ID_KEY + "=" 
+ m_tenantId +")(!(" + Tenant.ID_KEY + "=*)))" : "(&(|(" + Tenant.ID_KEY + "=" 
+ m_tenantId +")(!(" + Tenant.ID_KEY + "=*)))" + filter + ")";
+               return result;
+       }
+
+       @Override
+       public ServiceReference[] getAllServiceReferences(String clazz, String 
filter) throws InvalidSyntaxException {
+               try {
+                       return m_bundleContext.getAllServiceReferences(clazz, 
getCompleteFilter(filter));
+               }
+               catch (InvalidSyntaxException e) {
+                       e.printStackTrace();
+               }
+               return null;
+       }
+
+       @Override
+       public ServiceReference getServiceReference(String clazz) {
+               try {
+                       ServiceReference[] references = 
m_bundleContext.getServiceReferences(clazz, "(|(" + Tenant.ID_KEY + "=" + 
m_tenantId +")(!(" + Tenant.ID_KEY + "=*)))");
+                       if (references != null && references.length > 0) {
+                               if (references.length > 1) {
+                                       Arrays.sort(references);
+                               }
+                               return references[0];
+                       }
+               }
+               catch (InvalidSyntaxException e) {
+                       e.printStackTrace();
+               }
+               return null;
+       }
+
+       @Override
+       public Object getService(ServiceReference reference) {
+               return m_bundleContext.getService(reference);
+       }
+
+       @Override
+       public boolean ungetService(ServiceReference reference) {
+               return m_bundleContext.ungetService(reference);
+       }
+
+       @Override
+       public File getDataFile(String filename) {
+               if (m_dataFile == null) {
+                       m_dataFile = 
m_bundleContext.getDataFile(createTenantDataFile());
+                       if (m_dataFile == null) {
+                               return null;
+                       }
+                       m_dataFile.mkdir();
+               }
+               if (filename == null) {
+                       return m_dataFile;
+               }
+               else {
+                       return new File(m_dataFile, filename);
+               }
+       }
+
+       private String createTenantDataFile() {
+               return TENANT_DATAFILE_PREFIX + m_tenantId;
+       }
+
+       @Override
+       public Filter createFilter(String filter) throws InvalidSyntaxException 
{
+               return m_bundleContext.createFilter(filter);
+       }
+       
+       private class TenantAwareBundleListener implements BundleListener {
+               private final BundleListener m_listener;
+
+               public TenantAwareBundleListener(BundleListener listener) {
+                       m_listener = listener;
+               }
+
+               @Override
+               public void bundleChanged(BundleEvent event) {
+                       m_listener.bundleChanged(new 
TenantAwareBundleEvent(event));
+               }
+       }
+       
+       private class TenantAwareFrameworkListener implements FrameworkListener 
{
+               private final FrameworkListener m_listener;
+
+               public TenantAwareFrameworkListener(FrameworkListener listener) 
{
+                       m_listener = listener;
+                       
+               }
+
+               @Override
+               public void frameworkEvent(FrameworkEvent event) {
+                       m_listener.frameworkEvent(new 
TenantAwareFrameworkEvent(event));
+               }
+               
+       }
+       
+       private class TenantAwareBundleEvent extends BundleEvent {
+               private final BundleEvent m_event;
+               private final Bundle m_bundle;
+
+               public TenantAwareBundleEvent(BundleEvent event) {
+                       super(event.getType(), event.getBundle());
+                       m_event = event;
+                       Bundle eventBundle = m_event.getBundle();
+                       BundleContext eventBundleContext = 
eventBundle.getBundleContext();
+                       m_bundle = new TenantAwareBundle(eventBundle, 
m_tenantId);
+               }
+               
+               @Override
+               public Bundle getBundle() {
+                       return m_bundle;
+               }
+       }
+       
+       private class TenantAwareFrameworkEvent extends FrameworkEvent {
+               private final FrameworkEvent m_event;
+               private final Bundle m_bundle;
+
+               public TenantAwareFrameworkEvent(FrameworkEvent event) {
+                       super(event.getType(), event.getBundle(), 
event.getThrowable());
+                       m_event = event;
+                       Bundle eventBundle = m_event.getBundle();
+                       BundleContext eventBundleContext = 
eventBundle.getBundleContext();
+                       m_bundle = new TenantAwareBundle(eventBundle, 
m_tenantId);
+               }
+               
+               @Override
+               public Bundle getBundle() {
+                       return m_bundle;
+               }
+       }
+       
+       private class ServiceRegistrationAdapter implements ServiceRegistration 
{
+               private final ServiceRegistration m_registration;
+
+               public ServiceRegistrationAdapter(ServiceRegistration 
registration) {
+                       m_registration = registration;
+                       
+               }
+
+               @Override
+               public ServiceReference getReference() {
+                       return m_registration.getReference();
+               }
+
+               @Override
+               public void setProperties(Dictionary properties) {
+                       m_registration.setProperties(properties);
+               }
+
+               @Override
+               public void unregister() {
+                       m_serviceRegistrations.remove(this);
+                       m_registration.unregister();
+               }
+       }
+}

Added: sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/packageinfo
==============================================================================
--- (empty file)
+++ sandbox/marrs/amdatu-core/tenant/src/main/java/tenant/packageinfo   Wed Oct 
19 21:58:54 2011
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to