KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > oracle > toplink > essentials > internal > ejb > cmp3 > EntityManagerSetupImpl


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.internal.ejb.cmp3;
23
24 import java.security.AccessController JavaDoc;
25 import java.security.PrivilegedActionException JavaDoc;
26 import java.util.*;
27 import java.lang.reflect.Constructor JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30
31 import javax.persistence.spi.PersistenceUnitInfo;
32 import javax.persistence.spi.ClassTransformer;
33 import javax.persistence.PersistenceException;
34
35 import oracle.toplink.essentials.config.TopLinkProperties;
36 import oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider;
37 import oracle.toplink.essentials.ejb.cmp3.persistence.PersistenceUnitProcessor;
38 import oracle.toplink.essentials.internal.databaseaccess.DatasourcePlatform;
39 import oracle.toplink.essentials.internal.ejb.cmp3.base.PropertiesHandler;
40 import oracle.toplink.essentials.internal.weaving.TransformerFactory;
41 import oracle.toplink.essentials.jndi.JNDIConnector;
42 import oracle.toplink.essentials.logging.AbstractSessionLog;
43 import oracle.toplink.essentials.logging.SessionLog;
44 import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper;
45 import oracle.toplink.essentials.internal.security.PrivilegedClassForName;
46 import oracle.toplink.essentials.internal.sessions.AbstractSession;
47 import oracle.toplink.essentials.sequencing.Sequence;
48 import oracle.toplink.essentials.sessions.*;
49 import oracle.toplink.essentials.threetier.ReadConnectionPool;
50 import oracle.toplink.essentials.threetier.ServerSession;
51 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProcessor;
52 import oracle.toplink.essentials.tools.sessionmanagement.SessionManager;
53 import oracle.toplink.essentials.descriptors.ClassDescriptor;
54 import oracle.toplink.essentials.internal.ejb.cmp3.base.CMP3Policy;
55 import oracle.toplink.essentials.platform.server.CustomServerPlatform;
56 import oracle.toplink.essentials.platform.server.ServerPlatform;
57 import oracle.toplink.essentials.exceptions.*;
58 import oracle.toplink.essentials.internal.helper.EJB30ConversionManager;
59 import javax.persistence.spi.PersistenceUnitTransactionType;
60
61 import oracle.toplink.essentials.internal.ejb.cmp3.jdbc.base.DataSourceImpl;
62 import oracle.toplink.essentials.tools.sessionconfiguration.DescriptorCustomizer;
63 import oracle.toplink.essentials.tools.sessionconfiguration.SessionCustomizer;
64 import oracle.toplink.essentials.internal.security.SecurableObjectHolder;
65
66 /**
67  * INTERNAL:
68  * A TopLink specific implementer of the EntityManagerInitializer interface.
69  */

