KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > SessionContainer


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb;
23
24 // $Id: SessionContainer.java 43759 2006-04-13 18:59:32Z csuconic $
25

26 import java.lang.reflect.Method JavaDoc;
27 import java.rmi.RemoteException JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Hashtable JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.Map JavaDoc;
32
33 import javax.ejb.EJBHome JavaDoc;
34 import javax.ejb.EJBLocalHome JavaDoc;
35 import javax.ejb.EJBMetaData JavaDoc;
36 import javax.ejb.EJBObject JavaDoc;
37 import javax.ejb.Handle JavaDoc;
38 import javax.ejb.HomeHandle JavaDoc;
39 import javax.ejb.RemoveException JavaDoc;
40 import javax.ejb.TimedObject JavaDoc;
41 import javax.ejb.Timer JavaDoc;
42 import javax.management.ObjectName JavaDoc;
43
44 import org.jboss.invocation.Invocation;
45 import org.jboss.invocation.MarshalledInvocation;
46 import org.jboss.metadata.SessionMetaData;
47
48 /**
49  * <p>
50  * Container dedicated to session beans. Contains factored out
51  * redundancies between stateless and stateful treatments, because
52  * (extending the spec) we would like to also support stateful
53  * web services.
54  * </p>
55  * @author <a HREF="mailto:Christoph.Jung@infor.de">Christoph G. Jung</a>
56  * @version $Revision: 43759 $
57  * @since 30.10.2003
58  */

