KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > containers > ContainerFactoryImpl


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 in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
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 Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.ejb.containers;
24
25 import java.io.File JavaDoc;
26
27 import java.util.*;
28 import java.lang.reflect.*;
29 import java.rmi.Remote JavaDoc;
30
31 import javax.ejb.*;
32 import javax.naming.InitialContext JavaDoc;
33 import javax.naming.InvalidNameException JavaDoc;
34 import javax.transaction.*;
35
36 import javax.persistence.EntityManagerFactory;
37 import javax.persistence.EntityManager;
38
39 import com.sun.ejb.*;
40 import com.sun.enterprise.*;
41 import com.sun.enterprise.deployment.*;
42 import com.sun.enterprise.deployment.runtime.IASEjbExtraDescriptors;
43 import com.sun.enterprise.log.Log;
44 import com.sun.enterprise.security.SecurityContext;
45
46 import com.sun.ejb.containers.builder.BaseContainerBuilder;
47 import com.sun.ejb.containers.builder.StatefulContainerBuilder;
48
49 import com.sun.ejb.containers.util.LongHashMap;
50 import com.sun.enterprise.util.LocalStringManagerImpl;
51
52 import com.sun.enterprise.config.ConfigException;
53 import com.sun.enterprise.server.ServerContext;
54 import com.sun.enterprise.server.ApplicationServer;
55 import com.sun.enterprise.config.serverbeans.EjbContainer;
56 import com.sun.enterprise.config.serverbeans.Config;
57 import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
58 import com.sun.enterprise.config.ConfigContext;
59
60 import java.util.logging.*;
61 import com.sun.logging.*;
62
63 import com.sun.ejb.spi.container.ContainerService;
64 import com.sun.ejb.base.container.ContainerServiceImpl;
65 import com.sun.ejb.base.io.IOUtils;
66
67 import com.sun.ejb.spi.distributed.DistributedEJBServiceFactory;
68 import com.sun.ejb.spi.distributed.DistributedEJBTimerService;
69 import com.sun.ejb.base.distributed.AdminEJBTimerEventListenerImpl;
70
71 import com.sun.enterprise.server.event.*;
72 import com.sun.enterprise.util.EntityManagerFactoryWrapper;
73
74 /**
75  * A factory for containers. Called from JarManagerImpl during
76  * deployment of EJB JARs and everytime the J2EEServer starts up.
77  * There is exactly one instance of ContainerFactoryImpl per JVM.
78  *
79  * @author Darpan Dinker
80  */