70 public class EntityManagerSetupImpl {
71     protected MetadataProcessor processor = null;
72     protected PersistenceUnitInfo persistenceUnitInfo = null;
73     protected Map predeployProperties = null;
74     // may be positive only in STATE_DEPLOYED
75
protected int deploymentCount = 0;
76     protected ServerSession session = null;
77     protected boolean isInContainerMode = false;
78     // indicates whether weaving was used on the first run through predeploy (in STATE_INITIAL)
79
protected boolean enableLazyForOneToOne = false;
80     protected SecurableObjectHolder securableObjectHolder = new SecurableObjectHolder();
81     
82     public static final String JavaDoc STATE_INITIAL = "Initial";
83     public static final String JavaDoc STATE_PREDEPLOYED = "Predeployed";
84     public static final String JavaDoc STATE_DEPLOYED = "Deployed";
85     public static final String JavaDoc STATE_UNDEPLOYED = "Undeployed";
86     
87     protected String JavaDoc state = STATE_INITIAL;
88
89     public static final String JavaDoc ERROR_LOADING_XML_FILE = "error_loading_xml_file";
90     public static final String JavaDoc EXCEPTION_LOADING_ENTITY_CLASS = "exception_loading_entity_class";
91  
92     /**
93      * This method can be used to ensure the session represented by emSetupImpl
94      * is removed from the SessionManager.
95      */

96     protected void removeSessionFromGlobalSessionManager() {
97         if (session != null){
98             if(session.isConnected()) {
99                 session.logout();
100             }
101             SessionManager.getManager().getSessions().remove(session.getName());
102         }
103     }
104     
105     /**
106      * INTERNAL:
107      * Return a set of class names for each entity or embeddable found in the
108      * list of xml descriptor instance documents to be processed by the
109      * MetadataProcessor.
110      *
111      * @param loader
112      * @param persistenceUnitInfo
113      * @return
114      */

115     public Set buildPersistentClassSetFromXMLDocuments(ClassLoader JavaDoc loader, PersistenceUnitInfo persistenceUnitInfo) {
116         List<String JavaDoc> mappingFileNames = getORMXMLFileNames(loader);
117         HashSet classSet = new HashSet();
118
119         Iterator<String JavaDoc> fileNames = mappingFileNames.iterator();
120         InputStream JavaDoc stream = null;
121         String JavaDoc fileName = null;
122         while (fileNames.hasNext()){
123             try{
124                 fileName = fileNames.next();
125                 stream = PersistenceUnitProcessor.createInputStreamForFileInPersistenceUnit(fileName, persistenceUnitInfo, loader);
126                 if (stream != null){
127                     classSet.addAll(MetadataProcessor.buildClassSet(stream, fileName, loader));
128                 }
129             } catch (IOException JavaDoc exception){
130                 handleORMException(PersistenceUnitLoadingException.exceptionLoadingORMXML(fileName, exception), session, fileName);
131             } finally {
132                 try{
133                     if (stream != null){
134                         stream.close();
135                     }
136                 } catch (IOException JavaDoc e){};
137             }
138         }
139         return classSet;
140     }
141     
142     /**
143      * Create a list of the entities that will be deployed. This list is build from the information
144      * provided in the PersistenceUnitInfo argument.
145      * The list contains Classes specified in the PersistenceUnitInfo's class list and also
146      * files that are annotated with @Entity, @Embeddable and @MappedSuperclass in
147      * the jar files provided in the persistence info.
148      * This list of classes will used by TopLink to build a deployment project and to
149      * decide what classes to weave.
150      * @param info
151      * @param loader
152      * @return
153      */

154       public Collection buildEntityList(PersistenceUnitInfo info, ClassLoader JavaDoc loader) {
155           Set<String JavaDoc> classNames = PersistenceUnitProcessor.buildPersistentClassSet(info, loader);
156           
157           // append the list of entity classes that are defined in the XML descriptor
158
classNames.addAll(buildPersistentClassSetFromXMLDocuments(loader, info));
159
160           Vector entityList = new Vector();
161           Iterator i = classNames.iterator();
162           String JavaDoc className = null;
163           while (i.hasNext()){
164               try{
165                   className = (String JavaDoc)i.next();
166                   Class JavaDoc entityClass = loader.loadClass(className);
167                   entityList.add(entityClass);
168               } catch (ClassNotFoundException JavaDoc exc){
169                   AbstractSessionLog.getLog().log(SessionLog.CONFIG, "exception_loading_entity_class", className, exc);
170               }
171           }
172           return entityList;
173       }
174     
175     /**
176      * Deploy a persistence session and return an EntityManagerFactory.
177      *
178      * Deployment takes a session that was partially created in the predeploy call and makes it whole.
179      *
180      * This means doing any configuration that requires the real class definitions for the entities. In
181      * the predeploy phase we were in a stage where we were not let allowed to load the real classes.
182      *
183      * Deploy could be called several times - but only the first call does the actual deploying -
184      * additional calls allow to update session properties (provided the session is not connected) and
185      * encrease deploymentCount (which decreased by calls to undeploy method).
186      *
187      * @param realClassLoader The class loader that was used to load the entity classes. This loader
188      * will be maintained for the lifespan of the loaded classes.
189      * @param additionalProperties added to predeployProperties for updateServerSession overriding existing properties.
190      * In JSE case it allows to alter properties in main (as opposed to preMain where preDeploy is called).
191      * @return An EntityManagerFactory to be used by the Container to obtain EntityManagers
192      */

193     public synchronized ServerSession deploy(ClassLoader JavaDoc realClassLoader, Map additionalProperties) {
194         if(state != STATE_PREDEPLOYED && state != STATE_DEPLOYED) {
195             throw new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(persistenceUnitInfo.getPersistenceUnitName()));
196         }
197         session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_begin", new Object JavaDoc[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount});
198         try {
199             Map deployProperties = EntityManagerFactoryProvider.mergeMaps(additionalProperties, predeployProperties);
200             EntityManagerFactoryProvider.translateOldProperties(deployProperties, session);
201             
202             if(state == STATE_PREDEPLOYED) {
203                 Collection entities = buildEntityList(persistenceUnitInfo, realClassLoader);
204         
205                 // The project is initially created using class names rather than classes. This call will make the conversion
206
session.getProject().convertClassNamesToClasses(realClassLoader);
207         
208                 // listeners and queries require the real classes and are therefore built during deploy using the realClassLoader
209
processor.setClassLoader(realClassLoader);
210                 processor.addEntityListeners();
211                 processor.addNamedQueries();
212                 processor = null;
213         
214                 initServerSession(deployProperties);
215         
216                 if (session.getIntegrityChecker().hasErrors()){
217                     session.handleException(new IntegrityException(session.getIntegrityChecker()));
218                 }
219         
220                 session.getDatasourcePlatform().getConversionManager().setLoader(realClassLoader);
221             }
222             deploymentCount++;
223             state = STATE_DEPLOYED;
224             try{
225                 updateServerSession(deployProperties);
226                 if(!session.isConnected()) {
227                     if(isValidationOnly(deployProperties, false)) {
228                         session.initializeDescriptors();
229                     } else {
230                         EntityManagerFactoryProvider.login(session, deployProperties);
231                         EntityManagerFactoryProvider.generateDDLFiles(session, deployProperties, !isInContainerMode);
232                     }
233                 }
234             } catch (RuntimeException JavaDoc exception) {
235                 cleanUpSessionManager();
236                 throw exception;
237             }
238             return session;
239         } catch (oracle.toplink.essentials.exceptions.ValidationException exception) {
240             throw new javax.persistence.PersistenceException(exception);
241         } finally {
242             session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_end", new Object JavaDoc[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount});
243             if(state == STATE_UNDEPLOYED) {
244                 session = null;
245             }
246         }
247     }
248
249
250     /**
251      * INTERNAL:
252      * Adds descriptors plus sequencing info found on the project to the session.
253      */

254     protected void addProjectToSession(ServerSession session, Project project) {
255         DatasourcePlatform sessionPlatform = (DatasourcePlatform)session.getDatasourceLogin().getDatasourcePlatform();
256         DatasourcePlatform projectPlatform = (DatasourcePlatform)project.getDatasourceLogin().getDatasourcePlatform();
257         if (!sessionPlatform.hasDefaultSequence() && projectPlatform.hasDefaultSequence()) {
258             sessionPlatform.setDefaultSequence(projectPlatform.getDefaultSequence());
259         }
260         if ((sessionPlatform.getSequences() == null) || sessionPlatform.getSequences().isEmpty()) {
261             if ((projectPlatform.getSequences() != null) && !projectPlatform.getSequences().isEmpty()) {
262                 sessionPlatform.setSequences(projectPlatform.getSequences());
263             }
264         } else {
265             if ((projectPlatform.getSequences() != null) && !projectPlatform.getSequences().isEmpty()) {
266                 Iterator itProjectSequences = projectPlatform.getSequences().values().iterator();
267                 while (itProjectSequences.hasNext()) {
268                     Sequence sequence = (Sequence)itProjectSequences.next();
269                     if (!sessionPlatform.getSequences().containsKey(sequence.getName())) {
270                         sessionPlatform.addSequence(sequence);
271                     }
272                 }
273             }
274         }
275         session.addDescriptors(project);
276     }
277     
278     /**
279      * INTERNAL:
280      * Put the given session into the session manager so it can be looked up later
281      */

