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
