You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by hu...@apache.org on 2009/10/01 19:19:21 UTC

svn commit: r820722 [3/8] - in /incubator/aries/contrib: ./ ibm/ ibm/aries.image/ ibm/build/ ibm/build/buildtasks/ ibm/build/buildtasks/src/ ibm/build/buildtasks/src/com/ ibm/build/buildtasks/src/com/ibm/ ibm/build/buildtasks/src/com/ibm/aries/ ibm/bui...

Added: incubator/aries/contrib/ibm/build/imports/standard_properties.xml
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/build/imports/standard_properties.xml?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/build/imports/standard_properties.xml (added)
+++ incubator/aries/contrib/ibm/build/imports/standard_properties.xml Thu Oct  1 17:19:13 2009
@@ -0,0 +1,14 @@
+<!-- (C) Copyright IBM Corp. 2009 -->
+
+<project name="standard_properties">
+  <property name="report.dir" value="${basedir}/build/reports/"/>
+  <property name="output.jar" value="${ant.project.name}.jar" />
+  <property name="build.dir" value="${basedir}/build" />
+  <property name="lib.dir" value="${build.dir}/lib" />
+  <property name="classes.dir" value="${build.dir}/classes" />
+  <property name="src.dir" value="${basedir}/src" />
+  <property name="javac.debug.level" value="lines,vars,source" />
+  <available classname="com.ibm.team.build.ant.task.ArtifactFilePublisherTask" property="jazz.tasks.available"/>
+  <property name="scripts.dir" value="${basedir}/../build/scripts" />
+</project>
+

Added: incubator/aries/contrib/ibm/build/imports/standard_targets.xml
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/build/imports/standard_targets.xml?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/build/imports/standard_targets.xml (added)
+++ incubator/aries/contrib/ibm/build/imports/standard_targets.xml Thu Oct  1 17:19:13 2009
@@ -0,0 +1,10 @@
+<!-- (C) Copyright IBM Corp. 2009 -->
+
+<project name="standard_targets">
+  <import file="begin.xml" />
+  <import file="compile.xml" />
+  <import file="package.xml" />
+  <import file="publish.xml" />
+  <target name="build" depends="compile, package, publish" />
+</project>
+

Added: incubator/aries/contrib/ibm/build/imports/unittest.xml
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/build/imports/unittest.xml?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/build/imports/unittest.xml (added)
+++ incubator/aries/contrib/ibm/build/imports/unittest.xml Thu Oct  1 17:19:13 2009
@@ -0,0 +1,88 @@
+<!-- (C) Copyright IBM Corp. 2009 -->
+
+<project name="unittest">
+  <import file="standard_properties.xml" />
+  <import file="unittest_std_props.xml"/>
+	
+  <target name="checkUnittestsThere">
+    <available file="${unittest.srcdir}" property="unittest_available" />
+  </target>
+  
+  <target name="compile_unittest" depends="checkUnittestsThere" if="unittest_available">
+    <mkdir dir="${build.dir}" />
+    <mkdir dir="${unittest.classes.dir}" />
+    <javac srcdir="${unittest.srcdir}" destdir="${unittest.classes.dir}" classpath="${classes.dir}" classpathref="unittest.class.path" debuglevel="${javac.debug.level}" includeAntRuntime="no" debug="true"/>
+  </target>
+	
+  <target name="unittest" depends="checkUnittestsThere, compile_unittest" if="unittest_available">
+  	
+    <property name="unittest.run.timeout" value="${unittest.timeout}" />
+
+    <echo message="---------- Starting ${ant.project.name} unit tests ----------"/>
+    <property name="pattern" value="'Time stamp:' EEE MMM d yyyy 'at' hh:mm:ss"/>
+
+    <tstamp><format property="tstamp1" pattern="${pattern}"/></tstamp>
+    <echo message="Started at: ${tstamp1}"/>
+    <echo message="Timeout: ${unittest.run.timeout}"/>
+  	
+  	<mkdir dir="${unittest.reports}"/>
+  	
+  	<junit printsummary="on" dir="${basedir}" fork="on" forkmode="once" haltonfailure="no" timeout="${unittest.run.timeout}" >
+      <classpath>
+        <pathelement location="${classes.dir}"/>
+      	<pathelement location="${unittest.classes.dir}"/>
+      	<pathelement location="${unittest.srcdir}"/>
+        <pathelement location="${src.dir}"/>
+      	<path refid="unittest.class.path"/>
+      </classpath>
+  		<formatter type="xml" />
+        <syspropertyset>
+          <propertyref prefix="unittest.prop." />
+          <mapper type="glob" from="unittest.prop.*" to="*"/>
+        </syspropertyset>
+  		<batchtest todir="${unittest.reports}">
+  	      <fileset dir="${unittest.srcdir}">
+            <include name="**/*Test.java"/>
+  	      	<exclude name="**/*Lengthy*.java/"/>
+  	        <exclude name="**/*Recovery*.java/"/>
+          </fileset>
+        </batchtest>
+    </junit>
+  	
+  	<junit printsummary="on" dir="${basedir}" fork="on" forkmode="once" haltonfailure="no" timeout="${unittest.run.timeout}" >
+      <classpath>
+        <pathelement location="${classes.dir}"/>
+      	<pathelement location="${unittest.classes.dir}"/>
+      	<pathelement location="${unittest.srcdir}"/>
+        <pathelement location="${src.dir}"/>
+      	<path refid="unittest.class.path"/>
+      </classpath>
+  		<formatter type="xml" />
+        <syspropertyset>
+          <propertyref prefix="unittest.prop." />
+          <mapper type="glob" from="unittest.prop.*" to="*"/>
+        </syspropertyset>
+  		<batchtest todir="${unittest.reports}" if="unittest.lengthy">
+  	      <fileset dir="${unittest.srcdir}">
+  	      	<include name="**/*Lengthy*Test.java/"/>
+  	        <include name="**/*Recovery*Test.java/"/>
+          </fileset>
+        </batchtest>
+    </junit>
+  	
+    <echo message="---------- Finished ${ant.project.name} unit tests ----------"/>
+  	
+  	<antcall target="publishUnittestResults" inheritall="true">
+  	  <param name="label" value="Publishing results for ${ant.project.name}"/>
+    </antcall>
+  	
+  </target>
+	
+  <target name="publishUnittestResults" if="jazz.tasks.available">
+    <if if="production.build">
+    	<taskdef name="junitLogPublisher"
+    	      classname="com.ibm.team.build.ant.task.JUnitLogPublisherTask" />
+  	  <junitLogPublisher  buildresultuuid="${buildResultUUID}" filepath="${unittest.reports}" repositoryaddress="${repositoryAddress}" userid="${userId}" passwordfile="${passwordFile}"/>
+    </if>
+  </target>
+</project>
\ No newline at end of file