282     protected void addSessionToGlobalSessionManager() {
283         AbstractSession oldSession = (AbstractSession)SessionManager.getManager().getSessions().get(session.getName());
284         if(oldSession != null) {
285             throw new PersistenceException(EntityManagerSetupException.attemptedRedeployWithoutClose(session.getName()));
286         }
287         SessionManager.getManager().addSession(session);
288     }
289
290     /**
291      * INTERNAL:
292      * Assign a CMP3Policy to each descriptor
293      */

294     protected void assignCMP3Policy() {
295         // all descriptors assigned CMP3Policy
296
Project project = session.getProject();
297         for (Iterator iterator = project.getDescriptors().values().iterator(); iterator.hasNext();){
298             //bug:4406101 changed class cast to base class, which is used in projects generated from 904 xml
299
ClassDescriptor descriptor = (ClassDescriptor)iterator.next();
300             
301             if(descriptor.getCMPPolicy() == null) {
302                 descriptor.setCMPPolicy(new CMP3Policy());
303             }
304         }
305     }
306
307     /**
308      * INTERNAL:
309      * Build a default TopLink ServerPlatform class for use with this platform.
310      */

311     protected void updateServerPlatform(Map m) {
312         String JavaDoc serverPlatformClassName = (String JavaDoc)PropertiesHandler.getPropertyValueLogDebug(TopLinkProperties.TARGET_SERVER, m, session);
313         if (serverPlatformClassName == null) {
314             return;
315         }
316
317         ServerPlatform serverPlatform = null;
318         Class JavaDoc cls = findClassForProperty(serverPlatformClassName, TopLinkProperties.TARGET_SERVER);
319         try {
320             Constructor JavaDoc constructor = cls.getConstructor(new Class JavaDoc[]{oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.class});
321             serverPlatform = (ServerPlatform)constructor.newInstance(new Object JavaDoc[]{session});
322         } catch (Exception JavaDoc ex) {
323             if(ExternalTransactionController.class.isAssignableFrom(cls)) {
324                 CustomServerPlatform customServerPlatform = new CustomServerPlatform(session);
325                 customServerPlatform.setExternalTransactionControllerClass(cls);
326                 serverPlatform = customServerPlatform;
327             } else {
328                 throw EntityManagerSetupException.failedToInstantiateServerPlatform(serverPlatformClassName, TopLinkProperties.TARGET_SERVER, ex);
329             }
330         }
331         
332         if(!session.getLogin().shouldUseExternalTransactionController()) {
333             serverPlatform.disableJTA();
334         }
335         session.setServerPlatform(serverPlatform);
336
337         //Initialize the log for the serverPlatform
338
setNewLog(serverPlatform.getServerLog());
339     }
340
341     protected void setNewLog(SessionLog newLog) {
342         if(session.getSessionLog() == newLog) {
343             return;
344         }
345         
346         newLog.setLevel(session.getSessionLog().getLevel());
347         newLog.setShouldPrintDate(session.getSessionLog().shouldPrintDate());
348         newLog.setShouldPrintThread(session.getSessionLog().shouldPrintThread());
349         newLog.setShouldPrintSession(session.getSessionLog().shouldPrintSession());
350         newLog.setShouldLogExceptionStackTrace(session.getSessionLog().shouldLogExceptionStackTrace());
351         
352         session.setSessionLog(newLog);
353     }
354     
355     protected static Class JavaDoc findClass(String JavaDoc className) throws ClassNotFoundException JavaDoc, PrivilegedActionException JavaDoc {
356         if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
357             return (Class JavaDoc)AccessController.doPrivileged(new PrivilegedClassForName(className));
358         } else {
359             return oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(className);
360         }
361     }
362     
363     protected static Class JavaDoc findClassForProperty(String JavaDoc className, String JavaDoc propertyName) {
364         try {
365             return findClass(className);
366         } catch (PrivilegedActionException JavaDoc exception1) {
367             throw EntityManagerSetupException.classNotFoundForProperty(className, propertyName, exception1.getException());
368         } catch (ClassNotFoundException JavaDoc exception2) {
369             throw EntityManagerSetupException.classNotFoundForProperty(className, propertyName, exception2);
370         }
371     }
372     
373     protected void updateDescriptorCacheSettings(Map m) {
374         Map typeMap = PropertiesHandler.getPrefixValuesLogDebug(TopLinkProperties.CACHE_TYPE_, m, session);
375         Map sizeMap = PropertiesHandler.getPrefixValuesLogDebug(TopLinkProperties.CACHE_SIZE_, m, session);
376         Map sharedMap = PropertiesHandler.getPrefixValuesLogDebug(TopLinkProperties.CACHE_SHARED_, m, session);
377         if(typeMap.isEmpty() && sizeMap.isEmpty() && sharedMap.isEmpty()) {
378             return;
379         }
380
381         boolean hasDefault = false;
382         
383         String JavaDoc defaultTypeName = (String JavaDoc)typeMap.remove(TopLinkProperties.DEFAULT);
384         Class JavaDoc defaultType = null;
385         if(defaultTypeName != null) {
386             defaultType = findClassForProperty(defaultTypeName, TopLinkProperties.CACHE_TYPE_DEFAULT);
387             hasDefault = true;
388         }
389         
390         String JavaDoc defaultSizeString = (String JavaDoc)sizeMap.remove(TopLinkProperties.DEFAULT);
391         Integer JavaDoc defaultSize = null;
392         if(defaultSizeString != null) {
393             defaultSize = Integer.parseInt(defaultSizeString);
394             hasDefault = true;
395         }
396         
397         String JavaDoc defaultSharedString = (String JavaDoc)sharedMap.remove(TopLinkProperties.CACHE_SHARED_DEFAULT);
398         Boolean JavaDoc defaultShared = null;
399         if(defaultSharedString != null) {
400             defaultShared = Boolean.parseBoolean(defaultSharedString);
401             hasDefault = true;
402         }
403         
404         Iterator it = session.getDescriptors().values().iterator();
405         while (it.hasNext() && (hasDefault || !typeMap.isEmpty() || !sizeMap.isEmpty() || !sharedMap.isEmpty())) {
406             ClassDescriptor descriptor = (ClassDescriptor)it.next();
407             
408             if(descriptor.isAggregateDescriptor() || descriptor.isAggregateCollectionDescriptor()) {
409                 continue;
410             }
411             
412             String JavaDoc entityName = descriptor.getAlias();
413             String JavaDoc className = descriptor.getJavaClass().getName();
414             String JavaDoc name;
415             
416             Class JavaDoc type = defaultType;
417             name = entityName;
418             String JavaDoc typeName = (String JavaDoc)typeMap.remove(name);
419             if(typeName == null) {
420                 name = className;
421                 typeName = (String JavaDoc)typeMap.remove(name);
422             }
423             if(typeName != null) {
424                 type = findClassForProperty(typeName, TopLinkProperties.CACHE_TYPE_ + name);
425             }
426             if(type != null) {
427                 descriptor.setIdentityMapClass(type);
428             }
429
430             Integer JavaDoc size = defaultSize;
431             name = entityName;
432             String JavaDoc sizeString = (String JavaDoc)sizeMap.remove(name);
433             if(sizeString == null) {
434                 name = className;
435                 sizeString = (String JavaDoc)sizeMap.remove(name);
436             }
437             if(sizeString != null) {
438                 size = Integer.parseInt(sizeString);
439             }
440             if(size != null) {
441                 descriptor.setIdentityMapSize(size.intValue());
442             }
443
444             Boolean JavaDoc shared = defaultShared;
445             name = entityName;
446             String JavaDoc sharedString = (String JavaDoc)sharedMap.remove(name);
447             if(sharedString == null) {
448                 name = className;
449                 sharedString = (String JavaDoc)sharedMap.remove(name);
450             }
451             if(sharedString != null) {
452                 shared = Boolean.parseBoolean(sharedString);
453             }
454             if(shared != null) {
455                 descriptor.setIsIsolated(!shared.booleanValue());
456             }
457         }
458     }
459
460     /**
461      * Perform any steps necessary prior to actual deployment. This includes any steps in the session
462      * creation that do not require the real loaded domain classes.
463      *
464      * @return A transformer (which may be null) that should be plugged into the proper
465      * classloader to allow classes to be transformed as they get loaded.
466      * @see predeploy(Collection entities, ClassLoader privateClassLoader, PersistenceUnitInfo info)
467      */

