KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openejb > core > DeploymentInfo


1 /**
2  * Redistribution and use of this software and associated documentation
3  * ("Software"), with or without modification, are permitted provided
4  * that the following conditions are met:
5  *
6  * 1. Redistributions of source code must retain copyright
7  * statements and notices. Redistributions must also contain a
8  * copy of this document.
9  *
10  * 2. Redistributions in binary form must reproduce the
11  * above copyright notice, this list of conditions and the
12  * following disclaimer in the documentation and/or other
13  * materials provided with the distribution.
14  *
15  * 3. The name "Exolab" must not be used to endorse or promote
16  * products derived from this Software without prior written
17  * permission of Exoffice Technologies. For written permission,
18  * please contact info@exolab.org.
19  *
20  * 4. Products derived from this Software may not be called "Exolab"
21  * nor may "Exolab" appear in their names without prior written
22  * permission of Exoffice Technologies. Exolab is a registered
23  * trademark of Exoffice Technologies.
24  *
25  * 5. Due credit should be given to the Exolab Project
26  * (http://www.exolab.org/).
27  *
28  * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32  * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39  * OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Copyright 1999 (C) Exoffice Technologies Inc. All Rights Reserved.
42  *
43  * $Id: DeploymentInfo.java 2112 2005-08-26 21:28:34Z dblevins $
44  */

45 package org.openejb.core;
46
47 import java.lang.reflect.Field JavaDoc;
48 import java.lang.reflect.Method JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.HashSet JavaDoc;
51
52 import javax.ejb.EJBContext JavaDoc;
53 import javax.ejb.EJBHome JavaDoc;
54 import javax.ejb.EJBLocalHome JavaDoc;
55 import javax.ejb.EJBLocalObject JavaDoc;
56 import javax.ejb.SessionSynchronization JavaDoc;
57 import javax.naming.Context JavaDoc;
58
59 import org.openejb.Container;
60 import org.openejb.RpcContainer;
61 import org.openejb.alt.containers.castor_cmp11.CastorCMP11_EntityContainer;
62 import org.openejb.alt.containers.castor_cmp11.CastorCmpEntityTxPolicy;
63 import org.openejb.alt.containers.castor_cmp11.KeyGenerator;
64 import org.openejb.core.entity.EntityEjbHomeHandler;
65 import org.openejb.core.ivm.BaseEjbProxyHandler;
66 import org.openejb.core.ivm.EjbHomeProxyHandler;
67 import org.openejb.core.ivm.SpecialProxyInfo;
68 import org.openejb.core.stateful.SessionSynchronizationTxPolicy;
69 import org.openejb.core.stateful.StatefulBeanManagedTxPolicy;
70 import org.openejb.core.stateful.StatefulContainerManagedTxPolicy;
71 import org.openejb.core.stateful.StatefulEjbHomeHandler;
72 import org.openejb.core.stateless.StatelessBeanManagedTxPolicy;
73 import org.openejb.core.stateless.StatelessEjbHomeHandler;
74 import org.openejb.core.transaction.TransactionContainer;
75 import org.openejb.core.transaction.TransactionPolicy;
76 import org.openejb.core.transaction.TxManditory;
77 import org.openejb.core.transaction.TxNever;
78 import org.openejb.core.transaction.TxNotSupported;
79 import org.openejb.core.transaction.TxRequired;
80 import org.openejb.core.transaction.TxRequiresNew;
81 import org.openejb.core.transaction.TxSupports;
82 import org.openejb.util.proxy.ProxyManager;
83
84 /**
85  * Contains all the information needed by the container for a particular
86  * deployment. Some of this information is generic, but this class is
87  * largely becoming a dumping ground for information specific to individual
88  * containers. This class should be abstracted and subclassed in the individual
89  * container packages. The container should be required to provide its own DeploymentInfo
90  * implementation, possibly returning it to the assembler and OpenEJB in general via a
91  * new accessor method.
92  *
93  * @author <a HREF="mailto:Richard@Monson-Haefel.com">Richard Monson-Haefel</a>
94  * @author <a HREF="mailto:david.blevins@visi.com">David Blevins</a>
95  * @version $Revision: 2112 $ $Date: 2005-08-26 14:28:34 -0700 (Fri, 26 Aug 2005) $
96  */

