You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dw...@apache.org on 2009/07/22 21:17:12 UTC
svn commit: r796840 -
/geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/spi/PersistenceProviderResolverHolder.java
Author: dwoods
Date: Wed Jul 22 19:17:12 2009
New Revision: 796840
URL: http://svn.apache.org/viewvc?rev=796840&view=rev
Log:
GERONIMO-4410 - OPENJPA-1076 Implementations of PersistenceProviderResolver interface and PersistenceProviderResolverHolder class
Modified:
geronimo/specs/trunk/geronimo-jpa_2.0_spec/src/main/java/javax/persistence/spi/PersistenceProviderResolverHolder.java
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=796840&r1=796839&r2=796840&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 Wed Jul 22 19:17:12 2009
@@ -25,24 +25,138 @@
package javax.persistence.spi;
-/**
-* Holds global PersistenceProviderResolver instance.
-* If no PersistenceProviderResolver is set in the environment,
-* the default PersistenceProviderResolver is used.
-*
-* Implementations must be thread-safe.
-*/
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.persistence.PersistenceException;
+
+
public class PersistenceProviderResolverHolder {
- /**
- * Returns current persistence provider resolver
- */
+
+ private static PersistenceProviderResolver persistenceResolver =
+ new DefaultPersistenceProviderResolver();
+
public static PersistenceProviderResolver getPersistenceProviderResolver() {
- // TODO
- return null;
+ return persistenceResolver;
+ }
+
+ public static void setPersistenceProviderResolver(PersistenceProviderResolver resolver) {
+ if (resolver != null) {
+ if (persistenceResolver != null) {
+ persistenceResolver.clearCachedProviders();
+ }
+ persistenceResolver = resolver;
+ }
}
- public static void setPersistenceProviderResolver(
- PersistenceProviderResolver resolver) {
- // TODO
+ /*
+ * (non-Javadoc) Geronimo implementation specific code.
+ * Default implementation of a PersistenceProviderResolver
+ * to use when none are provided.
+ */
+ 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 static final Map<ClassLoader, List<PersistenceProvider>> providerCache =
+ new WeakHashMap<ClassLoader, List<PersistenceProvider>>();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.persistence.spi.PersistenceProviderResolver#getPersistenceProviders()
+ */
+ public List<PersistenceProvider> getPersistenceProviders() {
+ List<PersistenceProvider> providers;
+
+ // get our class loader
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if (cl == null)
+ cl = DefaultPersistenceProviderResolver.class.getClassLoader();
+
+ // use any previously cached providers
+ synchronized (providerCache) {
+ providers = providerCache.get(cl);
+ }
+ if (providers == null) {
+ // need to discover and load them for this class loader
+ providers = new ArrayList<PersistenceProvider>();
+ try {
+ // find all service provider files
+ Enumeration<URL> cfgs = cl.getResources(SERVICES_FILENAME);
+ while (cfgs.hasMoreElements()) {
+ URL url = cfgs.nextElement();
+ InputStream is = null;
+ try {
+ is = url.openStream();
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(is), 256);
+ String line = br.readLine();
+ // files may contain multiple providers and/or comments
+ while (line != null) {
+ line = line.trim();
+ if (!line.startsWith("#")) {
+ try {
+ // try loading the specified class
+ final Class<?> provider = cl.loadClass(line);
+ // create an instance to return
+ providers.add((PersistenceProvider) provider.newInstance());
+ } catch (ClassNotFoundException e) {
+ throw new PersistenceException("Failed to load provider " +
+ line + " configured in file " + url, e);
+ } catch (InstantiationException e) {
+ throw new PersistenceException("Failed to instantiate provider " +
+ line + " configured in file " + url, e);
+ } catch (IllegalAccessException e) {
+ throw new PersistenceException("Failed to access provider " +
+ line + " configured in file " + url, e);
+ }
+ }
+ line = br.readLine();
+ }
+ is.close();
+ is = null;
+ } catch (IOException e) {
+ throw new PersistenceException("Error trying to read " + url, e);
+ } finally {
+ if (is != null)
+ is.close();
+ }
+ }
+ } catch (IOException e) {
+ throw new PersistenceException("Error trying to load " + SERVICES_FILENAME, e);
+ }
+
+ // cache the discovered providers
+ synchronized (providerCache) {
+ providerCache.put(cl, providers);
+ }
+ }
+
+ // caller must handle the case of no providers found
+ return providers;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.persistence.spi.PersistenceProviderResolver#clearCachedProviders()
+ */
+ public void clearCachedProviders() {
+ synchronized (providerCache) {
+ providerCache.clear();
+ }
+ }
}
+
}