You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ga...@apache.org on 2009/10/06 22:41:32 UTC

svn commit: r822489 [2/3] - in /incubator/aries/trunk/jndi-contrib: jndi-core/src/main/java/org/apache/aries/jndi/ jndi-core/src/main/java/org/apache/aries/jndi/startup/ jndi-core/src/test/java/org/apache/aries/jndi/ jndi-url/src/main/java/org/apache/a...

Modified: incubator/aries/trunk/jndi-contrib/jndi-core/src/test/java/org/apache/aries/jndi/ObjectFactoryTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi-contrib/jndi-core/src/test/java/org/apache/aries/jndi/ObjectFactoryTest.java?rev=822489&r1=822488&r2=822489&view=diff
==============================================================================
--- incubator/aries/trunk/jndi-contrib/jndi-core/src/test/java/org/apache/aries/jndi/ObjectFactoryTest.java (original)
+++ incubator/aries/trunk/jndi-contrib/jndi-core/src/test/java/org/apache/aries/jndi/ObjectFactoryTest.java Tue Oct  6 20:41:31 2009
@@ -1,171 +1,171 @@
-///*
-// * 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 WARRANTIESOR 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;
-//
-//import static org.junit.Assert.assertEquals;
-//import static org.junit.Assert.assertSame;
-//
-//import java.lang.reflect.Field;
-//import java.util.Hashtable;
-//import java.util.Properties;
-//
-//import javax.naming.Context;
-//import javax.naming.Name;
-//import javax.naming.Reference;
-//import javax.naming.StringRefAddr;
-//import javax.naming.spi.NamingManager;
-//import javax.naming.spi.ObjectFactory;
-//
-//import mocks.BundleContextMock;
-//
-//import org.junit.After;
-//import org.junit.Before;
-//import org.junit.Test;
-//import org.osgi.framework.BundleContext;
-//
-//import com.ibm.aries.unittest.mocks.MethodCall;
-//import com.ibm.aries.unittest.mocks.Skeleton;
-//import org.apache.aries.jndi.ContextHelper;
-//import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
-//import org.apache.aries.jndi.startup.Activator;
-//
-//public class ObjectFactoryTest
-//{
-//  private BundleContext bc;
-//
-//  /**
-//   * This method does the setup .
-//   * @throws NoSuchFieldException 
-//   * @throws SecurityException 
-//   * @throws IllegalAccessException 
-//   * @throws IllegalArgumentException 
-//   */
-//  @Before
-//  public void setup() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
-//  {
-//    bc =  Skeleton.newMock(new BundleContextMock(), BundleContext.class);
-//    new Activator().start(bc);
-//    
-//    Field f = ContextHelper.class.getDeclaredField("context");
-//    f.setAccessible(true);
-//    f.set(null, bc);
-//    f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
-//    f.setAccessible(true);
-//    f.set(null, bc);
-//
-//  }
-//
-//  /**
-//   * Make sure we clear the caches out before the next test.
-//   */
-//  @After
-//  public void teardown()
-//  {
-//    new Activator().stop(bc);
-//    BundleContextMock.clear();
-//  }
-//
-//  @Test
-//  public void testURLReferenceWithNoMatchingHandler() throws Exception
-//  {
-//    Reference ref = new Reference(null);
-//    ref.add(new StringRefAddr("URL", "wibble"));
-//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
-//
-//    assertSame("The naming manager should have returned the reference object", ref, obj);
-//  }
-//
-//  @Test
-//  public void testURLReferenceWithMatchingHandler() throws Exception
-//  {
-//    String testObject = "Test object";
-//    ObjectFactory factory = Skeleton.newMock(ObjectFactory.class);
-//    Skeleton.getSkeleton(factory).setReturnValue(new MethodCall(ObjectFactory.class, "getObjectInstance", Object.class, Name.class, Context.class, Hashtable.class), testObject);
-//
-//    Properties props = new Properties();
-//    props.setProperty("osgi.jndi.urlScheme", "wibble");
-//
-//    bc.registerService(ObjectFactory.class.getName(), factory, props);
-//
-//    Reference ref = new Reference(null);
-//    ref.add(new StringRefAddr("URL", "wibble"));
-//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
-//    
-//    assertEquals("The naming manager should have returned the test object", testObject, obj);
-//  }
-//
-//  @Test
-//  public void testReferenceWithNoClassName() throws Exception
-//  {
-//    String testObject = "Test object";
-//    ObjectFactory factory = Skeleton.newMock(ObjectFactory.class);
-//    Skeleton.getSkeleton(factory).setReturnValue(new MethodCall(ObjectFactory.class, "getObjectInstance", Object.class, Name.class, Context.class, Hashtable.class), testObject);
-//
-//    bc.registerService(ObjectFactory.class.getName(), factory, null);
-//
-//    Reference ref = new Reference(null);
-//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
-//    
-//    assertEquals("The naming manager should have returned the test object", testObject, obj);
-//  }
-//
-//  @Test
-//  public void testSpecifiedFactoryWithMatchingFactory() throws Exception
-//  {
-//    String testObject = "Test object";
-//    ObjectFactory factory = Skeleton.newMock(ObjectFactory.class);
-//    Skeleton.getSkeleton(factory).setReturnValue(new MethodCall(ObjectFactory.class, "getObjectInstance", Object.class, Name.class, Context.class, Hashtable.class), testObject);
-//
-//    Reference ref = new Reference("dummy.class.name", factory.getClass().getName(), "");
-//
-//    bc.registerService(new String[] {ObjectFactory.class.getName(), factory.getClass().getName()}, 
-//                       factory, null);
-//
-//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
-//    
-//    assertEquals("The naming manager should have returned the test object", testObject, obj);
-//  }
-//
-//  @Test
-//  public void testSpecifiedFactoryWithRegisteredButNotMatchingFactory() throws Exception
-//  {
-//    String testObject = "Test object";
-//    ObjectFactory factory = Skeleton.newMock(ObjectFactory.class);
-//    Skeleton.getSkeleton(factory).setReturnValue(new MethodCall(ObjectFactory.class, "getObjectInstance", Object.class, Name.class, Context.class, Hashtable.class), testObject);
-//
-//    Reference ref = new Reference("dummy.class.name", "dummy.factory.class.name", "");
-//
-//    bc.registerService(new String[] {ObjectFactory.class.getName(), factory.getClass().getName()}, 
-//                       factory, null);
-//
-//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
-//
-//    assertSame("The naming manager should have returned the reference object", ref, obj);
-//  }
-//
-//  @Test
-//  public void testSpecifiedFactoryWithNoMatchingFactory() throws Exception
-//  {
-//    Reference ref = new Reference("dummy.class.name");
-//
-//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
-//
-//    assertSame("The naming manager should have returned the reference object", ref, obj);
-//  }
+///*
+// * 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 WARRANTIESOR 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;
+//
+//import static org.junit.Assert.assertEquals;
+//import static org.junit.Assert.assertSame;
+//
+//import java.lang.reflect.Field;
+//import java.util.Hashtable;
+//import java.util.Properties;
+//
+//import javax.naming.Context;
+//import javax.naming.Name;
+//import javax.naming.Reference;
+//import javax.naming.StringRefAddr;
+//import javax.naming.spi.NamingManager;
+//import javax.naming.spi.ObjectFactory;
+//
+//import mocks.BundleContextMock;
+//
+//import org.junit.After;
+//import org.junit.Before;
+//import org.junit.Test;
+//import org.osgi.framework.BundleContext;
+//
+//import com.ibm.aries.unittest.mocks.MethodCall;
+//import com.ibm.aries.unittest.mocks.Skeleton;
+//import org.apache.aries.jndi.ContextHelper;
+//import org.apache.aries.jndi.OSGiObjectFactoryBuilder;
+//import org.apache.aries.jndi.startup.Activator;
+//
+//public class ObjectFactoryTest
+//{
+//  private BundleContext bc;
+//
+//  /**
+//   * This method does the setup .
+//   * @throws NoSuchFieldException 
+//   * @throws SecurityException 
+//   * @throws IllegalAccessException 
+//   * @throws IllegalArgumentException 
+//   */
+//  @Before
+//  public void setup() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
+//  {
+//    bc =  Skeleton.newMock(new BundleContextMock(), BundleContext.class);
+//    new Activator().start(bc);
+//    
+//    Field f = ContextHelper.class.getDeclaredField("context");
+//    f.setAccessible(true);
+//    f.set(null, bc);
+//    f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
+//    f.setAccessible(true);
+//    f.set(null, bc);
+//
+//  }
+//
+//  /**
+//   * Make sure we clear the caches out before the next test.
+//   */
+//  @After
+//  public void teardown()
+//  {
+//    new Activator().stop(bc);
+//    BundleContextMock.clear();
+//  }
+//
+//  @Test
+//  public void testURLReferenceWithNoMatchingHandler() throws Exception
+//  {
+//    Reference ref = new Reference(null);
+//    ref.add(new StringRefAddr("URL", "wibble"));
+//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
+//
+//    assertSame("The naming manager should have returned the reference object", ref, obj);
+//  }
+//
+//  @Test
+//  public void testURLReferenceWithMatchingHandler() throws Exception
+//  {
+//    String testObject = "Test object";
+//    ObjectFactory factory = Skeleton.newMock(ObjectFactory.class);
+//    Skeleton.getSkeleton(factory).setReturnValue(new MethodCall(ObjectFactory.class, "getObjectInstance", Object.class, Name.class, Context.class, Hashtable.class), testObject);
+//
+//    Properties props = new Properties();
+//    props.setProperty("osgi.jndi.urlScheme", "wibble");
+//
+//    bc.registerService(ObjectFactory.class.getName(), factory, props);
+//
+//    Reference ref = new Reference(null);
+//    ref.add(new StringRefAddr("URL", "wibble"));
+//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
+//    
+//    assertEquals("The naming manager should have returned the test object", testObject, obj);
+//  }
+//
+//  @Test
+//  public void testReferenceWithNoClassName() throws Exception
+//  {
+//    String testObject = "Test object";
+//    ObjectFactory factory = Skeleton.newMock(ObjectFactory.class);
+//    Skeleton.getSkeleton(factory).setReturnValue(new MethodCall(ObjectFactory.class, "getObjectInstance", Object.class, Name.class, Context.class, Hashtable.class), testObject);
+//
+//    bc.registerService(ObjectFactory.class.getName(), factory, null);
+//
+//    Reference ref = new Reference(null);
+//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
+//    
+//    assertEquals("The naming manager should have returned the test object", testObject, obj);
+//  }
+//
+//  @Test
+//  public void testSpecifiedFactoryWithMatchingFactory() throws Exception
+//  {
+//    String testObject = "Test object";
+//    ObjectFactory factory = Skeleton.newMock(ObjectFactory.class);
+//    Skeleton.getSkeleton(factory).setReturnValue(new MethodCall(ObjectFactory.class, "getObjectInstance", Object.class, Name.class, Context.class, Hashtable.class), testObject);
+//
+//    Reference ref = new Reference("dummy.class.name", factory.getClass().getName(), "");
+//
+//    bc.registerService(new String[] {ObjectFactory.class.getName(), factory.getClass().getName()}, 
+//                       factory, null);
+//
+//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
+//    
+//    assertEquals("The naming manager should have returned the test object", testObject, obj);
+//  }
+//
+//  @Test
+//  public void testSpecifiedFactoryWithRegisteredButNotMatchingFactory() throws Exception
+//  {
+//    String testObject = "Test object";
+//    ObjectFactory factory = Skeleton.newMock(ObjectFactory.class);
+//    Skeleton.getSkeleton(factory).setReturnValue(new MethodCall(ObjectFactory.class, "getObjectInstance", Object.class, Name.class, Context.class, Hashtable.class), testObject);
+//
+//    Reference ref = new Reference("dummy.class.name", "dummy.factory.class.name", "");
+//
+//    bc.registerService(new String[] {ObjectFactory.class.getName(), factory.getClass().getName()}, 
+//                       factory, null);
+//
+//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
+//
+//    assertSame("The naming manager should have returned the reference object", ref, obj);
+//  }
+//
+//  @Test
+//  public void testSpecifiedFactoryWithNoMatchingFactory() throws Exception
+//  {
+//    Reference ref = new Reference("dummy.class.name");
+//
+//    Object obj = NamingManager.getObjectInstance(ref, null, null, null);
+//
+//    assertSame("The naming manager should have returned the reference object", ref, obj);
+//  }
 //}