81
82 import com.sun.ejb.containers.util.PoolCacheTimer;
83
84 public final class ContainerFactoryImpl implements ContainerFactory {
85     private boolean debugMonitoring=false;
86     private long debugMonitoringPeriodMS = 60 * 1000L;
87
88     private static Logger _logger;
89     static {
90         _logger=LogDomains.getLogger(LogDomains.EJB_LOGGER);
91     }
92
93     private static final boolean debug = false;
94     public static final byte HOME_KEY = (byte)0xff;
95     public static final byte[] homeInstanceKey = {HOME_KEY};
96
97     private EJBTimerService ejbTimerService;
98
99     private PMTransactionManagerImpl pmtm;
100     private Hashtable syncTable = new Hashtable();
101
102     LongHashMap containers = new LongHashMap(128);
103
104     private ThreadLocal JavaDoc threadLocalContext = new ThreadLocal JavaDoc();
105     private Hashtable txBeanTable = new Hashtable();
106
107     private static PoolCacheTimer _timer = new PoolCacheTimer();
108     
109     private PoolCacheTimer _localTimer;
110
111     private static LocalStringManagerImpl localStrings =
112         new LocalStringManagerImpl(ContainerFactoryImpl.class);
113
114     private static ContainerService _containerService;
115
116     public ContainerFactoryImpl()
117     {
118
119         // Create the PMTransactionManagerImpl, this is looked up
120
// thru JNDI by the PM at the name "java:pm/TransactionManager".
121
pmtm = new PMTransactionManagerImpl();
122
123         _localTimer = _timer;
124
125         getDebugMonitoringDetails();
126         
127         if(debugMonitoring) {
128             _timer.schedule(new DebugMonitor(), 0L, debugMonitoringPeriodMS);
129         }
130
131         _containerService = new ContainerServiceImpl();
132         _containerService.initializeService();
133
134         IOUtils.setJ2EEObjectStreamFactory(
135             _containerService.getJ2EEObjectStreamFactory());
136         
137     }
138
139     public static ContainerService getContainerService() {
140         return _containerService;
141     }
142
143     public EntityManager lookupExtendedEntityManager(EntityManagerFactory factory) {
144
145         Switch theSwitch = Switch.getSwitch();
146
147         InvocationManager invMgr = theSwitch.getInvocationManager();
148         ComponentInvocation inv = invMgr.getCurrentInvocation();
149
150         EntityManager em = null;
151         
152         if( (inv != null) &&
153             (inv.getInvocationType() == ComponentInvocation.EJB_INVOCATION )) {
154
155             EjbDescriptor ejbDesc = (EjbDescriptor)
156                 theSwitch.getDescriptorFor(inv.getContainerContext());
157
158             if( (ejbDesc instanceof EjbSessionDescriptor) &&
159                 ( ((EjbSessionDescriptor)ejbDesc).isStateful() ) ) {
160                 em = ((SessionContextImpl)inv.context).
161                     getExtendedEntityManager(factory);
162             }
163         }
164
165         return em;
166     }
167
168     public void initEJBTimerService() throws Exception JavaDoc {
169         ejbTimerService = null;
170     }
171
172     /**
173      * Set EJB Timer Service. Can be null if timer service is being disabled.
174      */

175     public void setEJBTimerService(EJBTimerService ejbTimerService) {
176         this.ejbTimerService = ejbTimerService;
177
178         DistributedEJBServiceFactory.setDistributedEJBTimerService(
179             (DistributedEJBTimerService)ejbTimerService );
180
181         if( null != ejbTimerService ) {
182             //Register the Admin event listener to satisfy requests from the
183
//admin cli. The AdminEJBTimerListerner is created as a singleton
184
AdminEJBTimerEventListenerImpl.getEjbTimerEventListener();
185         }
186     }
187
188     public void restoreEJBTimers() throws Exception JavaDoc {
189         if( ejbTimerService != null ) {
190             ejbTimerService.restoreTimers();
191         }
192     }
193
194     public void shutdownEJBTimerService() {
195         if( ejbTimerService != null ) {
196             ejbTimerService.shutdown();
197         }
198     }
199
200     private void getDebugMonitoringDetails() {
201         try{
202             Properties props = System.getProperties();
203             String JavaDoc str=props.getProperty("MONITOR_EJB_CONTAINER");
204             if( null != str) {
205         str = str.toLowerCase();
206                 debugMonitoring = Boolean.valueOf(str).booleanValue();
207         String JavaDoc period =
208             props.getProperty("MONITOR_EJB_TIME_PERIOD_SECONDS");
209         if (period != null) {
210                 debugMonitoringPeriodMS =
211             (new Long JavaDoc(period).longValue())* 1000;
212         }
213             }
214         } catch(Exception JavaDoc e) {
215             _logger.log(Level.INFO,
216                 "ContainerFactoryImpl.getDebugMonitoringDetails(), " +
217                 " Exception when trying to " +
218                 "get the System properties - ", e);
219         }
220     }
221
222     public static java.util.Timer JavaDoc getTimer() {
223         return _timer;
224     }
225
226     public TransactionManager getTransactionMgr()
227     {
228         return pmtm;
229     }
230
231     public Container createContainer(EjbDescriptor ejbDescriptor,
232                      ClassLoader JavaDoc loader,
233                      com.sun.enterprise.SecurityManager sm,
234                      ConfigContext dynamicConfigContext)
235          throws Exception JavaDoc
236     {
237         BaseContainer container = null;
238         boolean hasHome = true;
239         String JavaDoc commitOption = null;
240         String JavaDoc appid = ejbDescriptor.getApplication().getRegistrationName();
241         String JavaDoc archiveuri = ejbDescriptor.getEjbBundleDescriptor().
242             getModuleDescriptor().getArchiveUri();
243             
244         String JavaDoc modulename =
245             com.sun.enterprise.util.io.FileUtils.makeFriendlyFilename(archiveuri);
246         String JavaDoc ejbname = ejbDescriptor.getName();
247
248         IASEjbExtraDescriptors iased = null;
249         //Server svr = null;
250
Config cfg = null;
251         EjbContainer ejbContainerDesc = null;
252
253         try {
254             // instantiate container class
255
if (ejbDescriptor instanceof EjbSessionDescriptor) {
256                 EjbSessionDescriptor sd = (EjbSessionDescriptor)ejbDescriptor;
257                 if ( sd.isStateless() ) {
258                     container = new StatelessSessionContainer(ejbDescriptor, loader);
259                 } else {
260                     //container = new StatefulSessionContainer(ejbDescriptor, loader);
261
BaseContainerBuilder builder =
262             new StatefulContainerBuilder();
263             builder.buildContainer(ejbDescriptor, loader,
264             dynamicConfigContext);
265             container = builder.getContainer();
266             //containers.put(ejbDescriptor.getUniqueId(), container);
267
//builder.completeInitialization(sm);
268
}
269             } else if ( ejbDescriptor instanceof EjbMessageBeanDescriptor ) {
270                 container = new MessageBeanContainer(ejbDescriptor, loader);
271         // Message-driven beans don't have a home or remote interface.
272
hasHome = false;
273             } else {
274                 if (((EjbEntityDescriptor)ejbDescriptor).getIASEjbExtraDescriptors()
275                     .isIsReadOnlyBean()) {
276
277                     EjbEntityDescriptor robDesc = (EjbEntityDescriptor) ejbDescriptor;
278                     container = new ReadOnlyBeanContainer (ejbDescriptor, loader);
279                 } else
280                     if ((ejbDescriptor.getLocalHomeClassName() != null) &&
281                         (ejbDescriptor.getLocalHomeClassName()
282                          .equals("com.sun.ejb.containers.TimerLocalHome"))) {
283                         container = new TimerBeanContainer(ejbDescriptor, loader);
284                     } else {
285                         iased = ((EjbEntityDescriptor)ejbDescriptor).
286                             getIASEjbExtraDescriptors();
287                         if (iased != null) {
288                             commitOption = iased.getCommitOption();
289                         }
290                         if (commitOption == null) {
291                             try {
292                                 ServerContext sc =
293                                     ApplicationServer.getServerContext();
294
295                                 cfg = ServerBeansFactory.getConfigBean
296                                     (sc.getConfigContext());
297  
298                             } catch (ConfigException ex) {
299                                 _logger.log(Level.WARNING,
300                                             "ejb.createContainer_exception", ex);
301                             }
302
303                             ejbContainerDesc = cfg.getEjbContainer();
304  
305                             commitOption = ejbContainerDesc.getCommitOption();
306                         }
307                         if (commitOption.equals("A")) {
308                             _logger.log(Level.WARNING,
309                                         "ejb.commit_option_A_not_supported",
310                                         new Object JavaDoc []{ejbDescriptor.getName()}
311                                         );
312                             container =
313                                 new EntityContainer(ejbDescriptor, loader);
314                         } else if (commitOption.equals("C")) {
315                             _logger.log(Level.FINE, "Using commit option C for: "
316                                         + ejbDescriptor.getName());
317                             container = new CommitCEntityContainer(ejbDescriptor,
318                                                                    loader);
319                         } else {
320                             _logger.log(Level.FINE,"Using commit option B for: " +
321                                         ejbDescriptor.getName());
322                             container = new EntityContainer(ejbDescriptor, loader);
323                         }
324                     }
325                 ((EntityContainer)container).setTxBeanTable(txBeanTable);
326             }
327
328             containers.put(ejbDescriptor.getUniqueId(), container);
329         
330             container.setSecurityManager(sm);
331     
332             // Initialize home after putting the container into containers,
333
// so that any calls from ProtocolManager during home initialization
334
// (e.g. is_a during PRO.narrow) will work.
335
if ( hasHome ) {
336                 container.initializeHome();
337             }
338
339             container.setDebugMonitorFlag(debugMonitoring);
340
341             return container;
342         } catch ( InvalidNameException JavaDoc ex ) {
343             _logger.log(Level.SEVERE,"ejb.create_container_exception", ex.toString());
344             _logger.log(Level.SEVERE,"Invalid jndiName for" + "appId=" + appid +
345                         "; moduleName=" + modulename + "; ejbName=" + ejbname);
346             _logger.log(Level.SEVERE,"jndiName=" + ejbDescriptor.getJndiName());
347             
348             // removes the ejb from containers table
349
try {
350                 removeContainer(ejbDescriptor.getUniqueId());
351             } catch (Exception JavaDoc e) {
352                 _logger.log(Level.FINE, "", e);
353             }
354             
355             throw ex;
356         } catch (UnsupportedOperationException JavaDoc unSupEx) {
357             throw unSupEx;
358         } catch ( Exception JavaDoc ex ) {
359             _logger.log(Level.SEVERE,"ejb.create_container_exception", ex.toString());
360             _logger.log(Level.SEVERE,"appId=" + appid + " moduleName=" + modulename +
361                         " ejbName=" + ejbname);
362             if (debug) {
363                 _logger.log(Level.SEVERE, ex.getMessage(), ex);
364             }
365             
366             // removes the ejb from containers table
367
try {
368                 removeContainer(ejbDescriptor.getUniqueId());
369             } catch (Exception JavaDoc e) {
370                 _logger.log(Level.FINE, "", e);
371             }
372             
373             throw ex;
374         }
375     }
376
377
378     /**
379      * Get the container instance corresponding to the given EJB id.
380      * Called from the POAProtocolMgr when an invocation arrives for
381      * the home/remote object (and other callers).
382      */

383     public Container getContainer(long ejbId) {
384         return (Container)containers.get(ejbId);
385     }
386
387
388     /**
389      * Remove the container instance corresponding to the given EJB id.
390      */

391     public void removeContainer(long ejbId) {
392         containers.remove(ejbId);
393     }
394
395     /**
396      * List all container instances in this JVM.
397      */

398     public Enumeration listContainers() {
399         return containers.elements();
400     }
401
402
403     /**
404      * Return the EjbDescriptor for the given ejbId.
405      * Called from the ProtocolManager.
406      */

407     public EjbDescriptor getEjbDescriptor(long ejbId)
408     {
409         Container c = (Container)containers.get(ejbId);
410
411         if ( c == null ) {
412             return null;
413         }
414         return c.getEjbDescriptor();
415     }
416
417     public Object JavaDoc getEJBContextObject(String JavaDoc contextType) {
418
419         InvocationManager invMgr = Switch.getSwitch().getInvocationManager();
420
421         ComponentInvocation currentInv = invMgr.getCurrentInvocation();
422
423         if(currentInv == null) {
424             throw new IllegalStateException JavaDoc("no current invocation");
425         } else if (currentInv.getInvocationType() !=
426                    ComponentInvocation.EJB_INVOCATION) {
427             throw new IllegalStateException JavaDoc
428                 ("Illegal invocation type for EJB Context : "
429                  + currentInv.getInvocationType());
430         }
431         
432         Object JavaDoc returnObject = currentInv.context;
433
434         if( contextType.equals("javax.ejb.TimerService") ) {
435             if( ejbTimerService == null ) {
436                 throw new IllegalStateException JavaDoc("EJB Timer Service not " +
437                                                 "available");
438             }
439             returnObject = new EJBTimerServiceWrapper
440                 (ejbTimerService, (EJBContextImpl) currentInv.context);
441         }
442
443         return returnObject;
444     }
445
446     EJBTimerService getEJBTimerService() {
447         return ejbTimerService;
448     }
449     
450
451     /**
452      * Get/create a ContainerSynchronization object for the given tx.
453      * Called only from BaseContainer.
454      */

455     ContainerSynchronization getContainerSync(Transaction tx)
456         throws RollbackException, SystemException
457     {
458         ContainerSynchronization sync =
459             (ContainerSynchronization)syncTable.get(tx);
460         if ( sync == null ) {
461             sync = new ContainerSynchronization(tx, this);
462             tx.registerSynchronization(sync);
463             syncTable.put(tx, sync);
464         }
465         return sync;
466     }
467     
468     void removeContainerSync(Transaction tx) {
469         syncTable.remove(tx);
470         txBeanTable.remove(tx);
471     }
472
473
474     class DebugMonitor
475     extends java.util.TimerTask JavaDoc {
476         public void run() {
477             try {
478                 Enumeration enumContainers = listContainers();
479                 if( null == enumContainers ) {
480                     _logger.log(Level.INFO,
481                    "MONITORING:: No containers available to report monitoring stats");
482                     return;
483                 }
484                 while(enumContainers.hasMoreElements()) {
485                     BaseContainer container =
486             (BaseContainer) enumContainers.nextElement();
487             container.logMonitoredComponentsData();
488             /*
489                     if(container instanceof EntityContainer) {
490                         _logger.log(Level.INFO, "MONITORING::" +
491                            ((EntityContainer)container).getMonitorAttributeValues() );
492                     } else if (container instanceof StatefulSessionContainer) {
493                         _logger.log(Level.INFO, "MONITORING::" +
494                            ((StatefulSessionContainer)container).
495                                     getMonitorAttributeValues() );
496                     } else if (container instanceof StatelessSessionContainer) {
497                         _logger.log(Level.INFO, "MONITORING::" +
498                            ((StatelessSessionContainer)container).
499                                     getMonitorAttributeValues() );
500                     } else if (container instanceof MessageBeanContainer) {
501                         _logger.log(Level.INFO, "MONITORING::" +
502                            ((MessageBeanContainer)container).
503                                     getMonitorAttributeValues() );
504                     }
505             */

506                 }
507             } catch (Throwable JavaDoc th) {
508                 _logger.log(Level.FINE, "Exception thrown", th);
509             }
510         }
511     }
512
513 } //ContainerFactoryImpl
514

