1 // $Id: Persistence.java 14134 2007-10-25 22:34:46Z epbernard $
2 package javax.persistence;
3
4 import java.io.BufferedReader;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.InputStreamReader;
8 import java.net.URL;
9 import java.util.Enumeration;
10 import java.util.HashSet;
11 import java.util.Map;
12 import java.util.Set;
13 import java.util.regex.Matcher;
14 import java.util.regex.Pattern;
15 import javax.persistence.spi.PersistenceProvider;
16
17 /**
18 * Bootstrap class that provides access to an EntityManagerFactory.
19 */
20 public class Persistence {
21
22 //typo intended because it leaked into the JPA 1 spec. Do not use this constant.
23 public static final java.lang.String PERSISTENCE_PROVIDER = "javax.persistence.spi.PeristenceProvider";
24
25 protected static final Set<PersistenceProvider> providers = new HashSet<PersistenceProvider>();
26
27 /**
28 * Create and return an EntityManagerFactory for the named persistence unit.
29 *
30 * @param persistenceUnitName The name of the persistence unit
31 * @return The factory that creates EntityManagers configured according to the specified persistence unit
32 */
33 public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName) {
34 return createEntityManagerFactory( persistenceUnitName, null );
35 }
36
37 /**
38 * Create and return an EntityManagerFactory for the named persistence unit using the given properties.
39 *
40 * @param persistenceUnitName The name of the persistence unit
41 * @param properties Additional properties to use when creating the factory. The values of these properties override
42 * any values that may have been configured elsewhere
43 * @return The factory that creates EntityManagers configured according to the specified persistence unit
44 */
45 public static EntityManagerFactory createEntityManagerFactory(String persistenceUnitName, Map properties) {
46 EntityManagerFactory emf = null;
47
48 if ( providers.size() == 0 ) {
49 findAllProviders();
50 }
51 for ( PersistenceProvider provider : providers ) {
52 emf = provider.createEntityManagerFactory( persistenceUnitName, properties );
53 if ( emf != null ) break;
54 }
55 if ( emf == null ) {
56 throw new PersistenceException( "No Persistence provider for EntityManager named " + persistenceUnitName );
57 }
58 return emf;
59 }
60
61 // Helper methods
62
63 private static void findAllProviders() {
64 try {
65 ClassLoader loader = Thread.currentThread().getContextClassLoader();
66 Enumeration<URL> resources = loader.getResources( "META-INF/services/" + PersistenceProvider.class.getName() );
67 Set<String> names = new HashSet<String>();
68 while ( resources.hasMoreElements() ) {
69 URL url = resources.nextElement();
70 InputStream is = url.openStream();
71 try {
72 names.addAll( providerNamesFromReader( new BufferedReader( new InputStreamReader( is ) ) ) );
73 }
74 finally {
75 is.close();
76 }
77 }
78 for ( String s : names ) {
79 Class providerClass = loader.loadClass( s );
80 providers.add( (PersistenceProvider) providerClass.newInstance() );
81 }
82 }
83 catch (IOException e) {
84 throw new PersistenceException( e );
85 }
86 catch (InstantiationException e) {
87 throw new PersistenceException( e );
88 }
89 catch (IllegalAccessException e) {
90 throw new PersistenceException( e );
91 }
92 catch (ClassNotFoundException e) {
93 throw new PersistenceException( e );
94 }
95 }
96
97 private static final Pattern nonCommentPattern = Pattern.compile( "^([^#]+)" );
98
99 private static Set<String> providerNamesFromReader(BufferedReader reader) throws IOException {
100 Set<String> names = new HashSet<String>();
101 String line;
102 while ( ( line = reader.readLine() ) != null ) {
103 line = line.trim();
104 Matcher m = nonCommentPattern.matcher( line );
105 if ( m.find() ) {
106 names.add( m.group().trim() );
107 }
108 }
109 return names;
110 }
111 }