geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Donald Woods <dwo...@apache.org>
Subject Re: svn commit: r919017 [1/2] - in /geronimo/specs/trunk: geronimo-jpa_2.0_spec/ geronimo-jpa_2.0_spec/src/main/java/javax/persistence/spi/ geronimo-jpa_2.0_spec/src/main/java/org/apache/geronimo/specs/jpa/ geronimo-osgi-support/ geronimo-osgi-support/src/...
Date Thu, 04 Mar 2010 17:58:50 GMT
Rick, shouldn't we mark the new dependency as optional in the spec pom
and dynamically load ProviderLocator in the code?  Otherwise, upstream
maven builds (like OpenJPA) will have to pull in this new
geronimo-osgi-support dependency which is OSGi specific and not used in
J2SE environments....

> +        <dependency>
> +            <groupId>org.apache.geronimo.specs</groupId>
> +            <artifactId>geronimo-osgi-support</artifactId>
> +            <version>1.0.0-SNAPSHOT</version>
> +        </dependency>

Otherise, we have to tell openjpa-2.0.0.jar and other users that they
also need to include this new geronimo-osgi-support jar as a runtime prereq.


-Donald


On 3/4/10 10:16 AM, rickmcguire@apache.org wrote:
> Author: rickmcguire
> Date: Thu Mar  4 15:16:48 2010
> New Revision: 919017
> 
> URL: http://svn.apache.org/viewvc?rev=919017&view=rev
> Log:
> GERONIMO-5133 Geroinimo versions of the specs should pick up the additions made to the service mix versions of the bundles. 
> 
> Base OSGi support bundle plus changes to the JPA spec to use the new locator mechanism. 
> 
> 
> Added:
>     geronimo/specs/trunk/geronimo-osgi-support/
>     geronimo/specs/trunk/geronimo-osgi-support/LICENSE
>     geronimo/specs/trunk/geronimo-osgi-support/NOTICE
>     geronimo/specs/trunk/geronimo-osgi-support/pom.xml   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/Activator.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/Activator.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/api/
>     geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorTest.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/TestTarget.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/TestTarget2.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/TestTarget3.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/TestTargetTwo.java   (with props)
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/resources/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/resources/test/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/resources/test/OSGI-INF/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/resources/test/OSGI-INF/providers/
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/resources/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.DefaultTarget
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/resources/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.MultipleTarget
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/resources/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget
>     geronimo/specs/trunk/geronimo-osgi-support/src/test/resources/test/OSGI-INF/providers/org.apache.geronimo.osgi.registry.TestTarget2
> Modified:
>     geronimo/specs/trunk/geronimo-jpa_2.0_spec/pom.xml
>     geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/spi/PersistenceProviderResolverHolder.java
>     geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/org/apache/geronimo/specs/jpa/PersistenceActivator.java
> 
> Modified: geronimo/specs/trunk/geronimo-jpa_2.0_spec/pom.xml
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jpa_2.0_spec/pom.xml?rev=919017&r1=919016&r2=919017&view=diff
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-jpa_2.0_spec/pom.xml (original)
> +++ geronimo/specs/trunk/geronimo-jpa_2.0_spec/pom.xml Thu Mar  4 15:16:48 2010
> @@ -7,9 +7,9 @@
>      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
> @@ -100,6 +100,12 @@
>                  </exclusion>
>              </exclusions>
>          </dependency>
> +        <dependency>
> +            <groupId>org.apache.geronimo.specs</groupId>
> +            <artifactId>geronimo-osgi-support</artifactId>
> +            <version>1.0.0-SNAPSHOT</version>
> +        </dependency>
> +
>      </dependencies>
>  
>      <build>
> @@ -126,9 +132,9 @@
>                          <Specification-Title>JSR-317 Java Persistence API 2.0</Specification-Title>
>                          <Specification-Vendor>Sun Microsystems, Inc.</Specification-Vendor>
>                          <Specification-Version>2.0</Specification-Version>
> -                        <Private-Package>org.apache.geronimo.specs.jpa.*</Private-Package>
> +                        <Private-Package>org.apache.geronimo.specs.jpa.*;org.apache.geronimo.osgi.locator;-split-package:=merge-first</Private-Package>
>                          <Export-Package>javax.persistence.*;version=2.0</Export-Package>
> -                        <Import-Package>javax.persistence.*;version=2.0,javax.sql;resolution:=optional,org.osgi.framework;resolution:=optional,org.osgi.util.tracker;resolution:=optional</Import-Package>
> +                        <Import-Package>javax.persistence.*;version=2.0,javax.sql;resolution:=optional,org.osgi.framework;resolution:=optional,org.osgi.util.tracker;resolution:=optional,org.apache.geronimo.osgi.registry.api</Import-Package>
>                          <!-- Eclipse metadata
>                          <Eclipse-Autostart>false</Eclipse-Autostart>
>                          <Bundle-ClassPath>.</Bundle-ClassPath>
> 
> Modified: geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/spi/PersistenceProviderResolverHolder.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/spi/PersistenceProviderResolverHolder.java?rev=919017&r1=919016&r2=919017&view=diff
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/spi/PersistenceProviderResolverHolder.java (original)
> +++ geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/spi/PersistenceProviderResolverHolder.java Thu Mar  4 15:16:48 2010
> @@ -39,24 +39,26 @@
>  
>  import javax.persistence.PersistenceException;
>  
> +import org.apache.geronimo.osgi.locator.ProviderLocator;
> +
>  /**
>   * Contains Geronimo implemented code as required by the JPA spec.
>   *
>   * Finds/Creates the global {@link javax.persistence.spi.PersistenceProviderResolver}
> - * 
> + *
>   * Implementations must be thread-safe.
> - * 
> + *
>   * @since Java Persistence 2.0
>   */
>  public class PersistenceProviderResolverHolder {
>  
>      private static PersistenceProviderResolver persistenceResolver =
>          new DefaultPersistenceProviderResolver();
> -    
> +
>      public static PersistenceProviderResolver getPersistenceProviderResolver() {
>          return persistenceResolver;
>      }
> -    
> +
>      public static void setPersistenceProviderResolver(PersistenceProviderResolver resolver) {
>          if (persistenceResolver != null) {
>              persistenceResolver.clearCachedProviders();
> @@ -69,25 +71,25 @@
>              persistenceResolver = new DefaultPersistenceProviderResolver();
>          }
>      }
> -    
> +
>      /*
>       * (non-Javadoc) Default implementation of a PersistenceProviderResolver
>       * to use when none are provided.
> -     * 
> +     *
>       * Geronimo implementation specific code.
>       */
>      private static class DefaultPersistenceProviderResolver implements PersistenceProviderResolver {
> - 
> +
>          private static final String SERVICES_FILENAME = "META-INF/services/" +
>              PersistenceProvider.class.getName();
>  
>          // cache of providers per class loader
>          private volatile WeakHashMap<ClassLoader, List<PersistenceProvider>> providerCache =
>              new WeakHashMap<ClassLoader, List<PersistenceProvider>>();
> -        
> +
>          /*
>           * (non-Javadoc)
> -         * 
> +         *
>           * @see javax.persistence.spi.PersistenceProviderResolver#getPersistenceProviders()
>           */
>          public List<PersistenceProvider> getPersistenceProviders() {
> @@ -146,7 +148,25 @@
>                  } catch (IOException e) {
>                      throw new PersistenceException("Error trying to load " + SERVICES_FILENAME, e);
>                  }
> -                
> +
> +                try {
> +
> +                    // if we're running in an OSGi environment, there might be additional reqistered
> +                    // persistence providers.   Process them also
> +                    List<Class<?>> osgiProviders = ProviderLocator.locateAll(PersistenceProvider.class.getName());
> +
> +                    for (Class<?> provider : osgiProviders) {
> +                        // add this instance to the cache of providers
> +                        providers.add((PersistenceProvider) provider.newInstance());
> +                    }
> +                } catch (InstantiationException e) {
> +                    throw new PersistenceException("Failed to instantiate provider osgi provider", e);
> +                } catch (IllegalAccessException e) {
> +                    throw new PersistenceException("Failed to access osgi provider", e);
> +                } catch (ClassCastException e) {
> +                    throw new PersistenceException("Invalid osgi provider definition", e);
> +                }
> +
>                  // cache the discovered providers
>                  providerCache.put(cl, providers);
>              }
> @@ -157,7 +177,7 @@
>  
>          /*
>           * (non-Javadoc)
> -         * 
> +         *
>           * @see javax.persistence.spi.PersistenceProviderResolver#clearCachedProviders()
>           */
>          public void clearCachedProviders() {
> 
> Modified: geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/org/apache/geronimo/specs/jpa/PersistenceActivator.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/org/apache/geronimo/specs/jpa/PersistenceActivator.java?rev=919017&r1=919016&r2=919017&view=diff
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/org/apache/geronimo/specs/jpa/PersistenceActivator.java (original)
> +++ geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/org/apache/geronimo/specs/jpa/PersistenceActivator.java Thu Mar  4 15:16:48 2010
> @@ -32,13 +32,14 @@
>  import org.osgi.framework.ServiceReference;
>  import org.osgi.util.tracker.ServiceTracker;
>  import org.osgi.util.tracker.ServiceTrackerCustomizer;
> +import org.apache.geronimo.osgi.locator.Activator;
>  
>  /**
>   * Used to discover/resolve JPA providers in an OSGi environment.
>   *
>   * @version $Rev$ $Date$
>   */
> -public class PersistenceActivator implements BundleActivator, PersistenceProviderResolver {
> +public class PersistenceActivator extends Activator implements BundleActivator, PersistenceProviderResolver {
>  
>      public static final String PERSISTENCE_PROVIDER = PersistenceProvider.class.getName();
>  
> @@ -50,9 +51,10 @@
>       * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
>       */
>      public void start(BundleContext arg0) throws Exception {
> +        super.start(arg0);
>          // bundle context for later ServiceReference lookups
>          ctx = arg0;
> -        
> +
>          // track providers as they register themselves
>          ServiceTrackerCustomizer customizer = new PersistenceTracker(this);
>          tracker = new ServiceTracker(ctx, PERSISTENCE_PROVIDER, customizer);
> @@ -69,16 +71,18 @@
>          // cleanup provider tracker
>          tracker.close();
>          tracker = null;
> -        
> +
>          // cleanup providers and remove ourselves as a JPA provider resolver
>          PersistenceProviderResolverHolder.setPersistenceProviderResolver(null);
>          providers.clear();
> -        
> +
>          // cleanup context
>          ctx = null;
> +
> +        super.stop(arg0);
>      }
>  
> -    
> +
>      /* (non-Javadoc)
>       * @see javax.persistence.spi.PersistenceProviderResolver#clearCachedProviders()
>       */
> @@ -99,7 +103,7 @@
>          providers.put(name, provider);
>          return provider;
>      }
> -    
> +
>      protected void removeProvider(ServiceReference ref) {
>          String name = (String) ref.getProperty(PERSISTENCE_PROVIDER);
>          providers.remove(name);
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/LICENSE
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/LICENSE?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/LICENSE (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/LICENSE Thu Mar  4 15:16:48 2010
> @@ -0,0 +1,257 @@
> +
> +                                 Apache License
> +                           Version 2.0, January 2004
> +                        http://www.apache.org/licenses/
> +
> +   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
> +
> +   1. Definitions.
> +
> +      "License" shall mean the terms and conditions for use, reproduction,
> +      and distribution as defined by Sections 1 through 9 of this document.
> +
> +      "Licensor" shall mean the copyright owner or entity authorized by
> +      the copyright owner that is granting the License.
> +
> +      "Legal Entity" shall mean the union of the acting entity and all
> +      other entities that control, are controlled by, or are under common
> +      control with that entity. For the purposes of this definition,
> +      "control" means (i) the power, direct or indirect, to cause the
> +      direction or management of such entity, whether by contract or
> +      otherwise, or (ii) ownership of fifty percent (50%) or more of the
> +      outstanding shares, or (iii) beneficial ownership of such entity.
> +
> +      "You" (or "Your") shall mean an individual or Legal Entity
> +      exercising permissions granted by this License.
> +
> +      "Source" form shall mean the preferred form for making modifications,
> +      including but not limited to software source code, documentation
> +      source, and configuration files.
> +
> +      "Object" form shall mean any form resulting from mechanical
> +      transformation or translation of a Source form, including but
> +      not limited to compiled object code, generated documentation,
> +      and conversions to other media types.
> +
> +      "Work" shall mean the work of authorship, whether in Source or
> +      Object form, made available under the License, as indicated by a
> +      copyright notice that is included in or attached to the work
> +      (an example is provided in the Appendix below).
> +
> +      "Derivative Works" shall mean any work, whether in Source or Object
> +      form, that is based on (or derived from) the Work and for which the
> +      editorial revisions, annotations, elaborations, or other modifications
> +      represent, as a whole, an original work of authorship. For the purposes
> +      of this License, Derivative Works shall not include works that remain
> +      separable from, or merely link (or bind by name) to the interfaces of,
> +      the Work and Derivative Works thereof.
> +
> +      "Contribution" shall mean any work of authorship, including
> +      the original version of the Work and any modifications or additions
> +      to that Work or Derivative Works thereof, that is intentionally
> +      submitted to Licensor for inclusion in the Work by the copyright owner
> +      or by an individual or Legal Entity authorized to submit on behalf of
> +      the copyright owner. For the purposes of this definition, "submitted"
> +      means any form of electronic, verbal, or written communication sent
> +      to the Licensor or its representatives, including but not limited to
> +      communication on electronic mailing lists, source code control systems,
> +      and issue tracking systems that are managed by, or on behalf of, the
> +      Licensor for the purpose of discussing and improving the Work, but
> +      excluding communication that is conspicuously marked or otherwise
> +      designated in writing by the copyright owner as "Not a Contribution."
> +
> +      "Contributor" shall mean Licensor and any individual or Legal Entity
> +      on behalf of whom a Contribution has been received by Licensor and
> +      subsequently incorporated within the Work.
> +
> +   2. Grant of Copyright License. Subject to the terms and conditions of
> +      this License, each Contributor hereby grants to You a perpetual,
> +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
> +      copyright license to reproduce, prepare Derivative Works of,
> +      publicly display, publicly perform, sublicense, and distribute the
> +      Work and such Derivative Works in Source or Object form.
> +
> +   3. Grant of Patent License. Subject to the terms and conditions of
> +      this License, each Contributor hereby grants to You a perpetual,
> +      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
> +      (except as stated in this section) patent license to make, have made,
> +      use, offer to sell, sell, import, and otherwise transfer the Work,
> +      where such license applies only to those patent claims licensable
> +      by such Contributor that are necessarily infringed by their
> +      Contribution(s) alone or by combination of their Contribution(s)
> +      with the Work to which such Contribution(s) was submitted. If You
> +      institute patent litigation against any entity (including a
> +      cross-claim or counterclaim in a lawsuit) alleging that the Work
> +      or a Contribution incorporated within the Work constitutes direct
> +      or contributory patent infringement, then any patent licenses
> +      granted to You under this License for that Work shall terminate
> +      as of the date such litigation is filed.
> +
> +   4. Redistribution. You may reproduce and distribute copies of the
> +      Work or Derivative Works thereof in any medium, with or without
> +      modifications, and in Source or Object form, provided that You
> +      meet the following conditions:
> +
> +      (a) You must give any other recipients of the Work or
> +          Derivative Works a copy of this License; and
> +
> +      (b) You must cause any modified files to carry prominent notices
> +          stating that You changed the files; and
> +
> +      (c) You must retain, in the Source form of any Derivative Works
> +          that You distribute, all copyright, patent, trademark, and
> +          attribution notices from the Source form of the Work,
> +          excluding those notices that do not pertain to any part of
> +          the Derivative Works; and
> +
> +      (d) If the Work includes a "NOTICE" text file as part of its
> +          distribution, then any Derivative Works that You distribute must
> +          include a readable copy of the attribution notices contained
> +          within such NOTICE file, excluding those notices that do not
> +          pertain to any part of the Derivative Works, in at least one
> +          of the following places: within a NOTICE text file distributed
> +          as part of the Derivative Works; within the Source form or
> +          documentation, if provided along with the Derivative Works; or,
> +          within a display generated by the Derivative Works, if and
> +          wherever such third-party notices normally appear. The contents
> +          of the NOTICE file are for informational purposes only and
> +          do not modify the License. You may add Your own attribution
> +          notices within Derivative Works that You distribute, alongside
> +          or as an addendum to the NOTICE text from the Work, provided
> +          that such additional attribution notices cannot be construed
> +          as modifying the License.
> +
> +      You may add Your own copyright statement to Your modifications and
> +      may provide additional or different license terms and conditions
> +      for use, reproduction, or distribution of Your modifications, or
> +      for any such Derivative Works as a whole, provided Your use,
> +      reproduction, and distribution of the Work otherwise complies with
> +      the conditions stated in this License.
> +
> +   5. Submission of Contributions. Unless You explicitly state otherwise,
> +      any Contribution intentionally submitted for inclusion in the Work
> +      by You to the Licensor shall be under the terms and conditions of
> +      this License, without any additional terms or conditions.
> +      Notwithstanding the above, nothing herein shall supersede or modify
> +      the terms of any separate license agreement you may have executed
> +      with Licensor regarding such Contributions.
> +
> +   6. Trademarks. This License does not grant permission to use the trade
> +      names, trademarks, service marks, or product names of the Licensor,
> +      except as required for reasonable and customary use in describing the
> +      origin of the Work and reproducing the content of the NOTICE file.
> +
> +   7. Disclaimer of Warranty. Unless required by applicable law or
> +      agreed to in writing, Licensor provides the Work (and each
> +      Contributor provides its Contributions) on an "AS IS" BASIS,
> +      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> +      implied, including, without limitation, any warranties or conditions
> +      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
> +      PARTICULAR PURPOSE. You are solely responsible for determining the
> +      appropriateness of using or redistributing the Work and assume any
> +      risks associated with Your exercise of permissions under this License.
> +
> +   8. Limitation of Liability. In no event and under no legal theory,
> +      whether in tort (including negligence), contract, or otherwise,
> +      unless required by applicable law (such as deliberate and grossly
> +      negligent acts) or agreed to in writing, shall any Contributor be
> +      liable to You for damages, including any direct, indirect, special,
> +      incidental, or consequential damages of any character arising as a
> +      result of this License or out of the use or inability to use the
> +      Work (including but not limited to damages for loss of goodwill,
> +      work stoppage, computer failure or malfunction, or any and all
> +      other commercial damages or losses), even if such Contributor
> +      has been advised of the possibility of such damages.
> +
> +   9. Accepting Warranty or Additional Liability. While redistributing
> +      the Work or Derivative Works thereof, You may choose to offer,
> +      and charge a fee for, acceptance of support, warranty, indemnity,
> +      or other liability obligations and/or rights consistent with this
> +      License. However, in accepting such obligations, You may act only
> +      on Your own behalf and on Your sole responsibility, not on behalf
> +      of any other Contributor, and only if You agree to indemnify,
> +      defend, and hold each Contributor harmless for any liability
> +      incurred by, or claims asserted against, such Contributor by reason
> +      of your accepting any such warranty or additional liability.
> +
> +   END OF TERMS AND CONDITIONS
> +
> +   APPENDIX: How to apply the Apache License to your work.
> +
> +      To apply the Apache License to your work, attach the following
> +      boilerplate notice, with the fields enclosed by brackets "[]"
> +      replaced with your own identifying information. (Don't include
> +      the brackets!)  The text should be enclosed in the appropriate
> +      comment syntax for the file format. We also recommend that a
> +      file or class name and description of purpose be included on the
> +      same "printed page" as the copyright notice for easier
> +      identification within third-party archives.
> +
> +   Copyright [yyyy] [name of copyright owner]
> +
> +   Licensed 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.
> +
> +
> +#########################################################################
> +## ADDITIONAL LICENSES                                                 ##
> +#########################################################################
> +
> +The XMLSchema.dtd included in this project was developed by the
> +W3C Consortium (http://www.w3c.org/).
> +Use of the source code, thus licensed, and the resultant binary are
> +subject to the terms and conditions of the following license.
> +
> +W3C¨ SOFTWARE NOTICE AND LICENSE
> +Copyright © 1994-2002 World Wide Web Consortium, (Massachusetts Institute of
> +Technology, Institut National de Recherche en Informatique et en Automatique,
> +Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/
> +
> +This W3C work (including software, documents, or other related items) is
> +being provided by the copyright holders under the following license. By
> +obtaining, using and/or copying this work, you (the licensee) agree that you
> +have read, understood, and will comply with the following terms and
> +conditions:
> +
> +Permission to use, copy, modify, and distribute this software and its
> +documentation, with or without modification,  for any purpose and without
> +fee or royalty is hereby granted, provided that you include the following on
> +ALL copies of the software and documentation or portions thereof, including
> +modifications, that you make:
> +
> +   1. The full text of this NOTICE in a location viewable to users of the
> +         redistributed or derivative work.
> +   2. Any pre-existing intellectual property disclaimers, notices, or terms
> +         and conditions. If none exist, a short notice of the following form
> +         (hypertext is preferred, text is permitted) should be used within
> +         the body of any redistributed or derivative code: "Copyright ©
> +         [$date-of-software] World Wide Web Consortium, (Massachusetts Institute
> +         of Technology, Institut National de Recherche en Informatique et en
> +         Automatique, Keio University). All Rights Reserved.
> +         http://www.w3.org/Consortium/Legal/"
> +   3. Notice of any changes or modifications to the W3C files, including the
> +         date changes were made. (We recommend you provide URIs to the location
> +         from which the code is derived.)
> +
> +THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
> +NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
> +TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
> +THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS,
> +COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
> +
> +COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
> +CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
> +
> +The name and trademarks of copyright holders may NOT be used in advertising or
> +publicity pertaining to the software without specific, written prior permission.
> +Title to copyright in this software and any associated documentation will at all
> +times remain with copyright holders.
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/NOTICE
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/NOTICE?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/NOTICE (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/NOTICE Thu Mar  4 15:16:48 2010
> @@ -0,0 +1,21 @@
> +Apache Geronimo 
> +Copyright 2003-2009 The Apache Software Foundation
> +
> +This product includes software developed by
> +The Apache Software Foundation (http://www.apache.org/).
> +
> +This product includes software developed by
> +The Object Management Group.
> +
> +Copyright (c) 1999-2000 Object Management Group. Unlimited rights to
> +duplicate and use this code are hereby granted provided that this
> +copyright notice is included.
> +
> +This product includes software developed by
> +The W3C Consortium (http://www.w3.org/).
> +
> +Copyright © 1994-2002 World Wide Web Consortium, 
> +(Massachusetts Institute of Technology, Institut National 
> +de Recherche en Informatique et en Automatique, Keio 
> +University). All Rights Reserved. 
> +http://www.w3.org/Consortium/Legal/
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/pom.xml
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/pom.xml?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/pom.xml (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/pom.xml Thu Mar  4 15:16:48 2010
> @@ -0,0 +1,208 @@
> +<?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.genesis</groupId>
> +        <artifactId>genesis-java5-flava</artifactId>
> +        <version>2.0</version>
> +    </parent>
> +
> +    <groupId>org.apache.geronimo.specs</groupId>
> +    <artifactId>geronimo-osgi-support</artifactId>
> +    <packaging>bundle</packaging>
> +    <name>OSGI factory registry</name>
> +    <version>1.0.0-SNAPSHOT</version>
> +
> +    <description>
> +This bundle contains an extender that facilitates the use
> +of Geronimo spec providers (components typically plugged in to the
> +JRE through META-INF/services resources).  The service created by this
> +extender will maintain a registry of factory class implementations that
> +can be used by the spec bundles to locate factory classes that reside in
> +other bundles.
> +    </description>
> +
> +    <url>http://geronimo.apache.org/maven/${siteId}/${version}</url>
> +    <distributionManagement>
> +        <site>
> +            <id>apache-website</id>
> +            <url>${site.deploy.url}/maven/${siteId}/${version}</url>
> +        </site>
> +    </distributionManagement>
> +
> +    <properties>
> +        <siteId>specs/${artifactId}</siteId>
> +    </properties>
> +
> +    <scm>
> +        <connection>scm:svn:http://svn.apache.org/repos/asf/geronimo/specs/trunk/geronimo-osgi-support/</connection>
> +        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/geronimo/specs/trunk/geronimo-osgi-support/</developerConnection>
> +        <url>http://svn.apache.org/viewcvs.cgi/geronimo/specs/trunk/geronimo-osgi-support/</url>
> +    </scm>
> +
> +    <dependencies>
> +        <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>
> +        <dependency>
> +            <groupId>org.ops4j.pax.exam</groupId>
> +            <artifactId>pax-exam</artifactId>
> +            <version>1.2.0</version>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>org.ops4j.pax.exam</groupId>
> +            <artifactId>pax-exam-junit</artifactId>
> +            <version>1.2.0</version>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>org.ops4j.pax.exam</groupId>
> +            <artifactId>pax-exam-container-default</artifactId>
> +            <version>1.2.0</version>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>org.ops4j.pax.exam</groupId>
> +            <artifactId>pax-exam-junit-extender-impl</artifactId>
> +            <version>1.2.0</version>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>org.ops4j.pax.swissbox</groupId>
> +            <artifactId>pax-swissbox-tinybundles</artifactId>
> +            <version>1.2.0</version>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>org.ops4j.pax.logging</groupId>
> +            <artifactId>pax-logging-api</artifactId>
> +            <version>1.4</version>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>org.apache.felix</groupId>
> +            <artifactId>org.apache.felix.configadmin</artifactId>
> +            <version>1.2.4</version>
> +            <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.felix</groupId>
> +            <artifactId>maven-bundle-plugin</artifactId>
> +            <configuration>
> +                <instructions>
> +                  <Export-Package>org.apache.geronimo.osgi.registry.api;version=1.0</Export-Package>
> +                  <Import-Package>
> +                      *
> +                  </Import-Package>
> +                  <Private-Package>
> +                      org.apache.geronimo.osgi.registry,org.apache.geronimo.osgi.locator
> +                  </Private-Package>
> +                  <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
> +                  <Bundle-Activator>org.apache.geronimo.osgi.registry.Activator</Bundle-Activator>
> +                </instructions>
> +            </configuration>
> +        </plugin>
> +            <plugin>
> +                <groupId>org.apache.maven.plugins</groupId>
> +                <artifactId>maven-surefire-plugin</artifactId>
> +                <configuration>
> +                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
> +                    <failIfNoTests>false</failIfNoTests>
> +                    <includes>
> +                        <include>**/NonOSGi*.java</include>
> +                    </includes>
> +                    <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>
> +                    <excludes>
> +                        <exclude>**/NonOSGi*.java</exclude>
> +                    </excludes>
> +                    <systemProperties>
> +                      <property>
> +                        <name>build.bundle.name</name>
> +                        <value>${basedir}/target/${project.artifactId}-${project.version}.jar</value>
> +                      </property>
> +                    </systemProperties>
> +                </configuration>
> +            </plugin>
> +      </plugins>
> +    </build>
> +
> +</project>
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/pom.xml
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/pom.xml
> ------------------------------------------------------------------------------
>     svn:keywords = Date Revision
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/pom.xml
> ------------------------------------------------------------------------------
>     svn:mime-type = text/xml
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/Activator.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/Activator.java?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/Activator.java (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/Activator.java Thu Mar  4 15:16:48 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/src/main/java/org/apache/geronimo/osgi/locator/Activator.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/Activator.java
> ------------------------------------------------------------------------------
>     svn:keywords = Date Revision
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/Activator.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java Thu Mar  4 15:16:48 2010
> @@ -0,0 +1,113 @@
> +/**
> + * 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
> +    static private ServiceTracker 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);
> +        registryTracker.open();
> +    }
> +
> +
> +    /**
> +     * Cleanup resources on bundle shutdown.
> +     */
> +    public static void destroy() {
> +        // shutdown our tracking of the provider registry.
> +        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)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)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/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java
> ------------------------------------------------------------------------------
>     svn:keywords = Date Revision
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/locator/ProviderLocator.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/Activator.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/Activator.java?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/Activator.java (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/Activator.java Thu Mar  4 15:16:48 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/src/main/java/org/apache/geronimo/osgi/registry/Activator.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/Activator.java
> ------------------------------------------------------------------------------
>     svn:keywords = Date Revision
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/Activator.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java Thu Mar  4 15:16:48 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/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java
> ------------------------------------------------------------------------------
>     svn:keywords = Date Revision
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderBundleTrackerCustomizer.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java Thu Mar  4 15:16:48 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/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java
> ------------------------------------------------------------------------------
>     svn:keywords = Date Revision
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/ProviderRegistryImpl.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java Thu Mar  4 15:16:48 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/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java
> ------------------------------------------------------------------------------
>     svn:keywords = Date Revision
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/main/java/org/apache/geronimo/osgi/registry/api/ProviderRegistry.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java Thu Mar  4 15:16:48 2010
> @@ -0,0 +1,43 @@
> +/*
> + * 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 {
> +        // 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/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java
> ------------------------------------------------------------------------------
>     svn:keywords = Date Revision
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/NonOSGiLocatorTest.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> Added: geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java
> URL: http://svn.apache.org/viewvc/geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java?rev=919017&view=auto
> ==============================================================================
> --- geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java (added)
> +++ geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java Thu Mar  4 15:16:48 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...loaded directly from the project build directory
> +            bundle(new File(System.getProperty("build.bundle.name")).toURI().toURL().toString()),
> +            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/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java
> ------------------------------------------------------------------------------
>     svn:keywords = Date Revision
> 
> Propchange: geronimo/specs/trunk/geronimo-osgi-support/src/test/java/org/apache/geronimo/osgi/registry/OSGiLocatorMultipleProviderTest.java
> ------------------------------------------------------------------------------
>     svn:mime-type = text/plain
> 
> 
> 

Mime
View raw message