468     public ClassTransformer predeploy(PersistenceUnitInfo info, Map extendedProperties) {
469         if(state == STATE_INITIAL) {
470             persistenceUnitInfo = info;
471         }
472         ClassLoader JavaDoc privateClassLoader = persistenceUnitInfo.getNewTempClassLoader();
473         predeployProperties = EntityManagerFactoryProvider.mergeMaps(extendedProperties, persistenceUnitInfo.getProperties());
474
475         //Bug5389828. Update the logging settings for the singleton logger.
476
initOrUpdateLogging(true, predeployProperties, AbstractSessionLog.getLog());
477         // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use
478
Collection entities = buildEntityList(persistenceUnitInfo, privateClassLoader);
479
480         session = new ServerSession(new Project(new DatabaseLogin()));
481         EntityManagerFactoryProvider.translateOldProperties(predeployProperties, session);
482         initOrUpdateLogging(true, predeployProperties, session.getSessionLog());
483         session.getPlatform().setConversionManager(new EJB30ConversionManager());
484     
485         if(!isValidationOnly(predeployProperties, false) && persistenceUnitInfo != null && persistenceUnitInfo.getTransactionType() == PersistenceUnitTransactionType.JTA) {
486             if(persistenceUnitInfo.getJtaDataSource() == null) {
487                 throw new PersistenceException(EntityManagerSetupException.jtaPersistenceUnitInfoMissingJtaDataSource(persistenceUnitInfo.getPersistenceUnitName()));
488             }
489         }
490         
491         // this flag is used to disable work done as a result of the LAZY hint on OneToOne mappings
492
if(state == STATE_INITIAL ) {
493             enableLazyForOneToOne = true;
494             String JavaDoc weaving = getConfigPropertyAsString(TopLinkProperties.WEAVING);
495             if (weaving != null && weaving.equalsIgnoreCase("false")) {
496                 enableLazyForOneToOne = false;
497             }
498         }
499
500         // Process the Object/relational metadata from XML and annotations.
501
processORMetadata(privateClassLoader, session, entities, enableLazyForOneToOne);
502
503         // The connector will be reconstructed when the session is actually deployed
504
session.getProject().getLogin().setConnector(new DefaultConnector());
505
506         if (session.getIntegrityChecker().hasErrors()){
507             session.handleException(new IntegrityException(session.getIntegrityChecker()));
508         }
509
510         // The transformer is capable of altering domain classes to handle a LAZY hint for OneToOne mappings. It will only
511
// be returned if we we are mean to process these mappings
512
ClassTransformer transformer = null;
513         if (enableLazyForOneToOne){
514             transformer = TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader);
515         }
516         
517         state = STATE_PREDEPLOYED;
518         return transformer;
519     }
520
521     /**
522      * INTERNAL:
523      * In case the session is not connected applies to it properties m.
524      */

