KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > ejb > cmp3 > EntityManagerFactoryProvider


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21 // Copyright (c) 1998, 2006, Oracle. All rights reserved.
22
package oracle.toplink.essentials.ejb.cmp3;
23
24 import java.io.File JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import javax.persistence.*;
28 import javax.persistence.spi.*;
29
30 import oracle.toplink.essentials.config.TargetDatabase;
31 import oracle.toplink.essentials.config.TopLinkProperties;
32 import oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerFactoryImpl;
33 import oracle.toplink.essentials.internal.ejb.cmp3.JavaSECMPInitializer;
34 import oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl;
35 import oracle.toplink.essentials.internal.sessions.AbstractSession;
36 import oracle.toplink.essentials.logging.SessionLog;
37 import oracle.toplink.essentials.threetier.ServerSession;
38
39 import oracle.toplink.essentials.tools.schemaframework.SchemaManager;
40 import oracle.toplink.essentials.ejb.cmp3.persistence.SEPersistenceUnitInfo;
41
42 /**
43  * This is the TopLink EJB 3.0 provider
44  * The default constructor can be used to build the provider by reflection, after which it can
45  * be used to create EntityManagerFactories
46  */

47
48 public class EntityManagerFactoryProvider implements javax.persistence.spi.PersistenceProvider {
49
50     // The following constants are used in persistence xml or in createSessionManagerFactory methods to specify properties.
51
// Many property declarations were moved to oracle.toplink.essentials.config.TopLinkProperties class.
52

53     public static final String JavaDoc TOPLINK_ORM_THROW_EXCEPTIONS = "toplink.orm.throw.exceptions";
54     public static final String JavaDoc TOPLINK_VALIDATION_ONLY_PROPERTY = "toplink.validation-only";
55
56     public static final String JavaDoc DDL_GENERATION = "toplink.ddl-generation";
57     
58     public static final String JavaDoc CREATE_ONLY = "create-tables";
59     public static final String JavaDoc DROP_AND_CREATE = "drop-and-create-tables";
60     public static final String JavaDoc NONE = "none";
61     
62     public static final String JavaDoc APP_LOCATION = "toplink.application-location";
63     
64     public static final String JavaDoc CREATE_JDBC_DDL_FILE = "toplink.create-ddl-jdbc-file-name";
65     public static final String JavaDoc DROP_JDBC_DDL_FILE = "toplink.drop-ddl-jdbc-file-name";
66     
67     public static final String JavaDoc DEFAULT_APP_LOCATION = "." + File.separator;
68     public static final String JavaDoc DEFAULT_CREATE_JDBC_FILE_NAME = "createDDL.jdbc";
69     public static final String JavaDoc DEFAULT_DROP_JDBC_FILE_NAME = "dropDDL.jdbc";
70     public static final String JavaDoc JAVASE_DB_INTERACTION = "INTERACT_WITH_DB";
71     
72     public static final String JavaDoc DDL_GENERATION_MODE = "toplink.ddl-generation.output-mode";
73     public static final String JavaDoc DDL_SQL_SCRIPT_GENERATION = "sql-script";
74     public static final String JavaDoc DDL_DATABASE_GENERATION = "database";
75     public static final String JavaDoc DDL_BOTH_GENERATION = "both";
76     // This is the default for now to ensure we still play nicely with Glassfish.
77
public static final String JavaDoc DEFAULT_DDL_GENERATION_MODE = DDL_SQL_SCRIPT_GENERATION;
78     
79     // TEMPORARY - WILL BE REMOVED.
80
// Used to warn users about deprecated property name and suggest the valid name.
81
// TEMPORARY the old property names will be translated to the new ones and processed.
82
protected static final String JavaDoc oldPropertyNames[][] = {
83         {TopLinkProperties.JDBC_WRITE_CONNECTIONS_MAX, "toplink.max-write-connections"},
84         {TopLinkProperties.JDBC_WRITE_CONNECTIONS_MIN, "toplink.min-write-connections"},
85         {TopLinkProperties.JDBC_READ_CONNECTIONS_MAX, "toplink.max-read-connections"},
86         {TopLinkProperties.JDBC_READ_CONNECTIONS_MIN, "toplink.min-read-connections"},
87         {TopLinkProperties.JDBC_BIND_PARAMETERS, "toplink.bind-all-parameters"},
88         {TopLinkProperties.TARGET_DATABASE, "toplink.platform.class.name"},
89         {TopLinkProperties.TARGET_SERVER, "toplink.server.platform.class.name"},
90         {TopLinkProperties.CACHE_SIZE_DEFAULT, "toplink.cache.default-size"}
91     };
92
93     /**
94      * A default constructor is required by all Providers accoring the the EJB 3.0 specification
95      */

96     public EntityManagerFactoryProvider() {
97     }
98
99     /**
100     * Called by Persistence class when an EntityManagerFactory
101     * is to be created.
102     *
103     * @param emName The name of the persistence unit
104     * @param map A Map of properties for use by the
105     * persistence provider. These properties may be used to
106     * override the values of the corresponding elements in
107     * the persistence.xml file or specify values for
108     * properties not specified in the persistence.xml.
109     * @return EntityManagerFactory for the persistence unit,
110     * or null if the provider is not the right provider
111     */

112     public EntityManagerFactory createEntityManagerFactory(String JavaDoc emName, Map JavaDoc properties){
113         Map JavaDoc nonNullProperties = (properties == null) ? new HashMap JavaDoc() : properties;
114         String JavaDoc name = emName;
115         if (name == null){
116             name = "";
117         }
118         JavaSECMPInitializer initializer = JavaSECMPInitializer.getJavaSECMPInitializer(nonNullProperties);
119         EntityManagerSetupImpl emSetupImpl = initializer.getEntityManagerSetupImpl(name);
120         if(emSetupImpl.isUndeployed()) {
121             ((SEPersistenceUnitInfo)emSetupImpl.getPersistenceUnitInfo()).setClassLoader(JavaSECMPInitializer.getMainLoader());
122             ((SEPersistenceUnitInfo)emSetupImpl.getPersistenceUnitInfo()).setNewTempClassLoader(JavaSECMPInitializer.getMainLoader());
123             // the first parameter is ignored if predeploy called after undeploy
124
emSetupImpl.predeploy(null, nonNullProperties);
125         }
126         
127         EntityManagerFactoryImpl factory = new EntityManagerFactoryImpl(emSetupImpl, nonNullProperties);
128
129         // This code has been added to allow validation to occur without actually calling createEntityManager
130
if (emSetupImpl.shouldGetSessionOnCreateFactory(nonNullProperties)) {
131             factory.getServerSession();
132         }
133         return factory;
134     }
135
136     /**
137     * Called by the container when an EntityManagerFactory
138     * is to be created.
139     *
140     * @param info Metadata for use by the persistence provider
141     * @return EntityManagerFactory for the persistence unit
142     * specified by the metadata
143     * @param map A Map of integration-level properties for use
144     * by the persistence provider.
145     */

146     public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map JavaDoc properties){
147         Map JavaDoc nonNullProperties = (properties == null) ? new HashMap JavaDoc() : properties;
148         EntityManagerSetupImpl emSetupImpl = new EntityManagerSetupImpl();
149         emSetupImpl.setIsInContainerMode(true);
150         ClassTransformer transformer = null;
151         if(!emSetupImpl.isDeployed()) {
152             transformer = emSetupImpl.predeploy(info, nonNullProperties);
153         }
154         if (transformer != null){
155             info.addTransformer(transformer);
156         }
157         // When EntityManagerFactory is created, the session is only partially created
158
// When the factory is actually accessed, the emSetupImpl will be used to complete the session construction
159
EntityManagerFactoryImpl factory = new EntityManagerFactoryImpl(emSetupImpl, nonNullProperties);
160
161         // This code has been added to allow validation to occur without actually calling createEntityManager
162
if (emSetupImpl.shouldGetSessionOnCreateFactory(nonNullProperties)) {
163             factory.getServerSession();
164         }
165         return factory;
166     }
167
168
169     /**
170      * Logs in to given session. If user has not specified <codeTARGET_DATABASE</code>
171      * the plaform would be auto detected
172      * @param session The session to login to.
173      * @param properties User specified properties for the persistence unit
174      */