59 public abstract class SessionContainer extends Container
60 {
61    /**
62     * These are the mappings between the home interface methods and the
63     * container methods.
64     */

65    protected Map JavaDoc homeMapping;
66
67    /**
68     * These are the mappings between the remote interface methods and the
69     * bean methods.
70     */

71    protected Map JavaDoc beanMapping;
72
73    /**
74     * This is the first interceptor in the chain. The last interceptor must
75     * be provided by the container itself
76     */

77    protected Interceptor interceptor;
78
79    /** this is the service endpoint class */
80    protected Class JavaDoc serviceEndpoint;
81
82    /** This is the instancepool that is to be used */
83    protected InstancePool instancePool;
84
85    /** set the instance pool */
86    public void setInstancePool(InstancePool ip)
87    {
88       if (ip == null)
89          throw new IllegalArgumentException JavaDoc("Null pool");
90
91       this.instancePool = ip;
92       ip.setContainer(this);
93    }
94
95    /** return instance pool */
96    public InstancePool getInstancePool()
97    {
98       return instancePool;
99    }
100
101    /** return local proxy factory */
102    public LocalProxyFactory getLocalProxyFactory()
103    {
104       return localProxyFactory;
105    }
106
107    /** add an additional interceptor to the chain */
108    public void addInterceptor(Interceptor in)
109    {
110       if (interceptor == null)
111       {
112          interceptor = in;
113       }
114       else
115       {
116          Interceptor current = interceptor;
117          while (current.getNext() != null)
118          {
119             current = current.getNext();
120          }
121
122          current.setNext(in);
123       }
124    }
125
126    /** return first interceptor */
127    public Interceptor getInterceptor()
128    {
129       return interceptor;
130    }
131
132    /** return service endpoint */
133    public Class JavaDoc getServiceEndpoint()
134    {
135       return serviceEndpoint;
136    }
137
138    // Container stuff
139

140    protected void createService() throws Exception JavaDoc
141    {
142       // Associate thread with classloader
143
ClassLoader JavaDoc oldCl = SecurityActions.getContextClassLoader();
144       SecurityActions.setContextClassLoader(getClassLoader());
145
146       try
147       {
148          // Acquire classes from CL
149
if (metaData.getHome() != null)
150             homeInterface = classLoader.loadClass(metaData.getHome());
151          if (metaData.getRemote() != null)
152             remoteInterface = classLoader.loadClass(metaData.getRemote());
153          if (((SessionMetaData) metaData).getServiceEndpoint() != null)
154          {
155             serviceEndpoint =
156                     classLoader.loadClass(((SessionMetaData) metaData).getServiceEndpoint());
157          }
158
159          // Call default init
160
super.createService();
161
162          // Make some additional validity checks with regards to the container configuration
163
checkCoherency();
164
165          // Map the bean methods
166
setupBeanMapping();
167
168          // Map the home methods
169
setupHomeMapping();
170
171          // Map the interfaces to Long
172
setupMarshalledInvocationMapping();
173
174          createInvokers();
175
176          createInstanceCache();
177
178          createInstancePool();
179
180          createPersistenceManager();
181
182          createInterceptors();
183       }
184       finally
185       {
186          // Reset classloader
187
SecurityActions.setContextClassLoader(oldCl);
188       }
189    }
190
191    /**
192     * how home methods are treated by container
193     */

194    protected abstract void setupHomeMapping() throws Exception JavaDoc;
195
196    /** loop through methods and setup mapping */
197    protected void setUpBeanMappingImpl(Map JavaDoc map, Method JavaDoc[] methods, String JavaDoc declaringClass)
198            throws NoSuchMethodException JavaDoc
199    {
200       for (int i = 0; i < methods.length; i++)
201       {
202          Method JavaDoc m = methods[i];
203          if (m.getDeclaringClass().getName().equals(declaringClass) == false)
204          {
205             // Implemented by bean
206
try
207             {
208                Method JavaDoc beanMethod = beanClass.getMethod(m.getName(), m.getParameterTypes());
209                map.put(m, beanMethod);
210             }
211             catch (NoSuchMethodException JavaDoc ex)
212             {
213                throw new NoSuchMethodException JavaDoc("Not found in bean class: " + m);
214             }
215
216             log.debug("Mapped " + m.getName() + " HASH " + m.hashCode() + "to " + map.get(m));
217          }
218          else
219          {
220             // Implemented by container
221
try
222             {
223                Method JavaDoc containerMethod = getClass().getMethod(m.getName(), new Class JavaDoc[]{Invocation.class});
224                map.put(m, containerMethod);
225             }
226             catch (NoSuchMethodException JavaDoc e)
227             {
228                throw new NoSuchMethodException JavaDoc("Not found in container class: " + m);
229             }
230
231             log.debug("Mapped Container method " + m.getName() + " HASH " + m.hashCode());
232          }
233       }
234    }
235
236    /** build bean mappings for application logic */
237    protected void setupBeanMapping() throws NoSuchMethodException JavaDoc
238    {
239       Map JavaDoc map = new HashMap JavaDoc();
240
241       if (remoteInterface != null)
242       {
243          Method JavaDoc[] m = remoteInterface.getMethods();
244          setUpBeanMappingImpl(map, m, "javax.ejb.EJBObject");
245       }
246
247       if (localInterface != null)
248       {
249          Method JavaDoc[] m = localInterface.getMethods();
250          setUpBeanMappingImpl(map, m, "javax.ejb.EJBLocalObject");
251       }
252
253       if (TimedObject JavaDoc.class.isAssignableFrom(beanClass))
254       {
255          Method JavaDoc[] m = new Method JavaDoc[]{TimedObject JavaDoc.class.getMethod("ejbTimeout", new Class JavaDoc[]{Timer JavaDoc.class})};
256          setUpBeanMappingImpl(map, m, "javax.ejb.Timer");
257       }
258
259       if (serviceEndpoint != null)
260       {
261          Method JavaDoc[] m = serviceEndpoint.getMethods();
262          setUpBeanMappingImpl(map, m, "java.rmi.Remote");
263       }
264
265       beanMapping = map;
266    }
267
268    /**
269     * sets up marshalled invocation mappings
270     * @throws Exception
271     */

272
273    protected void setupMarshalledInvocationMapping() throws Exception JavaDoc
274    {
275       // Create method mappings for container invoker
276
if (homeInterface != null)
277       {
278          Method JavaDoc[] m = homeInterface.getMethods();
279          for (int i = 0; i < m.length; i++)
280          {
281             marshalledInvocationMapping.put(new Long JavaDoc(MarshalledInvocation.calculateHash(m[i])), m[i]);
282          }
283       }
284
285       if (remoteInterface != null)
286       {
287          Method JavaDoc[] m = remoteInterface.getMethods();
288          for (int j = 0; j < m.length; j++)
289          {
290             marshalledInvocationMapping.put(new Long JavaDoc(MarshalledInvocation.calculateHash(m[j])), m[j]);
291          }
292       }
293       // Get the getEJBObjectMethod
294
Method JavaDoc getEJBObjectMethod =
295               Class.forName("javax.ejb.Handle").getMethod("getEJBObject",
296                       new Class JavaDoc[0]);
297
298       // Hash it
299
marshalledInvocationMapping.put(new Long JavaDoc(MarshalledInvocation.calculateHash(getEJBObjectMethod)), getEJBObjectMethod);
300    }
301
302    protected void checkCoherency() throws Exception JavaDoc
303    {
304       // Check clustering cohrency wrt metadata
305
//
306
if (metaData.isClustered())
307       {
308          boolean clusteredProxyFactoryFound = false;
309          Iterator JavaDoc it = proxyFactories.keySet().iterator();
310          while (it.hasNext())
311          {
312             String JavaDoc invokerBinding = (String JavaDoc) it.next();
313             EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
314             if (ci instanceof org.jboss.proxy.ejb.ClusterProxyFactory)
315                clusteredProxyFactoryFound = true;
316          }
317
318          if (!clusteredProxyFactoryFound)
319          {
320             log.warn("*** EJB '"
321                     + this.metaData.getEjbName()
322                     + "' deployed as CLUSTERED but not a single clustered-invoker is bound to container ***");
323          }
324       }
325    }
326
327    /** creates a new instance pool */
328    protected void createInstancePool() throws Exception JavaDoc
329    {
330
331       // Try to register the instance pool as an MBean
332
try
333       {
334          ObjectName JavaDoc containerName = super.getJmxName();
335          Hashtable JavaDoc props = containerName.getKeyPropertyList();
336          props.put("plugin", "pool");
337          ObjectName JavaDoc poolName = new ObjectName JavaDoc(containerName.getDomain(), props);
338          server.registerMBean(instancePool, poolName);
339       }
340       catch (Throwable JavaDoc t)
341       {
342          log.debug("Failed to register pool as mbean", t);
343       }
344       // Initialize pool
345
instancePool.create();
346    }
347
348    /**
349     * no instance cache per default
350     */

351    protected void createInstanceCache() throws Exception JavaDoc
352    {
353    }
354
355    /** creates the invokers */
356    protected void createInvokers() throws Exception JavaDoc
357    {
358       // Init container invoker
359
for (Iterator JavaDoc it = proxyFactories.keySet().iterator(); it.hasNext();)
360       {
361          String JavaDoc invokerBinding = (String JavaDoc) it.next();
362          EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
363          ci.create();
364       }
365    }
366
367    /** Initialize the interceptors by calling the chain */
368    protected void createInterceptors() throws Exception JavaDoc
369    {
370       Interceptor in = interceptor;
371       while (in != null)
372       {
373          in.setContainer(this);
374          in.create();
375          in = in.getNext();
376       }
377    }
378
379    /**
380     * no persistence manager per default
381     */

382    protected void createPersistenceManager() throws Exception JavaDoc
383    {
384    }
385
386    protected void startService() throws Exception JavaDoc
387    {
388       // Associate thread with classloader
389
ClassLoader JavaDoc oldCl = SecurityActions.getContextClassLoader();
390       SecurityActions.setContextClassLoader(getClassLoader());
391
392       try
393       {
394          // Call default start
395
super.startService();
396
397          startInvokers();
398
399          startInstanceCache();
400
401          startInstancePool();
402
403          startPersistenceManager();
404
405          startInterceptors();
406          
407          // Restore persisted ejb timers
408
restoreTimers();
409       }
410       finally
411       {
412          // Reset classloader
413
SecurityActions.setContextClassLoader(oldCl);
414       }
415    }
416
417    /**
418     * no persistence manager per default
419     */

420    protected void startPersistenceManager() throws Exception JavaDoc
421    {
422    }
423
424    /**
425     * no instance cache per default
426     */

427    protected void startInstanceCache() throws Exception JavaDoc
428    {
429    }
430
431    /** Start container invokers */
432    protected void startInvokers() throws Exception JavaDoc
433    {
434       for (Iterator JavaDoc it = proxyFactories.keySet().iterator(); it.hasNext();)
435       {
436          String JavaDoc invokerBinding = (String JavaDoc) it.next();
437          EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
438          ci.start();
439       }
440    }
441
442    /** Start pool */
443    protected void startInstancePool() throws Exception JavaDoc
444    {
445       instancePool.start();
446    }
447
448    /** Start all interceptors in the chain **/
449    protected void startInterceptors() throws Exception JavaDoc
450    {
451       Interceptor in = interceptor;
452       while (in != null)
453       {
454          in.start();
455          in = in.getNext();
456       }
457    }
458
459    protected void stopService() throws Exception JavaDoc
460    {
461       // Associate thread with classloader
462
ClassLoader JavaDoc oldCl = SecurityActions.getContextClassLoader();
463       SecurityActions.setContextClassLoader(getClassLoader());
464
465       try
466       {
467          // Call default stop
468
super.stopService();
469
470          stopInvokers();
471
472          stopInstanceCache();
473
474          stopInstancePool();
475
476          stopPersistenceManager();
477
478          stopInterceptors();
479       }
480       finally
481       {
482          // Reset classloader
483
SecurityActions.setContextClassLoader(oldCl);
484       }
485    }
486
487    /** Stop all interceptors in the chain */
488    protected void stopInterceptors()
489    {
490       Interceptor in = interceptor;
491       while (in != null)
492       {
493          in.stop();
494          in = in.getNext();
495       }
496    }
497
498    /** no persistence */
499    protected void stopPersistenceManager()
500    {
501    }
502
503    /** Stop pool */
504    protected void stopInstancePool()
505    {
506       instancePool.stop();
507    }
508
509    /** no instance cache */
510    protected void stopInstanceCache()
511    {
512    }
513
514    /** Stop container invoker */
515    protected void stopInvokers()
516    {
517       for (Iterator JavaDoc it = proxyFactories.keySet().iterator(); it.hasNext();)
518       {
519          String JavaDoc invokerBinding = (String JavaDoc) it.next();
520          EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
521          ci.stop();
522       }
523    }
524
525    protected void destroyService() throws Exception JavaDoc
526    {
527       // Associate thread with classloader
528
ClassLoader JavaDoc oldCl = SecurityActions.getContextClassLoader();
529       SecurityActions.setContextClassLoader(getClassLoader());
530
531       try
532       {
533          destroyInvokers();
534
535          destroyInstanceCache();
536
537          destroyInstancePool();
538
539          destroyPersistenceManager();
540
541          destroyInterceptors();
542
543          destroyMarshalledInvocationMapping();
544
545          homeInterface = null;
546          remoteInterface = null;
547          serviceEndpoint = null;
548          beanMapping.clear();
549          
550          // Call default destroy
551
super.destroyService();
552       }
553       finally
554       {
555          // Reset classloader
556
SecurityActions.setContextClassLoader(oldCl);
557       }
558    }
559
560    protected void destroyMarshalledInvocationMapping()
561    {
562       MarshalledInvocation.removeHashes(homeInterface);
563       MarshalledInvocation.removeHashes(remoteInterface);
564    }
565
566    protected void destroyInterceptors()
567    {
568       // Destroy all the interceptors in the chain
569
Interceptor in = interceptor;
570       while (in != null)
571       {
572          in.destroy();
573          in.setContainer(null);
574          in = in.getNext();
575       }
576    }
577
578    protected void destroyPersistenceManager()
579    {
580    }
581
582    protected void destroyInstancePool()
583    {
584       // Destroy pool
585
instancePool.destroy();
586       instancePool.setContainer(null);
587       try
588       {
589          ObjectName JavaDoc containerName = super.getJmxName();
590          Hashtable JavaDoc props = containerName.getKeyPropertyList();
591          props.put("plugin", "pool");
592          ObjectName JavaDoc poolName = new ObjectName JavaDoc(containerName.getDomain(), props);
593          server.unregisterMBean(poolName);
594       }
595       catch (Throwable JavaDoc ignore)
596       {
597       }
598    }
599
600    protected void destroyInstanceCache()
601    {
602    }
603
604    protected void destroyInvokers()
605    {
606       // Destroy container invoker
607
for (Iterator JavaDoc it = proxyFactories.keySet().iterator(); it.hasNext();)
608       {
609          String JavaDoc invokerBinding = (String JavaDoc) it.next();
610          EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
611          ci.destroy();
612          ci.setContainer(null);
613       }
614    }
615
616    public Object JavaDoc internalInvokeHome(Invocation mi) throws Exception JavaDoc
617    {
618       Method JavaDoc method = mi.getMethod();
619       if (method != null && method.getName().equals("remove"))
620       {
621          // Handle or primary key?
622
Object JavaDoc arg = mi.getArguments()[0];
623          if (arg instanceof Handle JavaDoc)
624          {
625             if (arg == null)
626                throw new RemoteException JavaDoc("Null handle");
627             Handle JavaDoc handle = (Handle JavaDoc) arg;
628             EJBObject JavaDoc ejbObject = handle.getEJBObject();
629             ejbObject.remove();
630             return null;
631          }
632          else
633             throw new RemoveException JavaDoc("EJBHome.remove(Object) not allowed for session beans");
634       }
635       return getInterceptor().invokeHome(mi);
636    }
637
638    /**
639     * This method does invocation interpositioning of tx and security,
640     * retrieves the instance from an object table, and invokes the method
641     * on the particular instance
642     */

643    public Object JavaDoc internalInvoke(Invocation mi) throws Exception JavaDoc
644    {
645       // Invoke through interceptors
646
return getInterceptor().invoke(mi);
647    }
648
649    // EJBObject implementation --------------------------------------
650

651    /**
652     * While the following methods are implemented in the client in the case
653     * of JRMP we would need to implement them to fully support other transport
654     * protocols
655     *
656     * @return Always null
657     */

658    public Handle JavaDoc getHandle(Invocation mi) throws RemoteException JavaDoc
659    {
660       
661       // TODO
662
return null;
663    }
664
665    public Object JavaDoc getPrimaryKey(Invocation mi) throws RemoteException JavaDoc
666    {
667       return getPrimaryKey();
668    }
669
670    public Object JavaDoc getPrimaryKey() throws RemoteException JavaDoc
671    {
672       throw new RemoteException JavaDoc("Call to getPrimaryKey not allowed on session bean");
673    }
674    
675    public EJBHome JavaDoc getEJBHome(Invocation mi) throws RemoteException JavaDoc
676    {
677       EJBProxyFactory ci = getProxyFactory();
678       if (ci == null)
679       {
680          String JavaDoc msg = "No ProxyFactory, check for ProxyFactoryFinderInterceptor";
681          throw new IllegalStateException JavaDoc(msg);
682       }
683
684       return (EJBHome JavaDoc) ci.getEJBHome();
685    }
686
687    /**
688     * @return Always false
689     */

690    public boolean isIdentical(Invocation mi) throws RemoteException JavaDoc
691    {
692       EJBProxyFactory ci = getProxyFactory();
693       if (ci == null)
694       {
695          String JavaDoc msg = "No ProxyFactory, check for ProxyFactoryFinderInterceptor";
696          throw new IllegalStateException JavaDoc(msg);
697       }
698
699       return ci.isIdentical(this, mi);
700    }
701
702    public EJBMetaData JavaDoc getEJBMetaDataHome(Invocation mi) throws RemoteException JavaDoc
703    {
704       return getEJBMetaDataHome();
705    }
706    
707    public EJBMetaData JavaDoc getEJBMetaDataHome() throws RemoteException JavaDoc
708    {
709       EJBProxyFactory ci = getProxyFactory();
710       if (ci == null)
711       {
712          String JavaDoc msg = "No ProxyFactory, check for ProxyFactoryFinderInterceptor";
713          throw new IllegalStateException JavaDoc(msg);
714       }
715
716       return ci.getEJBMetaData();
717    }
718    
719    public HomeHandle JavaDoc getHomeHandleHome(Invocation mi) throws RemoteException JavaDoc
720    {
721       return getHomeHandleHome();
722    }
723    
724    public HomeHandle JavaDoc getHomeHandleHome() throws RemoteException JavaDoc
725    {
726       EJBProxyFactory ci = getProxyFactory();
727       if (ci == null)
728       {
729          String JavaDoc msg = "No ProxyFactory, check for ProxyFactoryFinderInterceptor";
730          throw new IllegalStateException JavaDoc(msg);
731       }
732
733       EJBHome JavaDoc home = (EJBHome JavaDoc) ci.getEJBHome();
734       return home.getHomeHandle();
735    }
736
737    // Home interface implementation ---------------------------------
738

739    // local object interface implementation
740

741    public EJBLocalHome JavaDoc getEJBLocalHome(Invocation mi)
742    {
743       return localProxyFactory.getEJBLocalHome();
744    }
745
746    /**
747     * needed for sub-inner-class access (old jdk compiler bug)
748     * @return
749     */

750    protected Map JavaDoc getHomeMapping()
751    {
752       return homeMapping;
753    }
754
755    /**
756     * needed for sub-inner-class access (old jdk compiler bug)
757     * @return
758     */

759    protected Map JavaDoc getBeanMapping()
760    {
761       return beanMapping;
762    }
763
764 }
765
Popular Tags