/****************************************************************************** * Copyright (c) 2006, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0 * is available at http://www.opensource.org/licenses/apache2.0.php. * You may elect to redistribute this code under either of these licenses. * * Contributors: * VMware Inc. *****************************************************************************/ package org.eclipse.gemini.blueprint.extender.internal; import java.util.ArrayList; import java.util.Arrays; import java.util.Dictionary; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Properties; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.eclipse.gemini.blueprint.mock.MockBundle; import org.eclipse.gemini.blueprint.mock.MockServiceReference; import org.eclipse.gemini.blueprint.service.exporter.OsgiServicePropertiesResolver; /** * Mock bundle useful for testing service dependencies. * * @author Costin Leau * */ public class DependencyMockBundle extends MockBundle { // bundles which depend on the current one protected List<Bundle> dependentOn = new ArrayList<Bundle>(); // bundles on which the current bundle depends on protected List<Bundle> dependsOn = new ArrayList<Bundle>(); private Map<Bundle, ServiceReference> inUseServices = new LinkedHashMap<Bundle, ServiceReference>(); private Map<Bundle, ServiceReference> registeredServices = new LinkedHashMap<Bundle, ServiceReference>(); public DependencyMockBundle() { super(); } public DependencyMockBundle(BundleContext context) { super(context); } public DependencyMockBundle(Dictionary headers) { super(headers); } public DependencyMockBundle(String location, Dictionary headers, BundleContext context) { super(location, headers, context); } public DependencyMockBundle(String location) { super(location); } private Dictionary createProps(int index, int[] serviceRanking, long[] serviceId) { // set Properties Dictionary props = new Properties(); props.put(Constants.SERVICE_RANKING, new Integer((index < serviceRanking.length ? serviceRanking[index] : serviceRanking[0]))); long id = (index < serviceId.length ? serviceId[index] : serviceId[0]); if (id >= 0) props.put(Constants.SERVICE_ID, new Long(id)); props.put(OsgiServicePropertiesResolver.SPRING_DM_BEAN_NAME_PROPERTY_KEY, new Long(id)); props.put(OsgiServicePropertiesResolver.BEAN_NAME_PROPERTY_KEY, new Long(id)); return props; } /** * Create one service reference returning the using bundle. * * @param dependent */ public void setDependentOn(final Bundle[] dependents, int[] serviceRanking, long[] serviceId) { this.dependentOn.addAll(Arrays.asList(dependents)); for (Bundle dependent : dependents) { if (dependent instanceof DependencyMockBundle) { ((DependencyMockBundle) dependent).dependsOn.add(this); } } // initialise registered services registeredServices.clear(); for (int i = 0; i < dependents.length; i++) { registeredServices.put(dependents[i], new MockServiceReference(DependencyMockBundle.this, createProps(i, serviceRanking, serviceId), null) { public Bundle[] getUsingBundles() { return DependencyMockBundle.this.dependentOn.toArray(new Bundle[dependentOn.size()]); } }); } } public void setDependentOn(final Bundle[] dependent, int serviceRanking, long serviceId) { setDependentOn(dependent, new int[] { serviceRanking }, new long[] { serviceId }); } public void setDependentOn(final Bundle[] dependent) { setDependentOn(dependent, 0, -1); } public void setDependentOn(Bundle dependent) { setDependentOn(new Bundle[] { dependent }, 0, -1); } public void setDependentOn(Bundle dependent, int serviceRanking, long serviceId) { setDependentOn(new Bundle[] { dependent }, serviceRanking, serviceId); } protected void setDependsOn(Bundle[] depends) { this.dependsOn.addAll(Arrays.asList(depends)); // initialize InUseServices inUseServices.clear(); final Bundle[] usingBundles = new Bundle[] { this }; for (final Bundle dependencyBundle : dependsOn) { // make connection from the opposite side also if (dependencyBundle instanceof DependencyMockBundle) { ((DependencyMockBundle) dependencyBundle).setDependentOn(this); } Properties props = new Properties(); props.put(OsgiServicePropertiesResolver.SPRING_DM_BEAN_NAME_PROPERTY_KEY, new Long(System .identityHashCode(dependencyBundle))); props.put(OsgiServicePropertiesResolver.BEAN_NAME_PROPERTY_KEY, new Long(System .identityHashCode(dependencyBundle))); inUseServices.put(dependencyBundle, new MockServiceReference() { public Bundle getBundle() { return dependencyBundle; } public Bundle[] getUsingBundles() { return usingBundles; } }); } } protected void setDependsOn(Bundle depends) { setDependsOn(new Bundle[] { depends }); } public ServiceReference[] getRegisteredServices() { return registeredServices.values().toArray(new ServiceReference[registeredServices.size()]); } public ServiceReference[] getServicesInUse() { return inUseServices.values().toArray(new ServiceReference[registeredServices.size()]); } @Override public void stop(int options) throws BundleException { if (dependentOn != null) for (Bundle dependent : dependentOn) { if (dependent instanceof DependencyMockBundle) { DependencyMockBundle dep = ((DependencyMockBundle) dependent); List<Bundle> list = dep.dependsOn; if (list != null) list.remove(this); dep.inUseServices.remove(dependent); } } dependentOn = null; if (dependsOn != null) for (Bundle dependent : dependsOn) { if (dependent instanceof DependencyMockBundle) { DependencyMockBundle dep = ((DependencyMockBundle) dependent); List<Bundle> list = dep.dependentOn; if (list != null) list.remove(this); } } dependsOn = null; inUseServices.clear(); registeredServices.clear(); } }