You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by gn...@apache.org on 2018/02/21 09:05:04 UTC
svn commit: r1824944 [1/2] - in /aries/trunk/jndi/jndi-core/src:
main/java/org/apache/aries/jndi/ main/java/org/apache/aries/jndi/startup/
main/java/org/apache/aries/jndi/tracker/ test/java/org/apache/aries/jndi/
Author: gnodet
Date: Wed Feb 21 09:05:04 2018
New Revision: 1824944
URL: http://svn.apache.org/viewvc?rev=1824944&view=rev
Log:
[jndi] Big refactoring, introducing caching per ARIES-1068
Added:
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java
- copied, changed from r1824943, aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/CachingServiceTracker.java
Removed:
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/Tuple.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/AugmenterInvokerImpl.java
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/ContextProvider.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.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/JREInitialContextFactoryBuilder.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiInitialContextFactoryBuilder.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiObjectFactoryBuilder.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/ProviderAdminServiceFactory.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/URLContextProvider.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/Utils.java
aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
aries/trunk/jndi/jndi-core/src/test/java/org/apache/aries/jndi/InitialContextTest.java
aries/trunk/jndi/jndi-core/src/test/java/org/apache/aries/jndi/ObjectFactoryTest.java
Modified: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/AugmenterInvokerImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/AugmenterInvokerImpl.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/AugmenterInvokerImpl.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/AugmenterInvokerImpl.java Wed Feb 21 09:05:04 2018
@@ -22,43 +22,28 @@ import org.apache.aries.jndi.spi.Augment
import org.apache.aries.jndi.spi.EnvironmentAugmentation;
import org.apache.aries.jndi.spi.EnvironmentUnaugmentation;
import org.apache.aries.jndi.startup.Activator;
+import org.osgi.framework.BundleContext;
import java.util.Hashtable;
public class AugmenterInvokerImpl implements AugmenterInvoker {
- private static AugmenterInvokerImpl instance = null;
+ private final BundleContext context;
- public static AugmenterInvokerImpl getInstance() {
- if (instance == null) {
- instance = new AugmenterInvokerImpl();
- }
- return instance;
+ public AugmenterInvokerImpl(BundleContext context) {
+ this.context = context;
}
-
public void augmentEnvironment(Hashtable<?, ?> environment) {
- Object[] objects = Activator.getEnvironmentAugmentors();
-
- if (objects != null) {
- for (Object obj : objects) {
- if (obj instanceof EnvironmentAugmentation) {
- ((EnvironmentAugmentation) obj).augmentEnvironment(environment);
- }
- }
+ for (EnvironmentAugmentation svc : Activator.getServices(context, EnvironmentAugmentation.class)) {
+ svc.augmentEnvironment(environment);
}
}
public void unaugmentEnvironment(Hashtable<?, ?> environment) {
- Object[] objects = Activator.getEnvironmentUnaugmentors();
-
- if (objects != null) {
- for (Object obj : objects) {
- if (obj instanceof EnvironmentUnaugmentation) {
- ((EnvironmentUnaugmentation) obj).unaugmentEnvironment(environment);
- }
- }
+ for (EnvironmentUnaugmentation svc : Activator.getServices(context, EnvironmentUnaugmentation.class)) {
+ svc.unaugmentEnvironment(environment);
}
}
}
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=1824944&r1=1824943&r2=1824944&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 Feb 21 09:05:04 2018
@@ -19,9 +19,7 @@
package org.apache.aries.jndi;
import org.apache.aries.jndi.startup.Activator;
-import org.apache.aries.jndi.tracker.ServiceTrackerCustomizers;
import org.apache.aries.jndi.urls.URLObjectFactoryFinder;
-import org.apache.aries.util.service.registry.ServicePair;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
@@ -33,9 +31,9 @@ import javax.naming.NoInitialContextExce
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.ObjectFactory;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.util.Collection;
import java.util.Hashtable;
+import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -57,12 +55,6 @@ public final class ContextHelper {
/**
* This method is used to create a URL Context. It does this by looking for
* the URL context's ObjectFactory in the service registry.
- *
- * @param context
- * @param urlScheme
- * @param env
- * @return a Context
- * @throws NamingException
*/
public static ContextProvider createURLContext(final BundleContext context,
final String urlScheme,
@@ -87,33 +79,25 @@ public final class ContextHelper {
throws NamingException {
ServicePair<ObjectFactory> result = null;
- ServiceReference ref = ServiceTrackerCustomizers.URL_FACTORY_CACHE.find(urlScheme);
+ ServiceReference<ObjectFactory> ref = Activator.getUrlFactory(urlScheme);
if (ref == null) {
- ServiceReference<URLObjectFactoryFinder>[] refs = AccessController.doPrivileged(new PrivilegedAction<ServiceReference<URLObjectFactoryFinder>[]>() {
- public ServiceReference<URLObjectFactoryFinder>[] run() {
- return Activator.getURLObjectFactoryFinderServices();
- }
- });
- if (refs != null) {
- for (final ServiceReference<URLObjectFactoryFinder> finderRef : refs) {
- URLObjectFactoryFinder finder = Utils.getServicePrivileged(ctx, finderRef);
-
- if (finder != null) {
- ObjectFactory f = finder.findFactory(urlScheme, environment);
-
- if (f != null) {
- result = new ServicePair<ObjectFactory>(ctx, finderRef, f);
- break;
- } else {
- ctx.ungetService(finderRef);
- }
+ Collection<ServiceReference<URLObjectFactoryFinder>> refs = Activator.getURLObjectFactoryFinderServices();
+ for (final ServiceReference<URLObjectFactoryFinder> finderRef : refs) {
+ URLObjectFactoryFinder finder = Activator.getService(ctx, finderRef);
+
+ if (finder != null) {
+ ObjectFactory f = finder.findFactory(urlScheme, environment);
+
+ if (f != null) {
+ result = new ServicePair<>(ctx, finderRef, f);
+ break;
}
}
}
} else {
- result = new ServicePair<ObjectFactory>(ctx, ref);
+ result = new ServicePair<>(ctx, ref);
}
return result;
@@ -125,13 +109,7 @@ public final class ContextHelper {
final Bundle jndiBundle = FrameworkUtil.getBundle(ContextHelper.class);
// if we are outside OSGi (like in our unittests) then we would get Null back here, so just make sure we don't.
if (jndiBundle != null) {
-
- BundleContext jndiBundleContext = AccessController.doPrivileged(new PrivilegedAction<BundleContext>() {
- public BundleContext run() {
- return jndiBundle.getBundleContext();
- }
- });
-
+ BundleContext jndiBundleContext = Utils.doPrivileged(jndiBundle::getBundleContext);
if (!jndiBundleContext.getClass().equals(context.getClass())) {
//the context passed in must have come from a child framework
//use the parent context instead
@@ -161,97 +139,65 @@ public final class ContextHelper {
String contextFactoryClass = (String) environment.get(Context.INITIAL_CONTEXT_FACTORY);
if (contextFactoryClass == null) {
// 1. get ContextFactory using builder
- provider = getInitialContextUsingBuilder(context, environment);
-
+ provider = getInitialContextUsingBuilder(context, environment)
// 2. lookup all ContextFactory services
- if (provider == null) {
-
- ServiceReference<InitialContextFactory>[] references = AccessController.doPrivileged(new PrivilegedAction<ServiceReference<InitialContextFactory>[]>() {
- public ServiceReference<InitialContextFactory>[] run() {
- return Activator.getInitialContextFactoryServices();
- }
- });
+ .orElseGet(() -> getInitialContextUsingFactoryServices(context, environment)
+ .orElse(null));
- if (references != null) {
- Context initialContext;
- for (ServiceReference<InitialContextFactory> reference : references) {
- InitialContextFactory factory = 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);
- }
- }
- }
- }
} else {
- ServiceReference<InitialContextFactory> ref = ServiceTrackerCustomizers.ICF_CACHE.find(contextFactoryClass);
-
+ // 1. lookup using specified InitialContextFactory
+ ServiceReference<InitialContextFactory> ref = Activator.getInitialContextFactory(contextFactoryClass);
if (ref != null) {
- Context initialContext;
- InitialContextFactory factory = Utils.getServicePrivileged(context, ref);
+ InitialContextFactory factory = Activator.getService(context, ref);
if (factory != null) {
- try {
- initialContext = factory.getInitialContext(environment);
- provider = new SingleContextProvider(context, ref, initialContext);
- } finally {
- if (provider == null) context.ungetService(ref);
- }
+ Context initialContext = factory.getInitialContext(environment);
+ provider = new SingleContextProvider(context, ref, initialContext);
}
}
// 2. get ContextFactory using builder
if (provider == null) {
- provider = getInitialContextUsingBuilder(context, environment);
+ provider = getInitialContextUsingBuilder(context, environment).orElse(null);
}
}
return provider;
}
- private static ContextProvider getInitialContextUsingBuilder(BundleContext context,
- Hashtable<?, ?> environment)
- throws NamingException {
-
- ContextProvider provider = null;
- ServiceReference<InitialContextFactoryBuilder>[] refs = AccessController.doPrivileged(new PrivilegedAction<ServiceReference<InitialContextFactoryBuilder>[]>() {
- public ServiceReference<InitialContextFactoryBuilder>[] run() {
- return Activator.getInitialContextFactoryBuilderServices();
- }
- });
-
- if (refs != null) {
- InitialContextFactory factory = null;
- for (ServiceReference<InitialContextFactoryBuilder> ref : refs) {
- InitialContextFactoryBuilder builder = Utils.getServicePrivileged(context, ref);
- try {
- factory = builder.createInitialContextFactory(environment);
- } catch (NamingException ne) {
- // TODO: log
- // ignore this, if the builder fails we want to move onto the next one
- } catch (NullPointerException npe) {
- logger.log(Level.SEVERE, "NPE caught in ContextHelper.getInitialContextUsingBuilder. context=" + context + " ref=" + ref);
- throw npe;
- }
-
+ private static Optional<ContextProvider> getInitialContextUsingFactoryServices(BundleContext context, Hashtable<?, ?> environment) {
+ for (ServiceReference<InitialContextFactory> reference : Activator.getInitialContextFactoryServices()) {
+ try {
+ InitialContextFactory factory = Activator.getService(context, reference);
+ Context initialContext = factory.getInitialContext(environment);
+ if (initialContext != null) {
+ return Optional.of(new SingleContextProvider(context, reference, initialContext));
+ }
+ } catch (NamingException e) {
+ // ignore this, if the builder fails we want to move onto the next one
+ logger.log(Level.FINE, "Exception caught", e);
+ }
+ }
+ return Optional.empty();
+ }
+
+ private static Optional<ContextProvider> getInitialContextUsingBuilder(BundleContext context,
+ Hashtable<?, ?> environment) {
+ for (ServiceReference<InitialContextFactoryBuilder> ref : Activator.getInitialContextFactoryBuilderServices()) {
+ InitialContextFactoryBuilder builder = Activator.getService(context, ref);
+ try {
+ InitialContextFactory factory = builder.createInitialContextFactory(environment);
if (factory != null) {
- 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.
+ return Optional.of(new SingleContextProvider(context, ref, factory.getInitialContext(environment)));
}
+ } catch (NamingException ne) {
+ // ignore this, if the builder fails we want to move onto the next one
+ logger.log(Level.FINE, "Exception caught", ne);
+ } catch (NullPointerException npe) {
+ logger.log(Level.SEVERE, "NPE caught in ContextHelper.getInitialContextUsingBuilder. context=" + context + " ref=" + ref);
+ throw npe;
}
}
- return provider;
+ return Optional.empty();
}
}
Modified: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java Wed Feb 21 09:05:04 2018
@@ -38,7 +38,6 @@ public abstract class ContextProvider {
}
public void close() throws NamingException {
- if (bc != null) bc.ungetService(reference);
}
public abstract Context getContext() throws NamingException;
Modified: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.java Wed Feb 21 09:05:04 2018
@@ -32,10 +32,10 @@ import java.util.Map;
public class DelegateContext implements DirContext, LdapContext {
- private final Hashtable<Object, Object> env = new Hashtable<Object, Object>();
+ private final Hashtable<Object, Object> env = new Hashtable<>();
private final BundleContext bundleContext;
- private final Map<String, ContextProvider> urlContexts = new HashMap<String, ContextProvider>();
+ private final Map<String, ContextProvider> urlContexts = new HashMap<>();
private final boolean rebind;
private ContextProvider contextProvider;
@@ -108,7 +108,7 @@ public class DelegateContext implements
}
public Hashtable<?, ?> getEnvironment() throws NamingException {
- Hashtable<Object, Object> theEnv = new Hashtable<Object, Object>();
+ Hashtable<Object, Object> theEnv = new Hashtable<>();
theEnv.putAll(env);
return theEnv;
}
@@ -196,7 +196,7 @@ public class DelegateContext implements
}
protected Context findContext(String name) throws NamingException {
- Context toReturn = null;
+ Context toReturn;
if (name.contains(":")) {
toReturn = getURLContext(name);
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=1824944&r1=1824943&r2=1824944&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 Feb 21 09:05:04 2018
@@ -19,15 +19,8 @@
package org.apache.aries.jndi;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import javax.naming.*;
-import javax.naming.directory.Attributes;
import javax.naming.spi.DirObjectFactory;
-import javax.naming.spi.ObjectFactory;
-import javax.naming.spi.ObjectFactoryBuilder;
-import java.util.Collection;
-import java.util.Hashtable;
public class DirObjectFactoryHelper extends ObjectFactoryHelper implements DirObjectFactory {
@@ -35,157 +28,4 @@ public class DirObjectFactoryHelper exte
super(defaultContext, callerContext);
}
- public Object getObjectInstance(Object obj,
- Name name,
- Context nameCtx,
- Hashtable<?, ?> environment,
- Attributes attrs) throws Exception {
-
- // Step 1
- if (obj instanceof Referenceable) {
- obj = ((Referenceable) obj).getReference();
- }
-
- Object result = obj;
-
- // Step 2
- if (obj instanceof Reference) {
- Reference ref = (Reference) obj;
- String className = ref.getFactoryClassName();
-
- if (className != null) {
- // Step 3
- result = getObjectInstanceUsingClassName(obj, className, obj, name, nameCtx, environment, attrs);
- }
- }
-
- // Step 4
- if (result == null || result == obj) {
- result = getObjectInstanceUsingObjectFactoryBuilders(obj, name, nameCtx, environment, attrs);
- }
-
- // Step 5
- if (result == null || result == obj) {
- if (!(obj instanceof Reference) || ((Reference) obj).getFactoryClassName() == null) {
- result = getObjectInstanceUsingObjectFactories(obj, name, nameCtx, environment, attrs);
- }
- }
-
- // Extra, non-standard, bonus step. If javax.naming.OBJECT_FACTORIES is set as
- // a property in the environment, use its value to construct additional object factories.
- // Added under Aries-822, with reference
- // to https://www.osgi.org/bugzilla/show_bug.cgi?id=138
- if (result == null || result == obj) {
- result = getObjectInstanceViaContextDotObjectFactories(obj, name, nameCtx, environment, attrs);
- }
-
- return (result == null) ? obj : result;
- }
-
- private Object getObjectInstanceUsingObjectFactories(Object obj,
- Name name,
- Context nameCtx,
- Hashtable<?, ?> environment,
- Attributes attrs)
- throws Exception {
-
- Object result = null;
- Collection<ServiceReference<DirObjectFactory>> refs = Utils.getReferencesPrivileged(callerContext, DirObjectFactory.class);
- for (ServiceReference<DirObjectFactory> ref : refs) {
-
- if (canCallObjectFactory(obj, ref)) {
- DirObjectFactory factory = 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.
- if (result != null && result != obj) {
- break;
- }
- }
- }
-
- if (result == null) {
- result = getObjectInstanceUsingObjectFactories(obj, name, nameCtx, environment);
- }
-
- return (result == null) ? obj : result;
- }
-
- private boolean canCallObjectFactory(Object obj, ServiceReference ref) {
- if (obj instanceof Reference) return true;
-
- Object prop = ref.getProperty("aries.object.factory.requires.reference");
-
- if (prop == null) return true;
-
- if (prop instanceof Boolean) return !(Boolean) prop; // if set to true we don't call.
-
- return true;
- }
-
- private Object getObjectInstanceUsingClassName(Object reference,
- String className,
- Object obj,
- Name name,
- Context nameCtx,
- Hashtable<?, ?> environment,
- Attributes attrs)
- throws Exception {
-
- Tuple<ServiceReference<ObjectFactory>, ObjectFactory> tuple = ObjectFactoryHelper.findObjectFactoryByClassName(defaultContext, className);
- Object result = null;
-
- if (tuple.second != null) {
- try {
- result = ((DirObjectFactory) tuple.second).getObjectInstance(reference, name, nameCtx, environment, attrs);
- } finally {
- defaultContext.ungetService(tuple.first);
- }
- }
-
- return (result == null) ? obj : result;
- }
-
- private Object getObjectInstanceUsingObjectFactoryBuilders(Object obj,
- Name name,
- Context nameCtx,
- Hashtable<?, ?> environment,
- Attributes attrs)
- throws Exception {
- ObjectFactory factory = null;
- Collection<ServiceReference<ObjectFactoryBuilder>> refs = Utils.getReferencesPrivileged(callerContext, ObjectFactoryBuilder.class);
- for (ServiceReference<ObjectFactoryBuilder> ref : refs) {
- ObjectFactoryBuilder builder = Utils.getServicePrivileged(callerContext, ref);
- try {
- factory = builder.createObjectFactory(obj, environment);
- } catch (NamingException e) {
- // TODO: log it
- } finally {
- callerContext.ungetService(ref);
- }
- if (factory != null) {
- break;
- }
- }
-
- Object result = null;
-
- if (factory != null) {
- if (factory instanceof DirObjectFactory) {
- result = ((DirObjectFactory) factory).getObjectInstance(obj, name, nameCtx, environment, attrs);
- } else {
- result = factory.getObjectInstance(obj, name, nameCtx, environment);
- }
- }
-
- return (result == null) ? obj : result;
- }
-
}
Modified: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/JREInitialContextFactoryBuilder.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/JREInitialContextFactoryBuilder.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/JREInitialContextFactoryBuilder.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/JREInitialContextFactoryBuilder.java Wed Feb 21 09:05:04 2018
@@ -22,26 +22,22 @@ import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.Hashtable;
public class JREInitialContextFactoryBuilder implements InitialContextFactoryBuilder {
public InitialContextFactory createInitialContextFactory(Hashtable<?, ?> environment)
throws NamingException {
- final String contextFactoryClass = (String) environment.get(Context.INITIAL_CONTEXT_FACTORY);
+ String contextFactoryClass = (String) environment.get(Context.INITIAL_CONTEXT_FACTORY);
if (contextFactoryClass != null) {
- return AccessController.doPrivileged(new PrivilegedAction<InitialContextFactory>() {
- public InitialContextFactory run() {
- try {
- @SuppressWarnings("unchecked")
- Class<? extends InitialContextFactory> clazz = (Class<? extends InitialContextFactory>) ClassLoader.
- getSystemClassLoader().loadClass(contextFactoryClass);
- return InitialContextFactory.class.cast(clazz.newInstance());
- } catch (Exception e) {
- return null;
- }
+ return Utils.doPrivileged(() -> {
+ try {
+ @SuppressWarnings("unchecked")
+ Class<? extends InitialContextFactory> clazz = (Class<? extends InitialContextFactory>) ClassLoader.
+ getSystemClassLoader().loadClass(contextFactoryClass);
+ return InitialContextFactory.class.cast(clazz.newInstance());
+ } catch (Exception e) {
+ return null;
}
});
}
Modified: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiInitialContextFactoryBuilder.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiInitialContextFactoryBuilder.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiInitialContextFactoryBuilder.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiInitialContextFactoryBuilder.java Wed Feb 21 09:05:04 2018
@@ -18,6 +18,7 @@
*/
package org.apache.aries.jndi;
+import org.apache.aries.jndi.startup.Activator;
import org.osgi.framework.BundleContext;
import javax.naming.Context;
@@ -30,23 +31,17 @@ import java.util.Hashtable;
public class OSGiInitialContextFactoryBuilder implements InitialContextFactoryBuilder, InitialContextFactory {
- public InitialContextFactory createInitialContextFactory(Hashtable<?, ?> environment)
- throws NamingException {
+ public InitialContextFactory createInitialContextFactory(Hashtable<?, ?> environment) {
return this;
}
- public Context getInitialContext(Hashtable<?, ?> environment)
- throws NamingException {
-
- AugmenterInvokerImpl.getInstance().augmentEnvironment(environment);
-
+ public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
+ Activator.getAugmenterInvoker().augmentEnvironment(environment);
BundleContext context = Utils.getBundleContext(environment, InitialContext.class);
if (context == null) {
throw new NoInitialContextException(Utils.MESSAGES.getMessage("cannot.find.callers.bundlecontext"));
}
-
- AugmenterInvokerImpl.getInstance().unaugmentEnvironment(environment);
-
+ Activator.getAugmenterInvoker().unaugmentEnvironment(environment);
return ContextHelper.getInitialContext(context, environment);
}
}
Modified: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiObjectFactoryBuilder.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiObjectFactoryBuilder.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiObjectFactoryBuilder.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/OSGiObjectFactoryBuilder.java Wed Feb 21 09:05:04 2018
@@ -18,6 +18,7 @@
*/
package org.apache.aries.jndi;
+import org.apache.aries.jndi.startup.Activator;
import org.osgi.framework.BundleContext;
import javax.naming.Context;
@@ -35,8 +36,7 @@ public class OSGiObjectFactoryBuilder im
defaultContext = ctx;
}
- public ObjectFactory createObjectFactory(Object obj, Hashtable<?, ?> environment)
- throws NamingException {
+ public ObjectFactory createObjectFactory(Object obj, Hashtable<?, ?> environment) {
return this;
}
@@ -45,16 +45,7 @@ public class OSGiObjectFactoryBuilder im
Context nameCtx,
Hashtable<?, ?> environment) throws Exception {
- if (environment == null) {
- environment = new Hashtable();
- }
-
- BundleContext callerContext = getCallerBundleContext(environment);
- if (callerContext == null) {
- return obj;
- }
- DirObjectFactoryHelper helper = new DirObjectFactoryHelper(defaultContext, callerContext);
- return helper.getObjectInstance(obj, name, nameCtx, environment);
+ return getObjectInstance(obj, name, nameCtx, environment, null);
}
public Object getObjectInstance(Object obj,
@@ -75,13 +66,13 @@ public class OSGiObjectFactoryBuilder im
return helper.getObjectInstance(obj, name, nameCtx, environment, attrs);
}
- private BundleContext getCallerBundleContext(Hashtable<?, ?> environment) throws NamingException {
- AugmenterInvokerImpl.getInstance().augmentEnvironment(environment);
+ private BundleContext getCallerBundleContext(Hashtable<?, ?> environment) {
+ Activator.getAugmenterInvoker().augmentEnvironment(environment);
BundleContext context = Utils.getBundleContext(environment, NamingManager.class);
if (context == null) {
context = Utils.getBundleContext(environment, DirectoryManager.class);
}
- AugmenterInvokerImpl.getInstance().unaugmentEnvironment(environment);
+ Activator.getAugmenterInvoker().unaugmentEnvironment(environment);
return context;
}
}
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=1824944&r1=1824943&r2=1824944&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 Feb 21 09:05:04 2018
@@ -18,9 +18,8 @@
*/
package org.apache.aries.jndi;
-import org.apache.aries.util.service.registry.ServicePair;
+import org.apache.aries.jndi.startup.Activator;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import javax.naming.*;
@@ -30,7 +29,6 @@ import javax.naming.spi.ObjectFactory;
import javax.naming.spi.ObjectFactoryBuilder;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.logging.Level;
@@ -39,6 +37,7 @@ import java.util.logging.Logger;
public class ObjectFactoryHelper implements ObjectFactory {
private static final Logger logger = Logger.getLogger(ObjectFactoryHelper.class.getName());
+
protected BundleContext defaultContext;
protected BundleContext callerContext;
@@ -47,127 +46,164 @@ public class ObjectFactoryHelper impleme
this.callerContext = callerContext;
}
- protected static String getUrlScheme(String name) {
- String scheme = name;
- int index = name.indexOf(':');
- if (index != -1) {
- scheme = name.substring(0, index);
- }
- return scheme;
- }
-
- static Tuple<ServiceReference<ObjectFactory>, ObjectFactory> findObjectFactoryByClassName(final BundleContext ctx, final String className) {
- return AccessController.doPrivileged(new PrivilegedAction<Tuple<ServiceReference<ObjectFactory>, ObjectFactory>>() {
- public Tuple<ServiceReference<ObjectFactory>, ObjectFactory> run() {
- ServiceReference<ObjectFactory> serviceReference = null;
-
- try {
- ServiceReference<?>[] refs = ctx.getServiceReferences(className, null);
- if (refs != null && refs.length > 0) {
- serviceReference = (ServiceReference<ObjectFactory>) 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 = ctx.getService(serviceReference);
- }
+ public Object getObjectInstance(Object obj,
+ Name name,
+ Context nameCtx,
+ Hashtable<?, ?> environment) throws Exception {
- return new Tuple<ServiceReference<ObjectFactory>, ObjectFactory>(serviceReference, factory);
- }
- });
+ return getObjectInstance(obj, name, nameCtx, environment, null);
}
public Object getObjectInstance(Object obj,
Name name,
Context nameCtx,
- Hashtable<?, ?> environment) throws Exception {
+ Hashtable<?, ?> environment,
+ Attributes attrs) throws Exception {
- // Step 1 ensure we have a reference rather than a referenceable
+ // Step 1
if (obj instanceof Referenceable) {
obj = ((Referenceable) obj).getReference();
}
- if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "obj = " + obj);
-
Object result = obj;
- // Step 2 - if we have a reference process it as a reference
+ // Step 2
if (obj instanceof Reference) {
Reference ref = (Reference) obj;
String className = ref.getFactoryClassName();
if (className != null) {
- // Step 3 - use the class name in the reference to get the factory class name
- result = getObjectInstanceUsingClassName(obj, className, obj, name, nameCtx, environment);
+ // Step 3
+ result = getObjectInstanceUsingClassName(obj, className, obj, name, nameCtx, environment, attrs);
} else {
// Step 4 - look, assuming url string ref addrs, for a url context object factory.
- result = getObjectInstanceUsingRefAddress(ref.getAll(), obj, name, nameCtx, environment);
+ result = getObjectInstanceUsingRefAddress(ref.getAll(), obj, name, nameCtx, environment, attrs);
}
}
- if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Step 4: result = " + result);
-
- // Step 5 - if we still don't have a resolved object goto the object factory builds in the SR.
+ // Step 4
if (result == null || result == obj) {
- result = getObjectInstanceUsingObjectFactoryBuilders(obj, name, nameCtx, environment);
+ result = getObjectInstanceUsingObjectFactoryBuilders(obj, name, nameCtx, environment, attrs);
}
- if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Step 5: result = " + result);
-
- // Step 6 - Attempt to use all the registered ObjectFactories in the SR.
+ // Step 5
if (result == null || result == obj) {
if (!(obj instanceof Reference) || ((Reference) obj).getFactoryClassName() == null) {
- result = getObjectInstanceUsingObjectFactories(obj, name, nameCtx, environment);
+ result = getObjectInstanceUsingObjectFactories(obj, name, nameCtx, environment, attrs);
}
}
- if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Step 6: result = " + result);
-
- // Extra, non-standard, bonus step 7. If javax.naming.OBJECT_FACTORIES is set as
+ // Extra, non-standard, bonus step. If javax.naming.OBJECT_FACTORIES is set as
// a property in the environment, use its value to construct additional object factories.
// Added under Aries-822, with reference
// to https://www.osgi.org/bugzilla/show_bug.cgi?id=138
if (result == null || result == obj) {
- result = getObjectInstanceViaContextDotObjectFactories(obj, name, nameCtx, environment);
+ result = getObjectInstanceViaContextDotObjectFactories(obj, name, nameCtx, environment, attrs);
}
- if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "Step 7: result = " + result);
+ return (result == null) ? obj : result;
+ }
+
+ private Object getObjectInstanceUsingObjectFactories(Object obj,
+ Name name,
+ Context nameCtx,
+ Hashtable<?, ?> environment,
+ Attributes attrs) throws Exception {
+ for (ServiceReference<ObjectFactory> ref : Activator.getReferences(callerContext, ObjectFactory.class)) {
+ if (canCallObjectFactory(obj, ref)) {
+ ObjectFactory factory = Activator.getService(callerContext, ref);
+ if (factory != null) {
+ Object result;
+ if (factory instanceof DirObjectFactory) {
+ result = ((DirObjectFactory) factory).getObjectInstance(obj, name, nameCtx, environment, attrs);
+ } else {
+ result = factory.getObjectInstance(obj, name, nameCtx, environment);
+ }
+ // 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.
+ if (result != null && result != obj) {
+ return result;
+ }
+ }
+ }
+ }
+ return obj;
+ }
+
+ private boolean canCallObjectFactory(Object obj, ServiceReference ref) {
+ if (obj instanceof Reference) return true;
+ Object prop = ref.getProperty("aries.object.factory.requires.reference");
+ return (prop == null) || !(prop instanceof Boolean) || !(Boolean) prop;
+ }
+
+ private Object getObjectInstanceUsingClassName(Object reference,
+ String className,
+ Object obj,
+ Name name,
+ Context nameCtx,
+ Hashtable<?, ?> environment,
+ Attributes attrs)
+ throws Exception {
+
+ Object result = null;
+
+ ObjectFactory factory = ObjectFactoryHelper.findObjectFactoryByClassName(defaultContext, className);
+ if (factory != null) {
+ if (factory instanceof DirObjectFactory) {
+ result = ((DirObjectFactory) factory).getObjectInstance(reference, name, nameCtx, environment, attrs);
+ } else {
+ result = factory.getObjectInstance(reference, name, nameCtx, environment);
+ }
+ }
return (result == null) ? obj : result;
}
- /*
- * Attempt to obtain an Object instance via the java.naming.factory.object property
- */
- protected Object getObjectInstanceViaContextDotObjectFactories(Object obj,
- Name name,
- Context nameCtx,
- Hashtable<?, ?> environment) throws Exception {
- return getObjectInstanceViaContextDotObjectFactories(obj, name, nameCtx, environment, null);
+ private Object getObjectInstanceUsingObjectFactoryBuilders(Object obj,
+ Name name,
+ Context nameCtx,
+ Hashtable<?, ?> environment,
+ Attributes attrs)
+ throws Exception {
+ ObjectFactory factory = null;
+ for (ObjectFactoryBuilder ofb : Activator.getServices(callerContext, ObjectFactoryBuilder.class)) {
+ try {
+ factory = ofb.createObjectFactory(obj, environment);
+ } catch (NamingException e) {
+ // TODO: log it
+ }
+ if (factory != null) {
+ break;
+ }
+ }
+
+ Object result = null;
+
+ if (factory != null) {
+ if (factory instanceof DirObjectFactory) {
+ result = ((DirObjectFactory) factory).getObjectInstance(obj, name, nameCtx, environment, attrs);
+ } else {
+ result = factory.getObjectInstance(obj, name, nameCtx, environment);
+ }
+ }
+
+ return (result == null) ? obj : result;
}
/*
* Attempt to obtain an Object instance via the java.naming.factory.object property
*/
- protected Object getObjectInstanceViaContextDotObjectFactories(Object obj,
- Name name,
- Context nameCtx,
- Hashtable<?, ?> environment,
- Attributes attrs) throws Exception {
+ private Object getObjectInstanceViaContextDotObjectFactories(Object obj,
+ Name name,
+ Context nameCtx,
+ Hashtable<?, ?> environment,
+ Attributes attrs) throws Exception {
Object result = null;
String factories = (String) environment.get(Context.OBJECT_FACTORIES);
if (factories != null && factories.length() > 0) {
String[] candidates = factories.split(":");
- ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
- public ClassLoader run() {
- return Thread.currentThread().getContextClassLoader();
- }
- });
+ ClassLoader cl = Utils.doPrivileged(Thread.currentThread()::getContextClassLoader);
for (String cand : candidates) {
ObjectFactory factory;
try {
@@ -181,11 +217,8 @@ public class ObjectFactoryHelper impleme
if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "cand=" + cand + " factory=" + factory);
if (factory != null) {
if (factory instanceof DirObjectFactory) {
- if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "its a DirObjectFactory");
- final DirObjectFactory dirFactory = (DirObjectFactory) factory;
- result = dirFactory.getObjectInstance(obj, name, nameCtx, environment, attrs);
+ result = ((DirObjectFactory) factory).getObjectInstance(obj, name, nameCtx, environment, attrs);
} else {
- if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "its an ObjectFactory");
result = factory.getObjectInstance(obj, name, nameCtx, environment);
}
}
@@ -196,56 +229,13 @@ public class ObjectFactoryHelper impleme
return (result == null) ? obj : result;
}
- protected Object getObjectInstanceUsingObjectFactories(Object obj,
- Name name,
- Context nameCtx,
- Hashtable<?, ?> environment)
- throws Exception {
- Object result = null;
- Collection<ServiceReference<ObjectFactory>> refs = Utils.getReferencesPrivileged(callerContext, ObjectFactory.class);
- for (ServiceReference<ObjectFactory> ref : refs) {
- if (canCallObjectFactory(obj, ref)) {
- ObjectFactory factory = 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
- // object then we should return the result, so break out of the
- // loop we are in.
- if (result != null && result != obj) {
- break;
- }
- }
- }
-
- return (result == null) ? obj : result;
- }
-
- private boolean canCallObjectFactory(Object obj, ServiceReference ref) {
- if (obj instanceof Reference) return true;
-
- Object prop = ref.getProperty("aries.object.factory.requires.reference");
-
- if (prop == null) return true;
-
- if (prop instanceof Boolean) return !(Boolean) prop; // if set to true we don't call.
-
- return true;
- }
-
private Object getObjectInstanceUsingRefAddress(Enumeration<RefAddr> addresses,
Object obj,
Name name,
Context nameCtx,
- Hashtable<?, ?> environment)
+ Hashtable<?, ?> environment,
+ Attributes attrs)
throws Exception {
- Object result = null;
while (addresses.hasMoreElements()) {
RefAddr address = addresses.nextElement();
if (address instanceof StringRefAddr && "URL".equals(address.getType())) {
@@ -256,78 +246,45 @@ public class ObjectFactoryHelper impleme
if (factoryService != null) {
ObjectFactory factory = factoryService.get();
+ Object result;
+
String value = (String) address.getContent();
- try {
+ if (factory instanceof DirObjectFactory) {
+ result = ((DirObjectFactory) factory).getObjectInstance(value, name, nameCtx, environment, attrs);
+ } else {
result = factory.getObjectInstance(value, name, nameCtx, environment);
- } finally {
- factoryService.unget();
}
// 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.
if (result != null && result != obj) {
- break;
+ return result;
}
}
}
}
- return (result == null) ? obj : result;
+ return obj;
}
- private Object getObjectInstanceUsingClassName(Object reference,
- String className,
- Object obj,
- Name name,
- Context nameCtx,
- Hashtable<?, ?> environment)
- throws Exception {
-
- Tuple<ServiceReference<ObjectFactory>, ObjectFactory> tuple = findObjectFactoryByClassName(defaultContext, className);
- Object result = null;
-
- if (tuple.second != null) {
- try {
- result = tuple.second.getObjectInstance(reference, name, nameCtx, environment);
- } finally {
- defaultContext.ungetService(tuple.first);
- }
+ private static String getUrlScheme(String name) {
+ String scheme = name;
+ int index = name.indexOf(':');
+ if (index != -1) {
+ scheme = name.substring(0, index);
}
-
- return (result == null) ? obj : result;
+ return scheme;
}
- private Object getObjectInstanceUsingObjectFactoryBuilders(Object obj,
- Name name,
- Context nameCtx,
- Hashtable<?, ?> environment)
- throws Exception {
-
- ObjectFactory factory = null;
-
- Collection<ServiceReference<ObjectFactoryBuilder>> refs = Utils.getReferencesPrivileged(callerContext, ObjectFactoryBuilder.class);
- for (ServiceReference<ObjectFactoryBuilder> ref : refs) {
- ObjectFactoryBuilder builder = Utils.getServicePrivileged(callerContext, ref);
- try {
- factory = builder.createObjectFactory(obj, environment);
- } catch (NamingException e) {
- // TODO: log it
- } finally {
- callerContext.ungetService(ref);
- }
- if (factory != null) {
- break;
+ private static ObjectFactory findObjectFactoryByClassName(final BundleContext ctx, final String className) {
+ return AccessController.doPrivileged((PrivilegedAction<ObjectFactory>) () -> {
+ ServiceReference<?> ref = ctx.getServiceReference(className);
+ if (ref != null) {
+ return (ObjectFactory) Activator.getService(ctx, ref);
}
- }
-
- Object result = null;
-
- if (factory != null) {
- result = factory.getObjectInstance(obj, name, nameCtx, environment);
- }
-
- return (result == null) ? obj : result;
+ return null;
+ });
}
}
\ No newline at end of file
Modified: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ProviderAdminServiceFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ProviderAdminServiceFactory.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ProviderAdminServiceFactory.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ProviderAdminServiceFactory.java Wed Feb 21 09:05:04 2018
@@ -23,7 +23,7 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
-public class ProviderAdminServiceFactory implements ServiceFactory {
+public class ProviderAdminServiceFactory implements ServiceFactory<ProviderAdminService> {
private BundleContext defaultContext;
@@ -31,12 +31,12 @@ public class ProviderAdminServiceFactory
this.defaultContext = defaultContext;
}
- public Object getService(Bundle bundle, ServiceRegistration registration) {
+ public ProviderAdminService getService(Bundle bundle, ServiceRegistration registration) {
return new ProviderAdminService(defaultContext, bundle.getBundleContext());
}
- public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
- ((ProviderAdminService) service).close();
+ public void ungetService(Bundle bundle, ServiceRegistration registration, ProviderAdminService service) {
+ service.close();
}
}
Copied: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java (from r1824943, aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java)
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java?p2=aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java&p1=aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java&r1=1824943&r2=1824944&rev=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java Wed Feb 21 09:05:04 2018
@@ -18,28 +18,40 @@
*/
package org.apache.aries.jndi;
+import org.apache.aries.jndi.startup.Activator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
-import javax.naming.Context;
-import javax.naming.NamingException;
+import java.util.function.Supplier;
-public abstract class ContextProvider {
- private final ServiceReference<?> reference;
- private final BundleContext bc;
-
- public ContextProvider(BundleContext ctx, ServiceReference<?> reference) {
- bc = ctx;
- this.reference = reference;
+public class ServicePair<T> implements Supplier<T> {
+
+ private BundleContext ctx;
+ private ServiceReference<?> ref;
+ private T svc;
+
+ public ServicePair(BundleContext context, ServiceReference<T> serviceRef) {
+ this.ctx = context;
+ this.ref = serviceRef;
+ }
+
+ public ServicePair(BundleContext context, ServiceReference<?> serviceRef, T service) {
+ this.ctx = context;
+ this.ref = serviceRef;
+ this.svc = service;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T get() {
+ return svc != null ? svc : ref != null ? (T) Activator.getService(ctx, ref) : null;
}
public boolean isValid() {
- return (reference.getBundle() != null);
+ return ref.getBundle() != null;
}
- public void close() throws NamingException {
- if (bc != null) bc.ungetService(reference);
+ public ServiceReference<?> getReference() {
+ return ref;
}
- public abstract Context getContext() throws NamingException;
}
Modified: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/URLContextProvider.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/URLContextProvider.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/URLContextProvider.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/URLContextProvider.java Wed Feb 21 09:05:04 2018
@@ -41,9 +41,7 @@ public class URLContextProvider extends
try {
return (Context) factory.getObjectInstance(null, null, null, environment);
} catch (Exception e) {
- NamingException ne = new NamingException();
- ne.initCause(e);
- throw ne;
+ throw (NamingException) new NamingException().initCause(e);
}
}
}
Modified: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/Utils.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/Utils.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/Utils.java (original)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/Utils.java Wed Feb 21 09:05:04 2018
@@ -19,22 +19,26 @@
package org.apache.aries.jndi;
import org.apache.aries.util.nls.MessageUtil;
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleReference;
import org.osgi.service.jndi.JNDIConstants;
import javax.naming.NamingException;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.*;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.function.Function;
+import java.util.function.Supplier;
/**
*/
public final class Utils {
- public static final Comparator<ServiceReference<?>> SERVICE_REFERENCE_COMPARATOR =
- new ServiceReferenceComparator();
public static final MessageUtil MESSAGES = MessageUtil.createMessageUtil(Utils.class, "org.apache.aries.jndi.nls.jndiMessages");
/**
@@ -49,17 +53,12 @@ public final class Utils {
* @return the bundle context for the caller.
* @throws NamingException
*/
- public static BundleContext getBundleContext(final Map<?, ?> env,
- final Class<?> namingClass) {
- return AccessController.doPrivileged(new PrivilegedAction<BundleContext>() {
- public BundleContext run() {
- return doGetBundleContext(env, namingClass);
- }
- });
+ public static BundleContext getBundleContext(final Map<?, ?> env, final Class<?> namingClass) {
+ return doPrivileged(() -> doGetBundleContext(env, namingClass));
}
private static BundleContext doGetBundleContext(Map<?, ?> env, Class<?> namingClass) {
- BundleContext result = null;
+ BundleContext result;
Object bc = (env == null) ? null : env.get(JNDIConstants.BUNDLE_CONTEXT);
@@ -115,11 +114,7 @@ public final class Utils {
}
public static String getSystemProperty(final String key, final String defaultValue) {
- return AccessController.doPrivileged(new PrivilegedAction<String>() {
- public String run() {
- return System.getProperty(key, defaultValue);
- }
- });
+ return doPrivileged(() -> System.getProperty(key, defaultValue));
}
public static Hashtable<?, ?> toHashtable(Map<?, ?> map) {
@@ -127,76 +122,65 @@ public final class Utils {
if (map instanceof Hashtable<?, ?>) {
env = (Hashtable<?, ?>) map;
} else if (map == null) {
- env = new Hashtable<Object, Object>();
+ env = new Hashtable<>();
} else {
env = new Hashtable<Object, Object>(map);
}
return env;
}
- public static <T> T doPrivileged(PrivilegedExceptionAction<T> action) throws Exception {
- try {
- return AccessController.doPrivileged(action);
- } catch (PrivilegedActionException e) {
- Exception cause = e.getException();
- throw cause;
- }
+ public static <T> T doPrivileged(Supplier<T> action) {
+ return AccessController.doPrivileged((PrivilegedAction<T>) action::get);
}
- public static <T> T doPrivilegedNaming(PrivilegedExceptionAction<T> action) throws NamingException {
- try {
- return AccessController.doPrivileged(action);
- } catch (PrivilegedActionException e) {
- Exception cause = e.getException();
- if (cause instanceof NamingException) {
- throw (NamingException) cause;
- } else {
- NamingException ex = new NamingException(cause.getMessage());
- ex.initCause(cause);
- throw ex;
- }
+ private static class StackFinder extends SecurityManager {
+ public Class<?>[] getClassContext() {
+ return super.getClassContext();
}
}
- public static <T> Collection<ServiceReference<T>> getReferencesPrivileged(final BundleContext ctx, final Class<T> clazz) {
- return AccessController.doPrivileged(new PrivilegedAction<Collection<ServiceReference<T>>>() {
- public Collection<ServiceReference<T>> run() {
- try {
- ServiceReference<?>[] refs = ctx.getServiceReferences(clazz.getName(), null);
- List<ServiceReference<T>> list = new ArrayList<ServiceReference<T>>();
- if (refs != null) {
- for (ServiceReference<?> ref : refs) {
- list.add((ServiceReference<T>) ref);
- }
- }
- Collections.sort(list, Utils.SERVICE_REFERENCE_COMPARATOR);
- return list;
- } catch (InvalidSyntaxException ise) {
- // should not happen
- throw new RuntimeException(MESSAGES.getMessage("null.is.invalid.filter"), ise);
- }
- }
- });
+ public static <U, V> Iterator<V> map(Iterator<U> iterator, Function<U, V> mapper) {
+ return new MappedIterator<>(iterator, mapper);
}
- public static <T> T getServicePrivileged(final BundleContext ctx, final ServiceReference<T> ref) {
- return AccessController.doPrivileged(new PrivilegedAction<T>() {
- public T run() {
- return ctx.getService(ref);
- }
- });
- }
+ private static class MappedIterator<U, V> implements Iterator<V> {
- private static class StackFinder extends SecurityManager {
- public Class<?>[] getClassContext() {
- return super.getClassContext();
+ private final Iterator<U> iterator;
+ private final Function<U, V> mapper;
+ private V nextElement;
+ private boolean hasNext;
+
+ public MappedIterator(Iterator<U> iterator, Function<U, V> mapper) {
+ this.iterator = iterator;
+ this.mapper = mapper;
+ nextMatch();
}
- }
- private static class ServiceReferenceComparator implements Comparator<ServiceReference<?>> {
- public int compare(ServiceReference<?> o1, ServiceReference<?> o2) {
- return o2.compareTo(o1);
+ @Override
+ public boolean hasNext() {
+ return hasNext;
}
- }
+ @Override
+ public V next() {
+ if (!hasNext) {
+ throw new NoSuchElementException();
+ }
+ return nextMatch();
+ }
+
+ private V nextMatch() {
+ V oldMatch = nextElement;
+ while (iterator.hasNext()) {
+ V o = mapper.apply(iterator.next());
+ if (o != null) {
+ hasNext = true;
+ nextElement = o;
+ return oldMatch;
+ }
+ }
+ hasNext = false;
+ return oldMatch;
+ }
+ }
}
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=1824944&r1=1824943&r2=1824944&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 Feb 21 09:05:04 2018
@@ -20,25 +20,22 @@ package org.apache.aries.jndi.startup;
import org.apache.aries.jndi.*;
import org.apache.aries.jndi.spi.AugmenterInvoker;
-import org.apache.aries.jndi.spi.EnvironmentAugmentation;
-import org.apache.aries.jndi.spi.EnvironmentUnaugmentation;
-import org.apache.aries.jndi.tracker.ServiceTrackerCustomizers;
+import org.apache.aries.jndi.tracker.CachingServiceTracker;
import org.apache.aries.jndi.urls.URLObjectFactoryFinder;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
+import org.osgi.framework.*;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.service.jndi.JNDIConstants;
import org.osgi.service.jndi.JNDIContextManager;
import org.osgi.service.jndi.JNDIProviderAdmin;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.osgi.util.tracker.BundleTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.naming.NamingException;
import javax.naming.spi.*;
import java.lang.reflect.Field;
-import java.util.Arrays;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
/**
* The activator for this bundle makes sure the static classes in it are
@@ -48,90 +45,88 @@ public class Activator implements Bundle
private static final Logger LOGGER = LoggerFactory.getLogger(Activator.class.getName());
- private static String FORCE_BUILDER = "org.apache.aries.jndi.force.builder";
- private static InitialContextFactoryBuilder originalICFBuilder;
- private static ObjectFactoryBuilder originalOFBuilder;
- private static volatile ServiceTracker<InitialContextFactoryBuilder, ServiceReference<InitialContextFactoryBuilder>> icfBuilders;
- private static volatile ServiceTracker<URLObjectFactoryFinder, ServiceReference<URLObjectFactoryFinder>> urlObjectFactoryFinders;
- private static volatile ServiceTracker<InitialContextFactory, ServiceReference<InitialContextFactory>> initialContextFactories;
- private static volatile ServiceTracker<ObjectFactory, ServiceReference<ObjectFactory>> objectFactories;
- private static volatile ServiceTracker<EnvironmentAugmentation, ServiceReference<EnvironmentAugmentation>> environmentAugmentors;
- private static volatile ServiceTracker<EnvironmentUnaugmentation, ServiceReference<EnvironmentUnaugmentation>> environmentUnaugmentors;
- private OSGiInitialContextFactoryBuilder icfBuilder;
- private OSGiObjectFactoryBuilder ofBuilder;
+ private static final String FORCE_BUILDER = "org.apache.aries.jndi.force.builder";
- /*
- * There are no public API to reset the InitialContextFactoryBuilder or
- * ObjectFactoryBuilder on the NamingManager so try to use reflection.
- */
- private static void setField(Class<?> expectedType, Object value, boolean saveOriginal) throws IllegalStateException {
- try {
- for (Field field : NamingManager.class.getDeclaredFields()) {
- if (expectedType.equals(field.getType())) {
- field.setAccessible(true);
- if (saveOriginal) {
- if (expectedType.equals(InitialContextFactoryBuilder.class)) {
- originalICFBuilder = (InitialContextFactoryBuilder) field.get(null);
- } else {
- originalOFBuilder = (ObjectFactoryBuilder) field.get(null);
- }
- }
+ private static volatile Activator instance;
- field.set(null, value);
- }
- }
- } catch (Throwable t) {
- // Ignore
- LOGGER.debug("Error setting field.", t);
- throw new IllegalStateException(t);
- }
- }
+ private BundleTracker<ServiceCache> bundleServiceCaches;
- public static ServiceReference<InitialContextFactoryBuilder>[] getInitialContextFactoryBuilderServices() {
- ServiceReference<InitialContextFactoryBuilder>[] refs = icfBuilders.getServiceReferences();
+ private CachingServiceTracker<InitialContextFactoryBuilder> icfBuilders;
+ private CachingServiceTracker<URLObjectFactoryFinder> urlObjectFactoryFinders;
+ private CachingServiceTracker<InitialContextFactory> initialContextFactories;
+ private CachingServiceTracker<ObjectFactory> objectFactories;
- if (refs != null) {
- Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
- }
+ private AugmenterInvoker augmenterInvoker;
- return refs;
+ private InitialContextFactoryBuilder originalICFBuilder;
+ private OSGiInitialContextFactoryBuilder icfBuilder;
+
+ private ObjectFactoryBuilder originalOFBuilder;
+ private OSGiObjectFactoryBuilder ofBuilder;
+
+ public static Collection<ServiceReference<InitialContextFactoryBuilder>> getInitialContextFactoryBuilderServices() {
+ return instance.icfBuilders.getReferences();
}
- public static ServiceReference<InitialContextFactory>[] getInitialContextFactoryServices() {
- ServiceReference<InitialContextFactory>[] refs = initialContextFactories.getServiceReferences();
+ public static Collection<ServiceReference<InitialContextFactory>> getInitialContextFactoryServices() {
+ return instance.initialContextFactories.getReferences();
+ }
- if (refs != null) {
- Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
- }
+ public static Collection<ServiceReference<URLObjectFactoryFinder>> getURLObjectFactoryFinderServices() {
+ return instance.urlObjectFactoryFinders.getReferences();
+ }
- return refs;
+ public static ServiceReference<ObjectFactory> getUrlFactory(String scheme) {
+ return instance.objectFactories.find(scheme);
}
- public static ServiceReference<URLObjectFactoryFinder>[] getURLObjectFactoryFinderServices() {
- ServiceReference<URLObjectFactoryFinder>[] refs = urlObjectFactoryFinders.getServiceReferences();
+ public static ServiceReference<InitialContextFactory> getInitialContextFactory(String interfaceName) {
+ return instance.initialContextFactories.find(interfaceName);
+ }
- if (refs != null) {
- Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
- }
- return refs;
+ public static AugmenterInvoker getAugmenterInvoker() {
+ return instance.augmenterInvoker;
}
- public static Object[] getEnvironmentAugmentors() {
- return environmentAugmentors.getServices();
+ public static <T> T getService(BundleContext context, ServiceReference<T> ref) {
+ ServiceCache cache = instance.bundleServiceCaches.getObject(context.getBundle());
+ return cache.getService(ref);
}
- public static Object[] getEnvironmentUnaugmentors() {
- return environmentUnaugmentors.getServices();
+ public static <T> Collection<ServiceReference<T>> getReferences(BundleContext context, Class<T> clazz) {
+ ServiceCache cache = instance.bundleServiceCaches.getObject(context.getBundle());
+ return cache.getReferences(clazz);
}
+ public static <T> Iterable<T> getServices(BundleContext context, Class<T> clazz) {
+ ServiceCache cache = instance.bundleServiceCaches.getObject(context.getBundle());
+ Collection<ServiceReference<T>> refs = cache.getReferences(clazz);
+ return () -> Utils.map(refs.iterator(), ref -> Activator.getService(context, ref));
+ }
+
+
public void start(BundleContext context) {
+ instance = this;
- initialContextFactories = initServiceTracker(context, InitialContextFactory.class, ServiceTrackerCustomizers.ICF_CACHE);
- objectFactories = initServiceTracker(context, ObjectFactory.class, ServiceTrackerCustomizers.URL_FACTORY_CACHE);
- icfBuilders = initServiceTracker(context, InitialContextFactoryBuilder.class, ServiceTrackerCustomizers.<InitialContextFactoryBuilder>LAZY());
- urlObjectFactoryFinders = initServiceTracker(context, URLObjectFactoryFinder.class, ServiceTrackerCustomizers.<URLObjectFactoryFinder>LAZY());
- environmentAugmentors = initServiceTracker(context, EnvironmentAugmentation.class, null);
- environmentUnaugmentors = initServiceTracker(context, EnvironmentUnaugmentation.class, null);
+ bundleServiceCaches = new BundleTracker<ServiceCache>(context, Bundle.ACTIVE, null) {
+ @Override
+ public ServiceCache addingBundle(Bundle bundle, BundleEvent event) {
+ return new ServiceCache(bundle.getBundleContext());
+ }
+ @Override
+ public void modifiedBundle(Bundle bundle, BundleEvent event, ServiceCache object) {
+ }
+ @Override
+ public void removedBundle(Bundle bundle, BundleEvent event, ServiceCache object) {
+ object.close();
+ }
+ };
+ bundleServiceCaches.open();
+
+ initialContextFactories = new CachingServiceTracker<>(context, InitialContextFactory.class, Activator::getInitialContextFactoryInterfaces);
+ objectFactories = new CachingServiceTracker<>(context, ObjectFactory.class, Activator::getObjectFactorySchemes);
+ icfBuilders = new CachingServiceTracker<>(context, InitialContextFactoryBuilder.class);
+ urlObjectFactoryFinders = new CachingServiceTracker<>(context, URLObjectFactoryFinder.class);
try {
OSGiInitialContextFactoryBuilder builder = new OSGiInitialContextFactoryBuilder();
@@ -140,7 +135,7 @@ public class Activator implements Bundle
} catch (IllegalStateException e) {
// use reflection to force the builder to be used
if (forceBuilder(context)) {
- setField(InitialContextFactoryBuilder.class, builder, true);
+ originalICFBuilder = swapStaticField(InitialContextFactoryBuilder.class, builder);
}
}
icfBuilder = builder;
@@ -160,7 +155,7 @@ public class Activator implements Bundle
} catch (IllegalStateException e) {
// use reflection to force the builder to be used
if (forceBuilder(context)) {
- setField(ObjectFactoryBuilder.class, builder, true);
+ originalOFBuilder = swapStaticField(ObjectFactoryBuilder.class, builder);
}
}
ofBuilder = builder;
@@ -186,10 +181,32 @@ public class Activator implements Bundle
null);
context.registerService(AugmenterInvoker.class.getName(),
- AugmenterInvokerImpl.getInstance(),
+ augmenterInvoker = new AugmenterInvokerImpl(context),
null);
}
+ public void stop(BundleContext context) {
+ bundleServiceCaches.close();
+
+ /*
+ * Try to reset the InitialContextFactoryBuilder and ObjectFactoryBuilder
+ * on the NamingManager.
+ */
+ if (icfBuilder != null) {
+ swapStaticField(InitialContextFactoryBuilder.class, originalICFBuilder);
+ }
+ if (ofBuilder != null) {
+ swapStaticField(ObjectFactoryBuilder.class, originalOFBuilder);
+ }
+
+ icfBuilders.close();
+ urlObjectFactoryFinders.close();
+ objectFactories.close();
+ initialContextFactories.close();
+
+ instance = null;
+ }
+
private boolean forceBuilder(BundleContext context) {
String forceBuilderProp = context.getProperty(FORCE_BUILDER);
if (forceBuilderProp != null) {
@@ -214,30 +231,87 @@ public class Activator implements Bundle
return "";
}
- private <S, T> ServiceTracker<S, T> initServiceTracker(BundleContext context,
- Class<S> type, ServiceTrackerCustomizer<S, T> custom) {
- ServiceTracker<S, T> t = new ServiceTracker<S, T>(context, type, custom);
- t.open();
- return t;
+ /*
+ * There are no public API to reset the InitialContextFactoryBuilder or
+ * ObjectFactoryBuilder on the NamingManager so try to use reflection.
+ */
+ private static <T> T swapStaticField(Class<T> expectedType, Object value) throws IllegalStateException {
+ try {
+ for (Field field : NamingManager.class.getDeclaredFields()) {
+ if (expectedType.equals(field.getType())) {
+ field.setAccessible(true);
+ T original = expectedType.cast(field.get(null));
+ field.set(null, value);
+ return original;
+ }
+ }
+ } catch (Throwable t) {
+ // Ignore
+ LOGGER.debug("Error setting field.", t);
+ throw new IllegalStateException(t);
+ }
+ throw new IllegalStateException("Error setting field: no field found for type " + expectedType);
}
- public void stop(BundleContext context) {
- /*
- * Try to reset the InitialContextFactoryBuilder and ObjectFactoryBuilder
- * on the NamingManager.
- */
- if (icfBuilder != null) {
- setField(InitialContextFactoryBuilder.class, originalICFBuilder, false);
+ private static List<String> getInitialContextFactoryInterfaces(ServiceReference<InitialContextFactory> ref) {
+ String[] interfaces = (String[]) ref.getProperty(Constants.OBJECTCLASS);
+ List<String> resultList = new ArrayList<>();
+ for (String interfaceName : interfaces) {
+ if (!InitialContextFactory.class.getName().equals(interfaceName)) {
+ resultList.add(interfaceName);
+ }
}
- if (ofBuilder != null) {
- setField(ObjectFactoryBuilder.class, originalOFBuilder, false);
+
+ return resultList;
+ }
+
+ private static List<String> getObjectFactorySchemes(ServiceReference<ObjectFactory> reference) {
+ Object scheme = reference.getProperty(JNDIConstants.JNDI_URLSCHEME);
+ List<String> result;
+
+ if (scheme instanceof String) {
+ result = new ArrayList<>();
+ result.add((String) scheme);
+ } else if (scheme instanceof String[]) {
+ result = Arrays.asList((String[]) scheme);
+ } else {
+ result = Collections.emptyList();
}
- icfBuilders.close();
- urlObjectFactoryFinders.close();
- objectFactories.close();
- initialContextFactories.close();
- environmentAugmentors.close();
- environmentUnaugmentors.close();
+ return result;
}
+
+ private static class ServiceCache {
+
+ private final BundleContext context;
+ private final Map<ServiceReference<?>, Object> cache = new ConcurrentHashMap<>();
+ private final Map<Class<?>, CachingServiceTracker<?>> trackers = new ConcurrentHashMap<>();
+
+ ServiceCache(BundleContext context) {
+ this.context = context;
+ }
+
+ @SuppressWarnings("unchecked")
+ <T> T getService(ServiceReference<T> ref) {
+ return (T) cache.computeIfAbsent(ref, this::doGetService);
+ }
+
+ @SuppressWarnings("unchecked")
+ <T> Collection<ServiceReference<T>> getReferences(Class<T> clazz) {
+ return (List) trackers.computeIfAbsent(clazz, c -> new CachingServiceTracker<>(context, c)).getReferences();
+ }
+
+ void close() {
+ cache.forEach(this::doUngetService);
+ }
+
+ Object doGetService(ServiceReference<?> ref) {
+ return Utils.doPrivileged(() -> context.getService(ref));
+ }
+
+ void doUngetService(ServiceReference<?> ref, Object svc) {
+ Utils.doPrivileged(() -> context.ungetService(ref));
+ }
+ }
+
}
Added: aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/CachingServiceTracker.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/CachingServiceTracker.java?rev=1824944&view=auto
==============================================================================
--- aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/CachingServiceTracker.java (added)
+++ aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/CachingServiceTracker.java Wed Feb 21 09:05:04 2018
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.jndi.tracker;
+
+import org.apache.aries.jndi.Utils;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import java.util.*;
+import java.util.function.Function;
+
+public class CachingServiceTracker<S> extends ServiceTracker<S, ServiceReference<S>> {
+
+ /** The cached references */
+ private volatile Map<String, ServiceReference<S>> cache;
+ /** The funtion to obtain the identifiers */
+ private final Function<ServiceReference<S>, Iterable<String>> properties;
+
+ public CachingServiceTracker(BundleContext context, Class<S> clazz) {
+ this(context, clazz, ref -> Collections.emptyList());
+ }
+
+ public CachingServiceTracker(BundleContext context, Class<S> clazz, Function<ServiceReference<S>, Iterable<String>> properties) {
+ super(context, clazz, null);
+ this.properties = properties;
+ open();
+ }
+
+ public ServiceReference<S> find(String identifier) {
+ Map<String, ServiceReference<S>> c = cache;
+ if (c == null) {
+ synchronized (this) {
+ if (cache == null) {
+ cache = new HashMap<>();
+ for (ServiceReference<S> ref : getReferences()) {
+ for (String key : properties.apply(ref)) {
+ cache.putIfAbsent(key, ref);
+ }
+ }
+ }
+ c = cache;
+ }
+ }
+ return c.get(identifier);
+ }
+
+ public List<ServiceReference<S>> getReferences() {
+ ServiceReference<S>[] refs = Utils.doPrivileged(this::getServiceReferences);
+ if (refs != null) {
+ Arrays.sort(refs, Comparator.reverseOrder());
+ return Arrays.asList(refs);
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ public synchronized ServiceReference<S> addingService(ServiceReference<S> reference) {
+ cache = null;
+ return reference;
+ }
+
+ public synchronized void removedService(ServiceReference<S> reference, ServiceReference<S> service) {
+ cache = null;
+ }
+
+ public void modifiedService(ServiceReference<S> reference, ServiceReference<S> service) {
+ cache = null;
+ }
+}
Modified: aries/trunk/jndi/jndi-core/src/test/java/org/apache/aries/jndi/InitialContextTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/jndi/jndi-core/src/test/java/org/apache/aries/jndi/InitialContextTest.java?rev=1824944&r1=1824943&r2=1824944&view=diff
==============================================================================
--- aries/trunk/jndi/jndi-core/src/test/java/org/apache/aries/jndi/InitialContextTest.java (original)
+++ aries/trunk/jndi/jndi-core/src/test/java/org/apache/aries/jndi/InitialContextTest.java Wed Feb 21 09:05:04 2018
@@ -58,7 +58,9 @@ public class InitialContextTest {
*/
@Before
public void setup() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
- bc = Skeleton.newMock(new BundleContextMock(), BundleContext.class);
+ BundleContextMock mock = new BundleContextMock();
+ mock.addBundle(mock.getBundle());
+ bc = Skeleton.newMock(mock, BundleContext.class);
activator = new Activator();
activator.start(bc);
}