525     public ServerSession getServerSession(Map m) {
526         updateServerSession(m);
527         return session;
528     }
529
530       /**
531    * Check the provided map for an object with the given key. If that object is not available, check the
532    * System properties. If it is not available from either location, return the default value.
533    * @param propertyKey
534    * @param map
535    * @param defaultValue
536    * @return
537    */

538     public String JavaDoc getConfigPropertyAsString(String JavaDoc propertyKey, String JavaDoc defaultValue){
539         return EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(propertyKey, predeployProperties, defaultValue, session);
540     }
541
542     public String JavaDoc getConfigPropertyAsString(String JavaDoc propertyKey){
543         return EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(propertyKey, predeployProperties, session);
544     }
545
546     /**
547      * Return the name of the session this SetupImpl is building. The session name is only known at deploy
548      * time and if this method is called prior to that, this method will return null.
549      * @return
550      */

551     public String JavaDoc getDeployedSessionName(){
552         return session != null ? session.getName() : null;
553     }
554     
555     public PersistenceUnitInfo getPersistenceUnitInfo(){
556         return persistenceUnitInfo;
557     }
558     
559     public boolean isValidationOnly(Map m) {
560         return isValidationOnly(m, true);
561     }
562     
563     protected boolean isValidationOnly(Map m, boolean shouldMergeMap) {
564         if(shouldMergeMap) {
565             m = mergeWithExistingMap(m);
566         }
567         String JavaDoc validationOnlyString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(EntityManagerFactoryProvider.TOPLINK_VALIDATION_ONLY_PROPERTY, m, session);
568         if(validationOnlyString != null) {
569             return Boolean.parseBoolean(validationOnlyString);
570         } else {
571             return false;
572         }
573     }
574     
575     public boolean shouldGetSessionOnCreateFactory(Map m) {
576         m = mergeWithExistingMap(m);
577         return isValidationOnly(m, false);
578     }
579     
580     protected Map mergeWithExistingMap(Map m) {
581         if(predeployProperties != null) {
582             return EntityManagerFactoryProvider.mergeMaps(m, predeployProperties);
583         } else if(persistenceUnitInfo != null) {
584             return EntityManagerFactoryProvider.mergeMaps(m, persistenceUnitInfo.getProperties());
585         } else {
586             return m;
587         }
588     }
589
590     public boolean isInContainerMode(){
591         return isInContainerMode;
592     }
593
594     /**
595      * Handle an exception that occured while processing ORM xml
596      */

597     protected void handleORMException(RuntimeException JavaDoc e, AbstractSession session, String JavaDoc mappingFileResourceName){
598         String JavaDoc throwXMLExceptions = getConfigPropertyAsString(EntityManagerFactoryProvider.TOPLINK_ORM_THROW_EXCEPTIONS, "true");
599         // if fail quietly
600
if (throwXMLExceptions == null || throwXMLExceptions.equalsIgnoreCase("false")) {
601             session.log(SessionLog.CONFIG, SessionLog.EJB_ORM, ERROR_LOADING_XML_FILE, new Object JavaDoc[] {mappingFileResourceName, e});
602         } else {
603             // fail loudly
604
session.handleException(e);
605         }
606     }
607    
608     private List<String JavaDoc> getORMXMLFileNames(ClassLoader JavaDoc loader){
609         ArrayList<String JavaDoc> list = new ArrayList<String JavaDoc>();
610         String JavaDoc ormXMLFile = "META-INF/orm.xml";
611         InputStream JavaDoc stream = null;
612         try {
613             stream = PersistenceUnitProcessor.createInputStreamForFileInPersistenceUnit(ormXMLFile, persistenceUnitInfo, loader);
614             if (stream != null){
615                 list.add(ormXMLFile);
616             }
617         } catch (IOException JavaDoc e){
618         } finally {
619             try{
620                 if (stream != null){
621                     stream.close();
622                 }
623             } catch (IOException JavaDoc e) {}
624         }
625         
626         if (persistenceUnitInfo != null) {
627             if (persistenceUnitInfo.getMappingFileNames() != null) {
628                 Iterator mappingFiles = persistenceUnitInfo.getMappingFileNames().iterator();{
629                     while (mappingFiles.hasNext()){
630                         list.add((String JavaDoc)mappingFiles.next());
631                     }
632                 }
633             }
634          }
635         return list;
636     }
637     
638
639   /**
640    * Override the default login creation method.
641    * If persistenceInfo is available, use the information from it to setup the login
642    * and possibly to set readConnectionPool.
643    * @param ss
644    * @param m
645    */

