blob: 59983d19c51350f54c9400156daf97ec24358581 [file] [log] [blame]
/***********************************************************************************************************************
* Copyright (c) 2008 empolis GmbH and brox IT Solutions GmbH. All rights reserved. This program and the accompanying
* materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: - Daniel Stucky (empolis GmbH) - initial API and implementation - Andreas Schank (Attensity Europe
* GmbH) - extension for unregistering of test services.
**********************************************************************************************************************/
package org.eclipse.smila.test;
import java.io.IOException;
import java.net.URL;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.smila.utils.log.BundleLogHelper;
import org.eclipse.smila.utils.service.ServiceUtils;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
/**
* Abstract base class for JUnit tests dealing with DeclarativeServices.
*/
public abstract class DeclarativeServiceTestCase extends TestCase {
/**
* The Constant DEFAULT_SERVICE_MAX_WAITING.
*/
protected static final int DEFAULT_SERVICE_MAX_WAITING = 60000;
/**
* static reference to a BundleContext. It is set in the BundleActivator.
*/
private static BundleContext s_bundleContext;
/**
* The log.
*/
protected final Log _log = LogFactory.getLog(getClass());
/** a map of registered services to ServiceRegistration. */
private final Map<Class<?>, ServiceRegistration> _registeredServices =
new HashMap<Class<?>, ServiceRegistration>();
/**
* Sets the BundleContext.
*
* @param bundleContext
* the BundleContext
*/
public static void setBundleContext(final BundleContext bundleContext) {
s_bundleContext = bundleContext;
}
/**
* Uses a ServiceTracker to get the given DeclarativeService.
*
* @param clazz
* the class name of the DeclarativeService interface
* @param timeout
* the number of milliseconds to wait for the ServiceTracker to find the service
*
* @return the DeclarativeService as Object. You have to do a type cast.
*
* @throws InterruptedException
* a InterruptedException
*/
@Deprecated
protected Object getService(final String clazz, final long timeout) throws InterruptedException {
final ServiceReference reference = s_bundleContext.getServiceReference(clazz);
if (reference != null) {
final Object service = s_bundleContext.getService(reference);
if (service != null) {
return service;
}
}
ServiceTracker st = null;
try {
st = new ServiceTracker(s_bundleContext, clazz, null);
st.open();
st.waitForService(timeout);
if (st.getService() == null) {
final String msg = "Unable to find service " + clazz;
_log.error(msg);
BundleLogHelper.logBundlesState();
throw new RuntimeException(msg);
}
return st.getService();
} finally {
if (st != null) {
st.close();
}
}
}
/**
* Uses a ServiceTracker to get the given DeclarativeService.
*
* @param clazz
* the service class of the DeclarativeService interface
* @param timeout
* the number of milliseconds to wait for the ServiceTracker to find the service
*
* @return the DeclarativeService.
*
* @throws InterruptedException
* a InterruptedException
*/
@SuppressWarnings("unchecked")
@Deprecated
protected <T> T getService(final Class<T> clazz, final long timeout) throws InterruptedException {
return (T) getService(clazz.getName(), timeout);
}
/**
* Gets the service with default wait delay.
*
* @param clazz
* the clazz
* @return the service
*
* @throws InterruptedException
* the interrupted exception
*/
@SuppressWarnings("unchecked")
protected <T> T getService(final Class<T> clazz) throws InterruptedException {
return (T) getService(clazz.getName(), DEFAULT_SERVICE_MAX_WAITING);
}
/**
* Uses a ServiceTracker to get the given DeclarativeService.
*
* @param clazz
* the service class of the DeclarativeService interface
* @param filter
* the filter
* @param timeout
* the number of milliseconds to wait for the ServiceTracker to find the service
*
* @return the DeclarativeService.
*
* @throws InterruptedException
* a InterruptedException
*/
@SuppressWarnings("unchecked")
protected <T> T getService(final Class<T> clazz, final String filter, final long timeout)
throws InterruptedException {
return (T) getService(clazz.getName(), filter, timeout);
}
/**
* Gets the service with default wait delay.
*
* @param clazz
* the clazz
* @param filter
* the filter
*
* @return the service
*
* @throws InterruptedException
* the interrupted exception
*/
@SuppressWarnings("unchecked")
protected <T> T getService(final Class<T> clazz, final String filter) throws InterruptedException {
return (T) getService(clazz.getName(), filter, DEFAULT_SERVICE_MAX_WAITING);
}
/**
* Uses a ServiceTracker to get the given DeclarativeService.
*
* @param clazz
* the class name of the DeclarativeService interface
* @param timeout
* the number of milliseconds to wait for the ServiceTracker to find the service
*
* @return the DeclarativeService as Object. You have to do a type cast.
*
* @throws InterruptedException
* a InterruptedException
*/
@Deprecated
protected Object getService(final String clazz, final String filter, final long timeout)
throws InterruptedException {
try {
final ServiceReference[] references = s_bundleContext.getServiceReferences(clazz, filter);
if (references != null) {
final Object service = s_bundleContext.getService(references[0]);
if (service != null) {
return service;
}
}
ServiceTracker st = null;
try {
final Filter serviceFilter = s_bundleContext.createFilter(filter);
st = new ServiceTracker(s_bundleContext, serviceFilter, null);
st.open();
st.waitForService(timeout);
if (st.getService() == null) {
final String msg = "Unable to find service " + clazz;
_log.error(msg);
BundleLogHelper.logBundlesState();
throw new RuntimeException(msg);
}
return st.getService();
} finally {
if (st != null) {
st.close();
}
}
} catch (final InvalidSyntaxException e) {
final String msg = "Unable to find service " + clazz;
_log.error(msg);
BundleLogHelper.logBundlesState();
throw new RuntimeException(msg, e);
}
}
/**
* Registers the given service and returns it.
*
* @param service
* the service to register
* @param properties
* properties
* @param clazz
* the service class of the DeclarativeService interface
* @param timeout
* the number of milliseconds to wait for the ServiceTracker to find the service
*
* @return the DeclarativeService
*
* @throws InterruptedException
* a InterruptedException
*/
protected <T> T registerService(final Object service, final Dictionary<String, ?> properties,
final Class<T> clazz, final long timeout) throws InterruptedException {
final ServiceRegistration sReg = s_bundleContext.registerService(clazz.getName(), service, properties);
_registeredServices.put(clazz, sReg);
return getService(clazz, timeout);
}
/**
* Unregisters the given service.
*
* @param clazz
* the service class to be unregistered
*
* @throws InterruptedException
* a InterruptedException
*
* @see {@link org.osgi.framework.BundleContext#ungetService(ServiceReference)}.
*/
protected void unregisterService(final Class<?> clazz) throws InterruptedException {
final ServiceRegistration sReg = _registeredServices.get(clazz);
if (sReg != null) {
sReg.unregister();
}
}
/**
* Resolve resource URL.
*
* @param relativePath
* the relative path
*
* @return the uRL
*
* @throws IOException
* Signals that an I/O exception has occurred.
*/
protected URL resolveResourceURL(final String relativePath) throws IOException {
final URL nativeUrl = getClass().getClassLoader().getResource(relativePath);
final URL url = FileLocator.resolve(nativeUrl);
return url;
}
/**
* check if a service with the given service and implementation class was registered.
*
* @param serviceInterface
* service interface class
* @param implementationClass
* implementation class
*/
protected static void assertServiceRegistered(final Class<?> serviceInterface, final Class<?> implementationClass) {
final ServiceReference[] refs = ServiceUtils.getServiceReferences(serviceInterface);
Assert.assertNotNull(refs);
for (final ServiceReference ref : refs) {
final Object service = ServiceUtils.getService(ref, serviceInterface);
if (service.getClass() == implementationClass) {
return;
}
}
Assert.fail(implementationClass.getName() + " service not registered");
}
}