97 public class DeploymentInfo implements org.openejb.DeploymentInfo{
98
99     private Class JavaDoc homeInterface;
100     private Class JavaDoc remoteInterface;
101     private Class JavaDoc localHomeInterface;
102     private Class JavaDoc localInterface;
103     private Class JavaDoc beanClass;
104     private Class JavaDoc pkClass;
105         
106     private boolean isBeanManagedTransaction;
107     private boolean isReentrant;
108     private Container container;
109     
110     private EJBHome JavaDoc ejbHomeRef;
111
112     private final DeploymentContext context;
113
114     /**
115      * Stateless session beans only have one create method. The getCreateMethod is
116      * used by instance manager of the core.stateless.StatelessContainer as a
117      * convenience method for obtaining the ejbCreate method.
118      */

119     private Method JavaDoc createMethod = null;
120     
121     /**
122      * Every Entity ejbCreate method has a matching ejbPostCreate method. This
123      * maps that relationship.
124      */

125     private HashMap JavaDoc postCreateMethodMap = new HashMap JavaDoc();
126     /**
127      * Can be one of the following DeploymentInfo values: STATEFUL, STATELESS,
128      * BMP_ENTITY, CMP_ENTITY.
129      */

130     private byte componentType;
131
132     private HashMap JavaDoc methodPermissions = new HashMap JavaDoc();
133     private HashMap JavaDoc methodTransactionAttributes = new HashMap JavaDoc();
134     private HashMap JavaDoc methodTransactionPolicies = new HashMap JavaDoc();
135     private HashMap JavaDoc methodMap = new HashMap JavaDoc();
136     /**
137      */

138     private HashMap JavaDoc securityRoleReferenceMap = new HashMap JavaDoc();
139     private HashSet JavaDoc methodsWithRemoteReturnTypes = null;
140     private EJBLocalHome JavaDoc ejbLocalHomeRef;
141
142     /**
143      * Constructs a DeploymentInfo object to represent the specified bean's
144      * deployment information.
145      *
146      * @param did the id of this bean deployment
147      * @param homeClass the bean's home interface definition
148      * @param remoteClass
149      * the bean's remote interface definition
150      * @param beanClass the bean's class definition
151      * @param pkClass the bean's primary key class
152      * @param componentType
153      * one of the component type constants defined in org.openejb.DeploymentInfo
154      * @exception org.openejb.SystemException
155      * @see org.openejb.Container#getContainerID
156      * @see org.openejb.DeploymentInfo#STATEFUL
157      * @see org.openejb.DeploymentInfo#STATELESS
158      * @see org.openejb.DeploymentInfo#BMP_ENTITY
159      * @see org.openejb.DeploymentInfo#CMP_ENTITY
160      */

161     public DeploymentInfo(DeploymentContext context, Class JavaDoc homeClass, Class JavaDoc remoteClass, Class JavaDoc localHomeClass, Class JavaDoc localClass, Class JavaDoc beanClass, Class JavaDoc pkClass, byte componentType)
162     throws org.openejb.SystemException{
163         this.context = context;
164         this.pkClass = pkClass;
165
166         this.homeInterface = homeClass;
167         this.remoteInterface = remoteClass;
168         this.localInterface = localClass;
169         this.localHomeInterface = localHomeClass;
170         this.remoteInterface = remoteClass;
171         this.beanClass = beanClass;
172         this.pkClass = pkClass;
173         this.componentType = componentType;
174         
175         createMethodMap();
176
177     }
178     
179
180     /**
181      * Container must have its Container set explicitly by the Assembler to avoid
182      * a chicken and egg problem: Which is created first the container or the
183      * DeploymentInfo This assembler will invoke this method when needed. The
184      * Container must be set before the bean is ready to process requests.
185      *
186      * @param cont
187      */

188     public void setContainer(Container cont){
189         container = cont;
190     }
191
192
193
194     //====================================
195
// begin DeploymentInfo Implementation
196
//
197

198     /**
199      * Gets the type of this bean component.
200      * Will return a
201      * <code>STATEFUL</code>,
202      * <code>STATELESS</code>,
203      * <code>BMP_ENTITY</code> or
204      * <code>CMP_ENTITY</code>.
205      *
206      * @return Returns <code>STATEFUL</code>, <code>STATELESS</code>, <code>BMP_ENTITY</code> or <code>CMP_ENTITY</code>.
207      * @see #STATEFUL
208      * @see #STATELESS
209      * @see #BMP_ENTITY
210      * @see #CMP_ENTITY
211      * @see #MESSAGE_DRIVEN
212      */

213     public byte getComponentType( ){
214         return componentType;
215     }
216
217     /**
218      * Gets the transaction attribute that must be applied to this method when
219      * executing.
220      *
221      * The type can be anyone of
222      * <code>TX_NEVER</code>,
223      * <code>TX_NOT_SUPPORTED</code>,
224      * <code>TX_SUPPORTS</code>,
225      * <code>TX_MANDITORY</code>,
226      * <code>TX_REQUIRED</code>,
227      * <code>TX_REQUIRES_NEW</code>,
228      *
229      * @param method the bean's method for which transaction attribute information is needed
230      * @return the transaction constant that states the method's transaction attribute
231      * @see #TX_NEVER
232      * @see #TX_NOT_SUPPORTED
233      * @see #TX_SUPPORTS
234      * @see #TX_MANDITORY
235      * @see #TX_REQUIRED
236      * @see #TX_REQUIRES_NEW
237      */

238     public byte getTransactionAttribute(Method JavaDoc method){
239
240         Byte JavaDoc byteWrapper = (Byte JavaDoc)methodTransactionAttributes.get(method);
241         if(byteWrapper==null)
242             return TX_NOT_SUPPORTED;// non remote or home interface method
243
else
244             return byteWrapper.byteValue();
245     }
246
247     public TransactionPolicy getTransactionPolicy(Method JavaDoc method){
248
249         TransactionPolicy policy = (TransactionPolicy)methodTransactionPolicies.get(method);
250         if(policy==null && !isBeanManagedTransaction) {
251             org.apache.log4j.Logger.getLogger("OpenEJB").warn("The following method doesn't have a transaction policy assigned: "+method);
252         }
253         if ( policy == null && container instanceof TransactionContainer) {
254             if ( isBeanManagedTransaction ) {
255                 if ( componentType == STATEFUL ) {
256                     policy = new StatefulBeanManagedTxPolicy((TransactionContainer) container );
257                 } else if (componentType == STATELESS) {
258                     policy = new StatelessBeanManagedTxPolicy((TransactionContainer) container );
259                 }
260             } else if ( componentType == STATEFUL ){
261                 policy = new TxNotSupported((TransactionContainer) container );
262                 policy = new StatefulContainerManagedTxPolicy( policy );
263             } else if ( componentType == CMP_ENTITY ){
264                 policy = new TxNotSupported((TransactionContainer) container );
265                 policy = new CastorCmpEntityTxPolicy( policy );
266             } else {
267                 policy = new TxNotSupported((TransactionContainer) container );
268             }
269             methodTransactionPolicies.put( method, policy );
270         }
271         return policy;
272     }
273
274     /**
275      * Gets the roles that are authorised to execute this method.
276      *
277      * Used primarily by the container to check the caller's rights to
278      * access and execute the specifed method.
279      *
280      * @param method the bean's method for which security information is needed
281      * @return a String array of the roles that are authorised to execute this method
282      * @see org.openejb.spi.SecurityService#isCallerAuthorized
283      */

284     public String JavaDoc [] getAuthorizedRoles(Method JavaDoc method){
285         HashSet JavaDoc roleSet = (HashSet JavaDoc)methodPermissions.get(method);
286         if(roleSet == null) return null;
287         String JavaDoc [] roles = new String JavaDoc[roleSet.size()];
288         return (String JavaDoc [])roleSet.toArray(roles);
289     }
290
291     public String JavaDoc [] getAuthorizedRoles(String JavaDoc action){
292         return null;
293     }
294
295     /**
296      * Gets the the container that this deployed bean is in.
297      *
298      * @return the the deployment's container.
299      * @see Container#getContainerID() Container.getContainerID()
300      */

301     public Container getContainer( ){
302         return container;
303     }
304
305     /**
306      * Gets the id of this bean deployment.
307      *
308      * @return the id of of this bean deployment
309      */

310     public Object JavaDoc getDeploymentID( ){
311         return context.getId();
312     }
313
314     /**
315      * Returns true if this bean deployment has chosen bean-managed transaction
316      * demarcation. Returns false if the continer will be managing the bean's
317      * transactions.
318      *
319      * @return Returns true if this bean deployment is managing its own transactions.
320      */

321     public boolean isBeanManagedTransaction(){
322         return isBeanManagedTransaction;
323     }
324
325     /**
326      * Gets the home interface for the bean deployment.
327      *
328      * Used primarily by Servers integrating OpenEJB into their platform. Aids in
329      * implementing the bean's home interface.
330      *
331      * @return a Class object of the bean's home interface
332      * @see javax.ejb.EJBHome
333      */

334     public Class JavaDoc getHomeInterface( ){
335         return homeInterface;
336     }
337
338     /**
339      * Gets the remote interface for the bean deployment.
340      *
341      * Used primarily by Servers integrating OpenEJB into their platform. Aids in
342      * implementing the bean's remote interface.
343      *
344      * @return a Class object of the bean's remote interface
345      * @see javax.ejb.EJBObject
346      */

347     public Class JavaDoc getRemoteInterface( ){
348         return remoteInterface;
349     }
350
351     public Class JavaDoc getLocalHomeInterface() {
352         return localHomeInterface;
353     }
354     
355     public Class JavaDoc getLocalInterface() {
356         return localInterface;
357     }
358     
359     /**
360      * Gets the bean's class definition.
361      *
362      * Used primarily by containers to instantiate new instances of a bean.
363      *
364      * @return a Class object of the bean's class definition
365      * @see javax.ejb.EnterpriseBean
366      */

367     public Class JavaDoc getBeanClass( ){
368         return beanClass;
369     }
370
371     /**
372      * Gets the Class type of the primary key for this bean deployment.
373      * Returns null if the bean is a type that does not need a primary key.
374      *
375      * @return the Class type of the bean's primary key or null if the bean doesn't need a primary key
376      */

377     public Class JavaDoc getPrimaryKeyClass( ){
378         return pkClass;
379     }
380
381     //
382
// end DeploymentInfo Implementation
383
//==================================
384

385
386     //===================================================
387
// begin accessors & mutators for this implementation
388
//
389

390     /**
391      * Gets the <code>EJBHome</code> object of this bean deployment.
392      *
393      * @return the javax.ejb.EJBHome object
394      * @see javax.ejb.EJBHome
395      */

396     public EJBHome JavaDoc getEJBHome() {
397         if (getHomeInterface() == null) {
398             throw new IllegalStateException JavaDoc("This component has no home interface: "+getDeploymentID());
399         }
400         if(ejbHomeRef == null){
401             ejbHomeRef = createEJBHomeRef();
402         }
403         return ejbHomeRef;
404     }
405     
406     public EJBLocalHome JavaDoc getEJBLocalHome() {
407         if (getLocalHomeInterface() == null) {
408             throw new IllegalStateException JavaDoc("This component has no local home interface: "+getDeploymentID());
409         }
410         if(ejbLocalHomeRef == null) {
411             ejbLocalHomeRef = createEJBLocalHomeRef();
412         }
413         return ejbLocalHomeRef;
414     }
415
416     /**
417      * Sets this bean deployment to container-managed or bean-managed transaction
418      * demarcation.
419      *
420      * @param value true if this bean is managing transaction, false if the container should manage them
421      */

422     public void setBeanManagedTransaction(boolean value){
423         isBeanManagedTransaction = value;
424     }
425
426     /**
427      * Gets the JNDI namespace for the bean's environment. This will be the ony
428      * namespace that the bean will be able to access using the java: URL in the JNDI.
429      *
430      * Used primarily by the IntraVM naming server to get a bean's environemtn naming context
431      * when the bean performs a lookup using the "java:" URL.
432      * @see javax.naming.Context
433      */

434     public javax.naming.Context JavaDoc getJndiEnc( ){
435         return context.getJndiContext();
436     }
437
438     /**
439      * Returns true if the bean deployment allows reenterace.
440      *
441      * @return boolean
442      */

443     public boolean isReentrant(){
444         return isReentrant;
445     }
446
447     public void setIsReentrant(boolean reentrant){
448         isReentrant = reentrant;
449     }
450     
451     /**
452      * Business methods that return EJBHome or EJBObject references to local beans
453      * (beans in the same container system) must have the return value converted
454      * to a ProxyInfo object, so that the server can provide the client with a
455      * proper remote reference. Local remote references are implemented using the
456      * org.openejb.core.ivm.BaseEjbProxyHandler types, which should not be
457      * returned to the client. Non-local remote references are assumed to be
458      * serializable and valid return types for the clients.
459      *
460      * If the reference is a local remote reference, then a subtype of ProxyInfo
461      * is returned. The subtype is a org.openejb.core.ivm.SpecialProxyInfo. This
462      * class type is useful when the calling server is the IntraVM server.
463      * Instead of creating a new remote ref from the proxy the IntraVM takes a
464      * short cut and reuses the original local remote reference -- they are thread
465      * safe with no synchronization.
466      *
467      * This method is based on a method map (methodWithRemoteReturnTypes) which is
468      * constructed in the createMethodMap( ) method of this class.
469      *
470      * See Section 2.2.1.2.5 Remote References of the OpenEJB 1.1 specification.
471      *
472      * @param businessMethod
473      * @param returnValue
474      * @return Object
475      */

476     public Object JavaDoc convertIfLocalReference(Method JavaDoc businessMethod, Object JavaDoc returnValue){
477         if(returnValue == null || methodsWithRemoteReturnTypes == null)
478            return returnValue;
479
480         // if its a local reference; local refs are always Proxy types whose handler is the BaseEjbProxyHandler
481
// the assumption is that the Set is faster then the instanceof operation,
482
// so its used to reduce the overhead of this method.
483
try{
484             if( methodsWithRemoteReturnTypes.contains(businessMethod)
485                && ProxyManager.isProxyClass( returnValue.getClass() )
486                && ProxyManager.getInvocationHandler( returnValue ) instanceof BaseEjbProxyHandler){
487     
488                return new SpecialProxyInfo( returnValue );
489             }
490         } catch (ClassCastException JavaDoc e) {
491             // Do nothing. This happens when the return value is in fact a
492
// proxy, a java.lang.reflect.Proxy for example, but the handler
493
// is not an OpenEJB implementation. This just means, it's not
494
// a local reference.
495
}
496         return returnValue;
497
498     }
499
500     /**
501      * Returns a method in the bean class that matches the method passed in.
502      *
503      * Used to map the methods from the home or remote interface to the methods in
504      * the bean class. This is needed because the java.lang.reflect.Method object
505      * passed into the container by the server is declared by a remote or home
506      * interface.
507      *
508      * Since the bean class is not required to implement either of these
509      * interfaces, the matching method on the bean class may be a different
510      * java.lang.reflect.Method object. Invoking a the remote or home interface
511      * Method object on the bean class will not work if the bean doesn't implement
512      * the Method's interface. This method provide the container with the proper
513      * Method object.
514      *
515      * The mapping is performed at assembly time by the createMethodMap( )
516      * declared in this class.
517      *
518      * @param interfaceMethod the Method of the home or remote interface
519      * @return the Method in the bean class that maps to the method specified
520      */

521     public Method JavaDoc getMatchingBeanMethod(Method JavaDoc interfaceMethod){
522         Method JavaDoc mthd = (Method JavaDoc)methodMap.get(interfaceMethod);
523         return (mthd == null)? interfaceMethod : mthd;
524     }
525
526     /**
527      * Appends a Method and a list of authorized roles to the internal list of mehtod permissions.
528      *
529      * @param m the Method the roles map to
530      * @param roleNames the roles that are authorized to execute the specified method
531      * @see java.lang.reflect.Method
532      */

533     public void appendMethodPermissions(Method JavaDoc m, String JavaDoc [] roleNames){
534         HashSet JavaDoc hs = (HashSet JavaDoc)methodPermissions.get(m);
535         if(hs == null){
536             hs = new HashSet JavaDoc( );// FIXME: Set appropriate load and intial capacity
537
methodPermissions.put(m,hs);
538         }
539         for(int i = 0; i < roleNames.length; i++){
540             hs.add(roleNames[i]);
541         }
542     }
543     /**
544      * Beans can test to see if the current principal is a member of a specified
545      * role using the method EJBContext.isPrincipalInRole(String roleName). The
546      * role name used is a logical role name specified by the bean provider. When
547      * the bean is packaged this role name must be declared in the
548      * security-role-ref and linked to a security-role element in the deployment
549      * descriptor.
550      *
551      * In OpenEJB the security-role element is also assigned a physical role,
552      * ased on the target environment. Its this physical role that must be mapped
553      * to the security-role-reference used by the bean provider.
554      * <p>
555      * The org.openejb.core.CoreContext uses this method to obtain the physical
556      * role mapped to the logical role used by the bean.
557      * <p>
558      *
559      * @param securityRoleReference
560      * the role used by the bean code; the security-role-ref
561      * @return the physical role in the target environment that is mapped to the security-
562      * @see #addSecurityRoleReference
563      */

564     public String JavaDoc [] getPhysicalRole(String JavaDoc securityRoleReference){
565         return (String JavaDoc[])securityRoleReferenceMap.get(securityRoleReference);
566     }
567     /**
568      * Adds a security-role-ref to physical role mapping. The security-role-ref is
569      * used to test the caller's membership in a particular role at runtime.
570      * <p>
571      *
572      * @param securityRoleReference the role used by the bean code; the security-role-ref
573      * @param physicalRoles
574      * @see #getPhysicalRole(String)
575      */

576     public void addSecurityRoleReference(String JavaDoc securityRoleReference, String JavaDoc [] physicalRoles){
577         securityRoleReferenceMap.put(securityRoleReference, physicalRoles);
578     }
579     /**
580      * Gets the <code>EJBContext</code> this container manager will expose to the
581      * <code>Container</code>s it manages.
582      *
583      * @return an EJBContext that containers can give to beans.
584      * @see "javax.ejb.EJBContext"
585      */

586     public EJBContext JavaDoc getEJBContext( ){
587         if(componentType == STATEFUL)
588             return new org.openejb.core.stateful.StatefulContext();
589         else if(componentType == STATELESS)
590             return new org.openejb.core.stateless.StatelessContext();
591         else if(componentType == BMP_ENTITY || componentType == CMP_ENTITY )
592             return new org.openejb.core.entity.EntityContext();
593         else
594             return null;
595
596     }
597
598     /**
599      * Sets the transaction attribute of the method in the bean's class.
600      * There are six valid transaction attributes: "Supports", "RequiresNew",
601      * "Manditory", "NotSupported", "Required", and "Never".
602      *
603      * @param method the Method the specified transaction attribute applies to.
604      * @param transAttribute
605      * one of "Supports", "RequiresNew", "Manditory", "NotSupported", "Required", or "Never".
606      * @see java.lang.reflect.Method
607      */

608     public void setMethodTransactionAttribute(Method JavaDoc method, String JavaDoc transAttribute){
609         Byte JavaDoc byteValue = null;
610         TransactionPolicy policy = null;
611
612         if(transAttribute.equals("Supports")){
613             if (container instanceof TransactionContainer) {
614                 policy = new TxSupports((TransactionContainer)container);
615             }
616             byteValue = new Byte JavaDoc(TX_SUPPORTS);
617
618         } else if(transAttribute.equals("RequiresNew")) {
619             if (container instanceof TransactionContainer) {
620                 policy = new TxRequiresNew((TransactionContainer)container);
621             }
622             byteValue = new Byte JavaDoc(TX_REQUIRES_NEW);
623
624         } else if(transAttribute.equals("Mandatory")) {
625             if (container instanceof TransactionContainer) {
626                 policy = new TxManditory((TransactionContainer)container);
627             }
628             byteValue = new Byte JavaDoc(TX_MANDITORY);
629
630         } else if(transAttribute.equals("NotSupported")) {
631             if (container instanceof TransactionContainer) {
632                 policy = new TxNotSupported((TransactionContainer)container);
633             }
634             byteValue = new Byte JavaDoc(TX_NOT_SUPPORTED);
635
636         } else if(transAttribute.equals("Required")) {
637             if (container instanceof TransactionContainer) {
638                 policy = new TxRequired((TransactionContainer)container);
639             }
640             byteValue = new Byte JavaDoc(TX_REQUIRED);
641
642         } else if(transAttribute.equals("Never")) {
643             if (container instanceof TransactionContainer) {
644                 policy = new TxNever((TransactionContainer)container);
645             }
646             byteValue = new Byte JavaDoc(TX_NEVER);
647         } else{
648             throw new IllegalArgumentException JavaDoc("Invalid transaction attribute \""+transAttribute+"\" declared for method "+method.getName()+". Please check your configuration.");
649         }
650         
651         /* EJB 1.1 page 55
652          Only a stateful Session bean with container-managed transaction demarcation may implement the
653          SessionSynchronization interface. A stateless Session bean must not implement the SessionSynchronization
654          interface.
655          */

656         // If this is a Stateful SessionBean that implements the
657
// SessionSynchronization interface and the method transaction
658
// attribute is not Never or notSupported, then wrap the TransactionPolicy
659
// with a SessionSynchronizationTxPolicy
660
if ( componentType == STATEFUL && !isBeanManagedTransaction && container instanceof TransactionContainer){
661
662             // we have a stateful session bean with container-managed transactions
663
if ( SessionSynchronization JavaDoc.class.isAssignableFrom(beanClass) ) {
664                 if ( !transAttribute.equals("Never") && !transAttribute.equals("NotSupported") ){
665                     // wrap the policy unless attribute is "never" or "NotSupported"
666
policy = new SessionSynchronizationTxPolicy( policy );
667                 }
668             } else {
669                 // CMT stateful session bean but does not implement SessionSynchronization
670
policy = new StatefulContainerManagedTxPolicy( policy );
671             }
672
673         } else if ( componentType == CMP_ENTITY ){
674             policy = new CastorCmpEntityTxPolicy( policy );
675         }
676         methodTransactionAttributes.put( method, byteValue );
677         methodTransactionPolicies.put( method, policy );
678     }
679
680     //
681
// end accessors & mutators for this implementation
682
//=================================================
683

684     //====================================
685
// Begin DeploymentInfo Initialization
686
//
687

688     /**
689      * Attempts to lookup and instantiate the EJBHome proxy for the bean deployment.
690      *
691      * @exception RuntimeException
692      * if there is a problem locating or instantiating the EJBHome proxy
693      */

694     private javax.ejb.EJBHome JavaDoc createEJBHomeRef(){
695
696         EjbHomeProxyHandler handler = null;
697         
698         switch ( getComponentType() ) {
699         case STATEFUL:
700             handler = new StatefulEjbHomeHandler((RpcContainer)container, null, getDeploymentID());
701             break;
702         
703         case STATELESS:
704             handler = new StatelessEjbHomeHandler((RpcContainer)container, null, getDeploymentID());
705             break;
706         case CMP_ENTITY:
707         case BMP_ENTITY:
708             handler = new EntityEjbHomeHandler((RpcContainer)container, null, getDeploymentID());
709             break;
710         }
711
712         Object JavaDoc proxy = null;
713         try{
714             Class JavaDoc[] interfaces = new Class JavaDoc[]{ this.getHomeInterface(), org.openejb.core.ivm.IntraVmProxy.class };
715             proxy = ProxyManager.newProxyInstance( interfaces , handler );
716         }catch(Exception JavaDoc e){
717             e.printStackTrace();
718             throw new RuntimeException JavaDoc("Can't create EJBHome stub" + e.getMessage());
719         }
720
721         return (javax.ejb.EJBHome JavaDoc)proxy;
722
723     }
724     
725     /**
726      * Attempts to instantiate the EJBLocalHome proxy for the bean deployment.
727      *
728      * @exception RuntimeException
729      * if there is a problem locating or instantiating the EJBHome proxy
730      */

731     private javax.ejb.EJBLocalHome JavaDoc createEJBLocalHomeRef(){
732
733         EjbHomeProxyHandler handler = null;
734         
735         switch ( getComponentType() ) {
736         case STATEFUL:
737             handler = new StatefulEjbHomeHandler((RpcContainer)container, null, getDeploymentID());
738             break;
739         
740         case STATELESS:
741             handler = new StatelessEjbHomeHandler((RpcContainer)container, null, getDeploymentID());
742             break;
743         case CMP_ENTITY:
744         case BMP_ENTITY:
745             handler = new EntityEjbHomeHandler((RpcContainer)container, null, getDeploymentID());
746             break;
747         }
748         handler.setLocal(true);
749         Object JavaDoc proxy = null;
750         try{
751             Class JavaDoc[] interfaces = new Class JavaDoc[]{ this.getLocalHomeInterface(), org.openejb.core.ivm.IntraVmProxy.class };
752             proxy = ProxyManager.newProxyInstance( interfaces , handler );
753         }catch(Exception JavaDoc e){
754             e.printStackTrace();
755             throw new RuntimeException JavaDoc("Can't create EJBLocalHome stub" + e.getMessage());
756         }
757
758         return (javax.ejb.EJBLocalHome JavaDoc)proxy;
759
760     }
761
762     /**
763      * Creates a HashMap that maps the methods from the home and remote interfaces
764      * to the methods in the bean class.
765      *
766      * @exception RuntimeException
767      * if the mothod in the remote or home interface cannot be mapped to a method in the bean class
768      * @exception org.openejb.SystemException
769      */

770     private void createMethodMap() throws org.openejb.SystemException{
771         if (homeInterface != null){
772             mapObjectInterface(remoteInterface, false);
773             mapHomeInterface(homeInterface);
774         }
775         if (localHomeInterface != null){
776             mapObjectInterface(localInterface, true);
777             mapHomeInterface(localHomeInterface);
778         }
779         
780         
781         try{
782             
783         if(componentType == STATEFUL || componentType == STATELESS){
784             Method JavaDoc beanMethod = javax.ejb.SessionBean JavaDoc.class.getDeclaredMethod("ejbRemove", new Class JavaDoc []{});
785             Method JavaDoc clientMethod = EJBHome JavaDoc.class.getDeclaredMethod("remove", new Class JavaDoc [] {javax.ejb.Handle JavaDoc.class});
786             methodMap.put(clientMethod, beanMethod);
787             clientMethod = EJBHome JavaDoc.class.getDeclaredMethod("remove", new Class JavaDoc [] {java.lang.Object JavaDoc.class});
788             methodMap.put(clientMethod, beanMethod);
789             clientMethod = javax.ejb.EJBObject JavaDoc.class.getDeclaredMethod("remove", null);
790             methodMap.put(clientMethod, beanMethod);
791         }else if(componentType == BMP_ENTITY || componentType == CMP_ENTITY){
792             Method JavaDoc beanMethod = javax.ejb.EntityBean JavaDoc.class.getDeclaredMethod("ejbRemove", new Class JavaDoc []{});
793             Method JavaDoc clientMethod = EJBHome JavaDoc.class.getDeclaredMethod("remove", new Class JavaDoc [] {javax.ejb.Handle JavaDoc.class});
794             methodMap.put(clientMethod, beanMethod);
795             clientMethod = EJBHome JavaDoc.class.getDeclaredMethod("remove", new Class JavaDoc [] {java.lang.Object JavaDoc.class});
796             methodMap.put(clientMethod, beanMethod);
797             clientMethod = javax.ejb.EJBObject JavaDoc.class.getDeclaredMethod("remove", null);
798             methodMap.put(clientMethod, beanMethod);
799         }
800         }catch(java.lang.NoSuchMethodException JavaDoc nsme){
801             throw new org.openejb.SystemException(nsme);
802         }
803
804     }
805
806     private void mapHomeInterface(Class JavaDoc intrface) {
807         Method JavaDoc [] homeMethods = intrface.getMethods();
808         for(int i = 0; i < homeMethods.length; i++){
809             Method JavaDoc method = homeMethods[i];
810             Class JavaDoc owner = method.getDeclaringClass();
811             if( owner == javax.ejb.EJBHome JavaDoc.class || owner == EJBLocalHome JavaDoc.class ) {
812                 continue;
813             }
814             
815             try{
816                 Method JavaDoc beanMethod = null;
817                 if(method.getName().equals("create")){
818                     beanMethod = beanClass.getMethod("ejbCreate",method.getParameterTypes());
819                     createMethod = beanMethod;
820                     /*
821                     Entity beans have a ejbCreate and ejbPostCreate methods with matching
822                     parameters. This code maps that relationship.
823                     */

824                     if(this.componentType==BMP_ENTITY || this.componentType==CMP_ENTITY){
825                         Method JavaDoc postCreateMethod = beanClass.getMethod("ejbPostCreate",method.getParameterTypes());
826                         postCreateMethodMap.put(createMethod,postCreateMethod);
827                     }
828                     /*
829                      * Stateless session beans only have one create method. The getCreateMethod is
830                      * used by instance manager of the core.stateless.StatelessContainer as a convenience
831                      * method for obtaining the ejbCreate method.
832                     */

833                 }else if(method.getName().startsWith("find")){
834                     if(this.componentType == BMP_ENTITY ){
835                         // CMP 1.1 beans do not define a find method in the bean class
836
String JavaDoc beanMethodName = "ejbF"+method.getName().substring(1);
837                         beanMethod = beanClass.getMethod(beanMethodName,method.getParameterTypes());
838                     }
839                 }else {
840                     String JavaDoc beanMethodName = "ejbHome"+method.getName().substring(0,1).toUpperCase()+method.getName().substring(1);
841                     beanMethod = beanClass.getMethod(beanMethodName,method.getParameterTypes());
842                 }
843                 if(beanMethod!=null){
844                     methodMap.put(homeMethods[i],beanMethod);
845                 }
846             }catch(NoSuchMethodException JavaDoc nsme){
847                 throw new RuntimeException JavaDoc("Invalid method ["+method+"] Not declared by "+beanClass.getName()+" class");
848             }
849         }
850     }
851
852
853     private void mapObjectInterface(Class JavaDoc intrface, boolean isLocal) {
854         Method JavaDoc [] interfaceMethods = intrface.getMethods();
855         for(int i = 0; i < interfaceMethods.length; i++){
856             Method JavaDoc method = interfaceMethods[i];
857             Class JavaDoc declaringClass = method.getDeclaringClass();
858             if(declaringClass == javax.ejb.EJBObject JavaDoc.class || declaringClass == EJBLocalObject JavaDoc.class){
859                 continue;
860             }
861             try{
862                 Method JavaDoc beanMethod = beanClass.getMethod(method.getName(),method.getParameterTypes());
863                 methodMap.put(method,beanMethod);
864             }catch(NoSuchMethodException JavaDoc nsme){
865                 throw new RuntimeException JavaDoc("Invalid method ["+ method +"]. Not declared by "+beanClass.getName()+" class");
866             }
867             /*
868                check for return type of java.rmi.Remote. If one of the business method returns a
869                java.rmi.Remote type, it may be a org.openejb.ivm.BaseEjbProxyHandler type at runtime,
870                in which case it will need to be converted by the container into a ProxyInfo object.
871                The container will use the convertIfLocalReference() to check.
872                This block of code sets up that method.
873              */

874             if(!isLocal && java.rmi.Remote JavaDoc.class.isAssignableFrom(method.getReturnType())) {
875                 if( methodsWithRemoteReturnTypes == null ) {
876                     methodsWithRemoteReturnTypes = new HashSet JavaDoc();
877                 }
878                 methodsWithRemoteReturnTypes.add(method);
879             }
880         }
881     }
882
883
884     protected String JavaDoc extractHomeBeanMethodName(String JavaDoc methodName){
885         if(methodName.equals("create"))
886             return "ejbCreate";
887         else if(methodName.startsWith("find"))
888             return "ejbF"+methodName.substring(1);
889         else
890             return "ejbH"+methodName.substring(1);
891     }
892     /**
893      * Used for stateless session beans only
894      *
895      * @return Method
896      */

897     public Method JavaDoc getCreateMethod( ){
898         return createMethod;
899     }
900     /**
901      * Used for entity beans only.
902      *
903      * @param createMethod
904      * @return Method
905      */

906     public Method JavaDoc getMatchingPostCreateMethod(Method JavaDoc createMethod){
907         return (Method JavaDoc)this.postCreateMethodMap.get(createMethod);
908     }
909     
910     //
911
// End DeploymentInfo Initialization
912
//==================================
913

914
915     //==================================
916
// Castor CMP Container Specific
917
//
918
private KeyGenerator keyGenerator;
919     private Field JavaDoc primKeyField;
920     private String JavaDoc[] cmrFields;
921     
922     
923     /**
924      * Each query method, ejbFind or ejbSelect(EJB 2.0), can be mapped to
925      * query string which describes the behavior of the method. For example,
926      * with the Castor JDO CMP container for EJB 1.1, every ejbFind method
927      * for each Deployment maps to a specific OQL statement which Castor JDO
928      * uses to access the object cache.
929      */

930     private HashMap JavaDoc queryMethodMap = new HashMap JavaDoc();
931
932     
933     /**
934      * Gets the Field of the CMP entity bean class which corresponds to the simple
935      * primary key. Entity beans that have complex primary keys (keys with several
936      * fields) will not have a primkey-field.
937      * <P>
938      * Useful for Container-Managed Persistence (CMP) Entity beans with Simple
939      * Primary Keys.
940      * </P>
941      *
942      * @return the EntityBean field that corresponds to the simple primary key.
943      * return null if the bean is not a CMP Entity bean with a simple Primary key
944      */

945     public Field JavaDoc getPrimaryKeyField( ){
946         return primKeyField;
947     }
948     
949     public void setPrimKeyField(String JavaDoc fieldName)
950     throws java.lang.NoSuchFieldException JavaDoc{
951         if(componentType == CMP_ENTITY){
952             
953             primKeyField = beanClass.getField(fieldName);
954         }
955     }
956     
957     /**
958      * Returns the names of the bean's container-managed fields. Used for
959      * container-managed persistence only.
960      *
961      * @return String[]
962      */

963     public String JavaDoc [] getCmrFields( ){
964         return cmrFields;
965     }
966     
967     public void setCmrFields(String JavaDoc [] cmrFields){
968         this.cmrFields = cmrFields;
969     }
970     
971     public KeyGenerator getKeyGenerator(){
972         return keyGenerator;
973     }
974     
975     public void setKeyGenerator(KeyGenerator keyGenerator){
976         this.keyGenerator = keyGenerator;
977     }
978
979     /**
980      * This method maps a query method (ejbFind) to a query string.
981      * <P>
982      * Each query method, ejbFind or ejbSelect(EJB 2.0), can be mapped to
983      * query string which describes the behavior of the method. For example,
984      * with the Castor JDO CMP container for EJB 1.1, every ejbFind method
985      * for each Deployment maps to a specific OQL statement which Castor JDO
986      * uses to access the object cache.
987      * </P>
988      *
989      * @param queryMethod
990      * @param queryString
991      */

992     public void addQuery(Method JavaDoc queryMethod, String JavaDoc queryString){
993         queryMethodMap.put(queryMethod, queryString);
994     }
995     /**
996      * This method retrieves the query string associated with the query method.
997      * <P>
998      * Each query method, ejbFind or ejbSelect(EJB 2.0), can be mapped to
999      * query string which describes the behavior of the method. For example,
1000     * with the Castor JDO CMP container for EJB 1.1, every ejbFind method
1001     * for each Deployment maps to a specific OQL statement which Castor JDO
1002     * uses to access the object cache.
1003     * </P>
1004     *
1005     * @param queryMethod
1006     * @return String
1007     */

1008    public String JavaDoc getQuery(Method JavaDoc queryMethod){
1009        return (String JavaDoc)queryMethodMap.get(queryMethod);
1010    }
1011    //
1012
// Castor CMP Container Specific
1013
//==================================
1014
}
1015
Popular Tags