geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rickmcgu...@apache.org
Subject svn commit: r919392 [1/2] - in /geronimo/specs/trunk/geronimo-osgi-support: ./ geronimo-osgi-locator-itests/ geronimo-osgi-locator-itests/src/ geronimo-osgi-locator-itests/src/test/ geronimo-osgi-locator-itests/src/test/java/ geronimo-osgi-locator-ites...
Date Fri, 05 Mar 2010 12:42:26 GMT
Author: rickmcguire
Date: Fri Mar  5 12:42:25 2010
New Revision: 919392

URL: http://svn.apache.org/viewvc?rev=919392&view=rev
Log:
GERONIMO-5133 Geroinimo versions of the specs should pick up the additions made to the service mix versions of the bundles. 

The original commit had a problem when used outside of an OSGi environment because it used an OSGi framework class directly. 
This fixes that problem, and reorganizes this into subprojects so that the tests can be run with the 
appropriate classpath to ensure this code is working correctly. 


Added:
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/pom.xml   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/registry/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/pom.xml   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/Activator.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/Activator.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/api/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/pom.xml   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorTest.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget2.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget3.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTargetTwo.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/resources/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/resources/test/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/resources/test/OSGI-INF/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/resources/test/OSGI-INF/providers/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/resources/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.DefaultTarget
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/resources/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.MultipleTarget
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/resources/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/resources/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget2
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/pom.xml   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/locator/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/locator/Activator.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/registry/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/registry/Activator.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java   (with props)
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/registry/api/
    geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java   (with props)
Removed:
    geronimo/specs/trunk/geronimo-osgi-support/src/
