KickJava   Java API By Example, From Geeks To Geeks.

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


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 import java.lang.reflect.InvocationTargetException JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.security.AccessController JavaDoc;
28 import java.security.Policy JavaDoc;
29 import java.security.PrivilegedActionException JavaDoc;
30 import java.security.PrivilegedExceptionAction JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.HashSet JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.rmi.MarshalException JavaDoc;
37
38 import javax.ejb.EJBException JavaDoc;
39 import javax.ejb.EJBObject JavaDoc;
40 import javax.ejb.TimedObject JavaDoc;
41 import javax.ejb.Timer JavaDoc;
42 import javax.ejb.TimerService JavaDoc;
43 import javax.ejb.spi.HandleDelegate JavaDoc;
44 import javax.management.MBeanException JavaDoc;
45 import javax.management.MalformedObjectNameException JavaDoc;
46 import javax.management.ObjectName JavaDoc;
47 import javax.naming.Context JavaDoc;
48 import javax.naming.InitialContext JavaDoc;
49 import javax.naming.LinkRef JavaDoc;
50 import javax.naming.NamingException JavaDoc;
51 import javax.naming.Reference JavaDoc;
52 import javax.naming.StringRefAddr JavaDoc;
53 import javax.transaction.TransactionManager JavaDoc;
54 import javax.xml.soap.SOAPMessage JavaDoc;
55
56 import org.jboss.deployers.spi.deployer.DeploymentUnit;
57 import org.jboss.deployment.DeploymentException;
58 import org.jboss.deployment.DeploymentInfo;
59 import org.jboss.ejb.plugins.local.BaseLocalProxyFactory;
60 import org.jboss.ejb.txtimer.EJBTimerService;
61 import org.jboss.invocation.*;
62 import org.jboss.logging.Logger;
63 import org.jboss.metadata.ApplicationMetaData;
64 import org.jboss.metadata.BeanMetaData;
65 import org.jboss.metadata.EjbLocalRefMetaData;
66 import org.jboss.metadata.EjbRefMetaData;
67 import org.jboss.metadata.EnvEntryMetaData;
68 import org.jboss.metadata.MessageDestinationMetaData;
69 import org.jboss.metadata.MessageDestinationRefMetaData;
70 import org.jboss.metadata.ResourceEnvRefMetaData;
71 import org.jboss.metadata.ResourceRefMetaData;
72 import org.jboss.mx.util.ObjectNameConverter;
73 import org.jboss.mx.util.ObjectNameFactory;
74 import org.jboss.naming.ENCThreadLocalKey;
75 import org.jboss.naming.NonSerializableFactory;
76 import org.jboss.naming.Util;
77 import org.jboss.security.AnybodyPrincipal;
78 import org.jboss.security.AuthenticationManager;
79 import org.jboss.security.AuthorizationManager;
80 import org.jboss.security.RealmMapping;
81 import org.jboss.system.ServiceMBeanSupport;
82 import org.jboss.util.NestedError;
83 import org.jboss.util.NestedRuntimeException;
84 import org.jboss.webservice.ServiceRefHandler;
85 import org.jboss.webservice.ServiceRefHandlerFactory;
86 import org.omg.CORBA.ORB JavaDoc;
87
88 /**
89  * This is the base class for all EJB-containers in JBoss. A Container
90  * functions as the central hub of all metadata and plugins. Through this
91  * the container plugins can get hold of the other plugins and any metadata
92  * they need.
93  *
94  * <p>The EJBDeployer creates instances of subclasses of this class
95  * and calls the appropriate initialization methods.
96  *
97  * <p>A Container does not perform any significant work, but instead delegates
98  * to the plugins to provide for all kinds of algorithmic functionality.
99  *
100  * @see EJBDeployer
101  *
102  * @author <a HREF="mailto:rickard.oberg@jboss.org">Rickard �berg</a>
103  * @author <a HREF="mailto:marc.fleury@jboss.org">Marc Fleury</a>
104  * @author <a HREF="mailto:Scott.Stark@jboss.org">Scott Stark</a>.
105  * @author <a HREF="bill@burkecentral.com">Bill Burke</a>
106  * @author <a HREF="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
107  * @author <a HREF="mailto:christoph.jung@infor.de">Christoph G. Jung</a>
108  * @version $Revision: 58204 $
109  *
110  * @jmx.mbean extends="org.jboss.system.ServiceMBean"
111  */

