You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ju...@apache.org on 2011/10/31 16:00:17 UTC
svn commit: r1195494 - in
/tika/trunk/tika-core/src/main/java/org/apache/tika/config:
ServiceLoader.java TikaActivator.java
Author: jukka
Date: Mon Oct 31 15:00:16 2011
New Revision: 1195494
URL: http://svn.apache.org/viewvc?rev=1195494&view=rev
Log:
TIKA-565: Improved OSGi bundling
Listen for all Parser and Detector services within an OSGi environment
Modified:
tika/trunk/tika-core/src/main/java/org/apache/tika/config/ServiceLoader.java
tika/trunk/tika-core/src/main/java/org/apache/tika/config/TikaActivator.java
Modified: tika/trunk/tika-core/src/main/java/org/apache/tika/config/ServiceLoader.java
URL: http://svn.apache.org/viewvc/tika/trunk/tika-core/src/main/java/org/apache/tika/config/ServiceLoader.java?rev=1195494&r1=1195493&r2=1195494&view=diff
==============================================================================
--- tika/trunk/tika-core/src/main/java/org/apache/tika/config/ServiceLoader.java (original)
+++ tika/trunk/tika-core/src/main/java/org/apache/tika/config/ServiceLoader.java Mon Oct 31 15:00:16 2011
@@ -24,8 +24,10 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
@@ -43,6 +45,15 @@ public class ServiceLoader {
private static volatile ClassLoader contextClassLoader = null;
/**
+ * The dynamic set of services available in an OSGi environment.
+ * Managed by the {@link TikaActivator} class and used as an additional
+ * source of service instances in the {@link #loadServiceProviders(Class)}
+ * method.
+ */
+ private static final Map<Object, Object> services =
+ new HashMap<Object, Object>();
+
+ /**
* Returns the context class loader of the current thread. If such
* a class loader is not available, then the loader of this class or
* finally the system class loader is returned.
@@ -74,6 +85,18 @@ public class ServiceLoader {
contextClassLoader = loader;
}
+ static void addService(Object reference, Object service) {
+ synchronized (services) {
+ services.put(reference, service);
+ }
+ }
+
+ static Object removeService(Object reference) {
+ synchronized (services) {
+ return services.remove(reference);
+ }
+ }
+
private final ClassLoader loader;
private final LoadErrorHandler handler;
@@ -90,7 +113,7 @@ public class ServiceLoader {
public ServiceLoader() {
this(getContextClassLoader());
}
-
+
/**
* Returns all the available service resources matching the
* given pattern, such as all instances of tika-mimetypes.xml
@@ -111,18 +134,27 @@ public class ServiceLoader {
/**
* Returns all the available service providers of the given type.
*
- * @param service service provider interface
+ * @param iface service provider interface
* @return available service providers
*/
@SuppressWarnings("unchecked")
- public <T> List<T> loadServiceProviders(Class<T> service) {
+ public <T> List<T> loadServiceProviders(Class<T> iface) {
List<T> providers = new ArrayList<T>();
+ synchronized (services) {
+ for (Object service : services.values()) {
+ if (iface.isAssignableFrom(service.getClass())) {
+ providers.add((T) service);
+ }
+ }
+ }
+
if (loader != null) {
Set<String> names = new HashSet<String>();
- String serviceName = service.getName();
- Enumeration<URL> resources = findServiceResources("META-INF/services/" + serviceName);
+ String serviceName = iface.getName();
+ Enumeration<URL> resources =
+ findServiceResources("META-INF/services/" + serviceName);
for (URL resource : Collections.list(resources)) {
try {
names.addAll(getServiceClassNames(resource));
@@ -134,7 +166,7 @@ public class ServiceLoader {
for (String name : names) {
try {
Class<?> klass = loader.loadClass(name);
- if (service.isAssignableFrom(klass)) {
+ if (iface.isAssignableFrom(klass)) {
providers.add((T) klass.newInstance());
}
} catch (Throwable t) {
Modified: tika/trunk/tika-core/src/main/java/org/apache/tika/config/TikaActivator.java
URL: http://svn.apache.org/viewvc/tika/trunk/tika-core/src/main/java/org/apache/tika/config/TikaActivator.java?rev=1195494&r1=1195493&r2=1195494&view=diff
==============================================================================
--- tika/trunk/tika-core/src/main/java/org/apache/tika/config/TikaActivator.java (original)
+++ tika/trunk/tika-core/src/main/java/org/apache/tika/config/TikaActivator.java Mon Oct 31 15:00:16 2011
@@ -18,6 +18,9 @@ package org.apache.tika.config;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
/**
* Bundle activator that adjust the class loading mechanism of the
@@ -30,15 +33,36 @@ import org.osgi.framework.BundleContext;
*
* @since Apache Tika 0.9
*/
-public class TikaActivator implements BundleActivator {
+public class TikaActivator
+ implements BundleActivator, ServiceListener {
+
+ private BundleContext bundleContext;
+
+ //-----------------------------------------------------< BundleActivator >
public void start(BundleContext context) throws Exception {
- ServiceLoader.setContextClassLoader(
- TikaActivator.class.getClassLoader());
+ bundleContext = context;
+ bundleContext.addServiceListener(this,
+ "(|(objectClass=org.apache.tika.detect.Detector)"
+ + "(objectClass=org.apache.tika.parser.Parser))");
}
public void stop(BundleContext context) throws Exception {
- ServiceLoader.setContextClassLoader(null);
+ bundleContext.removeServiceListener(this);
+ }
+
+ //-----------------------------------------------------< ServiceListener >
+
+ public synchronized void serviceChanged(ServiceEvent event) {
+ if (event.getType() == ServiceEvent.REGISTERED) {
+ ServiceReference reference = event.getServiceReference();
+ Object service = bundleContext.getService(reference);
+ ServiceLoader.addService(reference, service);
+ } else if (event.getType() == ServiceEvent.UNREGISTERING) {
+ ServiceReference reference = event.getServiceReference();
+ ServiceLoader.removeService(reference);
+ bundleContext.ungetService(reference);
+ }
}
}