175     public static void login(ServerSession session, Map JavaDoc properties) {
176         String JavaDoc toplinkPlatform = (String JavaDoc)properties.get(TopLinkProperties.TARGET_DATABASE);
177         if (!session.isConnected()) {
178             if (toplinkPlatform == null || toplinkPlatform.equals(TargetDatabase.Auto)) {
179                 // if user has not specified a database platform, try to detect
180
session.loginAndDetectDatasource();
181             } else {
182                 session.login();
183             }
184         }
185     }
186
187     public static void generateDDLFiles(ServerSession session, Map JavaDoc props,
188             boolean inSEmode) {
189         boolean createTables = false, shouldDropFirst = false;
190         String JavaDoc appLocation;
191         String JavaDoc createDDLJdbc;
192         String JavaDoc dropDDLJdbc;
193         String JavaDoc ddlGeneration = NONE;
194         
195         if(null == props){
196             return;
197         }
198
199         ddlGeneration = (String JavaDoc)getConfigPropertyAsString(DDL_GENERATION, props, NONE);
200         ddlGeneration = ddlGeneration.toLowerCase();
201         if(ddlGeneration.equals(NONE)) {
202             return;
203         }
204
205         if(ddlGeneration.equals(CREATE_ONLY) ||
206             ddlGeneration.equals(DROP_AND_CREATE)) {
207             createTables = true;
208             if(ddlGeneration.equals(DROP_AND_CREATE)) {
209                 shouldDropFirst = true;
210             }
211         }
212         
213         if (createTables) {
214             String JavaDoc ddlGenerationMode = (String JavaDoc) getConfigPropertyAsString(DDL_GENERATION_MODE, props, DEFAULT_DDL_GENERATION_MODE);
215             // Optimize for cases where the value is explicitly set to NONE
216
if (ddlGenerationMode.equals(NONE)) {
217                 return;
218             }
219             
220             appLocation = (String JavaDoc)getConfigPropertyAsString( APP_LOCATION, props, DEFAULT_APP_LOCATION);
221             createDDLJdbc = (String JavaDoc)getConfigPropertyAsString( CREATE_JDBC_DDL_FILE, props, DEFAULT_CREATE_JDBC_FILE_NAME);
222             dropDDLJdbc = (String JavaDoc)getConfigPropertyAsString( DROP_JDBC_DDL_FILE, props, DEFAULT_DROP_JDBC_FILE_NAME);
223             
224             SchemaManager mgr = new SchemaManager(session);
225             
226             // The inSEmode checks here are only temporary to ensure we still
227
// play nicely with Glassfish.
228
if (ddlGenerationMode.equals(DDL_DATABASE_GENERATION) || inSEmode) {
229                 runInSEMode(mgr, shouldDropFirst);
230                 
231                 if (inSEmode) {
232                     writeDDLsToFiles(mgr, appLocation, createDDLJdbc, dropDDLJdbc);
233                 }
234             } else if (ddlGenerationMode.equals(DDL_SQL_SCRIPT_GENERATION)) {
235                 writeDDLsToFiles(mgr, appLocation, createDDLJdbc, dropDDLJdbc);
236             } else if (ddlGenerationMode.equals(DDL_BOTH_GENERATION)) {
237                 runInSEMode(mgr, shouldDropFirst);
238                 writeDDLsToFiles(mgr, appLocation, createDDLJdbc, dropDDLJdbc);
239             }
240         }
241     }
242    
243     public static void runInSEMode(SchemaManager mgr, boolean shouldDropFirst) {
244         String JavaDoc str = getConfigPropertyAsString(JAVASE_DB_INTERACTION, null ,"true");
245         boolean interactWithDB = Boolean.valueOf(str.toLowerCase()).booleanValue();
246         if (!interactWithDB){
247             return;
248         }
249         createOrReplaceDefaultTables(mgr, shouldDropFirst);
250     }
251     
252   /**
253    * Check the provided map for an object with the given key. If that object is not available, check the
254    * System properties. If it is not available from either location, return the default value.
255    * @param propertyKey
256    * @param map
257    * @param defaultValue
258    * @return
259    */

