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();
+            }
+        }
     }
+
 }