\ No newline at end of file

Propchange: incubator/aries/trunk/jndi-contrib/jndi-core/src/test/java/org/apache/aries/jndi/ObjectFactoryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java?rev=822489&r1=822488&r2=822489&view=diff
==============================================================================
--- incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java (original)
+++ incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java Tue Oct  6 20:41:31 2009
@@ -1,251 +1,251 @@
-/*
- * 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 WARRANTIESOR 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.services;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleReference;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-/**
- * This helper provides access to services registered in the OSGi service registry.
- * If a matching service cannot be located null may be returned. A caller should not
- * expect to get the same object if multiple requests are made to this API. A caller
- * should not expect to get a different object if multiple requests are made to this API.
- * A caller should avoid caching the returned service. OSGi is a dynamic environment and
- * the service may become unavailable while a reference to it is held. To minimize this
- * risk the caller should hold onto the service for the minimum length of time.
- * 
- * <p>This API should not be used from within an OSGi bundle. When in an OSGi environment
- *   the BundleContext for the bundle should be used to obtain the service.
- * </p>
- */
-public final class ServiceHelper
-{
-  /** The bundle context used for service registry queries */
-  private static BundleContext context;
-  /** A cache of what service was returned last time the query was performed */
-  private static ConcurrentMap<ServiceKey, Set<ServiceReference>> cache = new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
-
-  public static void setBundleContext(BundleContext ctx)
-  {
-    context = ctx;
-  }
-  
-  /**
-   * This class is used as the key into the cache. It holds information to identify 
-   * who performed the query, along with the className and filter used. The thread context
-   * class loader is used in the key, so two different modules will potentially get different
-   * services.
-   */
-  private static final class ServiceKey
-  {
-    /** The class loader of the invoking application */
-    private ClassLoader classLoader;
-    /** The name of the class being queried from the registry */
-    private String className;
-    /** the registry filter, this may be null */
-    private String filter;
-    /** The cached hashCode */
-    private final int hashCode;
-
-    /**
-     * Boring unimportant comment.
-     * 
-     * @param cl
-     * @param cn
-     * @param f
-     */
-    public ServiceKey(ClassLoader cl, String cn, String f)
-    {
-      classLoader = cl;
-      className = cn;
-      filter = f;
-      
-      int classNameHash = (className == null) ? 0 : className.hashCode();
-      hashCode = System.identityHashCode(classLoader) * 1000003 + classNameHash;
-    }
-
-    @Override
-    public int hashCode()
-    {
-      return hashCode;
-    }
-
-    @Override
-    public boolean equals(Object other)
-    {
-      if (other == this) return true;
-      if (other == null) return false;
-
-      if (other instanceof ServiceKey) {
-        ServiceKey otherKey = (ServiceKey) other;
-        if (hashCode != otherKey.hashCode) return false;
-
-        if (classLoader != otherKey.classLoader) return false;
-        if (!!!comparePossiblyNullObjects(className, otherKey.className)) return false;
-        return comparePossiblyNullObjects(filter, otherKey.filter);
-      }
-
-      return false;
-    }
-    
-    /**
-     * Compares two objects where one or other (or both) may be null.
-     * 
-     * @param a the first object to compare.
-     * @param b the second object to compare.
-     * @return true if they are ==, both null or identity equals, false otherwise.
-     */
-    public boolean comparePossiblyNullObjects(Object a, Object b) {
-      if (a == b) return true;
-      else if (a == null) return false;
-      else return a.equals(b);
-    }
-  }
-
-  /**
-   * This method is used to obtain a single instance of a desired service from the OSGi
-   * service registry. If the filter and class name identify multiple services the first
-   * one is returned. If no service is found null will be returned.
-   * 
-   * @param className The class name used to register the desired service. If null is provided
-   *                  then all services are eligible to be returned.
-   * @param filter    An RFC 1960 query into the properties of the registered services. e.g.
-   *                  (service.description=really useful)
-   * @return          The desired service
-   * 
-   * @throws IllegalArgumentException If the filter is not valid. See RFC 1960 to work out what 
-   *                                  it should be.
-   */
-  public static Object getService(String className, String filter) throws IllegalArgumentException
-  {
-    Object service = null;
-    try {
-      BundleContext callerCtx = getBundleContext();
-      ServiceReference[] refs = callerCtx.getAllServiceReferences(className, filter);
-      
-      if (refs != null) {
-        for (ServiceReference ref : refs) {
-          List<Object> services = getServices(callerCtx, className, filter, ref);
-          if (!!!services.isEmpty()) {
-            service = services.get(0);
-            break;
-          }
-        }
-      }      
-    } catch (InvalidSyntaxException e) {
-      throw new IllegalArgumentException(e.getMessage(), e);
-    }
-    
-    return service;
-  }
-  
-  /**
-   * This method is used to obtain a list of service instances from the OSGi
-   * service registry. If no service is found an empty list will be returned.
-   * 
-   * @param className The class name used to register the desired service. If null is provided
-   *                  then all services are eligible to be returned.
-   * @param filter    An RFC 1960 query into the properties of the registered services. e.g.
-   *                  (service.description=really useful)
-   * @return          A list of matching services.
-   * 
-   * @throws IllegalArgumentException If the filter is not valid. See RFC 1960 to work out what 
-   *                                  it should be.
-   */
-  public static List<?> getServices(String className, String filter)
-      throws IllegalArgumentException
-  {
-    List<Object> services;
-    try {
-      BundleContext callerCtx = getBundleContext();
-      ServiceReference[] refs = callerCtx.getAllServiceReferences(className, filter);
-      
-      services = getServices(callerCtx, className, filter, refs);
-    } catch (InvalidSyntaxException e) {
-      throw new IllegalArgumentException(e.getMessage(), e);
-    }
-    
-    return services;
-  }
-  
-  /**
-   * @return the bundle context for the caller.
-   */
-  private static BundleContext getBundleContext()
-  {
-    BundleContext result = context;
-    ClassLoader cl = Thread.currentThread().getContextClassLoader();
-    if (cl instanceof BundleReference) {
-      result = ((BundleReference)cl).getBundle().getBundleContext();
-    } 
-    
-    if (result == null) result = context;
-    return result;
-  }
-
-  /**
-   * This worker method obtains the requested service(s) and if the service(s) 
-   * exist updates the cache and releases the previous service(s).
-   * 
-   * @param callerCtx The caller context.
-   * @param className The class name used to query for the service.
-   * @param filter    The filter name used to query for the service.
-   * @param refs      The references to get.
-   * @return          The service, if one was found, or null.
-   */
-  private static List<Object> getServices(BundleContext callerCtx, String className, String filter, ServiceReference...refs)
-  {
-    List<Object> data = new LinkedList<Object>();
-    
-    if (refs != null) {
-      Set<ServiceReference> refSet = new HashSet<ServiceReference>();
-      for (ServiceReference ref : refs) {
-        Object service = callerCtx.getService(ref);
-        if (service != null) {
-          data.add(service);
-          refSet.add(ref);
-        }
-      }
-      
-      ClassLoader cl = Thread.currentThread().getContextClassLoader();
-      ServiceKey key = new ServiceKey(cl, className, filter);
-      
-      // we do not need any synchronization around this. The map is concurrent
-      // and until here we do not touch any shared state.
-      refSet = cache.put(key, refSet);
-      
-      if (refSet != null) {
-        for (ServiceReference ref : refSet) {
-          callerCtx.ungetService(ref);
-        }
-      }
-    }
-    
-    return data;
-  }
+/*
+ * 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 WARRANTIESOR 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.services;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * This helper provides access to services registered in the OSGi service registry.
+ * If a matching service cannot be located null may be returned. A caller should not
+ * expect to get the same object if multiple requests are made to this API. A caller
+ * should not expect to get a different object if multiple requests are made to this API.
+ * A caller should avoid caching the returned service. OSGi is a dynamic environment and
+ * the service may become unavailable while a reference to it is held. To minimize this
+ * risk the caller should hold onto the service for the minimum length of time.
+ * 
+ * <p>This API should not be used from within an OSGi bundle. When in an OSGi environment
+ *   the BundleContext for the bundle should be used to obtain the service.
+ * </p>
+ */
+public final class ServiceHelper
+{
+  /** The bundle context used for service registry queries */
+  private static BundleContext context;
+  /** A cache of what service was returned last time the query was performed */
+  private static ConcurrentMap<ServiceKey, Set<ServiceReference>> cache = new ConcurrentHashMap<ServiceKey, Set<ServiceReference>>();
+
+  public static void setBundleContext(BundleContext ctx)
+  {
+    context = ctx;
+  }
+  
+  /**
+   * This class is used as the key into the cache. It holds information to identify 
+   * who performed the query, along with the className and filter used. The thread context
+   * class loader is used in the key, so two different modules will potentially get different
+   * services.
+   */
+  private static final class ServiceKey
+  {
+    /** The class loader of the invoking application */
+    private ClassLoader classLoader;
+    /** The name of the class being queried from the registry */
+    private String className;
+    /** the registry filter, this may be null */
+    private String filter;
+    /** The cached hashCode */
+    private final int hashCode;
+
+    /**
+     * Boring unimportant comment.
+     * 
+     * @param cl
+     * @param cn
+     * @param f
+     */
+    public ServiceKey(ClassLoader cl, String cn, String f)
+    {
+      classLoader = cl;
+      className = cn;
+      filter = f;
+      
+      int classNameHash = (className == null) ? 0 : className.hashCode();
+      hashCode = System.identityHashCode(classLoader) * 1000003 + classNameHash;
+    }
+
+    @Override
+    public int hashCode()
+    {
+      return hashCode;
+    }
+
+    @Override
+    public boolean equals(Object other)
+    {
+      if (other == this) return true;
+      if (other == null) return false;
+
+      if (other instanceof ServiceKey) {
+        ServiceKey otherKey = (ServiceKey) other;
+        if (hashCode != otherKey.hashCode) return false;
+
+        if (classLoader != otherKey.classLoader) return false;
+        if (!!!comparePossiblyNullObjects(className, otherKey.className)) return false;
+        return comparePossiblyNullObjects(filter, otherKey.filter);
+      }
+
+      return false;
+    }
+    
+    /**
+     * Compares two objects where one or other (or both) may be null.
+     * 
+     * @param a the first object to compare.
+     * @param b the second object to compare.
+     * @return true if they are ==, both null or identity equals, false otherwise.
+     */
+    public boolean comparePossiblyNullObjects(Object a, Object b) {
+      if (a == b) return true;
+      else if (a == null) return false;
+      else return a.equals(b);
+    }
+  }
+
+  /**
+   * This method is used to obtain a single instance of a desired service from the OSGi
+   * service registry. If the filter and class name identify multiple services the first
+   * one is returned. If no service is found null will be returned.
+   * 
+   * @param className The class name used to register the desired service. If null is provided
+   *                  then all services are eligible to be returned.
+   * @param filter    An RFC 1960 query into the properties of the registered services. e.g.
+   *                  (service.description=really useful)
+   * @return          The desired service
+   * 
+   * @throws IllegalArgumentException If the filter is not valid. See RFC 1960 to work out what 
+   *                                  it should be.
+   */
+  public static Object getService(String className, String filter) throws IllegalArgumentException
+  {
+    Object service = null;
+    try {
+      BundleContext callerCtx = getBundleContext();
+      ServiceReference[] refs = callerCtx.getAllServiceReferences(className, filter);
+      
+      if (refs != null) {
+        for (ServiceReference ref : refs) {
+          List<Object> services = getServices(callerCtx, className, filter, ref);
+          if (!!!services.isEmpty()) {
+            service = services.get(0);
+            break;
+          }
+        }
+      }      
+    } catch (InvalidSyntaxException e) {
+      throw new IllegalArgumentException(e.getMessage(), e);
+    }
+    
+    return service;
+  }
+  
+  /**
+   * This method is used to obtain a list of service instances from the OSGi
+   * service registry. If no service is found an empty list will be returned.
+   * 
+   * @param className The class name used to register the desired service. If null is provided
+   *                  then all services are eligible to be returned.
+   * @param filter    An RFC 1960 query into the properties of the registered services. e.g.
+   *                  (service.description=really useful)
+   * @return          A list of matching services.
+   * 
+   * @throws IllegalArgumentException If the filter is not valid. See RFC 1960 to work out what 
+   *                                  it should be.
+   */
+  public static List<?> getServices(String className, String filter)
+      throws IllegalArgumentException
+  {
+    List<Object> services;
+    try {
+      BundleContext callerCtx = getBundleContext();
+      ServiceReference[] refs = callerCtx.getAllServiceReferences(className, filter);
+      
+      services = getServices(callerCtx, className, filter, refs);
+    } catch (InvalidSyntaxException e) {
+      throw new IllegalArgumentException(e.getMessage(), e);
+    }
+    
+    return services;
+  }
+  
+  /**
+   * @return the bundle context for the caller.
+   */
+  private static BundleContext getBundleContext()
+  {
+    BundleContext result = context;
+    ClassLoader cl = Thread.currentThread().getContextClassLoader();
+    if (cl instanceof BundleReference) {
+      result = ((BundleReference)cl).getBundle().getBundleContext();
+    } 
+    
+    if (result == null) result = context;
+    return result;
+  }
+
+  /**
+   * This worker method obtains the requested service(s) and if the service(s) 
+   * exist updates the cache and releases the previous service(s).
+   * 
+   * @param callerCtx The caller context.
+   * @param className The class name used to query for the service.
+   * @param filter    The filter name used to query for the service.
+   * @param refs      The references to get.
+   * @return          The service, if one was found, or null.
+   */
+  private static List<Object> getServices(BundleContext callerCtx, String className, String filter, ServiceReference...refs)
+  {
+    List<Object> data = new LinkedList<Object>();
+    
+    if (refs != null) {
+      Set<ServiceReference> refSet = new HashSet<ServiceReference>();
+      for (ServiceReference ref : refs) {
+        Object service = callerCtx.getService(ref);
+        if (service != null) {
+          data.add(service);
+          refSet.add(ref);
+        }
+      }
+      
+      ClassLoader cl = Thread.currentThread().getContextClassLoader();
+      ServiceKey key = new ServiceKey(cl, className, filter);
+      
+      // we do not need any synchronization around this. The map is concurrent
+      // and until here we do not touch any shared state.
+      refSet = cache.put(key, refSet);
+      
+      if (refSet != null) {
+        for (ServiceReference ref : refSet) {
+          callerCtx.ungetService(ref);
+        }
+      }
+    }
+    
+    return data;
+  }
 }
\ No newline at end of file

Propchange: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/services/ServiceHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java?rev=822489&r1=822488&r2=822489&view=diff
==============================================================================
--- incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java (original)
+++ incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java Tue Oct  6 20:41:31 2009
@@ -1,50 +1,50 @@
-/*
- * 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 WARRANTIESOR 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.url;
-
-import java.util.Hashtable;
-
-import javax.naming.spi.ObjectFactory;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-import org.apache.aries.jndi.services.ServiceHelper;
-
-public class Activator implements BundleActivator {
-
-  private ServiceRegistration reg;
-	
-  public void start(BundleContext context)
-  {
-    ServiceHelper.setBundleContext(context);
-    
-    Hashtable<Object, Object> props = new Hashtable<Object, Object>();
-    props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
-    reg = context.registerService(ObjectFactory.class.getName(), new OsgiURLContextFactory(), props);
-  }
-
-
-  public void stop(BundleContext context)
-  {
-	reg.unregister();
-  }
-
-}
+/*
+ * 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 WARRANTIESOR 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.url;
+
+import java.util.Hashtable;
+
+import javax.naming.spi.ObjectFactory;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import org.apache.aries.jndi.services.ServiceHelper;
+
+public class Activator implements BundleActivator {
+
+  private ServiceRegistration reg;
+	
+  public void start(BundleContext context)
+  {
+    ServiceHelper.setBundleContext(context);
+    
+    Hashtable<Object, Object> props = new Hashtable<Object, Object>();
+    props.put("osgi.jndi.urlScheme", new String[] {"osgi", "aries"} );
+    reg = context.registerService(ObjectFactory.class.getName(), new OsgiURLContextFactory(), props);
+  }
+
+
+  public void stop(BundleContext context)
+  {
+	reg.unregister();
+  }
+
+}

Propchange: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/Activator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java?rev=822489&r1=822488&r2=822489&view=diff
==============================================================================
--- incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java (original)
+++ incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java Tue Oct  6 20:41:31 2009
@@ -1,80 +1,80 @@
-/*
- * 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 WARRANTIESOR 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.url;
-
-import java.util.Hashtable;
-
-import javax.naming.ConfigurationException;
-import javax.naming.Context;
-import javax.naming.Name;
-import javax.naming.NamingException;
-import javax.naming.spi.ObjectFactory;
-
-/**
- * A factory for the aries JNDI context
- */
-public class OsgiURLContextFactory implements ObjectFactory
-{
-  public Object getObjectInstance(Object obj, Name name, Context nameCtx,
-      Hashtable<?, ?> environment) throws Exception
-  {
-    if (obj == null) {
-      return new ServiceRegistryContext(environment);
-    } else if (obj instanceof String) {
-      Context ctx = null;
-      try {
-        
-        ctx = new ServiceRegistryContext(environment);
-        
-        return ctx.lookup((String)obj);
-      } finally {
-        if (ctx != null) ctx.close();
-      }
-    } else if (obj instanceof String[]) {
-      // Try each URL until either lookup succeeds or they all fail
-      String[] urls = (String[])obj;
-      if (urls.length == 0) throw new ConfigurationException("ariesURLContextFactory: empty URL array");
-      Context context = new ServiceRegistryContext(environment);
-      try
-      {
-        NamingException ne = null;
-        for(int i=0; i< urls.length; i++)
-        {
-          try
-          {
-            return context.lookup(urls[i]);
-          }
-          catch(NamingException e)
-          {
-            ne = e;
-          }
-        }
-        throw ne;
-      }
-      finally
-      {
-        context.close();
-      }    
-      
-    }
-
-    return null;
-  }
-
-}
+/*
+ * 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 WARRANTIESOR 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.url;
+
+import java.util.Hashtable;
+
+import javax.naming.ConfigurationException;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.spi.ObjectFactory;
+
+/**
+ * A factory for the aries JNDI context
+ */
+public class OsgiURLContextFactory implements ObjectFactory
+{
+  public Object getObjectInstance(Object obj, Name name, Context nameCtx,
+      Hashtable<?, ?> environment) throws Exception
+  {
+    if (obj == null) {
+      return new ServiceRegistryContext(environment);
+    } else if (obj instanceof String) {
+      Context ctx = null;
+      try {
+        
+        ctx = new ServiceRegistryContext(environment);
+        
+        return ctx.lookup((String)obj);
+      } finally {
+        if (ctx != null) ctx.close();
+      }
+    } else if (obj instanceof String[]) {
+      // Try each URL until either lookup succeeds or they all fail
+      String[] urls = (String[])obj;
+      if (urls.length == 0) throw new ConfigurationException("ariesURLContextFactory: empty URL array");
+      Context context = new ServiceRegistryContext(environment);
+      try
+      {
+        NamingException ne = null;
+        for(int i=0; i< urls.length; i++)
+        {
+          try
+          {
+            return context.lookup(urls[i]);
+          }
+          catch(NamingException e)
+          {
+            ne = e;
+          }
+        }
+        throw ne;
+      }
+      finally
+      {
+        context.close();
+      }    
+      
+    }
+
+    return null;
+  }
+
+}

Propchange: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/OsgiURLContextFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java?rev=822489&r1=822488&r2=822489&view=diff
==============================================================================
--- incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java (original)
+++ incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java Tue Oct  6 20:41:31 2009
@@ -1,358 +1,358 @@
-/*
- * 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 WARRANTIESOR 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.url;
-
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.naming.Binding;
-import javax.naming.Context;
-import javax.naming.InvalidNameException;
-import javax.naming.Name;
-import javax.naming.NameClassPair;
-import javax.naming.NameNotFoundException;
-import javax.naming.NameParser;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.OperationNotSupportedException;
-
-import org.apache.aries.jndi.services.ServiceHelper;
-
-/**
- * A JNDI context for looking stuff up from the service registry.
- */
-public class ServiceRegistryContext implements Context
-{
-  private static final String ARIES_SERVICES = "aries:services/";
-  /** The name parser for the service registry name space */
-  private NameParser parser = new ServiceRegistryNameParser();
-  /** The environment for this context */
-  private Map<Object, Object> env;
-  
-  /**
-   * Why Mr Java this class does indeed take a fine copy of the provided 
-   * environment. One might imagine that it is worried that the provider is
-   * not to be trusted.
-   * 
-   * @param environment
-   */
-  public ServiceRegistryContext(@SuppressWarnings("unused") Hashtable<?, ?> environment)
-  {
-    env = new HashMap<Object, Object>();
-    env.putAll(environment);
-  }
-
-  public Object addToEnvironment(String propName, Object propVal) throws NamingException
-  {
-    return env.put(propName, propVal);
-  }
-
-  public void bind(Name name, Object obj) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public void bind(String name, Object obj) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public void close() throws NamingException
-  {
-    env = null;
-    parser = null;
-  }
-
-  public Name composeName(Name name, Name prefix) throws NamingException
-  {
-    String result = prefix + "/" + name;
-
-    String ns = ARIES_SERVICES;
-    
-    if (result.startsWith(ns)) {
-      ns = "";
-    }
-    
-    return parser.parse(ns + result);
-  }
-
-  public String composeName(String name, String prefix) throws NamingException
-  {
-    String result = prefix + "/" + name;
-
-    String ns = ARIES_SERVICES;
-    
-    if (result.startsWith(ns)) {
-      ns = "";
-    }
-    
-    parser.parse(ns + result);
-    
-    return result;
-  }
-
-  public Context createSubcontext(Name name) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public Context createSubcontext(String name) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public void destroySubcontext(Name name) throws NamingException
-  {
-    //No-op we don't support sub-contexts in our context   
-  }
-
-  public void destroySubcontext(String name) throws NamingException
-  {
-    //No-op we don't support sub-contexts in our context
-    
-  }
-
-  public Hashtable<?, ?> getEnvironment() throws NamingException
-  {
-    Hashtable<Object, Object> environment = new Hashtable<Object, Object>();
-    environment.putAll(env);
-    return environment;
-  }
-
-  public String getNameInNamespace() throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public NameParser getNameParser(Name name) throws NamingException
-  {
-    return parser;
-  }
-
-  public NameParser getNameParser(String name) throws NamingException
-  {
-    return parser;
-  }
-
-  public NamingEnumeration<NameClassPair> list(final Name name) throws NamingException
-  {
-    int nameSize = validateName(name);
-    
-    String className = name.get(0);
-    String filter = null;
-    
-    if (nameSize == 2) {
-      filter = name.get(1);
-    }
-    
-    try {
-      final Iterator<?> it = ServiceHelper.getServices(className, filter).iterator();
-      
-      return new NamingEnumeration<NameClassPair>() {
-        public void close() throws NamingException
-        {
-          // TODO return stuff to the registry, maybe???
-        }
-
-        public boolean hasMore()
-        {
-          return it.hasNext();
-        }
-
-        public NameClassPair next()
-        {
-          return nextElement();
-        }
-
-        public boolean hasMoreElements()
-        {
-          return it.hasNext();
-        }
-
-        public NameClassPair nextElement()
-        {
-          return new NameClassPair(name.toString(), it.next().getClass().getCanonicalName(), false);
-        }
-      };
-    } catch (IllegalArgumentException e) {
-      NamingException ne = new NamingException(e.getMessage());
-      ne.initCause(e);
-      throw ne;
-    }  }
-
-  public NamingEnumeration<NameClassPair> list(String name) throws NamingException
-  {
-    return list(parser.parse(name));
-  }
-
-  public NamingEnumeration<Binding> listBindings(final Name name) throws NamingException
-  {
-    String className = null;
-    String filter = null;
-    
-    int nameSize = validateName(name);
-    
-    className = name.get(0);
-
-    if (nameSize == 2) {
-      filter = name.get(1);
-    }
-    
-    try {
-      final Iterator<?> it = ServiceHelper.getServices(className, filter).iterator();
-      
-      return new NamingEnumeration<Binding>() {
-        public void close() throws NamingException
-        {
-          // TODO return stuff to the registry, maybe???
-        }
-
-        public boolean hasMore()
-        {
-          return it.hasNext();
-        }
-
-        public Binding next()
-        {
-          return nextElement();
-        }
-
-        public boolean hasMoreElements()
-        {
-          return it.hasNext();
-        }
-
-        public Binding nextElement()
-        {
-          return new Binding(name.toString(), it.next(), false);
-        }
-      };
-    } catch (IllegalArgumentException e) {
-      NamingException ne = new NamingException(e.getMessage());
-      ne.initCause(e);
-      throw ne;
-    }
-  }
-
-  public NamingEnumeration<Binding> listBindings(String name) throws NamingException
-  {
-    return listBindings(parser.parse(name));
-  }
-
-  public Object lookup(Name name) throws NamingException
-  {
-    int nameSize = validateName(name);
-    String className = name.get(0);
-
-    String filter = null;
-    
-    if (nameSize == 2) {
-      filter = name.get(1);
-    }
-    
-    try {
-      Object result = ServiceHelper.getService(className, filter);
-      
-      if (result == null) {
-        throw new NameNotFoundException("We couldn't find an object in the registry matching the query " + name);
-      }
-      
-      return result;
-    } catch (IllegalArgumentException e) {
-      NamingException ne = new NamingException(e.getMessage());
-      ne.initCause(e);
-      throw ne;
-    }
-  }
-
-  public Object lookup(String name) throws NamingException
-  {
-    return lookup(parser.parse(name));
-  }
-
-  public Object lookupLink(Name name) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public Object lookupLink(String name) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public void rebind(Name name, Object obj) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public void rebind(String name, Object obj) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public Object removeFromEnvironment(String propName) throws NamingException
-  {
-    return env.remove(propName);
-  }
-
-  public void rename(Name oldName, Name newName) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public void rename(String oldName, String newName) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public void unbind(Name name) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-
-  public void unbind(String name) throws NamingException
-  {
-    throw new OperationNotSupportedException();
-  }
-  
-  /**
-   * Check that the name conforms to the expected format
-   * @param name
-   * @return the size of the name
-   * @throws InvalidNameException
-   */
-  private int validateName(final Name name) throws InvalidNameException
-  {
-    int nameSize = name.size();
-    if (nameSize == 0) {
-      throw new InvalidNameException("The provided name does not have any components" + name);
-    } 
-    
-    if ("aries:services".equals(name.get(0))) {
-      throw new InvalidNameException("The composite name should not start with aries:services");
-    }
-    
-    if (nameSize > 2) {
-      throw new InvalidNameException("This JNDI context only expects 2 components, but it found " + nameSize);
-    }
-    return nameSize;
-  }
+/*
+ * 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 WARRANTIESOR 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.url;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
+
+import org.apache.aries.jndi.services.ServiceHelper;
+
+/**
+ * A JNDI context for looking stuff up from the service registry.
+ */
+public class ServiceRegistryContext implements Context
+{
+  private static final String ARIES_SERVICES = "aries:services/";
+  /** The name parser for the service registry name space */
+  private NameParser parser = new ServiceRegistryNameParser();
+  /** The environment for this context */
+  private Map<Object, Object> env;
+  
+  /**
+   * Why Mr Java this class does indeed take a fine copy of the provided 
+   * environment. One might imagine that it is worried that the provider is
+   * not to be trusted.
+   * 
+   * @param environment
+   */
+  public ServiceRegistryContext(@SuppressWarnings("unused") Hashtable<?, ?> environment)
+  {
+    env = new HashMap<Object, Object>();
+    env.putAll(environment);
+  }
+
+  public Object addToEnvironment(String propName, Object propVal) throws NamingException
+  {
+    return env.put(propName, propVal);
+  }
+
+  public void bind(Name name, Object obj) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public void bind(String name, Object obj) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public void close() throws NamingException
+  {
+    env = null;
+    parser = null;
+  }
+
+  public Name composeName(Name name, Name prefix) throws NamingException
+  {
+    String result = prefix + "/" + name;
+
+    String ns = ARIES_SERVICES;
+    
+    if (result.startsWith(ns)) {
+      ns = "";
+    }
+    
+    return parser.parse(ns + result);
+  }
+
+  public String composeName(String name, String prefix) throws NamingException
+  {
+    String result = prefix + "/" + name;
+
+    String ns = ARIES_SERVICES;
+    
+    if (result.startsWith(ns)) {
+      ns = "";
+    }
+    
+    parser.parse(ns + result);
+    
+    return result;
+  }
+
+  public Context createSubcontext(Name name) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public Context createSubcontext(String name) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public void destroySubcontext(Name name) throws NamingException
+  {
+    //No-op we don't support sub-contexts in our context   
+  }
+
+  public void destroySubcontext(String name) throws NamingException
+  {
+    //No-op we don't support sub-contexts in our context
+    
+  }
+
+  public Hashtable<?, ?> getEnvironment() throws NamingException
+  {
+    Hashtable<Object, Object> environment = new Hashtable<Object, Object>();
+    environment.putAll(env);
+    return environment;
+  }
+
+  public String getNameInNamespace() throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public NameParser getNameParser(Name name) throws NamingException
+  {
+    return parser;
+  }
+
+  public NameParser getNameParser(String name) throws NamingException
+  {
+    return parser;
+  }
+
+  public NamingEnumeration<NameClassPair> list(final Name name) throws NamingException
+  {
+    int nameSize = validateName(name);
+    
+    String className = name.get(0);
+    String filter = null;
+    
+    if (nameSize == 2) {
+      filter = name.get(1);
+    }
+    
+    try {
+      final Iterator<?> it = ServiceHelper.getServices(className, filter).iterator();
+      
+      return new NamingEnumeration<NameClassPair>() {
+        public void close() throws NamingException
+        {
+          // TODO return stuff to the registry, maybe???
+        }
+
+        public boolean hasMore()
+        {
+          return it.hasNext();
+        }
+
+        public NameClassPair next()
+        {
+          return nextElement();
+        }
+
+        public boolean hasMoreElements()
+        {
+          return it.hasNext();
+        }
+
+        public NameClassPair nextElement()
+        {
+          return new NameClassPair(name.toString(), it.next().getClass().getCanonicalName(), false);
+        }
+      };
+    } catch (IllegalArgumentException e) {
+      NamingException ne = new NamingException(e.getMessage());
+      ne.initCause(e);
+      throw ne;
+    }  }
+
+  public NamingEnumeration<NameClassPair> list(String name) throws NamingException
+  {
+    return list(parser.parse(name));
+  }
+
+  public NamingEnumeration<Binding> listBindings(final Name name) throws NamingException
+  {
+    String className = null;
+    String filter = null;
+    
+    int nameSize = validateName(name);
+    
+    className = name.get(0);
+
+    if (nameSize == 2) {
+      filter = name.get(1);
+    }
+    
+    try {
+      final Iterator<?> it = ServiceHelper.getServices(className, filter).iterator();
+      
+      return new NamingEnumeration<Binding>() {
+        public void close() throws NamingException
+        {
+          // TODO return stuff to the registry, maybe???
+        }
+
+        public boolean hasMore()
+        {
+          return it.hasNext();
+        }
+
+        public Binding next()
+        {
+          return nextElement();
+        }
+
+        public boolean hasMoreElements()
+        {
+          return it.hasNext();
+        }
+
+        public Binding nextElement()
+        {
+          return new Binding(name.toString(), it.next(), false);
+        }
+      };
+    } catch (IllegalArgumentException e) {
+      NamingException ne = new NamingException(e.getMessage());
+      ne.initCause(e);
+      throw ne;
+    }
+  }
+
+  public NamingEnumeration<Binding> listBindings(String name) throws NamingException
+  {
+    return listBindings(parser.parse(name));
+  }
+
+  public Object lookup(Name name) throws NamingException
+  {
+    int nameSize = validateName(name);
+    String className = name.get(0);
+
+    String filter = null;
+    
+    if (nameSize == 2) {
+      filter = name.get(1);
+    }
+    
+    try {
+      Object result = ServiceHelper.getService(className, filter);
+      
+      if (result == null) {
+        throw new NameNotFoundException("We couldn't find an object in the registry matching the query " + name);
+      }
+      
+      return result;
+    } catch (IllegalArgumentException e) {
+      NamingException ne = new NamingException(e.getMessage());
+      ne.initCause(e);
+      throw ne;
+    }
+  }
+
+  public Object lookup(String name) throws NamingException
+  {
+    return lookup(parser.parse(name));
+  }
+
+  public Object lookupLink(Name name) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public Object lookupLink(String name) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public void rebind(Name name, Object obj) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public void rebind(String name, Object obj) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public Object removeFromEnvironment(String propName) throws NamingException
+  {
+    return env.remove(propName);
+  }
+
+  public void rename(Name oldName, Name newName) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public void rename(String oldName, String newName) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public void unbind(Name name) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+
+  public void unbind(String name) throws NamingException
+  {
+    throw new OperationNotSupportedException();
+  }
+  
+  /**
+   * Check that the name conforms to the expected format
+   * @param name
+   * @return the size of the name
+   * @throws InvalidNameException
+   */
+  private int validateName(final Name name) throws InvalidNameException
+  {
+    int nameSize = name.size();
+    if (nameSize == 0) {
+      throw new InvalidNameException("The provided name does not have any components" + name);
+    } 
+    
+    if ("aries:services".equals(name.get(0))) {
+      throw new InvalidNameException("The composite name should not start with aries:services");
+    }
+    
+    if (nameSize > 2) {
+      throw new InvalidNameException("This JNDI context only expects 2 components, but it found " + nameSize);
+    }
+    return nameSize;
+  }
 }
\ No newline at end of file

Propchange: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java?rev=822489&r1=822488&r2=822489&view=diff
==============================================================================
--- incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java (original)
+++ incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java Tue Oct  6 20:41:31 2009
@@ -1,48 +1,48 @@
-/*
- * 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 WARRANTIESOR 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.url;
-
-import java.util.Enumeration;
-
-import javax.naming.CompositeName;
-
-/**
- * A composite name for the aries namespace. We only have this so that we can
- * provide a nicer toString()
- */
-public final class ServiceRegistryName extends CompositeName
-{
-  /** The serial version UID */
-  private static final long serialVersionUID = 6617580228852444656L;
-  
-  @Override
-  public String toString()
-  {
-    StringBuilder buffer = new StringBuilder();
-    
-    buffer.append("aries:services");
-    Enumeration<String> components = getAll();
-    while (components.hasMoreElements()) {
-      buffer.append('/');
-      buffer.append(components.nextElement());
-    }
-    
-    return buffer.toString();
-  }
+/*
+ * 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 WARRANTIESOR 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.url;
+
+import java.util.Enumeration;
+
+import javax.naming.CompositeName;
+
+/**
+ * A composite name for the aries namespace. We only have this so that we can
+ * provide a nicer toString()
+ */
+public final class ServiceRegistryName extends CompositeName
+{
+  /** The serial version UID */
+  private static final long serialVersionUID = 6617580228852444656L;
+  
+  @Override
+  public String toString()
+  {
+    StringBuilder buffer = new StringBuilder();
+    
+    buffer.append("aries:services");
+    Enumeration<String> components = getAll();
+    while (components.hasMoreElements()) {
+      buffer.append('/');
+      buffer.append(components.nextElement());
+    }
+    
+    return buffer.toString();
+  }
 }
\ No newline at end of file

Propchange: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryName.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java?rev=822489&r1=822488&r2=822489&view=diff
==============================================================================
--- incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java (original)
+++ incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java Tue Oct  6 20:41:31 2009
@@ -1,70 +1,70 @@
-/*
- * 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 WARRANTIESOR 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.url;
-
-import javax.naming.InvalidNameException;
-import javax.naming.Name;
-import javax.naming.NameParser;
-import javax.naming.NamingException;
-
-/**
- * A parser for the aries namespace
- */
-public final class ServiceRegistryNameParser implements NameParser
-{
-
-  public Name parse(String name) throws NamingException
-  {
-    if (!!!name.startsWith("aries:services/") &&
-        !!!name.startsWith("osgi:services/")) throw new InvalidNameException("The JNDI name did not start with aries:, or osgi:");
-    
-    name = name.substring(name.indexOf('/') + 1);
-    
-    int slashIndex = name.indexOf('/');
-    String interfaceName = name;
-    String filter = null;
-    
-    if (slashIndex != -1) {
-      interfaceName = name.substring(0, slashIndex);
-      filter = name.substring(slashIndex + 1);
-    }
-    
-    if (interfaceName.length() == 0) throw new InvalidNameException("No interface name was specified");
-    
-    Name result = new ServiceRegistryName();
-    result.add(interfaceName);
-    if (filter != null) {
-      result.add(filter);
-    }
-    
-    return result;
-  }
-
-  @Override
-  public boolean equals(Object other)
-  {
-    return other instanceof ServiceRegistryNameParser;
-  }
-  
-  @Override
-  public int hashCode()
-  {
-    return 100003;
-  }
+/*
+ * 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 WARRANTIESOR 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.url;
+
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingException;
+
+/**
+ * A parser for the aries namespace
+ */
+public final class ServiceRegistryNameParser implements NameParser
+{
+
+  public Name parse(String name) throws NamingException
+  {
+    if (!!!name.startsWith("aries:services/") &&
+        !!!name.startsWith("osgi:services/")) throw new InvalidNameException("The JNDI name did not start with aries:, or osgi:");
+    
+    name = name.substring(name.indexOf('/') + 1);
+    
+    int slashIndex = name.indexOf('/');
+    String interfaceName = name;
+    String filter = null;
+    
+    if (slashIndex != -1) {
+      interfaceName = name.substring(0, slashIndex);
+      filter = name.substring(slashIndex + 1);
+    }
+    
+    if (interfaceName.length() == 0) throw new InvalidNameException("No interface name was specified");
+    
+    Name result = new ServiceRegistryName();
+    result.add(interfaceName);
+    if (filter != null) {
+      result.add(filter);
+    }
+    
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object other)
+  {
+    return other instanceof ServiceRegistryNameParser;
+  }
+  
+  @Override
+  public int hashCode()
+  {
+    return 100003;
+  }
 }
\ No newline at end of file

Propchange: incubator/aries/trunk/jndi-contrib/jndi-url/src/main/java/org/apache/aries/jndi/url/ServiceRegistryNameParser.java
------------------------------------------------------------------------------
    svn:eol-style = native