112 public abstract class Container extends ServiceMBeanSupport
113    implements ContainerMBean, AllowedOperationsFlags
114 {
115    public final static String JavaDoc BASE_EJB_CONTAINER_NAME =
116            "jboss.j2ee:service=EJB";
117
118    public final static ObjectName JavaDoc ORB_NAME = ObjectNameFactory.create("jboss:service=CorbaORB");
119    
120    public final static ObjectName JavaDoc EJB_CONTAINER_QUERY_NAME =
121            ObjectNameFactory.create(BASE_EJB_CONTAINER_NAME + ",*");
122
123    protected static final Method JavaDoc EJBOBJECT_REMOVE;
124    /** A reference to {@link javax.ejb.TimedObject#ejbTimeout}. */
125    protected static final Method JavaDoc EJB_TIMEOUT;
126
127    /** This is the application that this container is a part of */
128    protected EjbModule ejbModule;
129
130    /**
131     * This is the classloader of this container. All classes and resources that
132     * the bean uses will be loaded from here. By doing this we make the bean
133     * re-deployable
134     */

135    protected ClassLoader JavaDoc classLoader;
136
137    /** The class loader for remote dynamic classloading */
138    protected ClassLoader JavaDoc webClassLoader;
139
140    /**
141     * Externally supplied configuration data
142     */

143    private DeploymentUnit di;
144
145    /**
146     * This is the new metadata. it includes information from both ejb-jar and
147     * jboss.xml the metadata for the application can be accessed trough
148     * metaData.getApplicationMetaData()
149     */

150    protected BeanMetaData metaData;
151
152    /** This is the EnterpriseBean class */
153    protected Class JavaDoc beanClass;
154
155    /** This is the Home interface class */
156    protected Class JavaDoc homeInterface;
157
158    /** This is the Remote interface class */
159    protected Class JavaDoc remoteInterface;
160
161    /** The local home interface class */
162    protected Class JavaDoc localHomeInterface;
163
164    /** The local inteface class */
165    protected Class JavaDoc localInterface;
166
167    /** This is the TransactionManager */
168    protected TransactionManager JavaDoc tm;
169
170    /** This is the SecurityManager */
171    protected AuthenticationManager sm;
172    
173    /**
174     * Authorization Manager
175     */

176    protected AuthorizationManager authorizationManager;
177
178    /** This is the realm mapping */
179    protected RealmMapping rm;
180
181    /** The custom security proxy used by the SecurityInterceptor */
182    protected Object JavaDoc securityProxy;
183
184    /** This is the bean lock manager that is to be used */
185    protected BeanLockManager lockManager;
186
187    /** ??? */
188    protected LocalProxyFactory localProxyFactory =
189            new BaseLocalProxyFactory();
190
191    /** This is a cache for method permissions */
192    private HashMap JavaDoc methodPermissionsCache = new HashMap JavaDoc();
193
194    /** Maps for MarshalledInvocation mapping */
195    protected Map JavaDoc marshalledInvocationMapping = new HashMap JavaDoc();
196
197    /** ObjectName of Container */
198    private ObjectName JavaDoc jmxName;
199    /** HashMap<String, EJBProxyFactory> for the invoker bindings */
200    protected HashMap JavaDoc proxyFactories = new HashMap JavaDoc();
201    /** A priviledged actions for MBeanServer.invoke when running with sec mgr */
202    private MBeanServerAction serverAction = new MBeanServerAction();
203
204    /**
205     * The Proxy factory is set in the Invocation. This TL is used
206     * for methods that do not have access to the Invocation.
207     */

208    protected ThreadLocal JavaDoc proxyFactoryTL = new ThreadLocal JavaDoc();
209
210    /** The number of create invocations that have been made */
211    protected long createCount;
212    /** The number of create invocations that have been made */
213    protected long removeCount;
214    /** Time statistics for the invoke(Invocation) methods */
215    protected InvocationStatistics invokeStats = new InvocationStatistics();
216
217    /** The JACC context id for the container */
218    protected String JavaDoc jaccContextID;
219    
220    /**
221     * Flag to denote whether a JACC configuration has been fitted for authorization
222     */

223    protected boolean isJaccEnabled = false;
224
225    static
226    {
227       try
228       {
229          EJBOBJECT_REMOVE = EJBObject JavaDoc.class.getMethod("remove", new Class JavaDoc[0]);
230          EJB_TIMEOUT = TimedObject JavaDoc.class.getMethod("ejbTimeout", new Class JavaDoc[]{Timer JavaDoc.class});
231       }
232       catch (Throwable JavaDoc t)
233       {
234          throw new NestedRuntimeException(t);
235       }
236    }
237
238    // Public --------------------------------------------------------
239

240    public Class JavaDoc getLocalClass()
241    {
242       return localInterface;
243    }
244
245    public Class JavaDoc getLocalHomeClass()
246    {
247       return localHomeInterface;
248    }
249
250    public Class JavaDoc getRemoteClass()
251    {
252       return remoteInterface;
253    }
254
255    /**
256     * this actually should be called remotehome, but for interface compliance purposes
257     * we keep it like that
258     */

259    public Class JavaDoc getHomeClass()
260    {
261       return homeInterface;
262    }
263
264    /**
265     * Whether the bean is call by value
266     *
267     * @return true for call by value
268     */

269    public boolean isCallByValue()
270    {
271       if (ejbModule.isCallByValue())
272          return true;
273       return metaData.isCallByValue();
274    }
275    
276    /**
277     * Sets a transaction manager for this container.
278     *
279     * @see javax.transaction.TransactionManager
280     *
281     * @param tm
282     */

283    public void setTransactionManager(final TransactionManager JavaDoc tm)
284    {
285       this.tm = tm;
286    }
287
288    /**
289     * Returns this container's transaction manager.
290     *
291     * @return A concrete instance of javax.transaction.TransactionManager
292     */

293    public TransactionManager JavaDoc getTransactionManager()
294    {
295       return tm;
296    }
297
298    public void setSecurityManager(AuthenticationManager sm)
299    {
300       this.sm = sm;
301    }
302
303    public AuthenticationManager getSecurityManager()
304    {
305       return sm;
306    }
307
308    /**
309     * Get the authorizationManager.
310     *
311     * @return the authorizationManager.
312     */

313    public AuthorizationManager getAuthorizationManager()
314    {
315       return authorizationManager;
316    }
317
318    /**
319     * Set the authorizationManager.
320     *
321     * @param authorizationManager The authorizationManager to set.
322     */

323    public void setAuthorizationManager(AuthorizationManager authorizationManager)
324    {
325       this.authorizationManager = authorizationManager;
326    }
327
328    public BeanLockManager getLockManager()
329    {
330       return lockManager;
331    }
332
333    public void setLockManager(final BeanLockManager lockManager)
334    {
335       this.lockManager = lockManager;
336       lockManager.setContainer(this);
337    }
338
339    public void addProxyFactory(String JavaDoc invokerBinding, EJBProxyFactory factory)
340    {
341       proxyFactories.put(invokerBinding, factory);
342    }
343
344    public void setRealmMapping(final RealmMapping rm)
345    {
346       this.rm = rm;
347    }
348
349    public RealmMapping getRealmMapping()
350    {
351       return rm;
352    }
353
354    public void setSecurityProxy(Object JavaDoc proxy)
355    {
356       this.securityProxy = proxy;
357    }
358
359    public Object JavaDoc getSecurityProxy()
360    {
361       return securityProxy;
362    }
363
364    public EJBProxyFactory getProxyFactory()
365    {
366       EJBProxyFactory factory = (EJBProxyFactory)proxyFactoryTL.get();
367       // There's no factory thread local which means this is probably
368
// a local invocation. Just use the first (usually only)
369
// proxy factory.
370
// TODO: define a default factory in the meta data or
371
// even better, let the return over the original transport
372
// plugin the transport layer for the generated proxy
373
if (factory == null && remoteInterface != null)
374       {
375          Iterator JavaDoc i = proxyFactories.values().iterator();
376          if (i.hasNext())
377             factory = (EJBProxyFactory) i.next();
378       }
379       return factory;
380    }
381
382    public void setProxyFactory(Object JavaDoc factory)
383    {
384       proxyFactoryTL.set(factory);
385    }
386
387    public EJBProxyFactory lookupProxyFactory(String JavaDoc binding)
388    {
389       return (EJBProxyFactory) proxyFactories.get(binding);
390    }
391
392    /**
393     * Gets the DeploymentInfo for this Container
394     * @deprecated use DeploymentUnit accessors
395     * @return The DeploymentInfo for this Container
396     */

397    public final DeploymentInfo getDeploymentInfo()
398    {
399       return null;
400    }
401    /**
402     * Sets the DeploymentInfo of this Container
403     * @deprecated use DeploymentUnit accessors
404     * @param di The new DeploymentInfo to be used
405     */

406    public final void setDeploymentInfo(DeploymentInfo di)
407    {
408    }
409
410    public final DeploymentUnit getDeploymentUnit()
411    {
412       return di;
413    }
414    public final void setDeploymentUnit(DeploymentUnit di)
415    {
416       this.di = di;
417    }
418
419    /**
420     * Sets the application deployment unit for this container. All the bean
421     * containers within the same application unit share the same instance.
422     *
423     * @param app application for this container
424     */

425    public void setEjbModule(EjbModule app)
426    {
427       ejbModule = app;
428    }
429
430    public String JavaDoc getJaccContextID()
431    {
432       return jaccContextID;
433    }
434    public void setJaccContextID(String JavaDoc id)
435    {
436       jaccContextID = id;
437    }
438    
439    /**
440     * Get the flag whether JACC is enabled
441     * @return
442     */

443    public boolean isJaccEnabled()
444    {
445       return isJaccEnabled;
446    }
447    
448    /**
449     * Set the flag that JACC is enabled
450     *
451     * @param isJaccEnabled
452     */

453    public void setJaccEnabled(boolean isJaccEnabled)
454    {
455       this.isJaccEnabled = isJaccEnabled;
456    }
457
458    /**
459     * Gets the application deployment unit for this container. All the bean
460     * containers within the same application unit share the same instance.
461     * @jmx.managed-attribute
462     */

463    public EjbModule getEjbModule()
464    {
465       return ejbModule;
466    }
467
468    /**
469     * Gets the number of create invocations that have been made
470     * @jmx.managed-attribute
471     */

472    public long getCreateCount()
473    {
474       return createCount;
475    }
476
477    /**
478     * Gets the number of remove invocations that have been made
479     * @jmx.managed-attribute
480     */

481    public long getRemoveCount()
482    {
483       return removeCount;
484    }
485
486    /** Gets the invocation statistics collection
487     * @jmx.managed-attribute
488     */

489    public InvocationStatistics getInvokeStats()
490    {
491       return invokeStats;
492    }
493
494    /**
495     * Sets the class loader for this container. All the classes and resources
496     * used by the bean in this container will use this classloader.
497     *
498     * @param cl
499     */

500    public void setClassLoader(ClassLoader JavaDoc cl)
501    {
502       this.classLoader = cl;
503    }
504
505    /**
506     * Returns the classloader for this container.
507     *
508     * @return
509     */

510    public ClassLoader JavaDoc getClassLoader()
511    {
512       return classLoader;
513    }
514
515    /** Get the class loader for dynamic class loading via http.
516     */

517    public ClassLoader JavaDoc getWebClassLoader()
518    {
519       return webClassLoader;
520    }
521
522    /** Set the class loader for dynamic class loading via http.
523     */

524    public void setWebClassLoader(final ClassLoader JavaDoc webClassLoader)
525    {
526       this.webClassLoader = webClassLoader;
527    }
528
529    /**
530     * Sets the meta data for this container. The meta data consists of the
531     * properties found in the XML descriptors.
532     *
533     * @param metaData
534     */

535    public void setBeanMetaData(final BeanMetaData metaData)
536    {
537       this.metaData = metaData;
538    }
539
540    /** Get the components environment context
541     * @jmx.managed-attribute
542     * @return Environment Context
543     */

544    public Context JavaDoc getEnvContext() throws NamingException JavaDoc
545    {
546       ClassLoader JavaDoc ccl = SecurityActions.getContextClassLoader();
547       try
548       {
549          // The ENC is a map keyed on the class loader
550
SecurityActions.setContextClassLoader(classLoader);
551          return (Context JavaDoc)new InitialContext JavaDoc().lookup("java:comp/env");
552       }
553       finally
554       {
555          SecurityActions.setContextClassLoader(ccl);
556       }
557    }
558
559    /**
560     * Returns the metadata of this container.
561     *
562     * @jmx.managed-attribute
563     * @return metaData;
564     */

565    public BeanMetaData getBeanMetaData()
566    {
567       return metaData;
568    }
569
570    /**
571     * Returns the permissions for a method. (a set of roles)
572     *
573     * @return assemblyDescriptor;
574     */

575    public Set JavaDoc getMethodPermissions(Method JavaDoc m, InvocationType iface)
576    {
577       Set JavaDoc permissions;
578
579       if (methodPermissionsCache.containsKey(m))
580       {
581          permissions = (Set JavaDoc) methodPermissionsCache.get(m);
582       }
583       else if( m.equals(EJB_TIMEOUT) )
584       {
585          // No role is required to access the ejbTimeout as this is
586
permissions = new HashSet JavaDoc();
587          permissions.add(AnybodyPrincipal.ANYBODY_PRINCIPAL);
588          methodPermissionsCache.put(m, permissions);
589       }
590       else
591       {
592          String JavaDoc name = m.getName();
593          Class JavaDoc[] sig = m.getParameterTypes();
594          permissions = getBeanMetaData().getMethodPermissions(name, sig, iface);
595          methodPermissionsCache.put(m, permissions);
596       }
597
598       return permissions;
599    }
600
601    /**
602     * Returns the bean class instance of this container.
603     *
604     * @return instance of the Enterprise bean class.
605     */

606    public Class JavaDoc getBeanClass()
607    {
608       return beanClass;
609    }
610
611    /**
612     * Returns a new instance of the bean class or a subclass of the bean class.
613     * This factory style method is speciffically used by a container to supply
614     * an implementation of the abstract accessors in EJB2.0, but could be
615     * usefull in other situations. This method should ALWAYS be used instead
616     * of getBeanClass().newInstance();
617     *
618     * @return the new instance
619     *
620     * @see java.lang.Class#newInstance
621     */

622    public Object JavaDoc createBeanClassInstance() throws Exception JavaDoc
623    {
624       return getBeanClass().newInstance();
625    }
626
627    /**
628     * Sets the codebase of this container.
629     *
630     * @param codebase a possibly empty, but non null String with
631     * a sequence of URLs separated by spaces
632     * /
633     public void setCodebase(final String codebase)
634     {
635     if (codebase != null)
636     this.codebase = codebase;
637     }
638     */

639    /**
640     * Gets the codebase of this container.
641     *
642     * @return this container's codebase String, a sequence of URLs
643     * separated by spaces
644     * /
645     public String getCodebase()
646     {
647     return codebase;
648     }
649     */

650    /** Build a JMX name using the pattern jboss.j2ee:service=EJB,jndiName=[jndiName]
651     where the [jndiName] is either the bean remote home JNDI binding, or
652     the local home JNDI binding if the bean has no remote interfaces.
653     */

654    public ObjectName JavaDoc getJmxName()
655    {
656       if (jmxName == null)
657       {
658          BeanMetaData beanMetaData = getBeanMetaData();
659          if (beanMetaData == null)
660          {
661             throw new IllegalStateException JavaDoc("Container metaData is null");
662          }
663
664          String JavaDoc jndiName = beanMetaData.getContainerObjectNameJndiName();
665          if (jndiName == null)
666          {
667             throw new IllegalStateException JavaDoc("Container jndiName is null");
668          }
669
670          // The name must be escaped since the jndiName may be arbitrary
671
String JavaDoc name = BASE_EJB_CONTAINER_NAME + ",jndiName=" + jndiName;
672          try
673          {
674             jmxName = ObjectNameConverter.convert(name);
675          }
676          catch (MalformedObjectNameException JavaDoc e)
677          {
678             throw new RuntimeException JavaDoc("Failed to create ObjectName, msg=" + e.getMessage());
679          }
680       }
681       return jmxName;
682    }
683
684    /**
685     * Creates the single Timer Service for this container if not already created
686     *
687     * @param pKey Bean id
688     * @return Container Timer Service
689     * @throws IllegalStateException If the type of EJB is not allowed to use the
690     * timer service, or the bean class does not implement javax.ejb.TimedObject
691     *
692     * @see javax.ejb.EJBContext#getTimerService
693     *
694     * @jmx.managed-operation
695     **/

696    public TimerService JavaDoc getTimerService(Object JavaDoc pKey)
697            throws IllegalStateException JavaDoc
698    {
699       if (this instanceof StatefulSessionContainer)
700          throw new IllegalStateException JavaDoc("Statefull Session Beans are not allowed to access the TimerService");
701
702       // Validate that the bean implements the TimedObject interface
703
Class JavaDoc beanClass = this.getBeanClass();
704       if( TimedObject JavaDoc.class.isAssignableFrom(beanClass) == false )
705       {
706          String JavaDoc msg = this.getBeanMetaData().getEjbName()
707             +" requested getTimerService but "+beanClass
708             +" does not implement javax.ejb.TimedObject";
709          throw new IllegalStateException JavaDoc(msg);
710       }
711
712       TimerService JavaDoc timerService = null;
713       try
714       {
715          EJBTimerService service = (EJBTimerService)SecurityActions.getMBeanProxy(EJBTimerService.class, EJBTimerService.OBJECT_NAME, server);
716          timerService = service.createTimerService(getJmxName(), pKey, this);
717       }
718       catch (Exception JavaDoc e)
719       {
720          throw new EJBException JavaDoc("Could not create timer service", e);
721       }
722       return timerService;
723    }
724
725    /**
726     * Removes Timer Service for this container
727     *
728     * @param pKey Bean id
729     * @throws IllegalStateException If the type of EJB is not allowed to use the timer service
730     *
731     * @jmx.managed-operation
732     **/

733    public void removeTimerService(Object JavaDoc pKey)
734            throws IllegalStateException JavaDoc
735    {
736       try
737       {
738          EJBTimerService service = (EJBTimerService)SecurityActions.getMBeanProxy(EJBTimerService.class, EJBTimerService.OBJECT_NAME, server);
739          if (pKey != null)
740          {
741             // entity bean->remove()
742
service.removeTimerService(getJmxName(), pKey);
743          }
744          else
745          {
746             // container stop, we choose whether active timers
747
// should be persisted (default), or not (legacy)
748
service.removeTimerService(getJmxName(), getBeanMetaData().getTimerPersistence());
749          }
750       }
751       catch (Exception JavaDoc e)
752       {
753          log.error("Could not remove timer service", e);
754       }
755    }
756
757    /**
758     * Restore any timers previously persisted for this container
759     */

760    protected void restoreTimers()
761    {
762       try
763       {
764          // pass to the ejb timer service the container ObjectName
765
server.invoke(
766                EJBTimerService.OBJECT_NAME,
767                "restoreTimers",
768                new Object JavaDoc[] { getServiceName(), getClassLoader() },
769                new String JavaDoc[] { "javax.management.ObjectName" , "java.lang.ClassLoader" } );
770       }
771       catch (Exception JavaDoc e)
772       {
773          log.warn("Could not restore ejb timers", e);
774       }
775    }
776    
777    /**
778     * The EJBDeployer calls this method. The EJBDeployer has set
779     * all the plugins and interceptors that this bean requires and now proceeds
780     * to initialize the chain. The method looks for the standard classes in
781     * the URL, sets up the naming environment of the bean. The concrete
782     * container classes should override this method to introduce
783     * implementation specific initialization behaviour.
784     *
785     * @throws Exception if loading the bean class failed
786     * (ClassNotFoundException) or setting up "java:"
787     * naming environment failed (DeploymentException)
788     */

789    protected void createService() throws Exception JavaDoc
790    {
791       // Acquire classes from CL
792
beanClass = classLoader.loadClass(metaData.getEjbClass());
793
794       if (metaData.getLocalHome() != null)
795          localHomeInterface = classLoader.loadClass(metaData.getLocalHome());
796       if (metaData.getLocal() != null)
797          localInterface = classLoader.loadClass(metaData.getLocal());
798
799       localProxyFactory.setContainer(this);
800       localProxyFactory.create();
801       if (localHomeInterface != null)
802          ejbModule.addLocalHome(this, localProxyFactory.getEJBLocalHome());
803       ejbModule.createMissingPermissions(this, metaData);
804       // Allow the policy to incorporate the policy configs
805
Policy.getPolicy().refresh();
806    }
807
808    /**
809     * A default implementation of starting the container service.
810     * The container registers it's dynamic MBean interface in the JMX base.
811     *
812     * The concrete container classes should override this method to introduce
813     * implementation specific start behaviour.
814     *
815     * todo implement the service lifecycle methods in an xmbean interceptor so
816     * non lifecycle managed ops are blocked when mbean is not started.
817     *
818     * @throws Exception An exception that occured during start
819     */

820    protected void startService() throws Exception JavaDoc
821    {
822       // Setup "java:comp/env" namespace
823
setupEnvironment();
824       
825       localProxyFactory.start();
826    }
827
828    /**
829     * A default implementation of stopping the container service (no-op). The
830     * concrete container classes should override this method to introduce
831     * implementation specific stop behaviour.
832     */

833    protected void stopService() throws Exception JavaDoc
834    {
835       localProxyFactory.stop();
836       removeTimerService(null);
837       teardownEnvironment();
838    }
839
840    /**
841     * A default implementation of destroying the container service (no-op).
842     * The concrete container classes should override this method to introduce
843     * implementation specific destroy behaviour.
844     */

845    protected void destroyService() throws Exception JavaDoc
846    {
847       localProxyFactory.destroy();
848       ejbModule.removeLocalHome(this);
849
850       beanClass = null;
851       homeInterface = null;
852       remoteInterface = null;
853       localHomeInterface = null;
854       localInterface = null;
855       methodPermissionsCache.clear();
856       invokeStats.resetStats();
857       marshalledInvocationMapping.clear();
858    }
859
860    /**
861     * This method is called when a method call comes
862     * in on the Home object. The Container forwards this call to the
863     * interceptor chain for further processing.
864     *
865     * @param mi the object holding all info about this invocation
866     * @return the result of the home invocation
867     *
868     * @throws Exception
869     */

870    public abstract Object JavaDoc internalInvokeHome(Invocation mi)
871            throws Exception JavaDoc;
872
873    /**
874     * This method is called when a method call comes
875     * in on an EJBObject. The Container forwards this call to the interceptor
876     * chain for further processing.
877     */

878    public abstract Object JavaDoc internalInvoke(Invocation mi)
879            throws Exception JavaDoc;
880
881    abstract Interceptor createContainerInterceptor();
882
883    public abstract void addInterceptor(Interceptor in);
884
885    /** The detached invoker operation.
886     *
887     * @jmx.managed-operation
888     *
889     * @param mi - the method invocation context
890     * @return the value of the ejb invocation
891     * @throws Exception on error
892     */

893    public Object JavaDoc invoke(Invocation mi)
894            throws Exception JavaDoc
895    {
896       ClassLoader JavaDoc callerClassLoader = SecurityActions.getContextClassLoader();
897       long start = System.currentTimeMillis();
898       Method JavaDoc m = null;
899
900       boolean setCl = false;
901       Object JavaDoc type = null;
902       String JavaDoc contextID = getJaccContextID();
903       try
904       {
905          if(!this.classLoader.equals(callerClassLoader))
906          {
907             setCl = true;
908             SecurityActions.setContextClassLoader(this.classLoader);
909          }
910
911          // Set the JACC context id
912
mi.setValue(InvocationKey.JACC_CONTEXT_ID, contextID);
913          contextID = SecurityActions.setContextID(contextID);
914          // Set the standard JACC policy context handler data is not a SEI msg
915
if( mi.getType() != InvocationType.SERVICE_ENDPOINT )
916          {
917             EJBArgsPolicyContextHandler.setArgs(mi.getArguments());
918          }
919          else
920          {
921             SOAPMessage JavaDoc msg = (SOAPMessage JavaDoc) mi.getValue(InvocationKey.SOAP_MESSAGE);
922             SOAPMsgPolicyContextHandler.setMessage(msg);
923          }
924          // Set custom JACC policy handlers
925
BeanMetaDataPolicyContextHandler.setMetaData(this.getBeanMetaData());
926
927          // Check against home, remote, localHome, local, getHome,
928
// getRemote, getLocalHome, getLocal
929
type = mi.getType();
930
931          // stat gathering: concurrent calls
932
this.invokeStats.callIn();
933
934          if (type == InvocationType.REMOTE ||
935                  type == InvocationType.LOCAL ||
936                  // web service calls come in as "ordinary" application invocations
937
type == InvocationType.SERVICE_ENDPOINT)
938          {
939             if (mi instanceof MarshalledInvocation)
940             {
941                ((MarshalledInvocation) mi).setMethodMap(
942                        marshalledInvocationMapping);
943
944                if (log.isTraceEnabled())
945                {
946                   log.trace("METHOD REMOTE INVOKE " +
947                           mi.getObjectName() + "||" +
948                           mi.getMethod().getName() + "||");
949                }
950             }
951
952             m = mi.getMethod();
953
954             Object JavaDoc obj = internalInvoke(mi);
955             return obj;
956          }
957          else if (type == InvocationType.HOME ||
958                  type == InvocationType.LOCALHOME)
959          {
960             if (mi instanceof MarshalledInvocation)
961             {
962
963                ((MarshalledInvocation) mi).setMethodMap(
964                        marshalledInvocationMapping);
965
966                if (log.isTraceEnabled())
967                {
968                   log.trace("METHOD HOME INVOKE " +
969                           mi.getObjectName() + "||" +
970                           mi.getMethod().getName() + "||" +
971                           mi.getArguments().toString());
972                }
973             }
974             m = mi.getMethod();
975
976             Object JavaDoc obj = internalInvokeHome(mi);
977             return obj;
978          }
979          else
980          {
981             throw new MBeanException JavaDoc(new IllegalArgumentException JavaDoc(
982                     "Unknown invocation type: " + type));
983          }
984       }
985       /**
986        * Having to catch this exception here in case can not
987        * unmarshall arguments, values, etc. Then, convert to
988        * UnmarshalException as defined by spec (JBAS-2999)
989        */

990       catch (JBossLazyUnmarshallingException e)
991       {
992          InvocationType calltype = mi.getType();
993          boolean isLocal =
994                calltype == InvocationType.LOCAL ||
995                calltype == InvocationType.LOCALHOME;
996
997          // handle unmarshalling exception which should only come if problem unmarshalling
998
// invocation payload, arguments, or value on remote end.
999
if (isLocal)
1000         {
1001            throw new EJBException JavaDoc("UnmarshalException", e);
1002         }
1003         else
1004         {
1005            throw new MarshalException JavaDoc("MarshalException", e);
1006         }
1007      }
1008      finally
1009      {
1010         if (m != null)
1011         {
1012            long end = System.currentTimeMillis();
1013            long elapsed = end - start;
1014            this.invokeStats.updateStats(m, elapsed);
1015         }
1016
1017         // stat gathering: concurrent calls
1018
this.invokeStats.callOut();
1019
1020         // Restore the incoming class loader
1021
if(setCl)
1022         {
1023            SecurityActions.setContextClassLoader(callerClassLoader);
1024         }
1025         // Restore the incoming context id
1026
contextID = SecurityActions.setContextID(contextID);
1027
1028         if (mi.getType() == InvocationType.SERVICE_ENDPOINT)
1029         {
1030            // Remove msg from ThreadLocal to prevent leakage into the thread pool
1031
SOAPMsgPolicyContextHandler.setMessage(null);
1032         }
1033         else
1034         {
1035            // Remove args from ThreadLocal to prevent leakage into the thread pool
1036
EJBArgsPolicyContextHandler.setArgs(null);
1037         }
1038      }
1039   }
1040
1041   // Private -------------------------------------------------------
1042

1043   /**
1044    * This method sets up the naming environment of the bean.
1045    * We create the java:comp/env namespace with properties, EJB-References,
1046    * and DataSource ressources.
1047    */

1048   private void setupEnvironment() throws Exception JavaDoc
1049   {
1050      BeanMetaData beanMetaData = getBeanMetaData();
1051
1052      // debug
1053
log.debug("Begin java:comp/env for EJB: " + beanMetaData.getEjbName());
1054      ClassLoader JavaDoc tcl = SecurityActions.getContextClassLoader();
1055      log.debug("TCL: " + tcl);
1056
1057      ORB JavaDoc orb = null;
1058      HandleDelegate JavaDoc hd = null;
1059      try
1060      {
1061         orb = (ORB JavaDoc) server.getAttribute(ORB_NAME, "ORB");
1062         hd = (HandleDelegate JavaDoc) server.getAttribute(ORB_NAME, "HandleDelegate");
1063      }
1064      catch (Throwable JavaDoc t)
1065      {
1066         log.debug("Unable to retrieve orb" + t.toString());
1067      }
1068      
1069      // Since the BCL is already associated with this thread we can start
1070
// using the java: namespace directly
1071
Context JavaDoc ctx = (Context JavaDoc) new InitialContext JavaDoc().lookup("java:comp");
1072
1073      // Bind the orb
1074
if (orb != null)
1075      {
1076         NonSerializableFactory.rebind(ctx, "ORB", orb);
1077         log.debug("Bound java:comp/ORB for EJB: " + getBeanMetaData().getEjbName());
1078
1079         NonSerializableFactory.rebind(ctx, "HandleDelegate", hd);
1080         log.debug("Bound java:comp:/HandleDelegate for EJB: " + getBeanMetaData().getEjbName());
1081      }
1082      
1083      Context JavaDoc envCtx = ctx.createSubcontext("env");
1084
1085      // Bind environment properties
1086
{
1087         Iterator JavaDoc i = beanMetaData.getEnvironmentEntries();
1088         while (i.hasNext())
1089         {
1090            EnvEntryMetaData entry = (EnvEntryMetaData) i.next();
1091            log.debug("Binding env-entry: " + entry.getName() + " of type: " +
1092                  entry.getType() + " to value:" + entry.getValue());
1093
1094            EnvEntryMetaData.bindEnvEntry(envCtx, entry);
1095         }
1096      }
1097
1098      // Bind EJB references
1099
{
1100         Iterator JavaDoc i = beanMetaData.getEjbReferences();
1101         while (i.hasNext())
1102         {
1103            EjbRefMetaData ref = (EjbRefMetaData) i.next();
1104            log.debug("Binding an EJBReference " + ref.getName());
1105
1106            if (ref.getLink() != null)
1107            {
1108               // Internal link
1109
String JavaDoc linkName = ref.getLink();
1110               String JavaDoc jndiName = EjbUtil.findEjbLink(server, di, linkName);
1111               log.debug("Binding " + ref.getName() +
1112                     " to ejb-link: " + linkName + " -> " + jndiName);
1113               
1114               if (jndiName == null)
1115               {
1116                  String JavaDoc msg = "Failed to resolve ejb-link: " + linkName
1117                          + " make by ejb-name: " + ref.getName();
1118                  throw new DeploymentException(msg);
1119               }
1120
1121               Util.bind(envCtx,
1122                       ref.getName(),
1123                       new LinkRef JavaDoc(jndiName));
1124
1125            }
1126            else
1127            {
1128               // Get the invoker specific ejb-ref mappings
1129
Iterator JavaDoc it = beanMetaData.getInvokerBindings();
1130               Reference JavaDoc reference = null;
1131               while (it.hasNext())
1132               {
1133                  String JavaDoc invokerBinding = (String JavaDoc) it.next();
1134                  // Check for an invoker level jndi-name
1135
String JavaDoc name = ref.getInvokerBinding(invokerBinding);
1136                  // Check for an global jndi-name
1137
if (name == null)
1138                     name = ref.getJndiName();
1139                  if (name == null)
1140                  {
1141                     throw new DeploymentException
1142                             ("ejb-ref " + ref.getName() +
1143                             ", expected either ejb-link in ejb-jar.xml or " +
1144                             "jndi-name in jboss.xml");
1145                  }
1146
1147                  StringRefAddr JavaDoc addr = new StringRefAddr JavaDoc(invokerBinding, name);
1148                  log.debug("adding " + invokerBinding + ":" + name +
1149                          " to Reference");
1150
1151                  if (reference == null)
1152                  {
1153                     reference = new Reference JavaDoc("javax.naming.LinkRef",
1154                             ENCThreadLocalKey.class.getName(),
1155                             null);
1156                  }
1157                  reference.add(addr);
1158               }
1159
1160               // If there were invoker bindings create bind the reference
1161
if (reference != null)
1162               {
1163                  if (ref.getJndiName() != null)
1164                  {
1165                     // Add default for the bean level ejb-ref/jndi-name
1166
StringRefAddr JavaDoc addr =
1167                             new StringRefAddr JavaDoc("default", ref.getJndiName());
1168                     reference.add(addr);
1169                  }
1170                  if (reference.size() == 1 && reference.get("default") == null)
1171                  {
1172                     /* There is only one invoker binding and its not default so
1173                     create a default binding to allow the link to have a value
1174                     when accessed without an invoker active.
1175                     */

1176                     StringRefAddr JavaDoc addr = (StringRefAddr JavaDoc) reference.get(0);
1177                     String JavaDoc target = (String JavaDoc) addr.getContent();
1178                     StringRefAddr JavaDoc addr1 = new StringRefAddr JavaDoc("default", target);
1179                     reference.add(addr1);
1180                  }
1181                  Util.bind(envCtx, ref.getName(), reference);
1182               }
1183               else
1184               {
1185                  // Bind the bean level ejb-ref/jndi-name
1186
if (ref.getJndiName() == null)
1187                  {
1188                     throw new DeploymentException("ejb-ref " + ref.getName() +
1189                             ", expected either ejb-link in ejb-jar.xml " +
1190                             "or jndi-name in jboss.xml");
1191                  }
1192                  Util.bind(envCtx,
1193                          ref.getName(),
1194                          new LinkRef JavaDoc(ref.getJndiName()));
1195               }
1196            }
1197         }
1198      }
1199
1200      // Bind Local EJB references
1201
{
1202         Iterator JavaDoc i = beanMetaData.getEjbLocalReferences();
1203         while (i.hasNext())
1204         {
1205            EjbLocalRefMetaData ref = (EjbLocalRefMetaData) i.next();
1206            String JavaDoc refName = ref.getName();
1207            log.debug("Binding an EJBLocalReference " + ref.getName());
1208
1209            if (ref.getLink() != null)
1210            {
1211               // Internal link
1212
log.debug("Binding " + refName + " to bean source: " + ref.getLink());
1213
1214               String JavaDoc jndiName = EjbUtil.findLocalEjbLink(server, di,
1215                       ref.getLink());
1216
1217               Util.bind(envCtx,
1218                       ref.getName(),
1219                       new LinkRef JavaDoc(jndiName));
1220            }
1221            else
1222            {
1223               // Bind the bean level ejb-local-ref/local-jndi-name
1224
if (ref.getJndiName() == null)
1225               {
1226                  throw new DeploymentException("ejb-local-ref " + ref.getName() +
1227                          ", expected either ejb-link in ejb-jar.xml " +
1228                          "or local-jndi-name in jboss.xml");
1229               }
1230               Util.bind(envCtx,
1231                       ref.getName(),
1232                       new LinkRef JavaDoc(ref.getJndiName()));
1233            }
1234         }
1235      }
1236
1237      // Bind service references
1238
Iterator JavaDoc serviceRefs = metaData.getServiceReferences().values().iterator();
1239      ServiceRefHandler refHandler = ServiceRefHandlerFactory.newInstance();
1240      if (refHandler != null && serviceRefs.hasNext())
1241         refHandler.setupServiceRefEnvironment(envCtx, serviceRefs, di);
1242
1243      // Bind resource references
1244
{
1245         Iterator JavaDoc i = beanMetaData.getResourceReferences();
1246
1247         // let's play guess the cast game ;) New metadata should fix this.
1248
ApplicationMetaData application =
1249                 beanMetaData.getApplicationMetaData();
1250
1251         while (i.hasNext())
1252         {
1253            ResourceRefMetaData ref = (ResourceRefMetaData) i.next();
1254
1255            String JavaDoc resourceName = ref.getResourceName();
1256            String JavaDoc finalName = application.getResourceByName(resourceName);
1257            String JavaDoc resType = ref.getType();
1258            // If there was no resource-manager specified then an immeadiate
1259
// jndi-name or res-url name should have been given
1260
if (finalName == null)
1261               finalName = ref.getJndiName();
1262
1263            if (finalName == null && resType.equals("java.net.URL") == false)
1264            {
1265               // the application assembler did not provide a resource manager
1266
// if the type is javax.sql.Datasoure use the default one
1267

1268               if (ref.getType().equals("javax.sql.DataSource"))
1269               {
1270                  // Go through JNDI and look for DataSource - use the first one
1271
Context JavaDoc dsCtx = new InitialContext JavaDoc();
1272                  try
1273                  {
1274                     // Check if it is available in JNDI
1275
dsCtx.lookup("java:/DefaultDS");
1276                     finalName = "java:/DefaultDS";
1277                  }
1278                  catch (Exception JavaDoc e)
1279                  {
1280                     log.debug("failed to lookup DefaultDS; ignoring", e);
1281                  }
1282                  finally
1283                  {
1284                     dsCtx.close();
1285                  }
1286               }
1287
1288               // Default failed? Warn user and move on
1289
// POTENTIALLY DANGEROUS: should this be a critical error?
1290
if (finalName == null)
1291               {
1292                  log.warn("No resource manager found for " +
1293                          ref.getResourceName());
1294                  continue;
1295               }
1296            }
1297
1298            if (resType.equals("java.net.URL"))
1299            {
1300               // URL bindings
1301
if( ref.getResURL() != null )
1302               {
1303                  // The URL string was given by the res-url
1304
log.debug("Binding URL: " + ref.getRefName() +
1305                          " to JDNI ENC as: " + ref.getResURL());
1306                  URL JavaDoc resURL = new URL JavaDoc(ref.getResURL());
1307                  Util.bind(envCtx, ref.getRefName(), resURL);
1308               }
1309               else
1310               {
1311                  log.debug("Binding URL: " + ref.getRefName() + " to: " + finalName);
1312                  Object JavaDoc bind = null;
1313                  if( ref.getJndiName() != null )
1314                  {
1315                     // Was the url given as a jndi-name reference to link to it
1316
bind = new LinkRef JavaDoc(finalName);
1317                  }
1318                  else
1319                  {
1320                     // The url string was given via a resource-name mapping
1321
bind = new URL JavaDoc(finalName);
1322                  }
1323                  Util.bind(envCtx, ref.getRefName(), bind);
1324               }
1325            }
1326            else
1327            {
1328               // Resource Manager bindings, should validate the type...
1329
log.debug("Binding resource manager: " + ref.getRefName() +
1330                     " to JDNI ENC as: " + finalName);
1331               Util.bind(envCtx, ref.getRefName(), new LinkRef JavaDoc(finalName));
1332            }
1333         }
1334      }
1335
1336      // Bind resource env references
1337
{
1338         Iterator JavaDoc i = beanMetaData.getResourceEnvReferences();
1339         while (i.hasNext())
1340         {
1341            ResourceEnvRefMetaData resRef =
1342                    (ResourceEnvRefMetaData) i.next();
1343            String JavaDoc encName = resRef.getRefName();
1344            String JavaDoc jndiName = resRef.getJndiName();
1345            // Should validate the type...
1346
log.debug("Binding env resource: " + encName +
1347                  " to JDNI ENC as: " + jndiName);
1348            Util.bind(envCtx, encName, new LinkRef JavaDoc(jndiName));
1349         }
1350      }
1351
1352      // Bind message destination references
1353
{
1354         Iterator JavaDoc i = beanMetaData.getMessageDestinationReferences();
1355
1356         while (i.hasNext())
1357         {
1358            MessageDestinationRefMetaData ref = (MessageDestinationRefMetaData) i.next();
1359
1360            String JavaDoc refName = ref.getRefName();
1361            String JavaDoc jndiName = ref.getJNDIName();
1362            String JavaDoc link = ref.getLink();
1363            if (link != null)
1364            {
1365               if (jndiName == null)
1366               {
1367                  MessageDestinationMetaData messageDestination = getMessageDestination(link);
1368                  if (messageDestination == null)
1369                     throw new DeploymentException("message-destination-ref '" + refName +
1370                        "' message-destination-link '" + link + "' not found and no jndi-name in jboss.xml");
1371                  else
1372                  {
1373                     String JavaDoc linkJNDIName = messageDestination.getJNDIName();
1374                     if (linkJNDIName == null)
1375                        log.warn("message-destination '" + link + "' has no jndi-name in jboss.xml");
1376                     else
1377                        jndiName = linkJNDIName;
1378                  }
1379               }
1380               else
1381                  log.warn("message-destination-ref '" + refName +
1382                     "' ignoring message-destination-link '" + link + "' because it has a jndi-name in jboss.xml");
1383            }
1384            else if (jndiName == null)
1385               throw new DeploymentException("message-destination-ref '" + refName +
1386                     "' has no message-destination-link in ejb-jar.xml and no jndi-name in jboss.xml");
1387            Util.bind(envCtx, refName, new LinkRef JavaDoc(jndiName));
1388         }
1389      }
1390
1391      // Create a java:comp/env/security/security-domain link to the container
1392
// or application security-domain if one exists so that access to the
1393
// security manager can be made without knowing the global jndi name.
1394

1395      String JavaDoc securityDomain =
1396              metaData.getContainerConfiguration().getSecurityDomain();
1397      if (securityDomain == null)
1398         securityDomain = metaData.getApplicationMetaData().getSecurityDomain();
1399      if (securityDomain != null)
1400      {
1401         log.debug("Binding securityDomain: " + securityDomain +
1402            " to JDNI ENC as: security/security-domain");
1403
1404         Util.bind( envCtx, "security/security-domain", new LinkRef JavaDoc(securityDomain));
1405         Util.bind( envCtx, "security/subject", new LinkRef JavaDoc(securityDomain + "/subject"));
1406         Util.bind(envCtx, "security/realmMapping", new LinkRef JavaDoc(securityDomain + "/realmMapping"));
1407         Util.bind(envCtx, "security/authorizationMgr", new LinkRef JavaDoc(securityDomain+"/authorizationMgr"));
1408      }
1409
1410      log.debug("End java:comp/env for EJB: " + beanMetaData.getEjbName());
1411   }
1412   
1413   public MessageDestinationMetaData getMessageDestination(String JavaDoc link)
1414   {
1415      return EjbUtil.findMessageDestination(server, di, link);
1416   }
1417
1418   /**
1419    *The <code>teardownEnvironment</code> method unbinds everything from
1420    * the comp/env context. It would be better do destroy the env context
1421    * but destroyContext is not currently implemented..
1422    *
1423    * @exception Exception if an error occurs
1424    */

1425   private void teardownEnvironment() throws Exception JavaDoc
1426   {
1427      Context JavaDoc ctx = (Context JavaDoc) new InitialContext JavaDoc().lookup("java:comp");
1428      ctx.unbind("env");
1429      log.debug("Removed bindings from java:comp/env for EJB: " + getBeanMetaData().getEjbName());
1430      try
1431      {
1432         NonSerializableFactory.unbind("ORB");
1433         log.debug("Unbound java:comp/ORB for EJB: " + getBeanMetaData().getEjbName());
1434
1435         NonSerializableFactory.unbind("HandleDelegate");
1436         log.debug("Unbound java:comp/HandleDelegate for EJB: " + getBeanMetaData().getEjbName());
1437      }
1438      catch (NamingException JavaDoc ignored)
1439      {
1440      }
1441   }
1442
1443   /**
1444    * The base class for container interceptors.
1445    *
1446    * <p>
1447    * All container interceptors perform the same basic functionality
1448    * and only differ slightly.
1449    */

1450   protected abstract class AbstractContainerInterceptor
1451           implements Interceptor
1452   {
1453      protected final Logger log = Logger.getLogger(this.getClass());
1454
1455      public void setContainer(Container con)
1456      {
1457      }
1458
1459      public void setNext(Interceptor interceptor)
1460      {
1461      }
1462
1463      public Interceptor getNext()
1464      {
1465         return null;
1466      }
1467
1468      public void create()
1469      {
1470      }
1471
1472      public void start()
1473      {
1474      }
1475
1476      public void stop()
1477      {
1478      }
1479
1480      public void destroy()
1481      {
1482      }
1483
1484      protected void rethrow(Exception JavaDoc e)
1485              throws Exception JavaDoc
1486      {
1487         if (e instanceof IllegalAccessException JavaDoc)
1488         {
1489            // Throw this as a bean exception...(?)
1490
throw new EJBException JavaDoc(e);
1491         }
1492         else if (e instanceof InvocationTargetException JavaDoc)
1493         {
1494            Throwable JavaDoc t = ((InvocationTargetException JavaDoc) e).getTargetException();
1495
1496            if (t instanceof EJBException JavaDoc)
1497            {
1498               throw (EJBException JavaDoc) t;
1499            }
1500            else if (t instanceof Exception JavaDoc)
1501            {
1502               throw (Exception JavaDoc) t;
1503            }
1504            else if (t instanceof Error JavaDoc)
1505            {
1506               throw (Error JavaDoc) t;
1507            }
1508            else
1509            {
1510               throw new NestedError("Unexpected Throwable", t);
1511            }
1512         }
1513
1514         throw e;
1515      }
1516
1517      // Monitorable implementation ------------------------------------
1518

1519      public void sample(Object JavaDoc s)
1520      {
1521         // Just here to because Monitorable request it but will be removed soon
1522
}
1523
1524      public Map JavaDoc retrieveStatistic()
1525      {
1526         return null;
1527      }
1528
1529      public void resetStatistic()
1530      {
1531      }
1532   }
1533
1534   /** Perform the MBeanServer.invoke op in a PrivilegedExceptionAction if
1535    * running with a security manager.
1536    */

1537   class MBeanServerAction implements PrivilegedExceptionAction JavaDoc
1538   {
1539      private ObjectName JavaDoc target;
1540      String JavaDoc method;
1541      Object JavaDoc[] args;
1542      String JavaDoc[] sig;
1543
1544      MBeanServerAction()
1545      {
1546      }
1547      MBeanServerAction(ObjectName JavaDoc target, String JavaDoc method, Object JavaDoc[] args, String JavaDoc[] sig)
1548      {
1549         this.target = target;
1550         this.method = method;
1551         this.args = args;
1552         this.sig = sig;
1553      }
1554
1555      public Object JavaDoc run() throws Exception JavaDoc
1556      {
1557         Object JavaDoc rtnValue = server.invoke(target, method, args, sig);
1558         return rtnValue;
1559      }
1560      Object JavaDoc invoke(ObjectName JavaDoc target, String JavaDoc method, Object JavaDoc[] args, String JavaDoc[] sig)
1561         throws Exception JavaDoc
1562      {
1563         SecurityManager JavaDoc sm = System.getSecurityManager();
1564         Object JavaDoc rtnValue = null;
1565         if( sm == null )
1566         {
1567            // Direct invocation on MBeanServer
1568
rtnValue = server.invoke(target, method, args, sig);
1569         }
1570         else
1571         {
1572            try
1573            {
1574               // Encapsulate the invocation in a PrivilegedExceptionAction
1575
MBeanServerAction action = new MBeanServerAction(target, method, args, sig);
1576               rtnValue = AccessController.doPrivileged(action);
1577            }
1578            catch (PrivilegedActionException JavaDoc e)
1579            {
1580               Exception JavaDoc ex = e.getException();
1581               throw ex;
1582            }
1583         }
1584         return rtnValue;
1585      }
1586   }
1587}
1588
Popular Tags