001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 // 021 // This source code implements specifications defined by the Java 022 // Community Process. In order to remain compliant with the specification 023 // DO NOT add / change / or delete method signatures! 024 // 025 package javax.persistence; 026 027 import java.io.BufferedReader; 028 import java.io.IOException; 029 import java.io.InputStreamReader; 030 import java.net.URL; 031 import java.util.Collections; 032 import java.util.Enumeration; 033 import java.util.Map; 034 import java.util.HashSet; 035 import java.util.Set; 036 037 import javax.persistence.spi.PersistenceProvider; 038 /** 039 * @version $Rev$ $Date$ 040 */ 041 042 /** 043 * Bootstrap class that is used to obtain {@link javax.persistence.EntityManagerFactory} 044 * references. 045 */ 046 public class Persistence { 047 048 protected static final Set<PersistenceProvider> providers = new HashSet<PersistenceProvider>(); 049 // Changed to the hard coded PERSISTENCE_PROVIDER value to pass signature tests. 050 // public static final java.lang.String PERSISTENCE_PROVIDER = PersistenceProvider.class.getName(); 051 public static final java.lang.String PERSISTENCE_PROVIDER = "javax.persistence.spi.PeristenceProvider"; 052 static final String PERSISTENCE_PROVIDER_PROPERTY = "javax.persistence.provider"; 053 static final String PERSISTENCE_PROVIDER_SERVICE = "META-INF/services/" 054 + PersistenceProvider.class.getName(); 055 /** 056 * Create and return an EntityManagerFactory for the named persistence unit. 057 * 058 * @param persistenceUnitName The name of the persistence unit 059 * @return The factory that creates EntityManagers configured according to the 060 * specified persistence unit 061 */ 062 public static EntityManagerFactory createEntityManagerFactory( 063 String persistenceUnitName) { 064 return createEntityManagerFactory(persistenceUnitName, Collections.EMPTY_MAP); 065 } 066 067 /** 068 * Create and return an EntityManagerFactory for the named persistence unit using the 069 * given properties. 070 * 071 * @param persistenceUnitName The name of the persistence unit 072 * @param properties Additional properties to use when creating the factory. The values of 073 * these properties override any values that may have been configured 074 * elsewhere. 075 * @return The factory that creates EntityManagers configured according to the 076 * specified persistence unit. 077 */ 078 public static EntityManagerFactory createEntityManagerFactory( 079 String persistenceUnitName, 080 Map properties) { 081 082 if (properties == null) { 083 properties = Collections.EMPTY_MAP; 084 } 085 086 // start by loading a provider explicitly specified in properties. The spec 087 // doesn't seem to forbid providers that are not deployed as a service 088 Object providerName = properties.get(PERSISTENCE_PROVIDER_PROPERTY); 089 if (providerName instanceof String) { 090 EntityManagerFactory factory = createFactory( 091 providerName.toString(), 092 persistenceUnitName, 093 properties); 094 if (factory != null) { 095 return factory; 096 } 097 } 098 099 //If we are deployed into an OSGi environment, leverage it 100 Class providerClass = org.apache.servicemix.specs.locator.OsgiLocator.locate("javax.persistence.spi.PersistenceProvider"); 101 if (providerClass != null) { 102 try { 103 PersistenceProvider provider = (PersistenceProvider) providerClass 104 .newInstance(); 105 return provider.createEntityManagerFactory(persistenceUnitName, 106 properties); 107 } 108 catch (Exception e) { 109 throw new PersistenceException("Provider error. Provider: " 110 + providerName, e); 111 } 112 } 113 114 // load correctly deployed providers 115 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 116 try { 117 Enumeration<URL> providers = loader 118 .getResources(PERSISTENCE_PROVIDER_SERVICE); 119 while (providers.hasMoreElements()) { 120 121 String name = getProviderName(providers.nextElement()); 122 123 if (name != null) { 124 125 EntityManagerFactory factory = createFactory( 126 name, 127 persistenceUnitName, 128 properties); 129 130 if (factory != null) { 131 return factory; 132 } 133 } 134 } 135 } 136 catch (IOException e) { 137 // spec doesn't mention any exceptions thrown by this method 138 } 139 140 return null; 141 } 142 143 static String getProviderName(URL url) throws IOException { 144 145 BufferedReader in = new BufferedReader(new InputStreamReader( 146 url.openStream(), 147 "UTF-8")); 148 149 String providerName; 150 151 try { 152 providerName = in.readLine(); 153 } 154 finally { 155 in.close(); 156 } 157 158 if (providerName != null) { 159 providerName = providerName.trim(); 160 } 161 162 return providerName; 163 } 164 165 static EntityManagerFactory createFactory( 166 String providerName, 167 String persistenceUnitName, 168 Map properties) 169 throws PersistenceException { 170 171 Class providerClass; 172 try { 173 providerClass = Class.forName(providerName, true, Thread 174 .currentThread().getContextClassLoader()); 175 } 176 catch (Exception e) { 177 throw new PersistenceException( 178 "Invalid or inaccessible provider class: " + providerName, 179 e); 180 } 181 182 try { 183 PersistenceProvider provider = (PersistenceProvider) providerClass 184 .newInstance(); 185 return provider.createEntityManagerFactory(persistenceUnitName, 186 properties); 187 } 188 catch (Exception e) { 189 throw new PersistenceException("Provider error. Provider: " 190 + providerName, e); 191 } 192 } 193 } 194