646     protected void updateLogins(Map m){
647         DatasourceLogin login = session.getLogin();
648     
649         // Note: This call does not checked the stored persistenceUnitInfo or extended properties because
650
// the map passed into this method should represent the full set of properties we expect to process
651

652         String JavaDoc user = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_USER, m, session);
653         String JavaDoc password = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_PASSWORD, m, session);
654         if(user != null) {
655             login.setUserName(user);
656         }
657         if(password != null) {
658             login.setPassword(securableObjectHolder.getSecurableObject().decryptPassword(password));
659         }
660
661         String JavaDoc toplinkPlatform = (String JavaDoc)PropertiesHandler.getPropertyValueLogDebug(TopLinkProperties.TARGET_DATABASE, m, session);
662         if (toplinkPlatform != null) {
663             login.setPlatformClassName(toplinkPlatform);
664         }
665
666         if (isValidationOnly(m, false) && persistenceUnitInfo.getTransactionType() == PersistenceUnitTransactionType.JTA && persistenceUnitInfo.getJtaDataSource() == null){
667             updateLoginDefaultConnector(login, m);
668             return;
669         }
670         
671         login.setUsesExternalTransactionController(persistenceUnitInfo.getTransactionType() == PersistenceUnitTransactionType.JTA);
672
673         javax.sql.DataSource JavaDoc mainDatasource = null;
674         javax.sql.DataSource JavaDoc readDatasource = null;
675         if(login.shouldUseExternalTransactionController()) {
676             // JtaDataSource is guaranteed to be non null - otherwise exception would've been thrown earlier
677
mainDatasource = persistenceUnitInfo.getJtaDataSource();
678             // only define readDatasource if there is jta mainDatasource
679
readDatasource = persistenceUnitInfo.getNonJtaDataSource();
680         } else {
681             // JtaDataSource will be ignored because transactionType is RESOURCE_LOCAL
682
if(persistenceUnitInfo.getJtaDataSource() != null) {
683                 session.log(SessionLog.WARNING, SessionLog.TRANSACTION, "resource_local_persistence_init_info_ignores_jta_data_source", persistenceUnitInfo.getPersistenceUnitName());
684             }
685             if(persistenceUnitInfo.getNonJtaDataSource() != null) {
686                 mainDatasource = persistenceUnitInfo.getNonJtaDataSource();
687             } else {
688                 updateLoginDefaultConnector(login, m);
689                 return;
690             }
691         }
692
693         // mainDatasource is guaranteed to be non null
694
if(!(login.getConnector() instanceof JNDIConnector)) {
695              JNDIConnector jndiConnector;
696             if (mainDatasource instanceof DataSourceImpl) {
697                 //Bug5209363 Pass in the datasource name instead of the dummy datasource
698
jndiConnector = new JNDIConnector(((DataSourceImpl)mainDatasource).getName());
699             } else {
700                 jndiConnector = new JNDIConnector(mainDatasource);
701             }
702             login.setConnector(jndiConnector);
703             login.setUsesExternalConnectionPooling(true);
704         }
705
706         // set readLogin
707
if(readDatasource != null) {
708             DatasourceLogin readLogin = (DatasourceLogin)login.clone();
709             readLogin.dontUseExternalTransactionController();
710             JNDIConnector jndiConnector;
711             if (readDatasource instanceof DataSourceImpl) {
712                 //Bug5209363 Pass in the datasource name instead of the dummy datasource
713
jndiConnector = new JNDIConnector(((DataSourceImpl)readDatasource).getName());
714             } else {
715                 jndiConnector = new JNDIConnector(readDatasource);
716             }
717             readLogin.setConnector(jndiConnector);
718             session.setReadConnectionPool(readLogin);
719         }
720         
721     }
722
723   /**
724    * In cases where there is no data source, we will use properties to configure the login for
725    * our session. This method gets those properties and sets them on the login.
726    * @param login
727    * @param m
728    */

729     protected void updateLoginDefaultConnector(DatasourceLogin login, Map m){
730         if((login.getConnector() instanceof DefaultConnector)) {
731             DatabaseLogin dbLogin = (DatabaseLogin)login;
732             // Note: This call does not checked the stored persistenceUnitInfo or extended properties because
733
// the map passed into this method should represent the full set of properties we expect to process
734
String JavaDoc jdbcDriver = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_DRIVER, m, session);
735             String JavaDoc connectionString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_URL, m, session);
736             if(connectionString != null) {
737                 dbLogin.setConnectionString(connectionString);
738             }
739             if(jdbcDriver != null) {
740                 dbLogin.setDriverClassName(jdbcDriver);
741             }
742         }
743     }
744
745     protected void updatePools(Map m) {
746         // Sizes are irrelevant for external connection pool
747
if(!session.getDefaultConnectionPool().getLogin().shouldUseExternalConnectionPooling()) {
748             String JavaDoc strWriteMin = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_WRITE_CONNECTIONS_MIN, m, session);
749             if(strWriteMin != null) {
750                 session.getDefaultConnectionPool().setMinNumberOfConnections(Integer.parseInt(strWriteMin));
751             }
752             String JavaDoc strWriteMax = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_WRITE_CONNECTIONS_MAX, m, session);
753             if(strWriteMax != null) {
754                 session.getDefaultConnectionPool().setMaxNumberOfConnections(Integer.parseInt(strWriteMax));
755             }
756         }
757         
758         // Sizes and shared option are irrelevant for external connection pool
759
if(!session.getReadConnectionPool().getLogin().shouldUseExternalConnectionPooling()) {
760             String JavaDoc strReadMin = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_READ_CONNECTIONS_MIN, m, session);
761             if(strReadMin != null) {
762                 session.getReadConnectionPool().setMinNumberOfConnections(Integer.parseInt(strReadMin));
763             }
764             String JavaDoc strReadMax = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_READ_CONNECTIONS_MAX, m, session);
765             if(strReadMax != null) {
766                 session.getReadConnectionPool().setMaxNumberOfConnections(Integer.parseInt(strReadMax));
767             }
768             String JavaDoc strShouldUseShared = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_READ_CONNECTIONS_SHARED, m,session);
769             if(strShouldUseShared != null) {
770                 boolean shouldUseShared = Boolean.parseBoolean(strShouldUseShared);
771                 boolean sessionUsesShared = session.getReadConnectionPool() instanceof ReadConnectionPool;
772                 if(shouldUseShared != sessionUsesShared) {
773                     Login readLogin = session.getReadConnectionPool().getLogin();
774                     int nReadMin = session.getReadConnectionPool().getMinNumberOfConnections();
775                     int nReadMax = session.getReadConnectionPool().getMaxNumberOfConnections();
776                     if(shouldUseShared) {
777                         session.useReadConnectionPool(nReadMin, nReadMax);
778                     } else {
779                         session.useExclusiveReadConnectionPool(nReadMin, nReadMax);
780                     }
781                     // keep original readLogin
782
session.getReadConnectionPool().setLogin(readLogin);
783                 }
784             }
785         }
786     }
787     
788   /**
789    * Normally when a property is missing nothing should be applied to the session.
790    * However there are several session attributes that defaulted in EJB3 to the values
791    * different from TopLink defaults (for instance, in TopLink defaults binding to false,
792    * EJB3 - to true).
793    * This function applies defaults for such properties.
794    * All other session-related properties are applied in updateServerSession.
795    * Note that updateServerSession may be called several times on the same session
796    * (before login), but initServerSession is called just once - before the first call
797    * to updateServerSession.
798    * @param ss
799    */