515 class BeanContext {
516     ClassLoader JavaDoc previousClassLoader;
517     boolean classLoaderSwitched;
518     SecurityContext previousSecurityContext;
519 }
520
521 class ArrayListStack
522     extends ArrayList
523 {
524     /**
525      * Creates a stack with the given initial size
526      */

527     public ArrayListStack(int size) {
528         super(size);
529     }
530     
531     /**
532      * Creates a stack with a default size
533      */

534     public ArrayListStack() {
535         super();
536     }
537
538     /**
539      * Pushes an item onto the top of this stack. This method will internally
540      * add elements to the <tt>ArrayList</tt> if the stack is full.
541      *
542      * @param obj the object to be pushed onto this stack.
543      * @see java.util.ArrayList#add
544      */

545     public void push(Object JavaDoc obj) {
546         super.add(obj);
547     }
548
549     /**
550      * Removes the object at the top of this stack and returns that
551      * object as the value of this function.
552      *
553      * @return The object at the top of this stack (the last item
554      * of the <tt>ArrayList</tt> object). Null if stack is empty.
555      */

556     public Object JavaDoc pop() {
557         int sz = super.size();
558         return (sz > 0) ? super.remove(sz-1) : null;
559     }
560     
561     /**
562      * Tests if this stack is empty.
563      *
564      * @return <code>true</code> if and only if this stack contains
565      * no items; <code>false</code> otherwise.
566      */

567     public boolean empty() {
568         return super.size() == 0;
569     }
570
571     /**
572      * Looks at the object at the top of this stack without removing it
573      * from the stack.
574      *
575      * @return the object at the top of this stack (the last item
576      * of the <tt>ArrayList</tt> object). Null if stack is empty.
577      */

578     public Object JavaDoc peek() {
579         int sz = size();
580         return (sz > 0) ? super.get(sz-1) : null;
581     }
582
583
584
585 } //ArrayListStack
586

587
Popular Tags