260     public static String JavaDoc getConfigPropertyAsString(String JavaDoc propertyKey, Map JavaDoc overrides, String JavaDoc defaultValue){
261         String JavaDoc value = getConfigPropertyAsString(propertyKey, overrides);
262         if (value == null){
263             value = defaultValue;
264         }
265         return value;
266     }
267     
268     public static String JavaDoc getConfigPropertyAsString(String JavaDoc propertyKey, Map JavaDoc overrides){
269         String JavaDoc value = null;
270         if (overrides != null){
271             value = (String JavaDoc)overrides.get(propertyKey);
272         }
273         if (value == null){
274             value = System.getProperty(propertyKey);
275         }
276         
277         return value;
278     }
279
280     public static String JavaDoc getConfigPropertyAsStringLogDebug(String JavaDoc propertyKey, Map JavaDoc overrides, String JavaDoc defaultValue, AbstractSession session){
281         String JavaDoc value = getConfigPropertyAsStringLogDebug(propertyKey, overrides, session);
282         if (value == null){
283             value = defaultValue;
284             session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "property_value_default", new Object JavaDoc[]{propertyKey, value});
285         }
286         return value;
287     }
288     
289     public static String JavaDoc getConfigPropertyAsStringLogDebug(String JavaDoc propertyKey, Map JavaDoc overrides, AbstractSession session){
290         String JavaDoc value = null;
291         if (overrides != null){
292             value = (String JavaDoc)overrides.get(propertyKey);
293         }
294         if (value == null){
295             value = System.getProperty(propertyKey);
296         }
297         if(value != null && session != null) {
298             session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "property_value_specified", new Object JavaDoc[]{propertyKey, value});
299         }
300         
301         return value;
302     }
303
304     public static void createOrReplaceDefaultTables(
305         SchemaManager mgr, boolean shouldDropFirst) {
306         if (shouldDropFirst){
307             mgr.replaceDefaultTables(true);
308         } else {
309             mgr.createDefaultTables();
310         }
311     }
312
313     public static void writeDDLsToFiles(SchemaManager mgr, String JavaDoc appLocation,
314         String JavaDoc createDDLJdbc, String JavaDoc dropDDLJdbc) {
315         // Ensure that the appLocation string ends with File.seperator
316
appLocation = addFileSeperator(appLocation);
317         if (null != createDDLJdbc) {
318             String JavaDoc createJdbcFileName = appLocation + createDDLJdbc;
319             mgr.outputCreateDDLToFile(createJdbcFileName);
320         }
321
322         if (null != dropDDLJdbc) {
323             String JavaDoc dropJdbcFileName = appLocation + dropDDLJdbc;
324             mgr.outputDropDDLToFile(dropJdbcFileName);
325         }
326
327         mgr.setCreateSQLFiles(false);
328         // When running in the application server environment always ensure that
329
// we write out both the drop and create table files.
330
createOrReplaceDefaultTables(mgr, true);
331         mgr.closeDDLWriter();
332     }
333     
334     public static String JavaDoc addFileSeperator(String JavaDoc appLocation) {
335         int strLength = appLocation.length();
336         if (appLocation.substring(strLength -1, strLength).equals(File.separator)) {
337             return appLocation;
338         } else {
339             return appLocation + File.separator;
340         }
341     }
342
343   /**
344    * Merge the properties from the source object into the target object. If the property
345    * exists in both objects, use the one from the target
346    * @param target
347    * @param source
348    * @return the target object
349    */

350     public static Map JavaDoc mergeMaps(Map JavaDoc target, Map JavaDoc source){
351         Map JavaDoc map = new HashMap JavaDoc();
352         if (source != null){
353             map.putAll(source);
354         }
355
356         if (target != null){
357             map.putAll(target);
358         }
359         return map;
360     }
361
362   /**
363    * This is a TEMPORARY method that will be removed.
364    * DON'T USE THIS METHOD - for internal use only.
365    * @param Map m
366    * @param AbstractSession session
367    */

368     public static void translateOldProperties(Map JavaDoc m, AbstractSession session) {
369         for(int i=0; i < oldPropertyNames.length; i++) {
370             Object JavaDoc value = getConfigPropertyAsString(oldPropertyNames[i][1], m);
371             if(value != null) {
372                 session.log(SessionLog.CONFIG, SessionLog.TRANSACTION, "deprecated_property", oldPropertyNames[i]);
373                 m.put(oldPropertyNames[i][0], value);
374             }
375         }
376     }
377 }
378
Popular Tags