800     protected void initServerSession(Map m) {
801         assignCMP3Policy();
802
803         // use default session name if none is provided
804
String JavaDoc name = EntityManagerFactoryProvider.getConfigPropertyAsString(TopLinkProperties.SESSION_NAME, m);
805         if(name == null) {
806             if (persistenceUnitInfo.getPersistenceUnitRootUrl() != null){
807                 name = persistenceUnitInfo.getPersistenceUnitRootUrl().toString() + "-" + persistenceUnitInfo.getPersistenceUnitName();
808             } else {
809                 name = persistenceUnitInfo.getPersistenceUnitName();
810             }
811             session.setName(name);
812 // session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "property_value_default", new Object[]{TopLinkProperties.SESSION_NAME, name});
813
addSessionToGlobalSessionManager();
814         }
815         
816         // shouldBindAllParameters is true by default - set it if no property provided
817
if (EntityManagerFactoryProvider.getConfigPropertyAsString(TopLinkProperties.JDBC_BIND_PARAMETERS, m) == null) {
818 // session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "property_value_default", new Object[]{TopLinkProperties.JDBC_BIND_PARAMETERS, "true"});
819
session.getPlatform().setShouldBindAllParameters(true);
820         }
821         
822         // set default descriptor cache size - set it to all descriptors if CACHE_SIZE_DEFAULT not provided
823
if (PropertiesHandler.getPrefixedPropertyValue(TopLinkProperties.CACHE_SIZE_, TopLinkProperties.DEFAULT, m) == null) {
824 // int defaultCacheSize = Integer.parseInt(PropertiesHandler.getDefaultPropertyValueLogDebug(TopLinkProperties.CACHE_SIZE_, session));
825
int defaultCacheSize = Integer.parseInt(PropertiesHandler.getDefaultPropertyValue(TopLinkProperties.CACHE_SIZE_));
826             Iterator descriptorsIterator = session.getDescriptors().values().iterator();
827             while (descriptorsIterator.hasNext()) {
828                  ((ClassDescriptor)descriptorsIterator.next()).setIdentityMapSize(defaultCacheSize);
829             }
830         }
831     }
832
833
834   /**
835    * Make any changes to our ServerSession that can be made after it is created.
836    * @param ss
837    * @param m
838    */

839     protected void updateServerSession(Map m) {
840         if (session == null || session.isConnected()) {
841             return;
842         }
843
844         initOrUpdateLogging(false, m, AbstractSessionLog.getLog());
845         initOrUpdateLogging(false, m, session.getSessionLog());
846
847         updateSessionName(m);
848         String JavaDoc shouldBindString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.JDBC_BIND_PARAMETERS, m, session);
849         if (shouldBindString != null) {
850             session.getPlatform().setShouldBindAllParameters(Boolean.parseBoolean(shouldBindString));
851         }
852
853         updateLogins(m);
854         
855         // update ServerPlatform must be called after updateLogins - to set correct useJTA flag
856
updateServerPlatform(m);
857
858         updatePools(m);
859         
860         updateDescriptorCacheSettings(m);
861
862         // Customizers should be processed last
863
processDescriptorCustomizers(m);
864         processSessionCustomizer(m);
865     }
866
867   /**
868    * This sets the isInContainerMode flag.
869    * "true" indicates container case, "false" - SE.
870    * @param isInContainerMode
871    */

