incubator-aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From n..@apache.org
Subject svn commit: r1005089 - in /incubator/aries/trunk/jndi: jndi-api/src/main/java/org/apache/aries/jndi/urls/ jndi-core/ jndi-core/src/main/java/org/apache/aries/jndi/ jndi-core/src/main/java/org/apache/aries/jndi/startup/ jndi-core/src/main/java/org/apach...
Date Wed, 06 Oct 2010 15:42:36 GMT
Author: not
Date: Wed Oct  6 15:42:36 2010
New Revision: 1005089

URL: http://svn.apache.org/viewvc?rev=1005089&view=rev
Log:
ARIES-440 Fixes for the following:

1. The core does the following: 
   i) Find an ICF service 
   ii) Get ICF 
   iii) Create a Context 
   iv) release ICF service 
   v) return Context 

   This means that the ICF cannot manage the lifecycle because it doesn't know when the context
is finished with. We should only release the service when the context has been closed. 
2. We do a lot of queries, which is kind of expensive. If we used a service tracker we could
remove all the queries and it would be more efficient and perform some amount better. 
3. Got some things wrong on ARIES-417. e.g. 
    ii) The URLObjectFactoryFinder doesn't get the environment, so it can't do things based
on the JNDI environment, this is bad. 
    
I would have liked to separate these things out more, but I managed to get my changes tangled.
Need to take more care next time.

Added:
    incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java
    incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/
    incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java
Modified:
    incubator/aries/trunk/jndi/jndi-api/src/main/java/org/apache/aries/jndi/urls/URLObjectFactoryFinder.java
    incubator/aries/trunk/jndi/jndi-core/pom.xml
    incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java
    incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.java
    incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java
    incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
    incubator/aries/trunk/jndi/jndi-url/pom.xml

Modified: incubator/aries/trunk/jndi/jndi-api/src/main/java/org/apache/aries/jndi/urls/URLObjectFactoryFinder.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-api/src/main/java/org/apache/aries/jndi/urls/URLObjectFactoryFinder.java?rev=1005089&r1=1005088&r2=1005089&view=diff
==============================================================================
--- incubator/aries/trunk/jndi/jndi-api/src/main/java/org/apache/aries/jndi/urls/URLObjectFactoryFinder.java
(original)
+++ incubator/aries/trunk/jndi/jndi-api/src/main/java/org/apache/aries/jndi/urls/URLObjectFactoryFinder.java
Wed Oct  6 15:42:36 2010
@@ -1,8 +1,11 @@
 package org.apache.aries.jndi.urls;
 
+import java.util.Hashtable;
+
+import javax.naming.NamingException;
 import javax.naming.spi.ObjectFactory;
 
 public interface URLObjectFactoryFinder 
 {
-  public ObjectFactory findFactory(String url);
+  public ObjectFactory findFactory(String url, Hashtable<?, ?> env) throws NamingException;
 }

Modified: incubator/aries/trunk/jndi/jndi-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-core/pom.xml?rev=1005089&r1=1005088&r2=1005089&view=diff
==============================================================================
--- incubator/aries/trunk/jndi/jndi-core/pom.xml (original)
+++ incubator/aries/trunk/jndi/jndi-core/pom.xml Wed Oct  6 15:42:36 2010
@@ -33,10 +33,10 @@
 
     <properties>
         <aries.osgi.export.pkg>
-            org.apache.aries.jndi
+            org.apache.aries.jndi.urls
         </aries.osgi.export.pkg>
         <aries.osgi.private.pkg>
-            org.apache.aries.jndi.startup
+            org.apache.aries.jndi*
         </aries.osgi.private.pkg>
         <aries.osgi.activator>
             org.apache.aries.jndi.startup.Activator
@@ -55,6 +55,11 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.aries.testsupport</groupId>
             <artifactId>org.apache.aries.testsupport.unit</artifactId>
             <scope>test</scope>

