package ddth.dasp.common.utils;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* OSGi related utilities.
*
* @author NBThanh <btnguyen2k@gmail.com>
*/
public class OsgiUtils {
private final static Logger LOGGER = LoggerFactory.getLogger(OsgiUtils.class);
/**
* Gets the string represented the bundle state.
*
* @param bundle
* @return
*/
public static String getBundleStateAsString(Bundle bundle) {
int state = bundle.getState();
if ((state & Bundle.UNINSTALLED) != 0) {
return "UNINSTALLED";
}
if ((state & Bundle.INSTALLED) != 0) {
return "INSTALLED";
}
if ((state & Bundle.RESOLVED) != 0) {
return "RESOLVED";
}
if ((state & Bundle.STARTING) != 0) {
return "STARTING";
}
if ((state & Bundle.STOPPING) != 0) {
return "STOPPING";
}
if ((state & Bundle.ACTIVE) != 0) {
return "ACTIVE";
}
return "UNKNOWN";
}
/**
* Obtains an OSGi service reference.
*
* @param bundleContext
* BundleContext
* @param clazz
* String
* @return ServiceReference
*/
public static ServiceReference<?> getServiceReference(BundleContext bundleContext, String clazz) {
return getServiceReference(bundleContext, clazz, (String) null);
}
/**
* Obtains an OSGi service reference.
*
* @param bundleContext
* BundleContext
* @param clazz
* String
* @param filter
* Map<String, String>
* @return ServiceReference
*/
public static ServiceReference<?> getServiceReference(BundleContext bundleContext,
String clazz, Map<String, String> filter) {
if (filter == null || filter.size() == 0) {
return getServiceReference(bundleContext, clazz, (String) null);
}
StringBuilder query = new StringBuilder("(&");
for (Entry<String, String> entry : filter.entrySet()) {
query.append("(");
query.append(entry.getKey());
query.append("=");
query.append(entry.getValue());
query.append(")");
}
query.append(")");
return getServiceReference(bundleContext, clazz, query.toString());
}
/**
* Obtains an OSGi service reference.
*
* @param bundleContext
* BundleContext
* @param clazz
* String
* @param query
* String
* @return ServiceReference
*/
public static ServiceReference<?> getServiceReference(BundleContext bundleContext,
String clazz, String query) {
ServiceReference<?>[] refs = getServiceReferences(bundleContext, clazz, query);
ServiceReference<?> ref = (refs != null && refs.length > 0) ? refs[0] : null;
for (int i = 1, n = refs != null ? refs.length : 0; i < n; i++) {
ServiceReference<?> temp = refs[i];
Object v1 = ref.getProperty("Version");
Object v2 = temp.getProperty("Version");
if (VersionUtils.compareVersions(v1 != null ? v1.toString() : null,
v2 != null ? v2.toString() : null) < 0) {
// unget unmatched service reference
ungetServiceReference(bundleContext, ref);
ref = temp;
} else {
// unget unmatched service reference
ungetServiceReference(bundleContext, temp);
}
}
return ref;
}
/**
* Obtains all OSGi service references by filter.
*
* @param bundleContext
* BundleContext
* @param clazz
* String
* @param filter
* Map<String, String>
* @return ServiceReference
*/
public static ServiceReference<?>[] getServiceReferences(BundleContext bundleContext,
String clazz, Map<String, String> filter) {
if (filter == null || filter.size() == 0) {
return getServiceReferences(bundleContext, clazz, (String) null);
}
StringBuilder query = new StringBuilder("(&");
for (Entry<String, String> entry : filter.entrySet()) {
query.append("(");
query.append(entry.getKey());
query.append("=");
query.append(entry.getValue());
query.append(")");
}
query.append(")");
return getServiceReferences(bundleContext, clazz, query.toString());
}
/**
* Obtains all OSGi service references by query.
*
* @param bundleContext
* BundleContext
* @param clazz
* String
* @param query
* String
* @return ServiceReference[]
*/
public static ServiceReference<?>[] getServiceReferences(BundleContext bundleContext,
String clazz, String query) {
if (query == null) {
ServiceReference<?> serviceRef = bundleContext.getServiceReference(clazz);
return serviceRef != null ? new ServiceReference[] { serviceRef }
: new ServiceReference[0];
} else {
try {
ServiceReference<?>[] serviceRefs = bundleContext
.getServiceReferences(clazz, query);
return serviceRefs != null ? serviceRefs : new ServiceReference[0];
} catch (InvalidSyntaxException e) {
LOGGER.error(
"Can not get service reference [" + clazz + "/" + query + "]: "
+ e.getMessage(), e);
return null;
}
}
}
/**
* Gets the service instance from the service reference.
*
* @param bundleContext
* BundleContext
* @param sref
* ServiceReference
* @return Object
*/
public static Object getService(BundleContext bundleContext, ServiceReference<?> sref) {
if (sref != null) {
return bundleContext.getService(sref);
}
return null;
}
/**
* Gets the service instance from the service reference.
*
* @param <T>
* @param bundleContext
* BundleContext
* @param sref
* ServiceReference
* @param clazz
* clazz
* @return T
*/
@SuppressWarnings("unchecked")
public static <T> T getService(BundleContext bundleContext, ServiceReference<?> sref,
Class<T> clazz) {
Object service = getService(bundleContext, sref);
if (service != null && clazz.isAssignableFrom(service.getClass())) {
return (T) service;
}
return null;
}
/**
* "Ungets" a service reference.
*
* @param bundleContext
* BundleContext
* @param sref
* ServiceReference
*/
public static void ungetServiceReference(BundleContext bundleContext, ServiceReference<?> sref) {
if (sref != null) {
bundleContext.ungetService(sref);
}
}
/**
* Gets an OSGi service. This method unregisters the
* {@link ServiceReference} so caller does not need to do it.
*
* @param <T>
* @param bundleContext
* BundleContext
* @param clazz
* Class<T>
* @return T
*/
public static <T> T getService(BundleContext bundleContext, Class<T> clazz) {
ServiceReference<?> sref = OsgiUtils.getServiceReference(bundleContext, clazz.getName());
if (sref != null) {
try {
return getService(bundleContext, sref, clazz);
} finally {
ungetServiceReference(bundleContext, sref);
}
}
return null;
}
/**
* Gets an OSGi service. This method unregisters the
* {@link ServiceReference} so caller does not need to do it.
*
* @param <T>
* @param bundleContext
* BundleContext
* @param clazz
* Class<T>
* @param filter
* Map<String, String>
* @return T
*/
public static <T> T getService(BundleContext bundleContext, Class<T> clazz,
Map<String, String> filter) {
ServiceReference<?> sref = OsgiUtils.getServiceReference(bundleContext, clazz.getName(),
filter);
if (sref != null) {
try {
return getService(bundleContext, sref, clazz);
} finally {
ungetServiceReference(bundleContext, sref);
}
}
return null;
}
/**
* Gets an OSGi service. This method unregisters the
* {@link ServiceReference} so caller does not need to do it.
*
* @param <T>
* @param bundleContext
* BundleContext
* @param clazz
* Class<T>
* @param query
* String
* @return T
*/
public static <T> T getService(BundleContext bundleContext, Class<T> clazz, String query) {
ServiceReference<?> sref = OsgiUtils.getServiceReference(bundleContext, clazz.getName(),
query);
if (sref != null) {
try {
return getService(bundleContext, sref, clazz);
} finally {
ungetServiceReference(bundleContext, sref);
}
}
return null;
}
/**
* Finds all resources from a location.
*
* @param bundleContext
* @param resourceLocaotion
* @return
* @throws IOException
*/
public static String[] enumResources(BundleContext bundleContext, String resourceLocation)
throws IOException {
return enumResources(bundleContext.getBundle(), resourceLocation);
}
/**
* Finds all resources from a location.
*
* @param bundle
* @param resourceLocation
* @return
* @throws IOException
*/
public static String[] enumResources(Bundle bundle, String resourceLocation) throws IOException {
List<String> result = new ArrayList<String>();
Enumeration<?> e = bundle.getEntryPaths(resourceLocation);
if (e != null) {
while (e.hasMoreElements()) {
Object obj = e.nextElement();
result.add(obj.toString());
}
}
return result.toArray(new String[0]);
}
/**
* Loads a resource located within the bundle.
*
* @param bundleContext
* @param resourceLocation
* @return
* @throws IOException
*/
public static InputStream loadBundleResource(BundleContext bundleContext,
String resourceLocation) throws IOException {
return loadBundleResource(bundleContext.getBundle(), resourceLocation);
}
/**
* Loads a resource located within the bundle.
*
* @param bundle
* @param resourceLocation
* @return
* @throws IOException
*/
public static InputStream loadBundleResource(Bundle bundle, String resourceLocation)
throws IOException {
URL url = bundle.getEntry(resourceLocation);
return url != null ? url.openStream() : null;
}
}