KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > cfg > EjbSessionBean


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.ejb.cfg;
31
32 import com.caucho.bytecode.JClass;
33 import com.caucho.bytecode.JMethod;
34 import com.caucho.config.BuilderProgram;
35 import com.caucho.config.BuilderProgramContainer;
36 import com.caucho.config.ConfigException;
37 import com.caucho.config.LineConfigException;
38 import com.caucho.config.j2ee.InjectIntrospector;
39 import com.caucho.ejb.AbstractServer;
40 import com.caucho.ejb.EjbServerManager;
41 import com.caucho.ejb.gen.BeanAssembler;
42 import com.caucho.ejb.gen.SessionAssembler;
43 import com.caucho.ejb.gen.StatelessAssembler;
44 import com.caucho.ejb.session.SessionServer;
45 import com.caucho.ejb.session.StatelessServer;
46 import com.caucho.java.gen.JavaClassGenerator;
47 import com.caucho.management.j2ee.J2EEManagedObject;
48 import com.caucho.management.j2ee.StatefulSessionBean;
49 import com.caucho.management.j2ee.StatelessSessionBean;
50 import com.caucho.util.L10N;
51
52 import javax.annotation.PostConstruct;
53 import javax.ejb.CreateException JavaDoc;
54 import javax.ejb.EJBHome JavaDoc;
55 import javax.ejb.EJBLocalHome JavaDoc;
56 import javax.ejb.SessionBean JavaDoc;
57 import javax.ejb.SessionSynchronization JavaDoc;
58 import java.lang.reflect.Modifier JavaDoc;
59 import java.util.ArrayList JavaDoc;
60
61 /**
62  * Configuration for an ejb entity bean.
63  */