Modified: incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java?rev=1005089&r1=1005088&r2=1005089&view=diff
==============================================================================
--- incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java
(original)
+++ incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextHelper.java
Wed Oct  6 15:42:36 2010
@@ -19,8 +19,6 @@
 package org.apache.aries.jndi;
 
 import java.security.PrivilegedExceptionAction;
-import java.util.Arrays;
-import java.util.Comparator;
 import java.util.Hashtable;
 
 import javax.naming.Context;
@@ -30,11 +28,11 @@ import javax.naming.spi.InitialContextFa
 import javax.naming.spi.InitialContextFactoryBuilder;
 import javax.naming.spi.ObjectFactory;
 
+import org.apache.aries.jndi.startup.Activator;
+import org.apache.aries.jndi.tracker.ServiceTrackerCustomizers;
 import org.apache.aries.jndi.urls.URLObjectFactoryFinder;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.jndi.JNDIConstants;
 
 /**
  * Provides helper methods for the DelegateContext. This provides the methods so
@@ -47,12 +45,12 @@ public final class ContextHelper {
         throw new RuntimeException();
     }
 
-    public static Context createURLContext(final BundleContext context,
+    public static ContextProvider createURLContext(final BundleContext context,
                                            final String urlScheme, 
                                            final Hashtable<?, ?> env)
         throws NamingException {
-        return Utils.doPrivilegedNaming(new PrivilegedExceptionAction<Context>() {
-            public Context run() throws Exception {
+        return Utils.doPrivilegedNaming(new PrivilegedExceptionAction<ContextProvider>()
{
+            public ContextProvider run() throws Exception {
                 return doCreateURLContext(context, urlScheme, env);
             }
         });
@@ -67,7 +65,7 @@ public final class ContextHelper {
      * @return a Context
      * @throws NamingException
      */