Modified:
    geronimo/specs/trunk/geronimo-osgi-support/pom.xml

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/pom.xml?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/pom.xml (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/pom.xml Fri Mar  5 12:42:25 2010
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.geronimo.specs</groupId>
+        <artifactId>geronimo-osgi-support</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.geronimo.specs</groupId>
+    <artifactId>geronimo-osgi-locator-itests</artifactId>
+
+    <description>
+This project contains integration tests to ensure that the code
+in the locator will function correctly if used outside of an OSGi framework.
+These tests will have no dependnecies on any OSGi classes when run, and should
+function without error.
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-osgi-locator</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
+                    <failIfNoTests>false</failIfNoTests>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/pom.xml
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.geronimo.osgi.registry;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+
+import org.apache.geronimo.osgi.locator.ProviderLocator;
+
+public class NonOSGiLocatorTest {
+    @Test
+    public void testLocator() throws Exception {
+        // this is verifying that the ProviderLocater can be called when used outside of
+        // an OSGi framework without causing an exception.  This will verify that the OSGi
+        // classes are not on the classpath before attempting this.
+        try {
+            this.getClass().getClassLoader().loadClass("org.osgi.util.tracker.ServiceTracker");
+            fail("OSGi framework classes must not be on the class path for this test");
+        } catch (ClassNotFoundException e) {
+            // this should happen if the test is run correctly.
+        }
+
+        // Run outside of an OSGi framework, this should just return null without
+        // causing an error
+        Class<?> target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.TestTarget");
+        assertNull(target);
+    }
+}

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator-itests/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/pom.xml?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/pom.xml (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/pom.xml Fri Mar  5 12:42:25 2010
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.geronimo.specs</groupId>
+        <artifactId>geronimo-osgi-support</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.geronimo.specs</groupId>
+    <artifactId>geronimo-osgi-locator</artifactId>
+    <packaging>bundle</packaging>
+    <name>Geronimo OSGi-enable spec bundle locator</name>
+    <version>1.0.0-SNAPSHOT</version>
+
+    <description>
+This bundle is not used as a standalone unit, but contains classes that
+should be copied into another bundle as a private package.
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-osgi-registry</artifactId>
+            <version>${version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>4.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <version>4.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Import-Package>*</Import-Package>
+                        <Private-Package>org.apache.geronimo.osgi.locator</Private-Package>
+                        <Bundle-SymbolicName>${groupId}.${artifactId};singleton=true</Bundle-SymbolicName>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/pom.xml
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/Activator.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/Activator.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/Activator.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/Activator.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.geronimo.osgi.locator;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+
+public class Activator implements BundleActivator {
+    private BundleContext bundleContext;
+
+    public synchronized void start(BundleContext bundleContext) throws Exception {
+        this.bundleContext = bundleContext;
+        // initialize the locator
+        ProviderLocator.init(bundleContext);
+    }
+
+    public synchronized void stop(BundleContext bundleContext) throws Exception {
+        // shut down the locator service
+        ProviderLocator.destroy();
+        this.bundleContext = null;
+    }
+
+    public void bundleChanged(BundleEvent event) {
+        // nothing to change here
+    }
+}

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/Activator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/Activator.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/Activator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,115 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.geronimo.osgi.locator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.geronimo.osgi.registry.api.ProviderRegistry;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ProviderLocator {
+    // our bundle context
+    static private BundleContext context;
+    // a service tracker for the registry service
+    // NB:  This is declared as just Object to avoid classloading issues if we're running
+    // outside of an OSGi environment.
+    static private Object registryTracker;
+
+    private ProviderLocator() {
+        // private constructor to prevent an instance from getting created.
+    }
+
+    /**
+     * initialize the tracker statics for this bundle
+     *
+     * @param c      The starup BundleContext.
+     */
+    public static void init(BundleContext c) {
+        context = c;
+        // just create a tracker for our lookup service
+        registryTracker = new ServiceTracker(context, ProviderRegistry.class.getName(), null);
+        ((ServiceTracker)registryTracker).open();
+    }
+
+
+    /**
+     * Cleanup resources on bundle shutdown.
+     */
+    public static void destroy() {
+        // shutdown our tracking of the provider registry.
+        ((ServiceTracker)registryTracker).close();
+        registryTracker = null;
+    }
+
+
+    /**
+     * Locate a class by its provider id indicator. .
+     *
+     * @param providerId The provider id (generally, a fully qualified class name).
+     *
+     * @return The Class corresponding to this provider id.  Returns null
+     *         if this is not registered or the indicated class can't be
+     *         loaded.
+     */
+    static public Class<?> locate(String providerId) {
+        // if not initialized in an OSGi environment, this is a failure
+        if (registryTracker == null) {
+            return null;
+        }
+        // get the service, if it exists.  NB:  if the tracker exists, then we
+        // were able to load the interface class in the first place, so we don't
+        // need to protect against that.
+        ProviderRegistry registry = (ProviderRegistry)((ServiceTracker)registryTracker).getService();
+        // it is also a failure if the service is not there.
+        if (registry == null) {
+            return null;
+        }
+        // the rest of the work is done by the registry
+        return registry.locate(providerId);
+    }
+
+    /**
+     * Locate all class files that match a given factory id.
+     *
+     * @param providerId The target provider identifier.
+     *
+     * @return A List containing the class objects corresponding to the
+     *         provider identifier.  Returns an empty list if no
+     *         matching classes can be located.
+     */
+    static public List<Class<?>> locateAll(String providerId) {
+        // if not initialized in an OSGi environment, this is a lookup failure
+        if (registryTracker == null) {
+            return new ArrayList<Class<?>>();
+        }
+        // get the service, if it exists.  NB:  if the tracker exists, then we
+        // were able to load the interface class in the first place, so we don't
+        // need to protect against that.
+        ProviderRegistry registry = (ProviderRegistry)((ServiceTracker)registryTracker).getService();
+        // it is also a failure if the service is not there.
+        if (registry == null) {
+            return new ArrayList<Class<?>>();
+        }
+        // the rest of the work is done by the registry
+        return registry.locateAll(providerId);
+    }
+}

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/Activator.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/Activator.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/Activator.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/Activator.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,119 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.geronimo.osgi.registry;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+import org.apache.geronimo.osgi.registry.api.ProviderRegistry;
+
+/**
+ * The activator that starts and manages the life-cycle of
+ * the class factory registry.
+ */
+public class Activator implements BundleActivator {
+    // tracker to watch for bundle updates
+    protected BundleTracker bt;
+    // service tracker for a logging service
+    protected ServiceTracker lst;
+    // Our provider registry
+    protected ProviderRegistryImpl registry;
+    // The service registration for the provider registry
+    protected ServiceRegistration registryRegistration;
+    // our bundle context
+    protected BundleContext context;
+    // an array of all active logging services.
+    List<LogService> logServices = new ArrayList<LogService>();
+
+
+    @Override
+    public synchronized void start(final BundleContext context) throws Exception {
+        this.context = context;
+        lst = new LogServiceTracker(context, LogService.class.getName(), null);
+        lst.open();
+
+        registry = new ProviderRegistryImpl(this);
+        // register this as a service
+        registryRegistration = context.registerService(ProviderRegistry.class.getName(), registry, null);
+
+        org.osgi.framework.ServiceReference ref = context.getServiceReference(ProviderRegistry.class.getName());
+
+	    bt = new BundleTracker(context, Bundle.ACTIVE, new ProviderBundleTrackerCustomizer(this, context.getBundle(), registry));
+	    bt.open();
+	}
+
+    @Override
+	public synchronized void stop(BundleContext context) throws Exception {
+	    bt.close();
+	    lst.close();
+        registryRegistration.unregister();
+	}
+
+	void log(int level, String message) {
+	    synchronized (logServices) {
+	        for (LogService log : logServices) {
+	            log.log(level, message);
+	        }
+        }
+	}
+
+	void log(int level, String message, Throwable th) {
+        synchronized (logServices) {
+            for (LogService log : logServices) {
+                log.log(level, message, th);
+            }
+        }
+    }
+
+	private final class LogServiceTracker extends ServiceTracker {
+        private LogServiceTracker(BundleContext context, String clazz,
+                ServiceTrackerCustomizer customizer) {
+            super(context, clazz, customizer);
+        }
+
+        @Override
+        public Object addingService(ServiceReference reference) {
+            Object svc = super.addingService(reference);
+            if (svc instanceof LogService) {
+                synchronized (logServices) {
+                    logServices.add((LogService) svc);
+                }
+            }
+            return svc;
+        }
+
+        @Override
+        public void removedService(ServiceReference reference, Object service) {
+            synchronized (logServices) {
+                logServices.remove(service);
+            }
+            super.removedService(reference, service);
+        }
+    }
+}

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/Activator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/Activator.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/Activator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.geronimo.osgi.registry;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.BundleTrackerCustomizer;
+
+public class ProviderBundleTrackerCustomizer implements BundleTrackerCustomizer {
+    // our base Activator (used as a service source)
+    private Activator activator;
+    // the bundle hosting this registry
+    private Bundle registryBundle;
+    // the registry we interact with
+    private ProviderRegistryImpl registry;
+    // the accumulated list of provider classes
+    private ConcurrentMap<Long, Map<String, Callable<Class>>> providers = new ConcurrentHashMap<Long, Map<String, Callable<Class>>>();
+
+    public ProviderBundleTrackerCustomizer(Activator a, Bundle b, ProviderRegistryImpl r) {
+        activator = a;
+        registryBundle = b;
+        registry = r;
+    }
+
+    /**
+     * Handle the activation of a new bundle.
+     *
+     * @param bundle The source bundle.
+     * @param event  The bundle event information.
+     *
+     * @return A return object.
+     */
+    @Override
+    public Object addingBundle(Bundle bundle, BundleEvent event) {
+        log(LogService.LOG_DEBUG, "Bundle Considered for class providers: " + bundle.getSymbolicName());
+        if (bundle.equals(registryBundle)) {
+            return null;
+        }
+
+        return registry.addBundle(bundle);
+    }
+
+    @Override
+    public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+        // nothing to do here
+    }
+
+    @Override
+    public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+        // have the registry process this
+        registry.removeBundle(bundle);
+    }
+
+    private void log(int level, String message) {
+        activator.log(level, message);
+    }
+
+    private void log(int level, String message, Throwable th) {
+        activator.log(level, message, th);
+    }
+}

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,338 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.geronimo.osgi.registry;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.log.LogService;
+
+/**
+ * The implementation of the provider registry used to store
+ * the bundle registrations.
+ */
+public class ProviderRegistryImpl implements org.apache.geronimo.osgi.registry.api.ProviderRegistry {
+    // our mapping between a provider id and the implementation information.  There
+    // might be a one-to-many relationship between the ids and implementing classes.
+    private Map<String, List<BundleProviderLoader>> providers = new HashMap<String, List<BundleProviderLoader>>();
+    // our list of bundles and a mapping to the set of providers that each bundle
+    // declares
+    private Map<Long, List<BundleProviderLoader>> providerBundles = new HashMap<Long, List<BundleProviderLoader>>();
+
+    // our base Activator (used as a service source)
+    private Activator activator;
+
+    public ProviderRegistryImpl(Activator activator) {
+        this.activator = activator;
+    }
+
+    /**
+     * Add a bundle to the provider registry.  This searches
+     * for services information in the OSGI-INF/providers
+     * directory of the bundle and registers this information
+     * in a provider registry.  Bundles that need to locate
+     * class instances can use the provider registry to
+     * locate classes that might reside in other bundles.
+     *
+     * @param bundle The source bundle.
+     *
+     * @return A map of the located registrations.  Returns null if
+     *         this bundle does not contain any providers.
+     */
+    public Object addBundle(Bundle bundle) {
+        // a list for accumulating providers for this bundle
+        List<BundleProviderLoader> list = new ArrayList<BundleProviderLoader>();
+        // look for services definitions in the bundle...we accumulate these as provider class
+        // definitions.
+        Enumeration e = bundle.findEntries("OSGI-INF/providers/", "*", false);
+        if (e != null) {
+            while (e.hasMoreElements()) {
+                final URL u = (URL) e.nextElement();
+                // go parse out the control file
+                parseProviderFile(u, bundle, list);
+            }
+        }
+
+        // if we have providers defined, add each to the global registry and
+        // also keep track of this in the bundle list
+        if (!list.isEmpty()) {
+            providerBundles.put(bundle.getBundleId(), list);
+            // process the registrations for each item
+            for (BundleProviderLoader loader: list) {
+                // add to the mapping table
+                register(loader);
+            }
+            // this will tell the tracker this is a bundle of interest.
+            return list ;
+        }
+        else {
+            // indicate our lack of interest here
+            return null;
+        }
+    }
+
+
+    /**
+     * Parse a provider definition file and create loaders
+     * for all definitions contained within the file.
+     *
+     * @param u      The URL of the file
+     * @param bundle The bundle this resides in.
+     * @param bundleProviders
+     *               The list used to accumulate the provider definitions.
+     */
+    private void parseProviderFile(URL u, Bundle bundle, List<BundleProviderLoader> bundleProviders) {
+        final String url = u.toString();
+        // ignore directories
+        if (url.endsWith("/")) {
+            return;
+        }
+        // initial size of the provider list.  If we don't add any because of parsing the
+        // lines, we can add a default one using the provider id as both key and mapped
+        // provider class.
+        int providerCount = bundleProviders.size();
+        // the identifier used for the provider is the last item in the URL.
+        final String providerId = url.substring(url.lastIndexOf("/") + 1);
+        try {
+            BufferedReader br = new BufferedReader(new InputStreamReader(u.openStream(), "UTF-8"));
+            String providerClassName = null;
+            // the file can be multiple lines long, with comments.  A single file can define multiple providers
+            // for a single key, so we might need to create multiple entries.  If the file does not contain any
+            // definition lines, then as a default, we use the providerId as an implementation class also.
+            String line = br.readLine();
+            while (line != null) {
+                // we allow comments on these lines, and a line can be all comment
+                int comment = line.indexOf('#');
+                if (comment != -1) {
+                    line = line.substring(0, comment);
+                }
+                line = line.trim();
+                // if there is nothing left on the line after stripping white space and comments, skip this
+                if (line.length() > 0) {
+                    // add this to our list
+                    bundleProviders.add(new BundleProviderLoader(providerId, line, bundle));
+                }
+                // keep reading until the end.
+                line = br.readLine();
+            }
+            br.close();
+        } catch (IOException e) {
+            // ignore errors and handle as default
+        }
+
+        // if nothing was defined inside the file, then add a default
+        if (providerCount == bundleProviders.size()) {
+            bundleProviders.add(new BundleProviderLoader(providerId, providerId, bundle));
+        }
+    }
+
+
+    /**
+     * Remove a bundle from the registry.
+     *
+     * @param bundle The target bundle.
+     */
+    public void removeBundle(Bundle bundle) {
+        List<BundleProviderLoader> list = providerBundles.remove(bundle.getBundleId());
+        if (list != null) {
+            for (BundleProviderLoader loader : list) {
+                // unregistry the individual entry
+                unregister(loader);
+            }
+        }
+    }
+
+    /**
+     * Removed a provider registration for a named provider id.
+     *
+     * @param id      The target id
+     * @param provider The provider registration instance
+     */
+    public synchronized void unregister(BundleProviderLoader provider) {
+        log(LogService.LOG_DEBUG, "unregistering provider " + provider);
+        if (providers != null) {
+            // this is stored as a list.  Just remove using the registration information
+            // This may move a different provider to the front of the list.
+            List<BundleProviderLoader> l = providers.get(provider.id());
+            if (l != null) {
+                l.remove(provider);
+            }
+        }
+    }
+
+
+    /**
+     * Register an individual provivider item by its provider identifier.
+     *
+     * @param id      The provider id.
+     * @param provider The loader used to resolve the provider class.
+     */
+    public synchronized void register(BundleProviderLoader provider) {
+        log(LogService.LOG_DEBUG, "registering provider " + provider);
+        // if this is the first registration, create the mapping table
+        if (providers == null) {
+            providers = new HashMap<String, List<BundleProviderLoader>>();
+        }
+
+        String providerId = provider.id();
+
+        // the providers are stored as a list...we use the first one registered
+        // when asked to locate.
+        List<BundleProviderLoader> l = providers.get(providerId);
+        if (l ==  null) {
+            l = new ArrayList<BundleProviderLoader>();
+            providers.put(providerId, l);
+        }
+        l.add(provider);
+    }
+
+
+    /**
+     * Locate a class by its provider id indicator. .
+     *
+     * @param providerId The provider id (generally, a fully qualified class name).
+     *
+     * @return The Class corresponding to this provider id.  Returns null
+     *         if this is not registered or the indicated class can't be
+     *         loaded.
+     */
+    public synchronized Class<?> locate(String providerId) {
+        if (providers != null) {
+            List<BundleProviderLoader> l = providers.get(providerId);
+            if (l != null && !l.isEmpty()) {
+                // we always use the first one registered
+                BundleProviderLoader c = l.get(0);
+                try {
+                    // this loads the class from the hosting bundle.
+                    return c.call();
+                } catch (Exception e) {
+                    log(LogService.LOG_DEBUG, "Exception loading provider " + this, e);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Locate all class files that match a given provider id.
+     *
+     * @param providerId The target provider identifier.
+     *
+     * @return A List containing the class objects corresponding to the
+     *         provider identifier.  Returns an empty list if no
+     *         matching classes can be located.
+     */
+    public synchronized List<Class<?>> locateAll(String providerId) {
+        List<Class<?>> classes = new ArrayList<Class<?>>();
+        if (providers != null) {
+            List<BundleProviderLoader> l = providers.get(providerId);
+            if (l != null) {
+                for (BundleProviderLoader c : l) {
+                	try {
+                    	classes.add(c.call());
+                	} catch (Exception e) {
+                        log(LogService.LOG_DEBUG, "Exception loading " + c, e);
+                	}
+				}
+            }
+        }
+        return classes;
+    }
+
+    private void log(int level, String message) {
+        activator.log(level, message);
+    }
+
+    private void log(int level, String message, Throwable th) {
+        activator.log(level, message, th);
+    }
+
+
+    /**
+     * Holder class for located services information.
+     */
+    private class BundleProviderLoader implements Callable<Class<?>> {
+        // the class name for this provider
+        private final String providerId;
+        // the mapped class name of the provider.
+        private final String providerClass;
+        // the hosting bundle.
+        private final Bundle bundle;
+
+        /**
+         * Create a loader for this registered provider.
+         *
+         * @param providerId The provider ID
+         * @param providerClass The mapped class name of the provider.
+         * @param bundle    The hosting bundle.
+         */
+        public BundleProviderLoader(String providerId, String providerClass, Bundle bundle) {
+            this.providerId = providerId;
+            this.providerClass = providerClass;
+            this.bundle = bundle;
+        }
+
+        public Class<?> call() throws Exception {
+            try {
+                log(LogService.LOG_DEBUG, "creating provider for: " + this);
+                return bundle.loadClass(providerClass);
+            } catch (Exception e) {
+                e.printStackTrace();
+                log(LogService.LOG_DEBUG, "exception caught while creating " + this, e);
+                throw e;
+            } catch (Error e) {
+                e.printStackTrace();
+                log(LogService.LOG_DEBUG, "error caught while creating " + this, e);
+                throw e;
+            }
+        }
+
+        public String id() {
+            return providerId;
+        }
+
+        @Override
+        public String toString() {
+            return "Provider interface=" + providerId + " ,provider class=" + providerClass;
+        }
+
+        @Override
+        public int hashCode() {
+            return providerId.hashCode() + providerClass.hashCode() + (int)bundle.getBundleId();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof BundleProviderLoader) {
+                return providerId.equals(((BundleProviderLoader)obj).providerId) &&
+                       providerClass.equals(((BundleProviderLoader)obj).providerClass) &&
+                       bundle.getBundleId() == ((BundleProviderLoader)obj).bundle.getBundleId();
+            } else {
+                return false;
+            }
+        }
+    }
+}

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.geronimo.osgi.registry.api;
+
+import java.util.List;
+
+/**
+ * The implementation of the factory registry used to store
+ * the bundle registrations.
+ */
+public interface ProviderRegistry {
+    /**
+     * Locate a class by its factory id indicator. .
+     *
+     * @param factoryId The factory id (generally, a fully qualified class name).
+     *
+     * @return The Class corresponding to this factory id.  Returns null
+     *         if this is not registered or the indicated class can't be
+     *         loaded.
+     */
+    public Class<?> locate(String factoryId);
+
+    /**
+     * Locate all class files that match a given factory id.
+     *
+     * @param factoryId The target factory identifier.
+     *
+     * @return A List containing the class objects corresponding to the
+     *         factory identifier.  Returns an empty list if no
+     *         matching classes can be located.
+     */
+    public List<Class<?>> locateAll(String factoryId);
+}

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-locator/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/pom.xml?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/pom.xml (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/pom.xml Fri Mar  5 12:42:25 2010
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+<!-- $Rev$ $Date$ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.geronimo.specs</groupId>
+        <artifactId>geronimo-osgi-support</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.geronimo.specs</groupId>
+    <artifactId>geronimo-osgi-registry-itests</artifactId>
+
+    <description>
+Tests for the OSGi provider registry inside of an OSGi framework.
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-osgi-registry</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-osgi-locator</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-container-default</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit-extender-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.swissbox</groupId>
+            <artifactId>pax-swissbox-tinybundles</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.logging</groupId>
+            <artifactId>pax-logging-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.configadmin</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.servicemix.tooling</groupId>
+                <artifactId>depends-maven-plugin</artifactId>
+                <version>1.1</version>
+                <executions>
+                    <execution>
+                        <id>generate-depends-file</id>
+                        <goals>
+                            <goal>generate-depends-file</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
+                    <failIfNoTests>false</failIfNoTests>
+                    <excludes>
+                        <exclude>**/OSGi*.java</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>failsafe-maven-plugin</artifactId>
+                <version>2.4.3-alpha-1</version>
+                <executions>
+                    <execution>
+                        <id>integration-test</id>
+                        <goals>
+                            <goal>integration-test</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>verify</id>
+                        <goals>
+                            <goal>verify</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
+                    <failIfNoTests>false</failIfNoTests>
+                    <includes>
+                        <include>**/OSGiLocatorTest.java</include>
+                        <include>**/OSGiLocatorMultipleProviderTest.java</include>
+                    </includes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/pom.xml
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.geronimo.osgi.registry;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.geronimo.osgi.locator.Activator;
+import org.apache.geronimo.osgi.locator.ProviderLocator;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.CoreOptions;
+import static org.ops4j.pax.exam.CoreOptions.equinox;
+import static org.ops4j.pax.exam.CoreOptions.felix;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+import org.ops4j.pax.exam.Customizer;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import static org.ops4j.pax.exam.OptionUtils.combine;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
+import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+@RunWith(JUnit4TestRunner.class)
+public class OSGiLocatorMultipleProviderTest {
+    @Inject
+    protected BundleContext bundleContext;
+
+    @org.ops4j.pax.exam.junit.Configuration
+    public static Option[] configuration() throws Exception {
+        Option[] options = options(
+            // the target code we're testing
+            mavenBundle("org.apache.geronimo.specs", "geronimo-osgi-registry"),
+            mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
+            felix(),
+            equinox().version("3.5.0"),
+            // we want to specify an activator for the test probe bundle that
+            // is the standard one for adding the locator service to a spec
+            // bundle.  We'll use our activator instance to perform class lookups
+            new Customizer()
+            {
+                @Override
+                public InputStream customizeTestProbe( InputStream testProbe )
+                    throws IOException
+                {
+                    return modifyBundle(testProbe)
+                        // these two classes need to be in every participating bundle
+                        .add(org.apache.geronimo.osgi.locator.Activator.class)
+                        .add(org.apache.geronimo.osgi.locator.ProviderLocator.class)
+                        // set the required activator also
+                        .set(Constants.BUNDLE_ACTIVATOR, org.apache.geronimo.osgi.locator.Activator.class.getName())
+                        // we need an import for activator to function properly.
+                        .set(Constants.IMPORT_PACKAGE, "org.apache.geronimo.osgi.registry.api")
+                        .build();
+                }
+            },
+            provision(newBundle()
+                .add(TestTarget.class)
+                .add("OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget", OSGiLocatorMultipleProviderTest.class.getResource("/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget"))
+                .set(Constants.BUNDLE_SYMBOLICNAME, "TestTargetProvider")
+                .set(Constants.BUNDLE_VERSION, "2.0.0")
+                .build(withBnd())),
+            provision(newBundle()
+                .add(TestTargetTwo.class)
+                .add("OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget", OSGiLocatorMultipleProviderTest.class.getResource("/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget2"))
+                .set( Constants.BUNDLE_SYMBOLICNAME, "TestTarget2Provider" )
+                .set(Constants.BUNDLE_VERSION, "2.0.0")
+                .build(withBnd()))
+        );
+        options = updateOptions(options);
+        return options;
+    }
+
+
+    @Test
+    public void testLocator() throws Exception {
+        Bundle bundle1 = getInstalledBundle("TestTargetProvider");
+        Bundle bundle2 = getInstalledBundle("TestTarget2Provider");
+        // check for the target class a verify we got the correct one
+        Class<?> target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.TestTarget");
+        assertNotNull(target);
+        // this should return the given class instance
+        assertEquals("org.apache.geronimo.osgi.registry.TestTarget", target.getName());
+
+        // now stop the first bundle, which should shuffle the deck
+        bundle1.stop();
+
+// ideally, we'd try loading again and verify that this reverts to the second registered
+// class.  Unfortunately, there appears to be a strange error in the PAX exam/tinybundles combination.
+// When we provision these two dynamically loaded bundles this way, for some strange reason we're
+// unable to load any classes from whichever bundle is created second.  So we'll just stop the
+// the second bundle and verify that a locate() call returns null.
+
+
+        // The returned class should now be from the second provisioned bundle
+//      target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.TestTarget");
+//      assertNotNull(target);
+        // this should return the given class instance
+//      assertEquals("org.apache.geronimo.osgi.registry.TestTarget", target.getName());
+
+        // now stop the the second bundle.  There should not be anything registred with that name now.
+        bundle2.stop();
+
+        // The returned class should now be null since there are no registered providers
+        target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.TestTarget");
+        assertNull(target);
+    }
+
+    protected Bundle getInstalledBundle(String symbolicName) {
+        for (Bundle b : bundleContext.getBundles()) {
+            if (b.getSymbolicName().equals(symbolicName)) {
+                return b;
+            }
+        }
+        return null;
+    }
+
+    public static MavenArtifactProvisionOption mavenBundle(String groupId, String artifactId) {
+        return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId).versionAsInProject();
+    }
+
+    protected static Option[] updateOptions(Option[] options) {
+        // We need to add pax-exam-junit here when running with the ibm
+        // jdk to avoid the following exception during the test run:
+        // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
+        if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
+            Option[] ibmOptions = options(
+                wrappedBundle(mavenBundle("org.ops4j.pax.exam", "pax-exam-junit"))
+            );
+            options = combine(ibmOptions, options);
+        }
+
+        return options;
+    }
+}

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorTest.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorTest.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorTest.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorTest.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.geronimo.osgi.registry;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.geronimo.osgi.locator.Activator;
+import org.apache.geronimo.osgi.locator.ProviderLocator;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.CoreOptions;
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.equinox;
+import static org.ops4j.pax.exam.CoreOptions.felix;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+import org.ops4j.pax.exam.Customizer;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import static org.ops4j.pax.exam.OptionUtils.combine;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
+import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+@RunWith(JUnit4TestRunner.class)
+public class OSGiLocatorTest {
+    @Inject
+    protected BundleContext bundleContext;
+
+    @org.ops4j.pax.exam.junit.Configuration
+    public static Option[] configuration() throws Exception {
+        Option[] options = options(
+            // the target code we're testing...
+            mavenBundle("org.apache.geronimo.specs", "geronimo-osgi-registry"),
+            mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
+            felix(),
+            equinox().version("3.5.0"),
+            // we want to specify an activator for the test probe bundle that
+            // is the standard one for adding the locator service to a spec
+            // bundle.  We'll use our activator instance to perform class lookups
+            new Customizer()
+            {
+                @Override
+                public InputStream customizeTestProbe( InputStream testProbe )
+                    throws IOException
+                {
+                    return modifyBundle(testProbe)
+                        // these two classes need to be in every participating bundle
+                        .add(org.apache.geronimo.osgi.locator.Activator.class)
+                        .add(org.apache.geronimo.osgi.locator.ProviderLocator.class)
+                        // set the required activator also
+                        .set(Constants.BUNDLE_ACTIVATOR, org.apache.geronimo.osgi.locator.Activator.class.getName())
+                        // we need an import for activator to function properly.
+                        .set(Constants.IMPORT_PACKAGE, "org.apache.geronimo.osgi.registry.api")
+                        .build();
+                }
+            },
+            provision(newBundle()
+                // need to ensure we have all of the loaded test classes
+                .add(TestTarget.class)
+                .add(TestTargetTwo.class)
+                .add(TestTarget2.class)
+                .add(TestTarget3.class)
+                // we're going to define multiple providers under different interface names, using a variety of
+                // control file types.
+                .add("OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget", OSGiLocatorTest.class.getResource("/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget"))
+                .add("OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget2", OSGiLocatorTest.class.getResource("/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget2"))
+                .add("OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget3", OSGiLocatorTest.class.getResource("/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.DefaultTarget"))
+                .add("OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget4", OSGiLocatorTest.class.getResource("/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.MultipleTarget"))
+                .set(Constants.BUNDLE_SYMBOLICNAME, "TestTargetProvider")
+                .set(Constants.BUNDLE_VERSION, "2.0.0")
+                .build(withBnd()))
+        );
+        options = updateOptions(options);
+        return options;
+    }
+
+
+    @Test
+    public void testLocator() throws Exception {
+        Bundle bundle1 = getInstalledBundle("TestTargetProvider");
+        // check for the target class a verify we got the correct one
+        Class<?> target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.TestTarget");
+        assertNotNull(target);
+        // this should return the given class instance
+        assertEquals("org.apache.geronimo.osgi.registry.TestTarget", target.getName());
+
+        List<Class<?>> targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.registry.TestTarget");
+        // should return one entry and it should be the same class mapping
+        assertEquals(1, targets.size());
+        assertEquals("org.apache.geronimo.osgi.registry.TestTarget", targets.get(0).getName());
+
+        // now load the second target interface.  This is really the same as the first, but
+        // uses a different commenting style.
+        target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.TestTarget2");
+        assertNotNull(target);
+        // this should return the given class instance
+        assertEquals("org.apache.geronimo.osgi.registry.TestTargetTwo", target.getName());
+
+        targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.registry.TestTarget2");
+        // should return one entry and it should be the same class mapping
+        assertEquals(1, targets.size());
+        assertEquals("org.apache.geronimo.osgi.registry.TestTargetTwo", targets.get(0).getName());
+
+        // this uses a default loading style that derives the implementation class from the control
+        // file name.
+        target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.TestTarget3");
+        assertNotNull(target);
+        // this should return the given class instance
+        assertEquals("org.apache.geronimo.osgi.registry.TestTarget3", target.getName());
+
+        targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.registry.TestTarget3");
+        // should return one entry and it should be the same class mapping
+        assertEquals(1, targets.size());
+        assertEquals("org.apache.geronimo.osgi.registry.TestTarget3", targets.get(0).getName());
+
+
+        // this mapping defines multiple classes for the single key.  The first should be returned for
+        // a singleton request, the locate all should return in definition order
+        target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.TestTarget4");
+        assertNotNull(target);
+        // this should return the given class instance
+        assertEquals("org.apache.geronimo.osgi.registry.TestTarget", target.getName());
+
+        targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.registry.TestTarget4");
+        // should return one entry and it should be the same class mapping
+        assertEquals(2, targets.size());
+        assertEquals("org.apache.geronimo.osgi.registry.TestTarget", targets.get(0).getName());
+        assertEquals("org.apache.geronimo.osgi.registry.TestTarget2", targets.get(1).getName());
+
+        // now stop the first bundle, which should shuffle the deck
+        bundle1.stop();
+
+        // The returned class should now be null since there are no registered providers
+        target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.TestTarget");
+        assertNull(target);
+
+        targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.registry.TestTarget3");
+        // should return an empty list
+        assertNotNull(targets);
+        assertEquals(0, targets.size());
+    }
+
+    protected Bundle getInstalledBundle(String symbolicName) {
+        for (Bundle b : bundleContext.getBundles()) {
+            if (b.getSymbolicName().equals(symbolicName)) {
+                return b;
+            }
+        }
+        return null;
+    }
+
+    public static MavenArtifactProvisionOption mavenBundle(String groupId, String artifactId) {
+        return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId).versionAsInProject();
+    }
+
+    protected static Option[] updateOptions(Option[] options) {
+        // We need to add pax-exam-junit here when running with the ibm
+        // jdk to avoid the following exception during the test run:
+        // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
+        if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
+            Option[] ibmOptions = options(
+                wrappedBundle(mavenBundle("org.ops4j.pax.exam", "pax-exam-junit"))
+            );
+            options = combine(ibmOptions, options);
+        }
+
+        return options;
+    }
+}

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget.java
URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget.java?rev=919392&view=auto
==============================================================================
--- geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget.java (added)
+++ geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget.java Fri Mar  5 12:42:25 2010
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.geronimo.osgi.registry;
+
+public class TestTarget {
+    public TestTarget() {
+    }
+
+    @Override
+    /**
+     * The toString method is a simple means for determining
+     * which class has been instantiated without requiring
+     * interface classes to be exported by the test bundles.
+     *
+     * @return The unique identifier for this class.
+     */
+    public String toString() {
+        return "TestTarget";
+    }
+}
+

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/specs/trunk/geronimo-osgi-support/geronimo-osgi-registry-itests/src/test/java/org/apache/geronimo/osgi/registry/TestTarget.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message