KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ejb > metadata > Bean


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.metadata;
31
32 import com.caucho.bytecode.JAnnotation;
33 import com.caucho.bytecode.JClass;
34 import com.caucho.bytecode.JMethod;
35 import com.caucho.config.ConfigException;
36 import com.caucho.config.types.InitProgram;
37 import com.caucho.ejb.EjbServerManager;
38 import com.caucho.ejb.cfg.EjbBean;
39 import com.caucho.ejb.cfg.EjbMethod;
40 import com.caucho.ejb.cfg.EjbMethodPattern;
41 import com.caucho.ejb.cfg.EjbSessionBean;
42 import com.caucho.ejb.cfg.MethodSignature;
43 import com.caucho.util.L10N;
44 import com.caucho.util.Log;
45
46 import javax.annotation.PostConstruct;
47 import javax.ejb.*;
48 import javax.persistence.Entity;
49 import java.util.ArrayList JavaDoc;
50 import java.util.logging.Logger JavaDoc;
51
52 /**
53  * Configuration for a new bean based on metadata.
54  */

55 public class Bean {
56   private static final L10N L = new L10N(Bean.class);
57   private static final Logger JavaDoc log = Log.open(Bean.class);
58
59   private ClassLoader JavaDoc _loader;
60   
61   private EjbServerManager _ejbManager;
62   
63   private JClass _type;
64   private String JavaDoc _name;
65
66   private ArrayList JavaDoc<InitProgram> _initList = new ArrayList JavaDoc<InitProgram>();
67
68   public Bean(EjbServerManager ejbManager)
69   {
70     _loader = Thread.currentThread().getContextClassLoader();
71     
72     _ejbManager = ejbManager;
73   }
74
75   protected String JavaDoc getEJBModuleName()
76   {
77     // XXX: s/b what?
78
return "introspected";
79   }
80
81   /**
82    * Sets the name.
83    */

84   public void setName(String JavaDoc name)
85   {
86     _name = name;
87   }
88
89   /**
90    * Sets the type.
91    */

92   public void setType(String JavaDoc typeName)
93     throws ConfigException, ClassNotFoundException JavaDoc
94   {
95     _type = _ejbManager.getJClassLoader().forName(typeName);
96
97     if (_type == null) {
98       throw new ConfigException(L.l("'{0}' is an unknown type",
99                     typeName));
100     }
101     else if (_type.getAnnotation(Stateless.class) != null) {
102     }
103     else if (_type.getAnnotation(Stateful.class) != null) {
104     }
105     else if (_type.getAnnotation(Entity.class) != null) {
106     }
107     else
108       throw new ConfigException(L.l("{0} is an unknown bean type. Beans expect Entity, Stateful, or Stateless class annotations.",
109                     _type.getName()));
110   }
111
112   /**
113    * Adds an init.
114    */

115   public void addInit(InitProgram init)
116   {
117     _initList.add(init);
118   }
119
120   /**
121    * Initializes the bean.
122    */

123   @PostConstruct
124   public void init()
125     throws ConfigException
126   {
127     if (_type == null)
128       throw new ConfigException(L.l("type is a require attribute of ejb-server"));
129     JAnnotation stateless = _type.getAnnotation(Stateless.class);
130     JAnnotation stateful = _type.getAnnotation(Stateful.class);
131
132     try {
133       if (stateless != null)
134     configureStateless(_type);
135       else if (stateful != null)
136     configureStateful(_type);
137       else
138     throw new ConfigException(L.l("only stateless beans are currently supported."));
139     } catch (RuntimeException JavaDoc e) {
140       throw e;
141     } catch (Exception JavaDoc e) {
142       throw new ConfigException(e);
143     }
144   }
145
146   private void configureStateless(JClass type)
147     throws ConfigException
148   {
149     String JavaDoc className = type.getName();
150     
151     JAnnotation stateless = type.getAnnotation(Stateless.class);
152
153     EjbSessionBean bean = new EjbSessionBean(_ejbManager.getConfig(), getEJBModuleName());
154     bean.setAllowPOJO(true);
155
156     bean.setSessionType("Stateless");
157     bean.setTransactionType("Container");
158
159     configureBean(bean, type, stateless.getString("name"));
160   }
161
162   private void configureStateful(JClass type)
163     throws ConfigException
164   {
165     String JavaDoc className = type.getName();
166     
167     JAnnotation stateful = type.getAnnotation(Stateful.class);
168
169     EjbSessionBean bean = new EjbSessionBean(_ejbManager.getConfig(), getEJBModuleName());
170     bean.setAllowPOJO(true);
171
172     bean.setSessionType("Stateful");
173     bean.setTransactionType("Container");
174
175     configureBean(bean, type, stateful.getString("name"));
176   }
177
178   private void configureBean(EjbBean bean, JClass type, String JavaDoc defaultName)
179     throws ConfigException
180   {
181     try {
182       bean.setEJBClassWrapper(type);
183
184       String JavaDoc name = _name;
185
186       if (name == null || name.equals(""))
187     name = defaultName;
188
189       if (name == null || name.equals("")) {
190     String JavaDoc className = type.getName();
191       
192     int p = className.lastIndexOf('.');
193
194     if (p > 0)
195       name = className.substring(p + 1);
196     else
197       name = className;
198       }
199
200       bean.setEJBName(name);
201
202       JAnnotation local = type.getAnnotation(Local.class);
203       if (local != null) {
204     Object JavaDoc []values = (Object JavaDoc []) local.get("value");
205
206     for (int i = 0; i < values.length; i++) {
207       JClass localClass = (JClass) values[i];
208       
209       bean.setLocalWrapper(localClass);
210     }
211
212       }
213
214       JAnnotation remote = type.getAnnotation(Remote.class);
215       if (remote != null) {
216     Object JavaDoc []values = (Object JavaDoc []) remote.get("value");
217
218     for (int i = 0; i < values.length; i++) {
219       JClass remoteClass = (JClass) values[i];
220       
221       bean.setRemoteWrapper(remoteClass);
222     }
223       }
224
225       JClass []ifs = type.getInterfaces();
226
227       for (int i = 0; i < ifs.length; i++) {
228     local = ifs[i].getAnnotation(Local.class);
229
230     if (local != null) {
231       bean.setLocalWrapper(ifs[i]);
232       continue;
233     }
234       
235     remote = ifs[i].getAnnotation(Remote.class);
236
237     if (remote != null || ifs[i].isAssignableTo(java.rmi.Remote JavaDoc.class)) {
238       bean.setRemoteWrapper(ifs[i]);
239       continue;
240     }
241       }
242
243       if (bean.getLocal() != null || bean.getRemote() != null) {
244       }
245       else if (ifs.length == 0)
246     throw new ConfigException(L.l("'{0}' has no interfaces. Can't currently generate.",
247                       type.getName()));
248       else if (ifs.length != 1)
249     throw new ConfigException(L.l("'{0}' has multiple interfaces, but none are marked as @Local or @Remote.",
250                       type.getName()));
251       else {
252     bean.setLocalWrapper(ifs[0]);
253       }
254
255       JAnnotation xa = type.getAnnotation(TransactionAttribute.class);
256       if (xa != null) {
257     MethodSignature sig = new MethodSignature();
258     sig.setMethodName("*");
259
260     EjbMethodPattern pattern = bean.createMethod(sig);
261
262     setPatternTransaction(pattern, xa);
263       }
264
265       configureMethods(bean, type);
266
267       for (int i = 0; i < _initList.size(); i++)
268     bean.addInitProgram(_initList.get(i).getBuilderProgram());
269
270       bean.init();
271
272       _ejbManager.getConfig().setBeanConfig(bean.getEJBName(), bean);
273     } catch (ConfigException e) {
274       throw e;
275     } catch (RuntimeException JavaDoc e) {
276       throw e;
277     } catch (Exception JavaDoc e) {
278       throw new ConfigException(e);
279     }
280   }
281
282   private void configureMethods(EjbBean bean, JClass type)
283     throws ConfigException
284   {
285     JMethod []methods = type.getDeclaredMethods();
286
287     for (int i = 0; i < methods.length; i++) {
288       JMethod method = methods[i];
289       
290       JAnnotation xa = method.getAnnotation(TransactionAttribute.class);
291
292       if (xa != null) {
293     EjbMethodPattern pattern = bean.createMethod(getSignature(method));
294
295     setPatternTransaction(pattern, xa);
296       }
297     }
298   }
299
300   private void setPatternTransaction(EjbMethodPattern pattern,
301                      JAnnotation xa)
302     throws ConfigException
303   {
304     TransactionAttributeType xaType;
305     xaType = (TransactionAttributeType) xa.get("value");
306     
307     switch (xaType) {
308     case REQUIRED:
309       pattern.setTransaction(EjbMethod.TRANS_REQUIRED);
310       break;
311       
312     case REQUIRES_NEW:
313       pattern.setTransaction(EjbMethod.TRANS_REQUIRES_NEW);
314       break;
315       
316     case MANDATORY:
317       pattern.setTransaction(EjbMethod.TRANS_MANDATORY);
318       break;
319       
320     case SUPPORTS:
321       pattern.setTransaction(EjbMethod.TRANS_SUPPORTS);
322       break;
323       
324     case NOT_SUPPORTED:
325       pattern.setTransaction(EjbMethod.TRANS_NOT_SUPPORTED);
326       break;
327       
328     case NEVER:
329       pattern.setTransaction(EjbMethod.TRANS_NEVER);
330       break;
331       
332     default:
333       throw new IllegalStateException JavaDoc();
334     }
335   }
336
337   private MethodSignature getSignature(JMethod method)
338     throws ConfigException
339   {
340     MethodSignature sig = new MethodSignature();
341
342     sig.setMethodName(method.getName());
343
344     JClass []paramTypes = method.getParameterTypes();
345
346     for (int i = 0; i < paramTypes.length; i++) {
347       sig.addParam(paramTypes[i].getName());
348     }
349
350     return sig;
351   }
352
353   /*
354   private void configureInject(EjbBean bean,
355                    JMethod method,
356                    Inject inject)
357     throws ConfigException
358   {
359     JClass []paramTypes = method.getParameterTypes();
360
361     if (paramTypes.length != 1)
362       throw new ConfigException(L.l("method '{0}' must have a single value for injection.",
363                     method.getName()));
364
365     JClass paramType = paramTypes[0];
366
367     String jndiName = inject.jndiName();
368     String prefix = "";
369
370     if (DataSource.class.isAssignableFrom(paramType)) {
371       prefix = "jdbc/";
372     }
373     
374     if (jndiName != null && ! jndiName.equals("")) {
375     }
376     else if (UserTransaction.class.equals(paramType)) {
377       jndiName = "java:comp/UserTransaction";
378     }
379     else {
380       jndiName = method.getName();
381
382       if (jndiName.startsWith("set") && jndiName.length() > 3) {
383     jndiName = jndiName.substring(3);
384
385     char ch = jndiName.charAt(0);
386     
387     if (Character.isUpperCase(ch) &&
388         (jndiName.length() == 4 ||
389          Character.isLowerCase(jndiName.charAt(1)))) {
390       jndiName = Character.toLowerCase(ch) + jndiName.substring(1);
391     }
392       }
393     }
394
395     int colon = jndiName.indexOf(':');
396     int slash = jndiName.indexOf('/');
397     
398     if (colon < 0 || slash > 0 && slash < colon)
399       jndiName = "java:comp/env/" + prefix + jndiName;
400
401     JndiInjectProgram program = new JndiInjectProgram(jndiName, method);
402
403     bean.addInitProgram(program);
404   }
405   */

406 }
407
408
Popular Tags