001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2006 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: SessionStatelessDesc.java 8256 2006-04-18 16:58:04Z benoitf $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas_ejb.deployment.api;
025:
026: import java.lang.reflect.Method;
027: import java.util.Iterator;
028:
029: import org.objectweb.jonas_ejb.deployment.xml.AssemblyDescriptor;
030: import org.objectweb.jonas_ejb.deployment.xml.CommonEjb;
031: import org.objectweb.jonas_ejb.deployment.xml.JonasSession;
032: import org.objectweb.jonas_ejb.deployment.xml.Session;
033: import org.objectweb.jonas_ejb.lib.BeanNaming;
034:
035: import org.objectweb.jonas_lib.deployment.api.DeploymentDescException;
036: import org.objectweb.jonas_lib.deployment.xml.JLinkedList;
037:
038: /**
039: * class to hold meta-information related to a stateless session bean.
040: *
041: * @author Christophe Ney [cney@batisseurs.com] : Initial developer
042: * @author Helene Joanin
043: */
044: public class SessionStatelessDesc extends SessionDesc {
045:
046: /**
047: * Default service endpoint jndi suffix
048: */
049: private static final String SERVICE_ENDPOINT_JNDI_SUFFIX = "_SE";
050:
051: /**
052: * class name of the JOnAS wrapper (without package prefix)
053: */
054: private String wrpServiceEndpointName;
055: private String wrpSEHomeName;
056:
057: /**
058: * Singleton=True if only 1 SessionSwitch (and 1 Remote) when possible.
059: */
060: protected boolean singleton = true;
061:
062: /**
063: * fully qualified class name of the JOnAS wrapper
064: */
065: private String fullWrpServiceEndpointName;
066: private String fullWrpSEHomeName;
067:
068: /**
069: * ServiceEndpoint Class
070: */
071: private Class serviceEndpointClass;
072:
073: /**
074: * jndi name
075: */
076: private String serviceEndpointJndiName;
077:
078: /**
079: * constructor: called when the DeploymentDescriptor is read. Currently,
080: * called by both GenIC and createContainer.
081: *
082: * @param classLoader ClassLoader to load Bean's classes
083: * @param ses XML Element for session standard deployment descriptor
084: * @param asd Assembly Descriptor of the EjbJar
085: * @param jSes XML Element for session jonas deployment descriptor
086: * @param filename bean's jar filename
087: *
088: * @throws DeploymentDescException When SessionDesc cannot be instanciated
089: */
090: public SessionStatelessDesc(ClassLoader classLoader, Session ses,
091: AssemblyDescriptor asd, JonasSession jSes,
092: JLinkedList jMDRList, String filename)
093: throws DeploymentDescException {
094: super (classLoader, ses, asd, jSes, jMDRList, filename);
095:
096: // create wrapper names
097: String ejbIdentifier = getIdentifier();
098: if (getServiceEndpointClass() != null) {
099: String packageName = BeanDesc.GENERATED_PREFIX
100: + BeanNaming
101: .getPackageName(getServiceEndpointClass()
102: .getName());
103: wrpServiceEndpointName = new String("JOnAS" + ejbIdentifier
104: + "ServiceEndpoint");
105: fullWrpServiceEndpointName = BeanNaming.getClassName(
106: packageName, wrpServiceEndpointName);
107: wrpSEHomeName = new String("JOnAS" + ejbIdentifier
108: + "SEHome");
109: fullWrpSEHomeName = BeanNaming.getClassName(packageName,
110: wrpSEHomeName);
111: }
112:
113: // get jndi-endpoint-name
114: if (jSes.getJndiEndpointName() != null) {
115: serviceEndpointJndiName = jSes.getJndiEndpointName();
116: } else {
117: serviceEndpointJndiName = getJndiName()
118: + SERVICE_ENDPOINT_JNDI_SUFFIX;
119: }
120:
121: // singleton
122: if (jSes.getSingleton() != null) {
123: if (jSes.getSingleton().equalsIgnoreCase("True")) {
124: singleton = true;
125: } else if (jSes.getSingleton().equalsIgnoreCase("False")) {
126: singleton = false;
127: } else {
128: throw new DeploymentDescException(
129: "Invalid singleton value for bean "
130: + this .ejbName);
131: }
132: }
133:
134: // cache TxAttribute for ejbTimeout
135: for (Iterator i = getMethodDescIterator(); i.hasNext();) {
136: MethodDesc methd = (MethodDesc) i.next();
137: if (methd.getMethod().getName().equals("ejbTimeout")) {
138: timerTxAttribute = methd.getTxAttribute();
139: ejbTimeoutSignature = BeanNaming.getSignature(
140: getEjbName(), methd.getMethod());
141: }
142: }
143: }
144:
145: /**
146: * Check that the bean descriptor is valid
147: *
148: * @exception DeploymentDescException thrown for non-valid bean
149: */
150: public void check() throws DeploymentDescException {
151: super .check();
152: // ejbClass should not implement javax.ejb.SessionSynchronization
153: if (javax.ejb.SessionSynchronization.class
154: .isAssignableFrom(ejbClass)) {
155: throw new DeploymentDescException(
156: ejbClass.getName()
157: + " should NOT implement javax.ejb.SessionSynchronization");
158: }
159: }
160:
161: /**
162: * Permit Methods addition from subtypes Protected method that need to be
163: * overridden in subclasses
164: *
165: * @param len method array length
166: * @return new len value
167: *
168: * @throws DeploymentDescException when java reflection cannot be used on
169: * classes
170: */
171: protected int addEJBMethodDesc(int len)
172: throws DeploymentDescException {
173:
174: if (this .serviceEndpointClass != null) {
175: // session bean or entity bean with local interface
176: Method[] m = this .serviceEndpointClass.getMethods();
177: for (int i = 0; i < m.length; i++) {
178: addMethodDesc(m[i], this .serviceEndpointClass);
179: len++;
180: // check RemoteException is thrown
181: checkRemoteException(m[i], true);
182: }
183: }
184: return len;
185: }
186:
187: /**
188: * load class for service-endpoint
189: *
190: * @param bd XML Element representing EJB Descriptor
191: * @param classLoader ClassLoader used to load classes
192: *
193: * @throws DeploymentDescException when a class cannot be loaded
194: */
195: protected void loadExtraClasses(CommonEjb bd,
196: ClassLoader classLoader) throws DeploymentDescException {
197:
198: Session ses = (Session) bd;
199:
200: // load service-endpoint interface
201: if (ses.getServiceEndpoint() != null) {
202: try {
203: serviceEndpointClass = classLoader.loadClass(ses
204: .getServiceEndpoint());
205: // check service-endpoint extends java.rmi.Remote
206: if (!java.rmi.Remote.class
207: .isAssignableFrom(serviceEndpointClass)) {
208: throw new DeploymentDescException(
209: "ServiceEndpoint class '"
210: + ses.getServiceEndpoint()
211: + "' does not extend java.rmi.Remote");
212: }
213: } catch (ClassNotFoundException e) {
214: throw new DeploymentDescException(
215: "ServiceEndpoint class not found for bean "
216: + ejbName, e);
217: }
218: }
219:
220: }
221:
222: /**
223: * Returns the parent Class for a method given an interface type.
224: *
225: * @param intfType type of the interface (Home/Remote/LocalHome/Local or
226: * ServiceEndpoint)
227: *
228: * @return the parent class for a method given an interface type
229: *
230: * @throws DeploymentDescException when intfType is unknown
231: */
232: protected Class getParentClass(String intfType)
233: throws DeploymentDescException {
234: Class pClass = null;
235: if (intfType.equals("Home")) {
236: pClass = javax.ejb.EJBHome.class;
237: } else if (intfType.equals("Remote")) {
238: pClass = javax.ejb.EJBObject.class;
239: } else if (intfType.equals("LocalHome")) {
240: pClass = javax.ejb.EJBLocalHome.class;
241: } else if (intfType.equals("Local")) {
242: pClass = javax.ejb.EJBLocalObject.class;
243: } else if (intfType.equals("ServiceEndpoint")) {
244: pClass = java.rmi.Remote.class;
245: } else {
246: throw new DeploymentDescException(intfType
247: + " is invalid value for method-intf on bean "
248: + ejbName);
249: }
250: return pClass;
251: }
252:
253: /**
254: * @return Returns the serviceEndpointClass.
255: */
256: public Class getServiceEndpointClass() {
257: return serviceEndpointClass;
258: }
259:
260: private void checkValidServiceEndpointInterface() {
261: // extends java.rmi.Remote
262: // arguments and returns types are valid types for JAX-RPC (may be
263: // Holders)
264: // throws must includes java.rmi.RemoteException
265: // each endpoint method must have a matching session bean method :
266: // - same name
267: // - same number and types of arguments and same return type
268: // - session exceptions must eb included in endpoint
269: // no EJBObject or EJBLocalObject
270: // service endpoint interface must not include constants (public final
271: // static)
272: }
273:
274: /**
275: * @return jndi name where ServiceEndpoint interface will be binded
276: */
277: public String getJndiServiceEndpointName() {
278: return serviceEndpointJndiName;
279: }
280:
281: /**
282: * @return Returns the fullWrpServiceEndpointName.
283: */
284: public String getFullWrpServiceEndpointName() {
285: return fullWrpServiceEndpointName;
286: }
287:
288: /**
289: * @return Returns the wrpServiceEndpointName.
290: */
291: public String getWrpServiceEndpointName() {
292: return wrpServiceEndpointName;
293: }
294:
295: /**
296: * @return Returns the fullWrpSEHomeName.
297: */
298: public String getFullWrpSEHomeName() {
299: return fullWrpSEHomeName;
300: }
301:
302: /**
303: * @return Returns the wrpSEHomeName.
304: */
305: public String getWrpSEHomeName() {
306: return wrpSEHomeName;
307: }
308:
309: /**
310: * @return true for singleton session bean
311: */
312: public boolean isSingleton() {
313: return singleton;
314: }
315:
316: }
|