Author: hughesj
Date: Wed Sep 17 13:06:31 2014
New Revision: 1625570
URL: http://svn.apache.org/r1625570
Log:
ARIES-1068: backing out performance change due to some odd behaviour.
Modified:
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DirObjectFactoryHelper.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ObjectFactoryHelper.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java
Modified:
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java
URL:
http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java?rev=1625570&r1=1625569&r2=1625570&view=diff
==============================================================================
---
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java
(original)
+++
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java
Wed Sep 17 13:06:31 2014
@@ -96,7 +96,7 @@ public final class ContextHelper {
if (refs != null) {
for (final ServiceReference finderRef : refs) {
- URLObjectFactoryFinder finder = (URLObjectFactoryFinder)
ServiceTrackerCustomizers.URLOBJFACTORYFINDER_CACHE.getServiceFromRef(ctx,finderRef);
+ URLObjectFactoryFinder finder = (URLObjectFactoryFinder)
Utils.getServicePrivileged(ctx, finderRef);
if (finder != null) {
ObjectFactory f = finder.findFactory(urlScheme, environment);
@@ -104,6 +104,8 @@ public final class ContextHelper {
if (f != null) {
result = new ServicePair<ObjectFactory>(ctx, finderRef, f);
break;
+ } else {
+ ctx.ungetService(finderRef);
}
}
}
@@ -172,11 +174,15 @@ public final class ContextHelper {
if (references != null) {
Context initialContext = null;
for (ServiceReference reference : references) {
- InitialContextFactory factory =
(InitialContextFactory)
ServiceTrackerCustomizers.ICF_CACHE.getServiceFromRef(context, reference);
- initialContext =
factory.getInitialContext(environment);
- if (initialContext != null) {
- provider = new SingleContextProvider(context,
reference, initialContext);
- break;
+ InitialContextFactory factory =
(InitialContextFactory) Utils.getServicePrivileged(context, reference);
+ try {
+ initialContext =
factory.getInitialContext(environment);
+ if (initialContext != null) {
+ provider = new SingleContextProvider(context,
reference, initialContext);
+ break;
+ }
+ } finally {
+ if (provider == null)
context.ungetService(reference);
}
}
}
@@ -186,10 +192,14 @@ public final class ContextHelper {
if (ref != null) {
Context initialContext = null;
- InitialContextFactory factory = (InitialContextFactory)
ServiceTrackerCustomizers.ICF_CACHE.getServiceFromRef(context, ref);
+ InitialContextFactory factory = (InitialContextFactory)
Utils.getServicePrivileged(context, ref);
if (factory != null) {
- initialContext = factory.getInitialContext(environment);
- provider = new SingleContextProvider(context, ref,
initialContext);
+ try {
+ initialContext = factory.getInitialContext(environment);
+ provider = new SingleContextProvider(context, ref,
initialContext);
+ } finally {
+ if (provider == null) context.ungetService(ref);
+ }
}
}
@@ -218,7 +228,7 @@ public final class ContextHelper {
if (refs != null) {
InitialContextFactory factory = null;
for (ServiceReference ref : refs) {
- InitialContextFactoryBuilder builder =
(InitialContextFactoryBuilder)
ServiceTrackerCustomizers.ICFB_CACHE.getServiceFromRef(context, ref);
+ InitialContextFactoryBuilder builder =
(InitialContextFactoryBuilder) Utils.getServicePrivileged(context, ref);
try {
factory = builder.createInitialContextFactory(environment);
} catch (NamingException ne) {
@@ -230,8 +240,14 @@ public final class ContextHelper {
}
if (factory != null) {
- provider = new SingleContextProvider(context, ref,
factory.getInitialContext(environment));
+ try {
+ provider = new SingleContextProvider(context, ref,
factory.getInitialContext(environment));
+ } finally {
+ if (provider == null) context.ungetService(ref); // we
didn't get something back, so this was no good.
+ }
break;
+ } else {
+ context.ungetService(ref); // we didn't get something back,
so this was no good.
}
}
}
Modified:
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DirObjectFactoryHelper.java
URL:
http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DirObjectFactoryHelper.java?rev=1625570&r1=1625569&r2=1625570&view=diff
==============================================================================
---
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DirObjectFactoryHelper.java
(original)
+++
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DirObjectFactoryHelper.java
Wed Sep 17 13:06:31 2014
@@ -31,18 +31,13 @@ import javax.naming.spi.DirObjectFactory
import javax.naming.spi.ObjectFactory;
import javax.naming.spi.ObjectFactoryBuilder;
-import org.apache.aries.jndi.tracker.ServiceTrackerCustomizers;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class DirObjectFactoryHelper extends ObjectFactoryHelper implements
DirObjectFactory {
- private ServiceTrackerCustomizers.ContextServiceTrackerCustomizer
dirObjFactorySTC = null;
-
-
public DirObjectFactoryHelper(BundleContext defaultContext, BundleContext
callerContext) {
super(defaultContext, callerContext);
- dirObjFactorySTC =
ServiceTrackerCustomizers.getOrRegisterServiceTracker(callerContext,
DirObjectFactory.class.getName());
}
public Object getObjectInstance(Object obj,
@@ -101,15 +96,20 @@ public class DirObjectFactoryHelper exte
throws Exception {
Object result = null;
- ServiceReference[] refs = dirObjFactorySTC.getServiceRefs();
+ ServiceReference[] refs = Utils.getReferencesPrivileged(callerContext,
DirObjectFactory.class);
if (refs != null) {
Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
for (ServiceReference ref : refs) {
if (canCallObjectFactory(obj, ref)) {
- DirObjectFactory factory = (DirObjectFactory)
dirObjFactorySTC.getService(ref);
- result = factory.getObjectInstance(obj, name, nameCtx,
environment, attrs);
-
+ DirObjectFactory factory = (DirObjectFactory)
Utils.getServicePrivileged(callerContext, ref);
+
+ try {
+ result = factory.getObjectInstance(obj, name, nameCtx,
environment, attrs);
+ } finally {
+ callerContext.ungetService(ref);
+ }
+
// if the result comes back and is not null and not the
reference
// object then we should return the result, so break out
of the
// loop we are in.
@@ -149,11 +149,15 @@ public class DirObjectFactoryHelper exte
Attributes attrs)
throws Exception {
- Tuple<ServiceReference, ObjectFactory> tuple =
ObjectFactoryHelper.findObjectFactoryByClassName(defaultStC, className);
+ Tuple<ServiceReference, ObjectFactory> tuple =
ObjectFactoryHelper.findObjectFactoryByClassName(defaultContext, className);
Object result = null;
if (tuple.second != null) {
- result = ((DirObjectFactory)
tuple.second).getObjectInstance(reference, name, nameCtx, environment, attrs);
+ try {
+ result = ((DirObjectFactory)
tuple.second).getObjectInstance(reference, name, nameCtx, environment, attrs);
+ } finally {
+ defaultContext.ungetService(tuple.first);
+ }
}
return (result == null) ? obj : result;
@@ -166,15 +170,17 @@ public class DirObjectFactoryHelper exte
Attributes
attrs)
throws Exception {
ObjectFactory factory = null;
- ServiceReference[] refs = objFactoryBuilderStC.getServiceRefs();
+ ServiceReference[] refs = Utils.getReferencesPrivileged(callerContext,
ObjectFactoryBuilder.class);
if (refs != null) {
Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
for (ServiceReference ref : refs) {
- ObjectFactoryBuilder builder = (ObjectFactoryBuilder)
objFactoryBuilderStC.getService(ref);
+ ObjectFactoryBuilder builder = (ObjectFactoryBuilder)
Utils.getServicePrivileged(callerContext, ref);
try {
factory = builder.createObjectFactory(obj, environment);
} catch (NamingException e) {
// TODO: log it
+ } finally {
+ callerContext.ungetService(ref);
}
if (factory != null) {
break;
Modified:
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ObjectFactoryHelper.java
URL:
http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ObjectFactoryHelper.java?rev=1625570&r1=1625569&r2=1625570&view=diff
==============================================================================
---
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ObjectFactoryHelper.java
(original)
+++
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ObjectFactoryHelper.java
Wed Sep 17 13:06:31 2014
@@ -20,10 +20,7 @@ package org.apache.aries.jndi;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.Arrays;
-import java.util.Vector;
-import java.util.Iterator;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.logging.Level;
@@ -42,36 +39,19 @@ import javax.naming.spi.ObjectFactory;
import javax.naming.spi.ObjectFactoryBuilder;
import org.apache.aries.util.service.registry.ServicePair;
-import org.apache.aries.jndi.tracker.ServiceTrackerCustomizers;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
public class ObjectFactoryHelper implements ObjectFactory {
protected BundleContext defaultContext;
protected BundleContext callerContext;
-
- protected ServiceTrackerCustomizers.ContextServiceTrackerCustomizer
objFactoryBuilderStC = null;
- protected ServiceTrackerCustomizers.ContextServiceTrackerCustomizer
objFactoryStC = null;
- protected ServiceTrackerCustomizers.ContextServiceTrackerCustomizer
defaultStC = null;
-
private static final Logger logger =
Logger.getLogger(ObjectFactoryHelper.class.getName());
public ObjectFactoryHelper(BundleContext defaultContext, BundleContext
callerContext) {
this.defaultContext = defaultContext;
this.callerContext = callerContext;
-
- //Create service trackers for the contexts to allow caching of services
- objFactoryBuilderStC =
ServiceTrackerCustomizers.getOrRegisterServiceTracker(callerContext,
ObjectFactoryBuilder.class.getName());
-
- objFactoryStC =
ServiceTrackerCustomizers.getOrRegisterServiceTracker(callerContext,
ObjectFactory.class.getName());
-
- defaultStC =
ServiceTrackerCustomizers.getOrRegisterServiceTracker(defaultContext,
ObjectFactory.class.getName());
-
}
public Object getObjectInstance(Object obj,
@@ -200,19 +180,21 @@ public class ObjectFactoryHelper impleme
Hashtable<?, ?>
environment)
throws Exception {
Object result = null;
- ServiceReference[] refs = objFactoryStC.getServiceRefs();
+ ServiceReference[] refs = Utils.getReferencesPrivileged(callerContext,
ObjectFactory.class);
if (refs != null) {
Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
for (ServiceReference ref : refs) {
if (canCallObjectFactory(obj, ref)) {
- ObjectFactory factory = (ObjectFactory)
objFactoryStC.getService(ref);
+ ObjectFactory factory = (ObjectFactory)
Utils.getServicePrivileged(callerContext, ref);
try {
result = factory.getObjectInstance(obj, name, nameCtx,
environment);
} catch (NamingException ne) {
// Ignore this since we are doing last ditch finding,
another OF might work.
+ } finally {
+ callerContext.ungetService(ref);
}
// if the result comes back and is not null and not the
reference
@@ -287,15 +269,25 @@ public class ObjectFactoryHelper impleme
return (result == null) ? obj : result;
}
- static Tuple<ServiceReference,ObjectFactory>
findObjectFactoryByClassName(final
ServiceTrackerCustomizers.ContextServiceTrackerCustomizer ctxCache, final
String className) {
+ static Tuple<ServiceReference,ObjectFactory>
findObjectFactoryByClassName(final BundleContext ctx, final String className) {
return AccessController.doPrivileged(new
PrivilegedAction<Tuple<ServiceReference,ObjectFactory>>() {
public Tuple<ServiceReference,ObjectFactory> run() {
- ServiceReference serviceReference =
ctxCache.getServiceRef(className);
+ ServiceReference serviceReference = null;
+
+ try {
+ ServiceReference[] refs =
ctx.getServiceReferences(className, null);
+ if (refs != null && refs.length > 0) {
+ serviceReference = refs[0];
+ }
+ } catch (InvalidSyntaxException e) {
+ // should not happen
+ throw new
RuntimeException(Utils.MESSAGES.getMessage("null.is.invalid.filter"), e);
+ }
ObjectFactory factory = null;
if (serviceReference != null) {
- factory = (ObjectFactory)
ctxCache.getService(serviceReference);
+ factory = (ObjectFactory)
ctx.getService(serviceReference);
}
return new Tuple<ServiceReference,
ObjectFactory>(serviceReference, factory);
@@ -311,11 +303,15 @@ public class ObjectFactoryHelper impleme
Hashtable<?, ?>
environment)
throws Exception {
- Tuple<ServiceReference,ObjectFactory> tuple =
findObjectFactoryByClassName(defaultStC, className);
+ Tuple<ServiceReference,ObjectFactory> tuple =
findObjectFactoryByClassName(defaultContext, className);
Object result = null;
if (tuple.second != null) {
- result = tuple.second.getObjectInstance(reference, name, nameCtx,
environment);
+ try {
+ result = tuple.second.getObjectInstance(reference, name,
nameCtx, environment);
+ } finally {
+ defaultContext.ungetService(tuple.first);
+ }
}
return (result == null) ? obj : result;
@@ -329,15 +325,17 @@ public class ObjectFactoryHelper impleme
ObjectFactory factory = null;
- ServiceReference[] refs = objFactoryBuilderStC.getServiceRefs();
+ ServiceReference[] refs = Utils.getReferencesPrivileged(callerContext,
ObjectFactoryBuilder.class);
if (refs != null) {
Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
for (ServiceReference ref : refs) {
- ObjectFactoryBuilder builder = (ObjectFactoryBuilder)
objFactoryBuilderStC.getService(ref);
+ ObjectFactoryBuilder builder = (ObjectFactoryBuilder)
Utils.getServicePrivileged(callerContext, ref);
try {
factory = builder.createObjectFactory(obj, environment);
} catch (NamingException e) {
// TODO: log it
+ } finally {
+ callerContext.ungetService(ref);
}
if (factory != null) {
break;
Modified:
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
URL:
http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java?rev=1625570&r1=1625569&r2=1625570&view=diff
==============================================================================
---
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
(original)
+++
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
Wed Sep 17 13:06:31 2014
@@ -40,13 +40,11 @@ import org.apache.aries.jndi.spi.Environ
import org.apache.aries.jndi.spi.AugmenterInvoker;
import org.apache.aries.jndi.tracker.ServiceTrackerCustomizers;
import org.apache.aries.jndi.urls.URLObjectFactoryFinder;
-import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.jndi.JNDIContextManager;
import org.osgi.service.jndi.JNDIProviderAdmin;
-import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
@@ -68,14 +66,13 @@ public class Activator implements Bundle
private static ServiceTracker objectFactories;
private static ServiceTracker environmentAugmentors;
private static ServiceTracker environmentUnaugmentors;
- private BundleTracker bt = null;
public void start(BundleContext context) {
initialContextFactories = initServiceTracker(context,
InitialContextFactory.class, ServiceTrackerCustomizers.ICF_CACHE);
objectFactories = initServiceTracker(context, ObjectFactory.class,
ServiceTrackerCustomizers.URL_FACTORY_CACHE);
- icfBuilders = initServiceTracker(context,
InitialContextFactoryBuilder.class, ServiceTrackerCustomizers.ICFB_CACHE);
- urlObjectFactoryFinders = initServiceTracker(context,
URLObjectFactoryFinder.class,
ServiceTrackerCustomizers.URLOBJFACTORYFINDER_CACHE);
+ icfBuilders = initServiceTracker(context,
InitialContextFactoryBuilder.class, ServiceTrackerCustomizers.LAZY);
+ urlObjectFactoryFinders = initServiceTracker(context,
URLObjectFactoryFinder.class, ServiceTrackerCustomizers.LAZY);
environmentAugmentors = initServiceTracker(context,
EnvironmentAugmentation.class, null);
environmentUnaugmentors = initServiceTracker(context,
EnvironmentUnaugmentation.class, null);
@@ -116,14 +113,10 @@ public class Activator implements Bundle
context.registerService(JNDIContextManager.class.getName(),
new ContextManagerServiceFactory(),
null);
+ context.registerService(AugmenterInvoker.class.getName(),
+
AugmenterInvokerImpl.getInstance(),
+ null);
- context.registerService(AugmenterInvoker.class.getName(),
-
AugmenterInvokerImpl.getInstance(),
- null);
-
- //Start the bundletracker that clears out the cache. (only interested
in stopping events)
- bt = new BundleTracker(context,Bundle.STOPPING,new
ServiceTrackerCustomizers.CacheBundleTrackerCustomizer());
- bt.open();
}
private String getClassName(Class<?> expectedType)
@@ -168,11 +161,6 @@ public class Activator implements Bundle
initialContextFactories.close();
environmentAugmentors.close();
environmentUnaugmentors.close();
-
- if (bt != null) {
- bt.close();
- }
-
}
/*
Modified:
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java
URL:
http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java?rev=1625570&r1=1625569&r2=1625570&view=diff
==============================================================================
---
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java
(original)
+++
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java
Wed Sep 17 13:06:31 2014
@@ -18,40 +18,25 @@
*/
package org.apache.aries.jndi.tracker;
-import java.lang.IllegalStateException;
-import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import javax.naming.spi.InitialContextFactory;
-import org.apache.aries.jndi.Utils;
-import org.apache.aries.jndi.startup.Activator;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.jndi.JNDIConstants;
-import org.osgi.util.tracker.BundleTrackerCustomizer;
-import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
public class ServiceTrackerCustomizers
{
- private static final Logger LOGGER =
Logger.getLogger(ServiceTrackerCustomizers.class.getName());
-
public static interface CachingServiceTracker extends
ServiceTrackerCustomizer {
public ServiceReference find(String identifier);
- public Object getServiceFromRef(BundleContext bCtx, ServiceReference ref);
}
private static abstract class BaseCachingServiceTracker implements
CachingServiceTracker {
@@ -60,36 +45,6 @@ public class ServiceTrackerCustomizers
/** A list of service references that are being tracked */
protected List<ServiceReference> trackedReferences = new
ArrayList<ServiceReference>();
- protected ConcurrentHashMap<BundleContext,
ConcurrentHashMap<ServiceReference,Object>> ctxServiceRefServiceCache =
- new ConcurrentHashMap<BundleContext,
ConcurrentHashMap<ServiceReference,Object>>();
-
- private void clearCache(Bundle b) {
- for (BundleContext bCtx : ctxServiceRefServiceCache.keySet()) {
- Bundle cacheB = null;
- try {
- cacheB = bCtx.getBundle();
- } catch (IllegalStateException ise) {
- if (LOGGER.isLoggable(Level.FINE))
LOGGER.fine("BaseCachingServiceTracker.clearCache IllegalStateException caught
getting bundle on " + bCtx);
- }
- if (cacheB == null || cacheB.equals(b)) {
- Object removedObj = ctxServiceRefServiceCache.remove(bCtx);
- if (LOGGER.isLoggable(Level.FINE))
LOGGER.fine("BaseCachingServiceTracker.clearCache Removed " + removedObj);
- }
- }
- }
-
- public Object getServiceFromRef(BundleContext bCtx, ServiceReference ref) {
- if (ctxServiceRefServiceCache.get(bCtx) == null) {
- ctxServiceRefServiceCache.put(bCtx, new
ConcurrentHashMap<ServiceReference,Object>());
- }
- ConcurrentHashMap<ServiceReference,Object> ctxServiceCache =
ctxServiceRefServiceCache.get(bCtx);
- Object service = ctxServiceCache.get(ref);
- if (service == null) {
- service = Utils.getServicePrivileged(bCtx,ref);
- ctxServiceCache.put(ref, service);
- }
- return service;
- }
public ServiceReference find(String identifier)
{
return cache.get(identifier);
@@ -132,10 +87,6 @@ public class ServiceTrackerCustomizers
for (String interfaceName : keysToProcess) {
cache.remove(interfaceName, reference);
}
- //Work through the contexts to clear out this serviceref
- for (BundleContext bCtx : ctxServiceRefServiceCache.keySet()) {
- ctxServiceRefServiceCache.get(bCtx).remove(reference);
- }
}
public void modifiedService(ServiceReference reference, Object service) { }
@@ -165,21 +116,6 @@ public class ServiceTrackerCustomizers
}
};
- //An empty BaseCachingServiceTracker, just to use the caching.
- public static final CachingServiceTracker ICFB_CACHE = new
BaseCachingServiceTracker() {
- @Override
- protected List<String> getProperty(ServiceReference reference) {
- return new ArrayList<String>();
- }};
-
- //An empty BaseCachingServiceTracker, just to use the caching.
- public static final CachingServiceTracker URLOBJFACTORYFINDER_CACHE = new
BaseCachingServiceTracker() {
- @Override
- protected List<String> getProperty(ServiceReference reference) {
- return new ArrayList<String>();
- }};
-
-
// TODO we should probably cope with the url.scheme property changing.
public static final CachingServiceTracker URL_FACTORY_CACHE = new
BaseCachingServiceTracker() {
protected List<String> getProperty(ServiceReference reference) {
@@ -198,266 +134,4 @@ public class ServiceTrackerCustomizers
return result;
}
};
-
-//Links between the BundleContext, the classes they have registered an
interest in, and the service references from those.
- private static
ConcurrentHashMap<BundleContext,ConcurrentHashMap<String,CopyOnWriteArrayList<ServiceReference>>>
srCache
- = new ConcurrentHashMap<BundleContext,
ConcurrentHashMap<String,CopyOnWriteArrayList<ServiceReference>>>();
-
- //Links between references and services
- private static ConcurrentHashMap<ServiceReference, Object> refToService =
new ConcurrentHashMap<ServiceReference, Object>();
-
- //Links between BundleContexts and the classes they have registered an
interest in, and the ServiceTrackerCustomizers
- //running for those classes.
- private static ConcurrentHashMap<BundleContext,
ConcurrentHashMap<String,ContextServiceTrackerCustomizer>>
serviceTrackerCustomizerCache
- = new ConcurrentHashMap<BundleContext,
ConcurrentHashMap<String,ContextServiceTrackerCustomizer>>();
-
- //Maintain a list of service trackers created, so they can be closed off.
- private static ConcurrentHashMap<ServiceTrackerCustomizer, ServiceTracker>
serviceTrackers = new ConcurrentHashMap<ServiceTrackerCustomizer,
ServiceTracker>();
-
- public static ContextServiceTrackerCustomizer
getOrRegisterServiceTracker(BundleContext ctx,String clazz) {
-
- ConcurrentHashMap<String,ContextServiceTrackerCustomizer> stCacheForCtx =
serviceTrackerCustomizerCache.get(ctx);
- if (stCacheForCtx == null) {
- synchronized (serviceTrackerCustomizerCache) {
- //Check the ctx is still not known, and not set by another thread.
- stCacheForCtx = serviceTrackerCustomizerCache.get(ctx);
- if (stCacheForCtx == null) {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine("Creating cache
details for context " + ctx);
- stCacheForCtx = new ConcurrentHashMap<String,
ServiceTrackerCustomizers.ContextServiceTrackerCustomizer>();
- serviceTrackerCustomizerCache.put(ctx, stCacheForCtx);
- }
- }
- }
-
- ContextServiceTrackerCustomizer stc = stCacheForCtx.get(clazz);
- if (stc == null) {
- synchronized (stCacheForCtx) {
- stc = stCacheForCtx.get(clazz);
- if (stc == null) {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "Creating
" + clazz + " tracker for " + ctx);
- final BundleContext _ctx = ctx;
- stc = new
ServiceTrackerCustomizers.ContextServiceTrackerCustomizer(_ctx, clazz);
- ServiceTracker st = new ServiceTracker(
- _ctx,
- clazz,
- stc);
- serviceTrackers.put(stc, st);
- stCacheForCtx.put(clazz,stc);
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "Opening "
+ clazz + " tracker " + st);
- final ServiceTracker _st = st;
- try {
- Utils.doPrivileged(new PrivilegedExceptionAction<Object>() {
- public Object run() throws Exception {
- _st.open(true);
- return null;
- }
- });
-
- } catch (Exception e) {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE,
"Exception opening " + clazz + " tracker " + e.getMessage());
- }
- }
- }
- }
- return stc;
-
- }
-
- //Class to track services for a given context
- public static class ContextServiceTrackerCustomizer implements
ServiceTrackerCustomizer {
-
- private String clazz;
- final BundleContext _callerContext;
-
- public BundleContext getCallerContext() {
- return _callerContext;
- }
-
- private ConcurrentHashMap<String,ServiceReference> classToSR = new
ConcurrentHashMap<String,ServiceReference>();
-
- public ContextServiceTrackerCustomizer(BundleContext _callerContext,
String clazz) {
- this._callerContext = _callerContext;
- this.clazz = clazz;
- }
-
- public Object addingService(ServiceReference reference) {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE,
"addingService: " + reference + " for context " + _callerContext + " class " +
clazz);
- Object service = null;
- //Get the appropriate cache for references
- ConcurrentHashMap<String,CopyOnWriteArrayList<ServiceReference>>
ctxCache = srCache.get(_callerContext);
- if(ctxCache == null) {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "Creating
cache for " + _callerContext);
- ctxCache = new
ConcurrentHashMap<String,CopyOnWriteArrayList<ServiceReference>>();
- srCache.put(_callerContext,ctxCache);
- }
-
- if (!ctxCache.contains(clazz)) {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "Creating
class based cache for " + clazz);
- ctxCache.put(clazz,new CopyOnWriteArrayList<ServiceReference>());
- }
- CopyOnWriteArrayList<ServiceReference> cache = ctxCache.get(clazz);
- //Now see if the cache already has the ServiceReference (presumably it
shouldn't)
- if (!cache.contains(reference)) {
- cache.add(reference);
- service = _callerContext.getService(reference);
- refToService.put(reference, service);
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "Storing
reference in cache: " + reference + " and service " + service);
- } else {
- service = refToService.get(reference);
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "Reference
already in cache: " + reference + " returning service " + service);
- }
- //Get a list of the classNames the service is registered under, and add
to the class -> ServiceReference list
- String[] classNames = (String[])
reference.getProperty(Constants.OBJECTCLASS);
- if (classNames != null) {
- for (String cl : classNames) {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine("Storing link from
class " + cl + " to reference " + reference);
- classToSR.put(cl, reference);
- }
- }
- //Presumably we'll always want to track this reference.
- return service;
- }
- public void modifiedService(ServiceReference reference,
- java.lang.Object service) {
- //TODO do anything here??
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE,
"modifiedService: " + reference);
- }
-
- public void removedService(ServiceReference reference,
- java.lang.Object service) {
- //Unget the service to maintain the count correctly (got in
addingService)
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE,
"removedService: " + reference + " object: " + service);
- try {
- _callerContext.ungetService(reference);
- } catch (IllegalStateException e) {
- //Shouldn't matter that we get an IllegalStateException here.
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE,
"IllegalStateException ungetting " + reference + " from " + _callerContext);
- }
- Object removedService = refToService.remove(reference);
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "refToService
removed: " + removedService);
- //Get the appropriate cache for references
- if(srCache.containsKey(_callerContext)) {
- CopyOnWriteArrayList<ServiceReference> cache =
srCache.get(_callerContext).get(clazz);
- if (cache != null && cache.contains(reference)) {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "removing
reference from cache");
- cache.remove(reference);
- } else {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "cache did
not contain reference to remove");
- }
- } else {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE,
"removedService: no cache for callerContext: " + _callerContext);
- }
- }
-
- public ServiceReference getServiceRef(String clazz) {
- ServiceReference retObj = classToSR.get(clazz);
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine("getServiceRef: Returning
" + retObj);
- return retObj;
- }
-
-
- public ServiceReference[] getServiceRefs() {
- ServiceReference[] refs = null;
- if (srCache.containsKey(_callerContext)) {
- CopyOnWriteArrayList<ServiceReference> cache =
srCache.get(_callerContext).get(clazz);
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "Getting
service refs from " + cache + " for " + _callerContext);
- if (cache != null) {
- refs = cache.toArray(new ServiceReference[cache.size()]);
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "Found refs:
" + refs.length);
- } else {
- if (LOGGER.isLoggable(Level.FINE))LOGGER.log(Level.FINE, "Cache for
class " + clazz + " in context " + _callerContext + " does not exist");
- }
- } else {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "Cache for
context " + _callerContext + " does not exist");
- }
- return refs;
- }
-
-
- public Object getService(ServiceReference ref) {
- Object obj = refToService.get(ref);
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.log(Level.FINE, "getService
returning: " + obj);
- return obj;
- }
- }
-
- public static class CacheBundleTrackerCustomizer implements
BundleTrackerCustomizer {
-
- @Override
- public Object addingBundle(Bundle arg0, BundleEvent arg1) {
- //Request that all bundles are tracked, as even if it's not in the
cache, it might be later...
- return arg0;
- }
-
- @Override
- public void modifiedBundle(Bundle arg0, BundleEvent arg1, Object arg2) {
-
- }
-
- @Override
- public void removedBundle(Bundle arg0, BundleEvent arg1, Object arg2) {
- //Work through srCache to find the bundle by matching to the context
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine("removedBundle: Bundle "
+ arg0);
- for (BundleContext bCtx : srCache.keySet()) {
- Bundle cacheB = null;
- try {
- cacheB = bCtx.getBundle();
- } catch (IllegalStateException ise) {
- if (LOGGER.isLoggable(Level.FINE))
LOGGER.fine("CacheBundleTrackerCustomizer.removedBundle IllegalStateException
caught getting bundle on " + bCtx);
- }
- //If we found no bundle on the context, or one that matches, then
remove it.
- if (cacheB == null || cacheB.equals(arg0)) {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine("Found matching
bundleContext " + bCtx);
- //Removing the bundle in the cache, so clear it out.
- ConcurrentHashMap<String,CopyOnWriteArrayList<ServiceReference>>
classesCached = srCache.remove(bCtx);
- if (classesCached != null) {
- for (String clazz : classesCached.keySet()) {
- CopyOnWriteArrayList<ServiceReference> serviceRefs =
classesCached.get(clazz);
- //Now work through the serviceRefs, and clear out the
refsToService cache
- if (serviceRefs != null) {
- for (ServiceReference serviceRef : serviceRefs.toArray(new
ServiceReference[serviceRefs.size()])) {
- Object service = refToService.remove(serviceRef);
- //Unget the service from the framework, as it won't be
required now
- if (service != null) {
- try {
- bCtx.ungetService(serviceRef);
- } catch (IllegalStateException e) {
- //Shouldn't matter that we get an IllegalStateException
here.
- if (LOGGER.isLoggable(Level.FINE))
LOGGER.log(Level.FINE, "CacheBundleTrackerCustomizer.removedBundle
IllegalStateException ungetting " + serviceRef + " from " + bCtx);
- }
- }
- }
- }
- }
- }
- //Remove the service tracker customizer and stop the service tracker
- ConcurrentHashMap<String,ContextServiceTrackerCustomizer>
trackedClasses = serviceTrackerCustomizerCache.remove(bCtx);
- if (trackedClasses != null) {
- for (String classes : trackedClasses.keySet()) {
- ServiceTracker st =
serviceTrackers.remove(trackedClasses.get(classes));
- if (st != null) {
- final ServiceTracker _st = st;
- try {
- if (LOGGER.isLoggable(Level.FINE)) LOGGER.fine("Closing
ServiceTracker " + st);
- Utils.doPrivileged(new PrivilegedExceptionAction<Object>() {
- public Object run() throws Exception {
- _st.close();
- return null;
- }
- });
- } catch (Exception e) {
- //TODO logging?
- }
- }
- }
- }
- }
- }
- //Remove bundle from BaseCachingServiceTrackers
- ((BaseCachingServiceTracker) ICF_CACHE).clearCache(arg0);
- ((BaseCachingServiceTracker) ICFB_CACHE).clearCache(arg0);
- ((BaseCachingServiceTracker) URL_FACTORY_CACHE).clearCache(arg0);
- ((BaseCachingServiceTracker) URLOBJFACTORYFINDER_CACHE).clearCache(arg0);
- }
- }
}