64 public class EjbSessionBean extends EjbBean {
65   private static final L10N L = new L10N(EjbSessionBean.class);
66
67   private boolean _isStateless;
68   private boolean _isContainerTransaction;
69   
70   /**
71    * Creates a new session bean configuration.
72    */

73   public EjbSessionBean(EjbConfig ejbConfig, String JavaDoc ejbModuleName)
74   {
75     super(ejbConfig, ejbModuleName);
76   }
77
78   /**
79    * Returns the kind of bean.
80    */

81   public String JavaDoc getEJBKind()
82   {
83     return "session";
84   }
85
86   /**
87    * Sets the ejb implementation class.
88    */

89   public void setEJBClass(Class JavaDoc ejbClass)
90     throws ConfigException
91   {
92     super.setEJBClass(ejbClass);
93
94     if (Modifier.isAbstract(ejbClass.getModifiers()))
95       throw error(L.l("'{0}' must not be abstract. Session bean implementations must be fully implemented.", ejbClass.getName()));
96
97     if (! SessionBean.class.isAssignableFrom(ejbClass) && ! isAllowPOJO())
98       throw error(L.l("'{0}' must implement SessionBean. Session beans must implement javax.ejb.SessionBean.", ejbClass.getName()));
99
100   }
101
102   /**
103    * Returns true if it's a stateless session bean.
104    */

105   public boolean isStateless()
106   {
107     return _isStateless;
108   }
109
110   /**
111    * Set true if it's a stateless session bean.
112    */

113   public void setSessionType(String JavaDoc type)
114     throws ConfigException
115   {
116     if (type.equals("Stateful"))
117       _isStateless = false;
118     else if (type.equals("Stateless"))
119       _isStateless = true;
120     else
121       throw new ConfigException(L.l("'{0}' is an unknown session-type. session-type must be 'Stateless' or 'Stateful'.", type));
122   }
123
124   /**
125    * Returns true if the container handles transactions.
126    */

127   public boolean isContainerTransaction()
128   {
129     return _isContainerTransaction;
130   }
131
132   /**
133    * Set true if the container handles transactions.
134    */

135   public void setTransactionType(String JavaDoc type)
136     throws ConfigException
137   {
138     if (type.equals("Container"))
139       _isContainerTransaction = true;
140     else if (type.equals("Bean"))
141       _isContainerTransaction = false;
142     else
143       throw new ConfigException(L.l("'{0}' is an unknown transaction-type. transaction-type must be 'Container' or 'Bean'.", type));
144   }
145
146   /**
147    * Configure initialization.
148    */

149   @PostConstruct
150   public void init()
151     throws ConfigException
152   {
153     super.init();
154
155     try {
156       if (getRemoteHome() != null)
157     validateHome(getRemoteHome(), getRemote());
158       if (getLocalHome() != null)
159     validateHome(getLocalHome(), getLocal());
160       if (getRemote() != null)
161     validateRemote(getRemote());
162       if (getLocal() != null)
163     validateRemote(getLocal());
164
165       if (getEJBClass() == null) {
166     throw error(L.l("'{0}' does not have a defined ejb-class. Session beans must have an ejb-class.",
167             getEJBName()));
168       }
169
170       if (! getEJBClassWrapper().isAssignableTo(SessionSynchronization JavaDoc.class)) {
171       }
172       else if (isStateless()) {
173     throw error(L.l("'{0}' must not implement SessionSynchronization. Stateless session beans must not implement SessionSynchronization.",
174             getEJBClass().getName()));
175       }
176       else if (! _isContainerTransaction) {
177     throw error(L.l("'{0}' must not implement SessionSynchronization. Session beans with Bean-managed transactions may not use SessionSynchronization.",
178             getEJBClass().getName()));
179       }
180     } catch (LineConfigException e) {
181       throw e;
182     } catch (ConfigException e) {
183       throw new LineConfigException(getLocation() + e.getMessage(), e);
184     }
185
186     if (isStateless())
187       J2EEManagedObject.register(new StatelessSessionBean(this));
188     else
189       J2EEManagedObject.register(new StatefulSessionBean(this));
190   }
191
192   /**
193    * Creates the assembler for the bean.
194    */

195   protected BeanAssembler createAssembler(String JavaDoc fullClassName)
196   {
197     if (isStateless())
198       return new StatelessAssembler(this, fullClassName);
199     else
200       return new SessionAssembler(this, fullClassName);
201   }
202
203   /**
204    * Adds the assemblers.
205    */

206   protected void addImports(BeanAssembler assembler)
207   {
208     super.addImports(assembler);
209
210     if (isStateless()) {
211       assembler.addImport("com.caucho.ejb.session.StatelessServer");
212       assembler.addImport("com.caucho.ejb.session.AbstractStatelessContext");
213       assembler.addImport("com.caucho.ejb.session.StatelessHome");
214       assembler.addImport("com.caucho.ejb.session.StatelessObject");
215     }
216     else {
217       assembler.addImport("com.caucho.ejb.session.SessionServer");
218       assembler.addImport("com.caucho.ejb.session.AbstractSessionContext");
219       assembler.addImport("com.caucho.ejb.session.SessionHome");
220       assembler.addImport("com.caucho.ejb.session.SessionObject");
221     }
222   }
223
224   /**
225    * Creates the views.
226    */

227   protected EjbHomeView createHomeView(JClass homeClass, String JavaDoc prefix)
228     throws ConfigException
229   {
230     if (isStateless())
231       return new EjbStatelessHomeView(this, homeClass, prefix);
232     else
233       return new EjbSessionHomeView(this, homeClass, prefix);
234   }
235
236   /**
237    * Deploys the bean.
238    */

239   public AbstractServer deployServer(EjbServerManager ejbManager,
240                      JavaClassGenerator javaGen)
241     throws ClassNotFoundException JavaDoc, ConfigException
242   {
243     AbstractServer server;
244     
245     if (isStateless())
246       server = new StatelessServer(ejbManager);
247     else
248       server = new SessionServer(ejbManager);
249
250     server.setEJBName(getEJBName());
251     server.setJndiName(getJndiName());
252
253     JClass remoteHome = getRemoteHome();
254     if (remoteHome != null)
255       server.setRemoteHomeClass(remoteHome.getJavaClass());
256     
257     JClass remote = getRemote();
258     if (remote != null)
259       server.setRemoteObjectClass(remote.getJavaClass());
260
261     Class JavaDoc contextImplClass = javaGen.loadClass(getSkeletonName());
262     
263     server.setContextImplClass(contextImplClass);
264
265     Class JavaDoc beanClass = javaGen.loadClass(getEJBClass().getName());
266     
267     Thread JavaDoc thread = Thread.currentThread();
268     ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
269
270     try {
271       thread.setContextClassLoader(server.getClassLoader());
272
273       ArrayList JavaDoc<BuilderProgram> initList;
274       initList = InjectIntrospector.introspect(beanClass);
275
276       BuilderProgramContainer initContainer = getInitProgram();
277
278       if (initList != null && initList.size() > 0) {
279     if (initContainer == null)
280       initContainer = new BuilderProgramContainer();
281
282     for (BuilderProgram init : initList) {
283       initContainer.addProgram(init);
284     }
285       }
286     
287       server.setInitProgram(initContainer);
288
289       try {
290     if (getServerProgram() != null)
291       getServerProgram().configure(server);
292       } catch (ConfigException e) {
293     throw e;
294       } catch (Throwable JavaDoc e) {
295     throw new ConfigException(e);
296       }
297     } finally {
298       thread.setContextClassLoader(oldLoader);
299     }
300
301     return server;
302   }
303
304   private void validateMethods()
305     throws ConfigException
306   {
307   }
308
309   /**
310    * Validates the home interface.
311    */

312   private void validateHome(JClass homeClass, JClass objectClass)
313     throws ConfigException
314   {
315     JClass beanClass = getEJBClassWrapper();
316     String JavaDoc beanName = beanClass.getName();
317   
318     if (homeClass == null)
319       return;
320     String JavaDoc homeName = homeClass.getName();
321     String JavaDoc objectName = objectClass.getName();
322
323     boolean hasFindByPrimaryKey = false;
324   
325     if (! homeClass.isPublic())
326       throw error(L.l("'{0}' must be public", homeName));
327   
328     if (beanClass.isFinal())
329       throw error(L.l("'{0}' must not be final", beanName));
330
331     if (beanClass.isAbstract())
332       throw error(L.l("'{0}' must not be abstract", beanName));
333
334     if (! homeClass.isInterface())
335       throw error(L.l("'{0}' must be an interface", homeName));
336
337     boolean hasCreate = false;
338
339     JMethod []methods = getMethods(homeClass);
340     for (int i = 0; i < methods.length; i++) {
341       JMethod method = methods[i];
342       String JavaDoc name = method.getName();
343       JClass []param = method.getParameterTypes();
344       JClass retType = method.getReturnType();
345
346       if (method.getDeclaringClass().isAssignableFrom(EJBHome JavaDoc.class) ||
347           method.getDeclaringClass().isAssignableFrom(EJBLocalHome JavaDoc.class))
348         continue;
349
350       if (homeClass.isAssignableTo(EJBHome JavaDoc.class))
351         validateException(method, java.rmi.RemoteException JavaDoc.class);
352       
353       if (name.startsWith("create")) {
354         hasCreate = true;
355
356         if (isStateless() && (! name.equals("create") ||
357                               method.getParameterTypes().length != 0)) {
358           throw error(L.l("{0}: '{1}' forbidden in stateless session home. The create() method for a stateless session bean must have zero arguments.",
359                           method.getFullName(),
360                           homeName));
361         }
362
363     if (! isAllowPOJO())
364       validateException(method, CreateException JavaDoc.class);
365
366         if (! retType.equals(objectClass))
367           throw error(L.l("{0}: '{1}' must return {2}. Create methods must return the local or remote interface.",
368                           homeName,
369                           method.getFullName(),
370                           objectClass.getName()));
371
372         String JavaDoc createName = "ejbC" + name.substring(1);
373         JMethod implMethod =
374           validateNonFinalMethod(createName, param,
375                  method, homeClass, isAllowPOJO());
376
377     if (implMethod != null) {
378       if (! implMethod.getReturnType().getName().equals("void"))
379         throw error(L.l("'{0}' must return {1} in {2}",
380                 getFullMethodName(createName, param),
381                 "void",
382                 beanName));
383
384       validateExceptions(method, implMethod.getExceptionTypes());
385     }
386       }
387       else if (name.startsWith("ejb") || name.startsWith("remove")) {
388         throw error(L.l("'{0}' forbidden in {1}",
389                         method.getFullName(),
390                         homeClass.getName()));
391       }
392     }
393
394     if (! hasCreate)
395       throw error(L.l("'{0}' needs at least one create method. Session beans need a create method.",
396                       homeClass.getName()));
397   }
398 }
399
Popular Tags