-    private static Context doCreateURLContext(BundleContext context, String urlScheme, Hashtable<?,
?> env)
+    private static ContextProvider doCreateURLContext(BundleContext context, String urlScheme,
Hashtable<?, ?> env)
         throws NamingException {
       
         ServicePair<ObjectFactory> urlObjectFactory = getURLObjectFactory(context,
urlScheme, env);
@@ -77,13 +75,14 @@ public final class ContextHelper {
             
             if (factory != null) {
                 try {
-                    return (Context) factory.getObjectInstance(null, null, null, env);
+                    Context ctx = (Context) factory.getObjectInstance(null, null, null, env);
+                    
+                    return new ContextProvider(context, urlObjectFactory.getReference(),
ctx);
                 } catch (Exception e) {
+                    urlObjectFactory.unget();
                     NamingException e2 = new NamingException();
                     e2.initCause(e);
                     throw e2;
-                } finally {
-                    urlObjectFactory.unget();
                 }
             }
         }
@@ -96,49 +95,29 @@ public final class ContextHelper {
       throws NamingException
     {
       ServicePair<ObjectFactory> result = null;
-      try {
-          ServiceReference[] services = ctx.getServiceReferences(ObjectFactory.class.getName(),

-                                                                     "(" + JNDIConstants.JNDI_URLSCHEME
+ "=" + urlScheme.trim() + ")");
-
-          if (services != null) {
-              Arrays.sort(services);
-              result = new ServicePair<ObjectFactory>(ctx, services[services.length
- 1]);
-          }
-      } catch (InvalidSyntaxException e1) {
-          NamingException e = new NamingException("Argh this should never happen :)");
-          e.initCause(e1);
-          throw e;
-      }
       
-      if (result == null) {
-        ServiceReference[] refs;
-        try {
-          refs = ctx.getServiceReferences(URLObjectFactoryFinder.class.getName(), null);
-          if (refs != null) {
-            // need a reverse sort.
-            Arrays.sort(refs, new Comparator<ServiceReference>() {
-              public int compare(ServiceReference o1, ServiceReference o2) {
-                return o2.compareTo(o1);
-              }
-            });
-            
-            for (ServiceReference finderRef : refs) {
-              URLObjectFactoryFinder finder = (URLObjectFactoryFinder) ctx.getService(finderRef);
-              if (finder != null) {
-                ObjectFactory f = finder.findFactory(urlScheme);
-                
-                if (f != null) {
-                  result = new ServicePair<ObjectFactory>(ctx, finderRef, f);
-                  break;
-                } else {
-                  ctx.ungetService(finderRef);
-                }
+      ServiceReference ref = ServiceTrackerCustomizers.URL_FACTORY_CACHE.find(urlScheme);
+      
+      if (ref == null) {
+        ServiceReference[] refs = Activator.getURLObectFactoryFinderServices();
+        
+        if (refs != null) {
+          for (ServiceReference finderRef : refs) {
+            URLObjectFactoryFinder finder = (URLObjectFactoryFinder) ctx.getService(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);
               }
             }
           }
-        } catch (InvalidSyntaxException e) {
-          // Since the filter is null this cannot happen (famous last words).
         }
+      } else {
+        result = new ServicePair<ObjectFactory>(ctx, ref);
       }
       
       return result;
@@ -147,19 +126,16 @@ public final class ContextHelper {
     public static Context getInitialContext(BundleContext context, Hashtable<?, ?>
environment)
         throws NamingException {
         ContextProvider provider = getContextProvider(context, environment);
-        String contextFactoryClass = (String) environment.get(Context.INITIAL_CONTEXT_FACTORY);
-        if (contextFactoryClass == null) {
-            if (provider == null) {
-                return new DelegateContext(context, environment);
-            } else {
-                return new DelegateContext(context, provider);
-            }
+        
+        if (provider != null) {
+          return new DelegateContext(context, provider);
         } else {
-            if (provider == null) {
-                throw new NoInitialContextException("We could not find an InitialContextFactory
to use");
-            } else {
-                return new DelegateContext(context, provider);
-            }
+          String contextFactoryClass = (String) environment.get(Context.INITIAL_CONTEXT_FACTORY);
+          if (contextFactoryClass == null) {
+            return new DelegateContext(context, environment);
+          } else {
+            throw new NoInitialContextException("We could not find an InitialContextFactory
to use");
+          }
         }
     }
 
@@ -184,59 +160,39 @@ public final class ContextHelper {
 
             // 2. lookup all ContextFactory services
             if (provider == null) {
-                String filter = "(&(objectClass=javax.naming.spi.InitialContextFactory))";
-                ServiceReference[] references = null;
-                try {
-                    references = context.getAllServiceReferences(InitialContextFactory.class.getName(),
filter);
-                } catch (InvalidSyntaxException e) {
-                    NamingException ex = new NamingException("Bad filter: " + filter);
-                    ex.initCause(e);
-                    throw ex;
-                }
+                ServiceReference[] references = Activator.getInitialContextFactoryServices();
                 if (references != null) {
                     Context initialContext = null;
-                    Arrays.sort(references, Utils.SERVICE_REFERENCE_COMPARATOR);
                     for (ServiceReference reference : references) {
                         InitialContextFactory factory = (InitialContextFactory) context.getService(reference);
                         try {
                             initialContext = factory.getInitialContext(environment);
+                            if (initialContext != null) {
+                              provider = new ContextProvider(context, reference, initialContext);
+                              break;
+                          }
                         } finally {
-                            context.ungetService(reference);
-                        }
-                        if (initialContext != null) {
-                            provider = new ContextProvider(reference, initialContext);
-                            break;
+                            if (provider == null) context.ungetService(reference);
                         }
                     }
                 }
             }
         } else {
-            // 1. lookup ContextFactory using the factory class
-            String filter = "(&(objectClass=javax.naming.spi.InitialContextFactory)(objectClass="+
contextFactoryClass + "))";
-            ServiceReference[] references = null;
-            try {
-                references = context.getServiceReferences(InitialContextFactory.class.getName(),
filter);
-            } catch (InvalidSyntaxException e) {
-                NamingException ex = new NamingException("Bad filter: " + filter);
-                ex.initCause(e);
-                throw ex;
-            }
-
-            if (references != null && references.length > 0) {
-                Context initialContext = null;
-                Arrays.sort(references, Utils.SERVICE_REFERENCE_COMPARATOR);
-                ServiceReference reference = references[0];
-                InitialContextFactory factory = (InitialContextFactory) context.getService(reference);
+            ServiceReference ref = ServiceTrackerCustomizers.ICF_CACHE.find(contextFactoryClass);
+            
+            if (ref != null) {
+              Context initialContext = null;
+              InitialContextFactory factory = (InitialContextFactory) context.getService(ref);
+              if (factory != null) {
                 try {
                     initialContext = factory.getInitialContext(environment);
+                    provider = new ContextProvider(context, ref, initialContext);
                 } finally {
-                    context.ungetService(reference);
-                }
-                if (initialContext != null) {
-                    provider = new ContextProvider(reference, initialContext);          
         
+                    if (provider == null) context.ungetService(ref);
                 }
+              }
             }
-
+            
             // 2. get ContextFactory using builder
             if (provider == null) {
                 provider = getInitialContextUsingBuilder(context, environment);
@@ -250,46 +206,27 @@ public final class ContextHelper {
                                                                  Hashtable<?, ?> environment)
             throws NamingException {
         ContextProvider provider = null;
-        try {
-            ServiceReference[] refs = context.getAllServiceReferences(InitialContextFactoryBuilder.class.getName(),
null);
-            if (refs != null) {
-                InitialContextFactory factory = null;
-                Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
-                for (ServiceReference ref : refs) {                    
-                    InitialContextFactoryBuilder builder = (InitialContextFactoryBuilder)
context.getService(ref);
-                    try {
-                        factory = builder.createInitialContextFactory(environment);
-                    } catch (NamingException e) {
-                        // TODO: log
-                        // ignore
-                    } finally {
-                        context.ungetService(ref);
-                    }
+        ServiceReference[] refs = Activator.getInitialContextFactoryBuilderServices();
+        if (refs != null) {
+            InitialContextFactory factory = null;
+            for (ServiceReference ref : refs) {                    
+                InitialContextFactoryBuilder builder = (InitialContextFactoryBuilder) context.getService(ref);
+                try {
+                    factory = builder.createInitialContextFactory(environment);
                     if (factory != null) {
-                        provider = new ContextProvider(ref, factory.getInitialContext(environment));
-                        break;
+                      provider = new ContextProvider(context, ref, factory.getInitialContext(environment));
+                      break;
+                    } else {
+                      context.ungetService(ref); // we didn't get something back, so this
was no good.
                     }
+                } catch (NamingException e) {
+                    // TODO: log
+                    // ignore
+                    context.ungetService(ref);
                 }
             }
-        } catch (InvalidSyntaxException e) {
-            // ignore - should never happen
         }
         return provider;
     }
-    
-    public static class ContextProvider {
-        
-        ServiceReference reference;
-        Context context;
-        
-        public ContextProvider(ServiceReference reference, Context context) {
-            this.reference = reference;
-            this.context = context;
-        }        
-        
-        public boolean isValid() {
-            return (reference.getBundle() != null);
-        }
-    }
 
 }

Added: incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java?rev=1005089&view=auto
==============================================================================
--- incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java
(added)
+++ incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ContextProvider.java
Wed Oct  6 15:42:36 2010
@@ -0,0 +1,46 @@
+/**
+ * 
+ */
+package org.apache.aries.jndi;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class ContextProvider {
+    private ServicePair<?> pair;
+    private ServiceReference reference;
+    private Context context;
+    private BundleContext bc;
+    
+    public ContextProvider(BundleContext ctx, ServiceReference reference, Context context)
{
+        bc = ctx;
+        this.reference = reference;
+        this.context = context;
+    }
+    
+    public boolean isValid() {
+        return (reference.getBundle() != null);
+    }
+
+    public void close() throws NamingException {
+       if (bc != null) bc.ungetService(reference);
+       context.close();
+    }
+
+    public Context getContext() {
+      return context;
+    }
+    
+    @Override
+    public void finalize()
+    {
+      try {
+        close();
+      } catch (NamingException e) {
+        // we are just being nice here, so we ignore this if it happens.
+      }
+    }
+}
\ No newline at end of file

Modified: incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.java?rev=1005089&r1=1005088&r2=1005089&view=diff
==============================================================================
--- incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.java
(original)
+++ incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/DelegateContext.java
Wed Oct  6 15:42:36 2010
@@ -18,7 +18,9 @@
  */
 package org.apache.aries.jndi;
 
+import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.Map;
 
 import javax.naming.Binding;
 import javax.naming.Context;
@@ -34,7 +36,6 @@ import javax.naming.directory.Modificati
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 
-import org.apache.aries.jndi.ContextHelper.ContextProvider;
 import org.osgi.framework.BundleContext;
 
 public class DelegateContext implements DirContext {
@@ -43,6 +44,7 @@ public class DelegateContext implements 
 
     private BundleContext bundleContext;
     private ContextProvider contextProvider;
+    private Map<String, ContextProvider> urlContexts = new HashMap<String, ContextProvider>();
     private boolean rebind;
 
     public DelegateContext(BundleContext bundleContext, Hashtable<?, ?> theEnv) {
@@ -54,7 +56,7 @@ public class DelegateContext implements 
     public DelegateContext(BundleContext bundleContext, ContextProvider contextProvider)
throws NamingException {
         this.bundleContext = bundleContext;
         this.contextProvider = contextProvider;
-        env.putAll(contextProvider.context.getEnvironment());
+        env.putAll(contextProvider.getContext().getEnvironment());
         rebind = true;
     }
 
@@ -78,8 +80,14 @@ public class DelegateContext implements 
 
     public void close() throws NamingException {
         if (contextProvider != null) {
-            contextProvider.context.close();
+            contextProvider.close();
         }
+        
+        for (ContextProvider provider : urlContexts.values()) {
+          provider.close();
+        }
+        
+        urlContexts.clear();
         env.clear();
     }
 
@@ -223,7 +231,7 @@ public class DelegateContext implements 
             if (contextProvider == null) {
                 throw new NoInitialContextException();
             } else {
-                return contextProvider.context;
+                return contextProvider.getContext();
             }
         } else {
             throw new NoInitialContextException();
@@ -238,7 +246,14 @@ public class DelegateContext implements 
         if (index != -1) {
             String scheme = name.substring(0, index);
 
-            ctx = ContextHelper.createURLContext(bundleContext, scheme, env);
+            ContextProvider provider = urlContexts.get(scheme);
+            
+            if (provider == null || !!!provider.isValid()) {
+              provider = ContextHelper.createURLContext(bundleContext, scheme, env);
+              if (provider != null) urlContexts.put(scheme, provider);
+            }
+            
+            if (provider != null) ctx = provider.getContext();
         }
 
         if (ctx == null) {

Modified: incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java?rev=1005089&r1=1005088&r2=1005089&view=diff
==============================================================================
--- incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java
(original)
+++ incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/ServicePair.java
Wed Oct  6 15:42:36 2010
@@ -33,6 +33,10 @@ public class ServicePair<T>
     return serviceObject;
   }
   
+  public boolean isValid() {
+    return (ref.getBundle() != null);
+  }
+
   public void unget()
   {
     if (serviceObject != null) {
@@ -40,4 +44,9 @@ public class ServicePair<T>
       serviceObject = null;
     }
   }
+
+  public ServiceReference getReference() 
+  {
+    return ref;
+  }
 }

Modified: incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java?rev=1005089&r1=1005088&r2=1005089&view=diff
==============================================================================
--- incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
(original)
+++ incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
Wed Oct  6 15:42:36 2010
@@ -19,10 +19,13 @@
 package org.apache.aries.jndi.startup;
 
 import java.lang.reflect.Field;
+import java.util.Arrays;
 
 import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
 import javax.naming.spi.InitialContextFactoryBuilder;
 import javax.naming.spi.NamingManager;
+import javax.naming.spi.ObjectFactory;
 import javax.naming.spi.ObjectFactoryBuilder;
 
 import org.apache.aries.jndi.ContextManagerServiceFactory;
@@ -30,10 +33,16 @@ import org.apache.aries.jndi.JREInitialC
 import org.apache.aries.jndi.OSGiInitialContextFactoryBuilder;
 import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
 import org.apache.aries.jndi.ProviderAdminServiceFactory;
+import org.apache.aries.jndi.Utils;
+import org.apache.aries.jndi.tracker.ServiceTrackerCustomizers;
+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.service.jndi.JNDIContextManager;
 import org.osgi.service.jndi.JNDIProviderAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
 /**
  * The activator for this bundle makes sure the static classes in it are
@@ -43,9 +52,18 @@ public class Activator implements Bundle
     
     private OSGiInitialContextFactoryBuilder icfBuilder;
     private OSGiObjectFactoryBuilder ofBuilder;
+    private static ServiceTracker icfBuilders;
+    private static ServiceTracker urlObjectFactoryFinders;
+    private static ServiceTracker initialContextFactories;
+    private static ServiceTracker objectFactories;
     
     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.LAZY);
+        urlObjectFactoryFinders = initServiceTracker(context, URLObjectFactoryFinder.class,
ServiceTrackerCustomizers.LAZY);
+        
         try {
             OSGiInitialContextFactoryBuilder builder = new OSGiInitialContextFactoryBuilder();
             NamingManager.setInitialContextFactoryBuilder(builder);
@@ -79,6 +97,14 @@ public class Activator implements Bundle
                                 null);
     }
 
+    private ServiceTracker initServiceTracker(BundleContext context,
+        Class<?> type, ServiceTrackerCustomizer custom) 
+    {
+      ServiceTracker t = new ServiceTracker(context, type.getName(), custom);
+      t.open();
+      return t;
+    }
+
     public void stop(BundleContext context) {
         /*
          * Try to reset the InitialContextFactoryBuilder and ObjectFactoryBuilder
@@ -90,6 +116,12 @@ public class Activator implements Bundle
         if (ofBuilder != null) {
             unsetField(ObjectFactoryBuilder.class);
         }
+        
+        icfBuilders.close();
+        urlObjectFactoryFinders.close();
+        objectFactories.close();
+        initialContextFactories.close();
+        
     }
     
     /*
@@ -109,4 +141,31 @@ public class Activator implements Bundle
           t.printStackTrace();
         }
     }
+
+    public static ServiceReference[] getInitialContextFactoryBuilderServices()
+    {
+      ServiceReference[] refs = icfBuilders.getServiceReferences();
+      
+      if (refs != null) Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
+      
+      return refs;
+    }
+    
+    public static ServiceReference[] getInitialContextFactoryServices() 
+    {
+      ServiceReference[] refs = initialContextFactories.getServiceReferences();
+      
+      if (refs != null) Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
+      
+      return refs;
+    }
+
+    public static ServiceReference[] getURLObectFactoryFinderServices() 
+    {
+      ServiceReference[] refs = urlObjectFactoryFinders.getServiceReferences();
+      
+      if (refs != null) Arrays.sort(refs, Utils.SERVICE_REFERENCE_COMPARATOR);
+      
+      return refs;
+    }
 }

Added: incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java?rev=1005089&view=auto
==============================================================================
--- incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java
(added)
+++ incubator/aries/trunk/jndi/jndi-core/src/main/java/org/apache/aries/jndi/tracker/ServiceTrackerCustomizers.java
Wed Oct  6 15:42:36 2010
@@ -0,0 +1,119 @@
+package org.apache.aries.jndi.tracker;
+
+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 javax.naming.spi.InitialContextFactory;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.jndi.JNDIConstants;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+
+public class ServiceTrackerCustomizers 
+{
+  public static interface CachingServiceTracker extends ServiceTrackerCustomizer {
+    public ServiceReference find(String identifier);
+  }
+  
+  private static abstract class BaseCachingServiceTracker implements CachingServiceTracker
{
+    /** The cached references */
+    protected ConcurrentMap<String, ServiceReference> cache = new ConcurrentHashMap<String,
ServiceReference>();
+    /** A list of service references that are being tracked */
+    protected List<ServiceReference> trackedReferences = new ArrayList<ServiceReference>();
+
+    public ServiceReference find(String identifier) 
+    {
+      return cache.get(identifier);
+    }
+
+    public synchronized Object addingService(ServiceReference reference) 
+    {
+      List<String> cacheKeys = getProperty(reference);
+      
+      for (String key : cacheKeys) { 
+        cache.putIfAbsent(key, reference);
+      }
+      
+      trackedReferences.add(reference);
+      
+      return reference;
+    }
+
+    protected abstract List<String> getProperty(ServiceReference reference);
+
+    public synchronized void removedService(ServiceReference reference, Object service) 
+    {
+      trackedReferences.remove(reference);
+      
+      List<String> keysToProcess = new ArrayList<String>(getProperty(reference));
+      
+      refLoop: for (ServiceReference ref : trackedReferences) {
+        List<String> refInt = getProperty(ref);
+        for (String interfaceName : refInt) {
+          int index = keysToProcess.indexOf(interfaceName);
+          if (index >= 0) {
+            keysToProcess.remove(index);
+            if (cache.replace(interfaceName, reference, ref)) {
+              if (keysToProcess.isEmpty()) break refLoop;
+            }
+          }
+        }
+      }
+      
+      for (String interfaceName : keysToProcess) {
+        cache.remove(interfaceName, reference);
+      }
+    }
+
+    public void modifiedService(ServiceReference reference, Object service) { }
+  }
+  
+  public static final ServiceTrackerCustomizer LAZY = new ServiceTrackerCustomizer() {
+    public Object addingService(ServiceReference reference) 
+    {
+      return reference;
+    }
+    public void modifiedService(ServiceReference reference, Object service)  { }
+    public void removedService(ServiceReference reference, Object service)  { }
+  };
+
+  public static final CachingServiceTracker ICF_CACHE = new BaseCachingServiceTracker() {
+    public List<String> getProperty(ServiceReference ref)
+    {
+      String[] interfaces = (String[]) ref.getProperty(Constants.OBJECTCLASS);
+      List<String> resultList = new ArrayList<String>();
+      for (String interfaceName : interfaces) {
+        if (!!!InitialContextFactory.class.getName().equals(interfaceName)) {
+          resultList.add(interfaceName);
+        }
+      }
+      
+      return resultList;
+    }
+  };
+  
+  // 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) {
+      Object scheme = reference.getProperty(JNDIConstants.JNDI_URLSCHEME);
+      List<String> result;
+      
+      if (scheme instanceof String) {
+        result = new ArrayList<String>();
+        result.add((String) scheme);
+      } else if (scheme instanceof String[]) {
+        result = Arrays.asList((String[])scheme);
+      } else {
+        result = Collections.emptyList();
+      }
+      
+      return result;
+    }
+  };
+}

Modified: incubator/aries/trunk/jndi/jndi-url/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi/jndi-url/pom.xml?rev=1005089&r1=1005088&r2=1005089&view=diff
==============================================================================
--- incubator/aries/trunk/jndi/jndi-url/pom.xml (original)
+++ incubator/aries/trunk/jndi/jndi-url/pom.xml Wed Oct  6 15:42:36 2010
@@ -77,6 +77,11 @@
             <artifactId>org.apache.aries.testsupport.unit</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>



Mime
View raw message