Added: incubator/aries/contrib/ibm/build/imports/unittest_std_props.xml
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/build/imports/unittest_std_props.xml?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/build/imports/unittest_std_props.xml (added)
+++ incubator/aries/contrib/ibm/build/imports/unittest_std_props.xml Thu Oct  1 17:19:13 2009
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- (C) Copyright IBM Corp. 2009 -->
+
+<project name="unittest_std_props">
+  <!-- variables for unittest tasks -->
+  <property name="unittest.reports" value="${report.dir}/unittest/"/>
+  <property name="unittest.code.coverage.dir" value="${unittest.reports}/codecoverage"/>
+  <property name="unittest.jardir" value="${build.dir}/unittest/jars"/>
+  <property name="unittest.jarname" value="${unittest.jardir}/UnitTests.jar"/>
+  <property name="unittest.bucket.name" value="**/*Test.java"/>
+  <property name="unittest.full.bucket.name" value="**/*Test.java"/>
+  <property name="unittest.prop.LOGGING_DIR" value="${unittest.reports}" />
+  <property name="unittest.timeout" value="300000" />
+  <property name="unittest.srcdir" value="${basedir}/unittest" />
+  <property name="unittest.classes.dir" value="${build.dir}/unittest/classes" />
+</project>
\ No newline at end of file

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.aries
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.aries?rev=820722&view=auto
==============================================================================
    (empty)

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.classpath
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.classpath?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.classpath (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.classpath Thu Oct  1 17:19:13 2009
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="unittest"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/unittest.framework"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/com.ibm.osgi.jndi"/>
+	<classpathentry kind="output" path="build/classes"/>
+</classpath>

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.project
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.project?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.project (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/.project Thu Oct  1 17:19:13 2009
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>com.ibm.osgi.jndi.url</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/META-INF/MANIFEST.MF?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/META-INF/MANIFEST.MF (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/META-INF/MANIFEST.MF Thu Oct  1 17:19:13 2009
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Url Plug-in
+Bundle-SymbolicName: com.ibm.osgi.jndi.url
+Bundle-Version: 1.0.0
+Bundle-Activator: com.ibm.osgi.jndi.url.Activator
+Bundle-Vendor: IBM
+Import-Package: org.osgi.framework;version="1.3.0",
+ javax.naming.spi
+Export-Package: com.ibm.osgi.jndi.services

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/build.properties
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/build.properties?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/build.properties (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/build.properties Thu Oct  1 17:19:13 2009
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = build/classes/
+bin.includes = META-INF/,\
+               .

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/build.xml
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/build.xml?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/build.xml (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/build.xml Thu Oct  1 17:19:13 2009
@@ -0,0 +1,6 @@
+<!-- (C) Copyright IBM Corp. 2009 -->
+
+<project name="com.ibm.osgi.jndi.url" default="build" basedir=".">
+  <property name="aries.image" value="true"/>
+  <import file="../build/imports/standard_imports.xml"/>
+</project>
\ No newline at end of file

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/services/ServiceHelper.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/services/ServiceHelper.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/services/ServiceHelper.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/services/ServiceHelper.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,236 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.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

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/Activator.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/Activator.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/Activator.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/Activator.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.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 com.ibm.osgi.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();
+  }
+
+}

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/OsgiURLContextFactory.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/OsgiURLContextFactory.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/OsgiURLContextFactory.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/OsgiURLContextFactory.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.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;
+  }
+
+}

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryContext.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryContext.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryContext.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryContext.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,343 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.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 com.ibm.osgi.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

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryName.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryName.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryName.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryName.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.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

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryNameParser.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryNameParser.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryNameParser.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/src/com/ibm/osgi/jndi/url/ServiceRegistryNameParser.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.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

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceHelperTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceHelperTest.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceHelperTest.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceHelperTest.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,195 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.jndi.url;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+
+import mocks.BundleContextMock;
+import mocks.BundleMock;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import com.ibm.aries.unittest.mocks.MethodCall;
+import com.ibm.aries.unittest.mocks.Skeleton;
+import com.ibm.osgi.jndi.services.ServiceHelper;
+import com.ibm.osgi.jndi.url.Activator;
+
+
+/**
+ * This class contains tests for the ServiceHelper
+ */
+public class ServiceHelperTest
+{
+  /** The service we register by default */
+  private Thread service;
+  /** The bundle context for the test */
+  private BundleContext bc;
+  
+  /**
+   * This method does the setup to ensure we always have a service.
+   * @throws NoSuchFieldException 
+   * @throws SecurityException 
+   * @throws IllegalAccessException 
+   * @throws IllegalArgumentException 
+   */
+  @Before
+  public void registerService() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
+  {
+    
+    bc =  Skeleton.newMock(new BundleContextMock(), BundleContext.class);
+    new Activator().start(bc);
+    
+    Field f = ServiceHelper.class.getDeclaredField("context");
+    f.setAccessible(true);
+    f.set(null, bc);
+
+    service = new Thread();
+    
+    registerService(service);
+  }
+
+  /**
+   * Register a service in our map.
+   * 
+   * @param service2 The service to register.
+   */
+  private void registerService(Thread service2)
+  {
+    ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
+    Skeleton skel = Skeleton.getSkeleton(factory);
+    
+    skel.setReturnValue(new MethodCall(ServiceFactory.class, "getService", Bundle.class, ServiceRegistration.class), service2);
+    
+    bc.registerService(new String[] {"java.lang.Runnable"}, factory, new Hashtable<String, String>());
+  }
+  
+  /**
+   * Make sure we clear the caches out before the next test.
+   */
+  @After
+  public void teardown()
+  {
+    BundleContextMock.clear();
+  }
+  
+  /**
+   * Check that the basic behaviour is correct. Do we call ungetService, do
+   * we call getService the right number of times.
+   */
+  @Test
+  public void getAService()
+  {
+    Bundle b = Skeleton.newMock(new BundleMock("scooby.doo", new Properties()), Bundle.class);
+    
+    Skeleton skel = Skeleton.getSkeleton(b);
+    
+    Thread.currentThread().setContextClassLoader(((BundleMock)skel.getTemplateObject()).getClassLoader());
+    
+    skel = Skeleton.getSkeleton(b.getBundleContext());
+
+    Object retrievedService = ServiceHelper.getService("java.lang.Runnable", null);
+    
+    assertNotNull("We could not locate the service in the registry", retrievedService);
+    
+    assertTrue("We didn't get back the service we expected", service == retrievedService);
+    
+    MethodCall getService = new MethodCall(BundleContext.class, "getService", ServiceReference.class);
+    MethodCall ungetService = new MethodCall(BundleContext.class, "ungetService", ServiceReference.class);
+    
+    skel.assertNotCalled(ungetService);
+    skel.assertCalledExactNumberOfTimes(getService, 1);
+
+    Object retrievedService2 = ServiceHelper.getService("java.lang.Runnable", null);
+
+    assertTrue("We got different objects, which we did not want", retrievedService == retrievedService2);
+    skel.assertCalledExactNumberOfTimes(getService, 2);
+    skel.assertCalledExactNumberOfTimes(ungetService, 1);
+  }
+  
+  /**
+   * This method checks that we get two different services from different
+   * bundles if the thread context classloader is different.
+   */
+  @Test
+  public void getAServiceFromTwoDifferentApplications()
+  {
+    Bundle b = Skeleton.newMock(new BundleMock("scooby.doo", new Properties()), Bundle.class);
+    
+    Skeleton skel = Skeleton.getSkeleton(b);
+    
+    Thread.currentThread().setContextClassLoader(((BundleMock)skel.getTemplateObject()).getClassLoader());
+    
+    Object retrievedService = ServiceHelper.getService("java.lang.Runnable", null);
+    Bundle b2 = Skeleton.newMock(new BundleMock("scooby.doo", new Properties()), Bundle.class);
+    
+    skel = Skeleton.getSkeleton(b2);
+    
+    Thread.currentThread().setContextClassLoader(((BundleMock)skel.getTemplateObject()).getClassLoader());
+    Object retrievedService2 = ServiceHelper.getService("java.lang.Runnable", null);
+    
+    assertNotNull("We could not locate the service in the registry", retrievedService);
+    assertNotNull("We could not locate the service in the registry", retrievedService2);
+    
+    assertTrue("We got different objects, which we did not want", retrievedService == retrievedService2);
+    
+    assertFalse("We expected different bundles from our calls to the BundleMaker, but we got the same one", b == b2);
+    
+    MethodCall getService = new MethodCall(BundleContext.class, "getService", ServiceReference.class);
+    Skeleton.getSkeleton(b.getBundleContext()).assertCalledExactNumberOfTimes(getService, 1);
+    Skeleton.getSkeleton(b2.getBundleContext()).assertCalledExactNumberOfTimes(getService, 1);
+  }
+  
+  /**
+   * This test checks that the getServices method returns the expected number of
+   * services, and that it changes when new services are registered.
+   */
+  @Test
+  public void getMultipleServices()
+  {
+    Bundle b = Skeleton.newMock(new BundleMock("scooby.doo", new Properties()), Bundle.class);
+    
+    Skeleton skel = Skeleton.getSkeleton(b);
+    
+    Thread.currentThread().setContextClassLoader(((BundleMock)skel.getTemplateObject()).getClassLoader());
+    
+    MethodCall getService = new MethodCall(BundleContext.class, "getService", ServiceReference.class);
+    MethodCall ungetService = new MethodCall(BundleContext.class, "ungetService", ServiceReference.class);
+    
+    List<?> services = ServiceHelper.getServices("java.lang.Runnable", null);
+
+    skel = Skeleton.getSkeleton(b.getBundleContext());
+
+    skel.assertNotCalled(ungetService);
+    skel.assertCalledExactNumberOfTimes(getService, 1);
+
+    assertEquals("At this point we really should only have one service.", 1, services.size());
+    Thread anotherService = new Thread();
+    registerService(anotherService);
+    
+    services = ServiceHelper.getServices("java.lang.Runnable", null);
+    
+    assertEquals("At this point we really should have two services.", 2, services.size());
+    assertTrue("The master service was not there, odd.", services.contains(service));
+    assertTrue("The service we added just for this test was not there, odd.", services.contains(anotherService));
+    
+    // this should be 3 times, once for the first call to getServices, and twice for the second
+    skel.assertCalledExactNumberOfTimes(getService, 3);
+    skel.assertCalledExactNumberOfTimes(ungetService, 1);
+  }
+}
\ No newline at end of file

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceRegistryContextTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceRegistryContextTest.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceRegistryContextTest.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceRegistryContextTest.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,339 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.jndi.url;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.spi.ObjectFactory;
+
+import mocks.BundleContextMock;
+import mocks.BundleMock;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import com.ibm.aries.unittest.mocks.MethodCall;
+import com.ibm.aries.unittest.mocks.Skeleton;
+import com.ibm.osgi.jndi.ContextHelper;
+import com.ibm.osgi.jndi.OSGiObjectFactoryBuilder;
+import com.ibm.osgi.jndi.services.ServiceHelper;
+import com.ibm.osgi.jndi.url.Activator;
+
+/**
+ * Tests for our JNDI implementation for the service registry.
+ */
+public class ServiceRegistryContextTest
+{
+  /** The service we register by default */
+  private Thread service;
+  /** The bundle context for the test */
+  private BundleContext bc;
+  /** The service registration for the service */
+  private ServiceRegistration reg;
+  
+  /**
+   * This method does the setup to ensure we always have a service.
+   * @throws NamingException 
+   * @throws NoSuchFieldException 
+   * @throws SecurityException 
+   * @throws IllegalAccessException 
+   * @throws IllegalArgumentException 
+   */
+  @Before
+  public void registerService() throws NamingException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException 
+  {
+    bc =  Skeleton.newMock(new BundleContextMock(), BundleContext.class);
+    new Activator().start(bc);
+    new com.ibm.osgi.jndi.startup.Activator().start(bc);
+    
+    Field f = ServiceHelper.class.getDeclaredField("context");
+    f.setAccessible(true);
+    f.set(null, bc);
+    f = ContextHelper.class.getDeclaredField("context");
+    f.setAccessible(true);
+    f.set(null, bc);
+    f = OSGiObjectFactoryBuilder.class.getDeclaredField("context");
+    f.setAccessible(true);
+    f.set(null, bc);
+
+
+    service = new Thread();
+    
+    registerService(service);
+  }
+  
+  /**
+   * Register a service in our map.
+   * 
+   * @param service2 The service to register.
+   */
+  private void registerService(Thread service2)
+  {
+    ServiceFactory factory = Skeleton.newMock(ServiceFactory.class);
+    Skeleton skel = Skeleton.getSkeleton(factory);
+    
+    skel.setReturnValue(new MethodCall(ServiceFactory.class, "getService", Bundle.class, ServiceRegistration.class), service2);
+    
+    Hashtable<String, String> props = new Hashtable<String, String>();
+    props.put("rubbish", "smelly");
+    
+    reg = bc.registerService(new String[] {"java.lang.Runnable"}, factory, props);
+  }
+  
+  /**
+   * Make sure we clear the caches out before the next test.
+   */
+  @After
+  public void teardown()
+  {
+    BundleContextMock.clear();
+    
+    Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
+  }
+  
+  /**
+   * This test checks that we correctly register and deregister the url context
+   * object factory in the service registry.
+   */
+  @Test
+  public void testJNDIRegistration()
+  {
+    ServiceReference ref = bc.getServiceReference(ObjectFactory.class.getName());
+    
+    assertNotNull("The aries url context object factory was not registered", ref);
+    
+    ObjectFactory factory = (ObjectFactory) bc.getService(ref);
+    
+    assertNotNull("The aries url context object factory was null", factory);
+  }
+  
+  /**
+   * This test does a simple JNDI lookup to prove that works.
+   * @throws NamingException
+   */
+  @Test
+  public void simpleJNDILookup() throws NamingException
+  {
+    System.setProperty(Context.URL_PKG_PREFIXES, "helloMatey");
+        
+    InitialContext ctx = new InitialContext(new Hashtable<Object, Object>());
+    
+    BundleMock mock = new BundleMock("scooby.doo", new Properties());
+    
+    Thread.currentThread().setContextClassLoader(mock.getClassLoader());
+    
+    Object s = ctx.lookup("aries:services/java.lang.Runnable");
+    
+    assertNotNull("We didn't get a service back from our lookup :(", s);
+    
+    assertEquals("The SR did not return the object we expected", service, s);
+    
+    Skeleton skel = Skeleton.getSkeleton(mock.getBundleContext());
+    
+    skel.assertCalled(new MethodCall(BundleContext.class, "getAllServiceReferences", "java.lang.Runnable", null));
+
+    mock = new BundleMock("scooby.doo", new Properties());
+    
+    Thread.currentThread().setContextClassLoader(mock.getClassLoader());
+
+    s = ctx.lookup("osgi:services/java.lang.Runnable");
+    
+    // Check we have the packages set correctly
+    
+    String packages = System.getProperty(Context.URL_PKG_PREFIXES, null);
+    
+    assertTrue(ctx.getEnvironment().containsValue(packages));
+
+    
+    assertNotNull("We didn't get a service back from our lookup :(", s);
+    
+    assertEquals("The SR did not return the object we expected", service, s);
+
+    skel = Skeleton.getSkeleton(mock.getBundleContext());
+    skel.assertCalled(new MethodCall(BundleContext.class, "getAllServiceReferences", "java.lang.Runnable", null));
+  }
+
+  /**
+   * This test checks that we can pass a filter in without things blowing up.
+   * Right now our mock service registry does not implement filtering, so the
+   * effect is the same as simpleJNDILookup, but we at least know it is not
+   * blowing up.
+   * 
+   * @throws NamingException
+   */
+  @Test
+  public void jndiLookupWithFilter() throws NamingException
+  {
+    InitialContext ctx = new InitialContext();
+    
+    Object s = ctx.lookup("aries:services/java.lang.Runnable/(rubbish=smelly)");
+    
+    assertNotNull("We didn't get a service back from our lookup :(", s);
+    
+    assertEquals("The SR did not return the object we expected", service, s);
+    
+    Skeleton.getSkeleton(bc).assertCalled(new MethodCall(BundleContext.class, "getAllServiceReferences", "java.lang.Runnable", "(rubbish=smelly)"));
+  }
+  
+  /**
+   * Check that we get a NameNotFoundException if we lookup after the service
+   * has been unregistered.
+   * 
+   * @throws NamingException
+   */
+  @Test(expected=NameNotFoundException.class)
+  public void testLookupWhenServiceHasBeenRemoved() throws NamingException
+  {
+    reg.unregister();
+    InitialContext ctx = new InitialContext();
+    
+    ctx.lookup("aries:services/java.lang.Runnable");
+  }
+  
+  /**
+   * Check that we get a NameNotFoundException if we lookup something not in the
+   * registry.
+   * 
+   * @throws NamingException
+   */
+  @Test(expected=NameNotFoundException.class)
+  public void testLookupForServiceWeNeverHad() throws NamingException
+  {
+    InitialContext ctx = new InitialContext();
+    
+    ctx.lookup("aries:services/java.lang.Integer");
+  }
+  
+  /**
+   * This test checks that we can list the contents of the repository using the
+   * list method
+   * 
+   * @throws NamingException
+   */
+  @Test
+  public void listRepositoryContents() throws NamingException
+  {
+    InitialContext ctx = new InitialContext();
+    
+    NamingEnumeration<NameClassPair> serviceList = ctx.list("aries:services/java.lang.Runnable/(rubbish=smelly)");
+    
+    checkThreadRetrievedViaListMethod(serviceList);
+    
+    assertFalse("The repository contained more objects than we expected", serviceList.hasMoreElements());
+    
+    //Now add a second service
+    
+    registerService(new Thread());
+    
+    serviceList = ctx.list("aries:services/java.lang.Runnable/(rubbish=smelly)");
+    
+    checkThreadRetrievedViaListMethod(serviceList);
+    
+    checkThreadRetrievedViaListMethod(serviceList);
+    
+    assertFalse("The repository contained more objects than we expected", serviceList.hasMoreElements());
+    
+  }
+
+  /**
+   * Check that the NamingEnumeration passed in has another element, which represents a java.lang.Thread
+   * @param serviceList
+   * @throws NamingException
+   */
+  private void checkThreadRetrievedViaListMethod(NamingEnumeration<NameClassPair> serviceList)
+      throws NamingException
+  {
+    assertTrue("The repository was empty", serviceList.hasMoreElements());
+    
+    NameClassPair ncp = serviceList.next();
+    
+    assertNotNull("We didn't get a service back from our lookup :(", ncp);
+    
+    assertNotNull("The object from the SR was null", ncp.getClassName());
+    
+    assertEquals("The service retrieved was not of the correct type", "java.lang.Thread", ncp.getClassName());
+    
+    assertEquals("aries:services/java.lang.Runnable/(rubbish=smelly)", ncp.getName().toString());
+  }
+  
+  /**
+   * This test checks that we can list the contents of the repository using the
+   * list method
+   * 
+   * @throws NamingException
+   */
+  @Test
+  public void listRepositoryBindings() throws NamingException
+  {
+    InitialContext ctx = new InitialContext();
+    
+    NamingEnumeration<Binding> serviceList = ctx.listBindings("aries:services/java.lang.Runnable/(rubbish=smelly)");
+    
+    Object returnedService = checkThreadRetrievedViaListBindingsMethod(serviceList);
+    
+    assertFalse("The repository contained more objects than we expected", serviceList.hasMoreElements());
+    
+    assertTrue("The returned service was not the service we expected", returnedService == service);
+    
+    //Now add a second service
+    Thread secondService = new Thread();
+    registerService(secondService);
+    
+    serviceList = ctx.listBindings("aries:services/java.lang.Runnable/(rubbish=smelly)");
+    
+    Object returnedService1 = checkThreadRetrievedViaListBindingsMethod(serviceList);
+    
+    Object returnedService2 = checkThreadRetrievedViaListBindingsMethod(serviceList);
+    
+    assertFalse("The repository contained more objects than we expected", serviceList.hasMoreElements());
+    
+    assertTrue("The services were not the ones we expected!",(returnedService1 == service || returnedService2 == service) && (returnedService1 == secondService || returnedService2 == secondService) && (returnedService1 != returnedService2));
+    
+  }
+
+  /**
+   * Check that the NamingEnumeration passed in has another element, which represents a java.lang.Thread
+   * @param serviceList
+   * @return the object in the registry
+   * @throws NamingException
+   */
+  private Object checkThreadRetrievedViaListBindingsMethod(NamingEnumeration<Binding> serviceList)
+      throws NamingException
+  {
+    assertTrue("The repository was empty", serviceList.hasMoreElements());
+    
+    Binding binding = serviceList.nextElement();
+    
+    assertNotNull("We didn't get a service back from our lookup :(", binding);
+    
+    assertNotNull("The object from the SR was null", binding.getObject());
+    
+    assertTrue("The service retrieved was not of the correct type", binding.getObject() instanceof Thread);
+    
+    assertEquals("aries:services/java.lang.Runnable/(rubbish=smelly)", binding.getName().toString());
+    
+    return binding.getObject();
+  }
+  
+}
\ No newline at end of file

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceRegistryNameParserTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceRegistryNameParserTest.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceRegistryNameParserTest.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi.url/unittest/com/ibm/osgi/jndi/url/ServiceRegistryNameParserTest.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,79 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.jndi.url;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingException;
+
+import org.junit.Test;
+
+/**
+ * This is where we test the service registry name parser.
+ */
+public class ServiceRegistryNameParserTest
+{
+  /** The parser we are going to use for testing */
+  private NameParser parser = new ServiceRegistryNameParser();
+
+  /**
+   * OK, so we check that we can call checkNames multiple times.
+   * @throws NamingException
+   */
+  @Test
+  public void checkValidNames() throws NamingException
+  {
+    checkName("aries:services/java.lang.Runnable/(a=b)");
+    checkName("aries:services/java.lang.Runnable");
+  }
+  
+  /**
+   * Make sure it fails if we try to parse something that isn't in aries:services
+   * @throws NamingException
+   */
+  @Test(expected=InvalidNameException.class)
+  public void checkOutsideNamespace() throws NamingException
+  {
+    checkName("java:comp/env/jms/cf");
+  }
+  
+  /**
+   * Check that it fails if no interface name is provided.
+   * @throws NamingException
+   */
+  @Test(expected=InvalidNameException.class)
+  public void checkMissingInterface() throws NamingException
+  {
+    checkName("aries:services");
+  }
+  
+  /**
+   * Check that it fails if no interface name is provided in a subtly different
+   * way from the previous method.
+   * @throws NamingException
+   */
+  @Test(expected=InvalidNameException.class)
+  public void checkMissingInterface2() throws NamingException
+  {
+    checkName("aries:services/");
+  }
+
+  /**
+   * This method parses the name and then makes sure what was parsed was parsed
+   * correctly.
+   * 
+   * @param name
+   * @throws NamingException
+   */
+  private void checkName(String name) throws NamingException
+  {
+    Name n = parser.parse(name);
+    assertNotNull("We got a null name back, which is not allowed.", n);
+    assertEquals("The name's toString does not produce the original value", name, n.toString());
+  }
+}
\ No newline at end of file

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.aries
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.aries?rev=820722&view=auto
==============================================================================
    (empty)

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.classpath
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.classpath?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.classpath (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.classpath Thu Oct  1 17:19:13 2009
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="unittest"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/unittest.framework"/>
+	<classpathentry kind="output" path="build/classes"/>
+</classpath>

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.fbprefs
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.fbprefs?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.fbprefs (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.fbprefs Thu Oct  1 17:19:13 2009
@@ -0,0 +1,156 @@
+#FindBugs User Preferences
+#Tue Oct 21 11:41:34 BST 2008
+detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
+detectorBCPMethodReturnCheck=BCPMethodReturnCheck|false
+detectorBadAppletConstructor=BadAppletConstructor|false
+detectorBadResultSetAccess=BadResultSetAccess|true
+detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
+detectorBadUseOfReturnValue=BadUseOfReturnValue|true
+detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
+detectorBooleanReturnNull=BooleanReturnNull|true
+detectorBuildInterproceduralCallGraph=BuildInterproceduralCallGraph|false
+detectorBuildObligationPolicyDatabase=BuildObligationPolicyDatabase|true
+detectorCallToUnsupportedMethod=CallToUnsupportedMethod|true
+detectorCalledMethods=CalledMethods|true
+detectorCheckCalls=CheckCalls|false
+detectorCheckExpectedWarnings=CheckExpectedWarnings|false
+detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
+detectorCheckTypeQualifiers=CheckTypeQualifiers|true
+detectorCloneIdiom=CloneIdiom|true
+detectorComparatorIdiom=ComparatorIdiom|true
+detectorConfusedInheritance=ConfusedInheritance|true
+detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
+detectorCrossSiteScripting=CrossSiteScripting|true
+detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
+detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
+detectorDontUseEnum=DontUseEnum|true
+detectorDroppedException=DroppedException|true
+detectorDumbMethodInvocations=DumbMethodInvocations|true
+detectorDumbMethods=DumbMethods|true
+detectorDuplicateBranches=DuplicateBranches|true
+detectorEmptyZipFileEntry=EmptyZipFileEntry|true
+detectorEqStringTest=EqStringTest|false
+detectorFieldItemSummary=FieldItemSummary|true
+detectorFinalizerNullsFields=FinalizerNullsFields|true
+detectorFindBadCast=FindBadCast|false
+detectorFindBadCast2=FindBadCast2|true
+detectorFindBadEqualsImplementation=FindBadEqualsImplementation|false
+detectorFindBadForLoop=FindBadForLoop|true
+detectorFindBugsSummaryStats=FindBugsSummaryStats|true
+detectorFindCircularDependencies=FindCircularDependencies|false
+detectorFindDeadLocalStores=FindDeadLocalStores|true
+detectorFindDoubleCheck=FindDoubleCheck|true
+detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
+detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
+detectorFindFinalizeInvocations=FindFinalizeInvocations|true
+detectorFindFloatEquality=FindFloatEquality|true
+detectorFindFloatMath=FindFloatMath|false
+detectorFindHEmismatch=FindHEmismatch|true
+detectorFindInconsistentSync2=FindInconsistentSync2|true
+detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
+detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
+detectorFindMaskedFields=FindMaskedFields|true
+detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
+detectorFindNakedNotify=FindNakedNotify|true
+detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true
+detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true
+detectorFindNonShortCircuit=FindNonShortCircuit|true
+detectorFindNullDeref=FindNullDeref|true
+detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
+detectorFindOpenStream=FindOpenStream|true
+detectorFindPuzzlers=FindPuzzlers|true
+detectorFindRefComparison=FindRefComparison|true
+detectorFindReturnRef=FindReturnRef|true
+detectorFindRunInvocations=FindRunInvocations|true
+detectorFindSelfComparison=FindSelfComparison|true
+detectorFindSelfComparison2=FindSelfComparison2|true
+detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
+detectorFindSpinLoop=FindSpinLoop|true
+detectorFindSqlInjection=FindSqlInjection|true
+detectorFindTwoLockWait=FindTwoLockWait|true
+detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
+detectorFindUnconditionalWait=FindUnconditionalWait|true
+detectorFindUninitializedGet=FindUninitializedGet|true
+detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
+detectorFindUnreleasedLock=FindUnreleasedLock|true
+detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
+detectorFindUnsyncGet=FindUnsyncGet|true
+detectorFindUselessControlFlow=FindUselessControlFlow|true
+detectorFormatStringChecker=FormatStringChecker|true
+detectorHugeSharedStringConstants=HugeSharedStringConstants|true
+detectorIDivResultCastToDouble=IDivResultCastToDouble|true
+detectorIncompatMask=IncompatMask|true
+detectorInconsistentAnnotations=InconsistentAnnotations|true
+detectorInefficientMemberAccess=InefficientMemberAccess|false
+detectorInefficientToArray=InefficientToArray|true
+detectorInfiniteLoop=InfiniteLoop|true
+detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
+detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false
+detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
+detectorInitializationChain=InitializationChain|true
+detectorInstantiateStaticClass=InstantiateStaticClass|true
+detectorInvalidJUnitTest=InvalidJUnitTest|true
+detectorIteratorIdioms=IteratorIdioms|true
+detectorLazyInit=LazyInit|true
+detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
+detectorLockedFields=LockedFields|false
+detectorMethodReturnCheck=MethodReturnCheck|true
+detectorMethods=Methods|true
+detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
+detectorMutableLock=MutableLock|true
+detectorMutableStaticFields=MutableStaticFields|true
+detectorNaming=Naming|true
+detectorNoteAnnotationRetention=NoteAnnotationRetention|true
+detectorNoteCheckReturnValue=NoteCheckReturnValue|true
+detectorNoteCheckReturnValueAnnotations=NoteCheckReturnValueAnnotations|true
+detectorNoteDirectlyRelevantTypeQualifiers=NoteDirectlyRelevantTypeQualifiers|true
+detectorNoteJCIPAnnotation=NoteJCIPAnnotation|true
+detectorNoteNonNullAnnotations=NoteNonNullAnnotations|true
+detectorNoteNonnullReturnValues=NoteNonnullReturnValues|true
+detectorNoteSuppressedWarnings=NoteSuppressedWarnings|true
+detectorNoteUnconditionalParamDerefs=NoteUnconditionalParamDerefs|true
+detectorNumberConstructor=NumberConstructor|true
+detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
+detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
+detectorPublicSemaphores=PublicSemaphores|false
+detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
+detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
+detectorRedundantInterfaces=RedundantInterfaces|true
+detectorReflectiveClasses=ReflectiveClasses|true
+detectorRepeatedConditionals=RepeatedConditionals|true
+detectorResolveAllReferences=ResolveAllReferences|false
+detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
+detectorSerializableIdiom=SerializableIdiom|true
+detectorStartInConstructor=StartInConstructor|true
+detectorStaticCalendarDetector=StaticCalendarDetector|true
+detectorStringConcatenation=StringConcatenation|true
+detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
+detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
+detectorSwitchFallthrough=SwitchFallthrough|true
+detectorSynchronizationOnSharedBuiltinConstant=SynchronizationOnSharedBuiltinConstant|true
+detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
+detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
+detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
+detectorTestASM=TestASM|false
+detectorTestDataflowAnalysis=TestDataflowAnalysis|false
+detectorTestingGround=TestingGround|false
+detectorTrainFieldStoreTypes=TrainFieldStoreTypes|true
+detectorTrainNonNullAnnotations=TrainNonNullAnnotations|true
+detectorTrainUnconditionalDerefParams=TrainUnconditionalDerefParams|true
+detectorURLProblems=URLProblems|true
+detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
+detectorUnnecessaryMath=UnnecessaryMath|true
+detectorUnreadFields=UnreadFields|true
+detectorUseObjectEquals=UseObjectEquals|false
+detectorUselessSubclassMethod=UselessSubclassMethod|false
+detectorVarArgsProblems=VarArgsProblems|true
+detectorVolatileUsage=VolatileUsage|true
+detectorWaitInLoop=WaitInLoop|true
+detectorWrongMapIterator=WrongMapIterator|true
+detectorXMLFactoryBypass=XMLFactoryBypass|true
+detector_threshold=2
+effort=default
+excludefilter0=findbugs.exclude.xml
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,I18N,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false
+filter_settings_neg=|
+run_at_full_build=true

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.project
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.project?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.project (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi/.project Thu Oct  1 17:19:13 2009
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>com.ibm.osgi.jndi</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/META-INF/MANIFEST.MF?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi/META-INF/MANIFEST.MF (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi/META-INF/MANIFEST.MF Thu Oct  1 17:19:13 2009
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Helpers for bridging between non-OSGi and OSGi modules.
+Bundle-SymbolicName: com.ibm.osgi.jndi
+Bundle-Version: 1.0.0
+Bundle-Activator: com.ibm.osgi.jndi.startup.Activator
+Bundle-Vendor: IBM
+Import-Package: javax.naming.spi,
+ org.osgi.framework;version="1.3.0"
+Export-Package: com.ibm.osgi.jndi

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/build.properties
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/build.properties?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi/build.properties (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi/build.properties Thu Oct  1 17:19:13 2009
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/build.xml
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/build.xml?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi/build.xml (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi/build.xml Thu Oct  1 17:19:13 2009
@@ -0,0 +1,8 @@
+<!-- (C) Copyright IBM Corp. 2009 -->
+
+<project name="com.ibm.osgi.jndi" default="build" basedir=".">
+  <property name="aries.image" value="true"/>
+  <property name="pluginDirs" value="../prereqs/osgi/lib"/>
+  <property name="image.dir" value="waslib"/>
+  <import file="../build/imports/standard_imports.xml"/>
+</project>
\ No newline at end of file

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/findbugs.exclude.xml
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/findbugs.exclude.xml?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi/findbugs.exclude.xml (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi/findbugs.exclude.xml Thu Oct  1 17:19:13 2009
@@ -0,0 +1,11 @@
+<!-- (C) Copyright IBM Corp. 2009 -->
+
+<FindBugsFilter>
+   <!-- See http://findbugs.sourceforge.net/manual/filter.html for details of the syntax of this file -->
+   <Match>
+     <Package name="com.ibm.ws.osgi.helpers.test"/>
+   </Match>
+   <Match>
+     <Package name="com.ibm.ws.osgi.jndi.test"/>
+   </Match>
+</FindBugsFilter>
\ No newline at end of file

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/src/com/ibm/osgi/jndi/Constants.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/src/com/ibm/osgi/jndi/Constants.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi/src/com/ibm/osgi/jndi/Constants.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi/src/com/ibm/osgi/jndi/Constants.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,9 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.jndi;
+
+public class Constants {
+  public static final String OSGI_JNDI_FILTER_NAME = "osgi.jndi.serviceName";
+
+}

Added: incubator/aries/contrib/ibm/com.ibm.osgi.jndi/src/com/ibm/osgi/jndi/ContextHelper.java
URL: http://svn.apache.org/viewvc/incubator/aries/contrib/ibm/com.ibm.osgi.jndi/src/com/ibm/osgi/jndi/ContextHelper.java?rev=820722&view=auto
==============================================================================
--- incubator/aries/contrib/ibm/com.ibm.osgi.jndi/src/com/ibm/osgi/jndi/ContextHelper.java (added)
+++ incubator/aries/contrib/ibm/com.ibm.osgi.jndi/src/com/ibm/osgi/jndi/ContextHelper.java Thu Oct  1 17:19:13 2009
@@ -0,0 +1,237 @@
+/*
+ * (C) Copyright IBM Corp. 2009
+ */
+package com.ibm.osgi.jndi;
+
+import java.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.NoInitialContextException;
+import javax.naming.spi.InitialContextFactory;
+import javax.naming.spi.InitialContextFactoryBuilder;
+import javax.naming.spi.ObjectFactory;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Provides helper methods for the DelegateContext. This provides the methods so
+ * there can be many DelegateContexts, but few service trackers.
+ */
+public final class ContextHelper
+{
+	/** The bundle context we use for accessing the SR */
+  private static BundleContext context;
+  
+  /** Ensure no one constructs us */
+  private ContextHelper() { throw new RuntimeException(); }
+  
+  public static void setBundleContext(BundleContext ctx)
+  {
+  	context = ctx;
+  }
+  
+  /**
+   * This class creates a Context from an InitialContextFactory that may be
+   * named in the provided env. If no name is set the first InitialContextFactory
+   * returned from the service registry is used.
+   * 
+   * @param env
+   * @return the context.
+   * @throws NamingException
+   */
+  public static Context createContext(Hashtable<?,?> env)
+    throws NamingException
+  {
+  	
+    InitialContextFactory icf = null;
+    ServiceReference ref = null;
+
+    String icfFactory = (String) env.get(Context.INITIAL_CONTEXT_FACTORY);
+    
+    boolean icfFactorySet = true;
+
+    if (icfFactory == null) {
+      icfFactory = InitialContextFactory.class.getName();
+      icfFactorySet = false;
+    }
+    
+    try {
+      ServiceReference[] refs = context.getAllServiceReferences(icfFactory, null);
+      if (refs != null) {
+        ref = refs[0];
+        icf = (InitialContextFactory) context.getService(ref);
+      }
+    } catch (InvalidSyntaxException e) {
+      // TODO nls enable this.
+      NamingException e4 = new NamingException("Argh this should never happen :)");
+      e4.initCause(e);
+      
+      throw e4;
+    }
+
+    if (icf == null) {
+      try {
+        ServiceReference[] refs = context.getAllServiceReferences(InitialContextFactoryBuilder.class.getName(), null);
+
+        if (refs != null) {
+          for (ServiceReference icfbRef : refs) {
+            InitialContextFactoryBuilder builder = (InitialContextFactoryBuilder) context.getService(icfbRef);
+
+            icf = builder.createInitialContextFactory(env);
+            
+            context.ungetService(icfbRef);
+            if (icf != null) {
+              break;
+            }
+          }
+        }
+      } catch (InvalidSyntaxException e) {
+        // TODO nls enable this.
+        NamingException e4 = new NamingException("Argh this should never happen :)");
+        e4.initCause(e);    
+        throw e4;
+      }
+    }
+
+    if (icf == null && icfFactorySet) {
+      try {
+        Class<?> clazz = Class.forName(icfFactory, true, null);
+        icf = (InitialContextFactory) clazz.newInstance();
+      } catch (ClassNotFoundException e11) {
+        // TODO nls enable this.
+        NamingException e = new NamingException("Argh this should never happen :)");
+        e.initCause(e11);    
+        throw e;
+      } catch (InstantiationException e2) {
+        // TODO nls enable this.
+        NamingException e4 = new NamingException("Argh this should never happen :)");
+        e4.initCause(e2);    
+        throw e4;
+      } catch (IllegalAccessException e1) {
+        // TODO nls enable this.
+        NamingException e4 = new NamingException("Argh this should never happen :)");
+        e4.initCause(e1);    
+        throw e4;
+      }
+    }
+
+    if (icf == null) {
+
+      // TODO nls enable this.
+      NamingException e3 = new NoInitialContextException("We could not find an InitialContextFactory to use");
+      
+      throw e3;
+    }
+
+    Context ctx = icf.getInitialContext(env);
+
+    if (ref != null) context.ungetService(ref);
+
+    if (ctx == null) {
+      // TODO nls enable this
+      NamingException e = new NamingException("The ICF returned a null context");
+      throw e;
+    }
+
+    return ctx;
+  }
+  
+  
+  private static Context createIcfContext(Hashtable<?,?> env) throws NamingException
+  {
+    String icfFactory = (String) env.get(Context.INITIAL_CONTEXT_FACTORY);
+    InitialContextFactory icf = null;
+
+    if (icfFactory != null) {
+      try {
+        Class<?> clazz = Class.forName(icfFactory, true, Thread.currentThread()
+            .getContextClassLoader());
+        icf = (InitialContextFactory) clazz.newInstance();
+
+      } catch (ClassNotFoundException e11) {
+        NamingException e4 = new NamingException("Argh this should never happen :)");
+        e4.initCause(e11);
+        throw e4;
+      } catch (InstantiationException e2) {
+        NamingException e4 = new NamingException("Argh this should never happen :)");
+        e4.initCause(e2);
+        throw e4;
+      } catch (IllegalAccessException e1) {
+        NamingException e4 = new NamingException("Argh this should never happen :)");
+        e4.initCause(e1);
+        throw e4;
+      }
+    }
+    Context ctx = null;
+
+    if (icf != null) {
+      ctx = icf.getInitialContext(env);
+    }    
+    
+    return ctx;
+  }
+  
+  /**
+   * This method is used to create a URL Context. It does this by looking for 
+   * the URL context's ObjectFactory in the service registry.
+   * 
+   * @param urlScheme
+   * @param env
+   * @return a Context
+   * @throws NamingException
+   */
+  public static Context createURLContext(String urlScheme, Hashtable<?, ?> env)
+      throws NamingException
+  {
+    ObjectFactory factory = null;
+    ServiceReference ref = null;
+
+    Context ctx = null;
+
+    try {
+      ServiceReference[] services = context.getServiceReferences(ObjectFactory.class.getName(),
+          "(|(osgi.jndi.urlScheme=" + urlScheme + ")(urlScheme=" + urlScheme + "))");
+
+      if (services != null) {
+        ref = services[0];
+        factory = (ObjectFactory) context.getService(ref);
+      }
+    } catch (InvalidSyntaxException e1) {
+      // TODO nls enable this.
+      NamingException e = new NamingException("Argh this should never happen :)");
+      e.initCause(e1);
+      throw e;
+    }
+
+    if (factory != null) {
+      try {
+        ctx = (Context) factory.getObjectInstance(null, null, null, env);
+      } catch (Exception e) {
+        NamingException e2 = new NamingException();
+        e2.initCause(e);
+        throw e2;
+      } finally {
+        if (ref != null) context.ungetService(ref);
+      }
+    }
+
+    // TODO: This works for WAS - we believe - but is incorrect behaviour. We should not use an icf to generate the URLContext.
+    // Rather, the missing URLContext factories should be exported on behalf of WAS.
+    if (ctx == null) {
+      ctx = createIcfContext(env);
+    }
+    
+    if (ctx == null && factory == null) {
+      NamingException e = new NamingException("We could not find an ObjectFactory to use");
+      throw e;
+    } else if (ctx == null && factory != null) {
+      NamingException e = new NamingException("The ICF returned a null context");
+      throw e;
+    }
+
+    return ctx;
+  }
+}
\ No newline at end of file