872     public void setIsInContainerMode(boolean isInContainerMode) {
873         this.isInContainerMode = isInContainerMode;
874    }
875
876    protected void processSessionCustomizer(Map m) {
877         String JavaDoc sessionCustomizerClassName = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.SESSION_CUSTOMIZER, m, session);
878         if(sessionCustomizerClassName == null) {
879             return;
880         }
881         
882         Class JavaDoc sessionCustomizerClass = findClassForProperty(sessionCustomizerClassName, TopLinkProperties.SESSION_CUSTOMIZER);
883         SessionCustomizer sessionCustomizer;
884         try {
885             sessionCustomizer = (SessionCustomizer)sessionCustomizerClass.newInstance();
886             sessionCustomizer.customize(session);
887         } catch (Exception JavaDoc ex) {
888             throw EntityManagerSetupException.failedWhileProcessingProperty(TopLinkProperties.SESSION_CUSTOMIZER, sessionCustomizerClassName, ex);
889         }
890    }
891
892     protected void initOrUpdateLogging(boolean init, Map m, SessionLog log) {
893         String JavaDoc logLevelString = PropertiesHandler.getPropertyValueLogDebug(TopLinkProperties.LOGGING_LEVEL, m, session);
894         if(logLevelString == null && init) {
895             logLevelString = PropertiesHandler.getDefaultPropertyValueLogDebug(TopLinkProperties.LOGGING_LEVEL, session);
896         }
897         if (logLevelString != null) {
898             log.setLevel(AbstractSessionLog.translateStringToLoggingLevel(logLevelString));
899         }
900         String JavaDoc tsString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.LOGGING_TIMESTAMP, m, session);
901         if (tsString != null) {
902             log.setShouldPrintDate(Boolean.parseBoolean(tsString));
903         }
904         String JavaDoc threadString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.LOGGING_THREAD, m, session);
905         if (threadString != null) {
906             log.setShouldPrintThread(Boolean.parseBoolean(threadString));
907         }
908         String JavaDoc sessionString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.LOGGING_SESSION, m, session);
909         if (sessionString != null) {
910             log.setShouldPrintSession(Boolean.parseBoolean(sessionString));
911         }
912         String JavaDoc exString = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.LOGGING_EXCEPTIONS, m, session);
913         if (exString != null) {
914             log.setShouldLogExceptionStackTrace(Boolean.parseBoolean(exString));
915         }
916     }
917
918     protected void updateSessionName(Map m) {
919         String JavaDoc newName = EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(TopLinkProperties.SESSION_NAME, m, session);
920         if(newName == null || newName.equals(session.getName())) {
921             return;
922         }
923
924         removeSessionFromGlobalSessionManager();
925         session.setName(newName);
926         addSessionToGlobalSessionManager();
927     }
928     
929     protected void processDescriptorCustomizers(Map m) {
930         Map customizerMap = PropertiesHandler.getPrefixValuesLogDebug(TopLinkProperties.DESCRIPTOR_CUSTOMIZER_, m, session);
931         if(customizerMap.isEmpty()) {
932             return;
933         }
934
935         Iterator it = customizerMap.entrySet().iterator();
936         while (it.hasNext()) {
937             Map.Entry entry = (Map.Entry)it.next();
938             String JavaDoc name = (String JavaDoc)entry.getKey();
939             
940             ClassDescriptor descriptor = session.getDescriptorForAlias(name);
941             if(descriptor == null) {
942                 try {
943                     Class JavaDoc javaClass = findClass(name);
944                     descriptor = session.getDescriptor(javaClass);
945                 } catch (Exception JavaDoc ex) {
946                     // Ignore exception
947
}
948             }
949             if(descriptor != null) {
950                 String JavaDoc customizerClassName = (String JavaDoc)entry.getValue();
951                 Class JavaDoc customizerClass = findClassForProperty(customizerClassName, TopLinkProperties.DESCRIPTOR_CUSTOMIZER_ + name);
952                 try {
953                     DescriptorCustomizer customizer = (DescriptorCustomizer)customizerClass.newInstance();
954                     customizer.customize(descriptor);
955                 } catch (Exception JavaDoc ex) {
956                     throw EntityManagerSetupException.failedWhileProcessingProperty(TopLinkProperties.DESCRIPTOR_CUSTOMIZER_ + name, customizerClassName, ex);
957                 }
958             }
959         }
960     }
961     
962     private void processORMetadata(ClassLoader JavaDoc privateClassLoader, AbstractSession session, Collection entities, boolean enableLazyForOneToOne){
963         processor = new MetadataProcessor(session, privateClassLoader, enableLazyForOneToOne);
964        
965         List<String JavaDoc> mappingFileNames = getORMXMLFileNames(privateClassLoader);
966
967         // process persistence unit metadata/defaults defined in ORM XML instance documents in the persistence unit
968
processor.processPersistenceUnitMetadata(session, persistenceUnitInfo, mappingFileNames, entities);
969         
970         Iterator<String JavaDoc> fileNames = mappingFileNames.iterator();
971         InputStream JavaDoc inputStream = null;
972         String JavaDoc fileName = null;
973         while (fileNames.hasNext()){
974             try{
975                 fileName = fileNames.next();
976                 inputStream = PersistenceUnitProcessor.createInputStreamForFileInPersistenceUnit(fileName, persistenceUnitInfo, privateClassLoader);
977                 if (inputStream != null){
978                     processor.processXML(inputStream, fileName);
979                 }
980             } catch (RuntimeException JavaDoc e){
981                 handleORMException(e, session, fileName);
982             } catch (IOException JavaDoc exc){
983                 handleORMException(PersistenceUnitLoadingException.exceptionLoadingORMXML(fileName, exc), session, fileName);
984             } finally {
985                 try{
986                     if (inputStream != null){
987                         inputStream.close();
988                     }
989                 } catch (IOException JavaDoc exc){}
990             }
991         }
992         
993         session = (AbstractSession) processor.processAnnotations();
994     }
995     
996     public boolean isPredeployed() {
997         return state == STATE_PREDEPLOYED;
998     }
999
1000    public boolean isDeployed() {
1001        return state == STATE_DEPLOYED;
1002    }
1003
1004    public boolean isUndeployed() {
1005        return state == STATE_UNDEPLOYED;
1006    }
1007
1008    protected void cleanUpSessionManager() {
1009        deploymentCount--;
1010        if(deploymentCount > 0) {
1011            return;
1012        }
1013        state = STATE_UNDEPLOYED;
1014        removeSessionFromGlobalSessionManager();
1015    }
1016    
1017    /**
1018     * Undeploy may be called several times, but only the call that decreases
1019     * deploymentCount to 0 disconnects the session and removes it from the session manager.
1020     * Note that the session is an attribute of this class,
1021     * and could be deployed again (after been undeployed to deploymentCount 0 and disconnected).
1022     */

1023    public synchronized void undeploy() {
1024        if(state != STATE_DEPLOYED) {
1025            return;
1026        }
1027        session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_begin", new Object JavaDoc[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount});
1028        try {
1029            cleanUpSessionManager();
1030        } finally {
1031            session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_end", new Object JavaDoc[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount});
1032            if(state == STATE_UNDEPLOYED) {
1033                session = null;
1034            }
1035        }
1036    }
1037}
1038
Popular Tags