KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > config > j2ee > InjectIntrospector


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.config.j2ee;
31
32 import com.caucho.config.BuilderProgram;
33 import com.caucho.config.ConfigException;
34 import com.caucho.util.L10N;
35 import com.caucho.util.Log;
36
37 import javax.annotation.Resource;
38 import javax.annotation.Resources;
39 import javax.ejb.EJB JavaDoc;
40 import javax.naming.InitialContext JavaDoc;
41 import javax.naming.NameClassPair JavaDoc;
42 import javax.naming.NamingEnumeration JavaDoc;
43 import javax.persistence.PersistenceContext;
44 import javax.persistence.PersistenceUnit;
45 import javax.transaction.UserTransaction JavaDoc;
46 import javax.xml.ws.Service;
47 import javax.xml.ws.WebServiceRef;
48 import java.beans.Introspector JavaDoc;
49 import java.lang.reflect.AccessibleObject JavaDoc;
50 import java.lang.reflect.Field JavaDoc;
51 import java.lang.reflect.Method JavaDoc;
52 import java.util.ArrayList JavaDoc;
53 import java.util.logging.Level JavaDoc;
54 import java.util.logging.Logger JavaDoc;
55
56 /**
57  * Analyzes a bean for @Inject tags.
58  */

59 public class InjectIntrospector {
60   private static final L10N L = new L10N(InjectIntrospector.class);
61   private static final Logger JavaDoc log = Log.open(InjectIntrospector.class);
62
63   /**
64    * Analyzes a bean for @Inject tags, building an init program for them.
65    */

66   public static void configure(Object JavaDoc obj)
67     throws Throwable JavaDoc
68   {
69     if (obj != null) {
70       for (BuilderProgram program : introspect(obj.getClass())) {
71         program.configure(obj);
72       }
73     }
74   }
75
76   /**
77    * Analyzes a bean for @Inject tags, building an init program for them.
78    */

79   public static InjectProgram introspectProgram(Class JavaDoc type)
80     throws ConfigException
81   {
82     return new InjectProgram(introspect(type));
83   }
84
85   /**
86    * Analyzes a bean for @Inject tags, building an init program for them.
87    */

88   public static ArrayList JavaDoc<BuilderProgram> introspectStatic(Class JavaDoc type)
89     throws ConfigException
90   {
91     return introspect(type);
92   }
93
94   /**
95    * Analyzes a bean for @Inject tags, building an init program for them.
96    */

97   public static ArrayList JavaDoc<BuilderProgram> introspect(Class JavaDoc type)
98     throws ConfigException
99   {
100     ArrayList JavaDoc<BuilderProgram> initList = new ArrayList JavaDoc<BuilderProgram>();
101
102     try {
103       introspectImpl(initList, type);
104     } catch (ClassNotFoundException JavaDoc e) {
105     } catch (Error JavaDoc e) {
106     }
107
108     return initList;
109   }
110
111   private static void introspectImpl(ArrayList JavaDoc<BuilderProgram> initList,
112                                      Class JavaDoc type)
113     throws ConfigException, ClassNotFoundException JavaDoc
114   {
115     if (type == null || type.equals(Object JavaDoc.class))
116       return;
117
118     introspectImpl(initList, type.getSuperclass());
119
120     configureClassResources(initList, type);
121
122     for (Method JavaDoc method : type.getDeclaredMethods()) {
123       String JavaDoc fieldName = method.getName();
124       Class JavaDoc []param = method.getParameterTypes();
125
126       if (param.length != 1)
127         continue;
128
129       if (fieldName.startsWith("set") && fieldName.length() > 3) {
130         fieldName = fieldName.substring(3);
131
132         char ch = fieldName.charAt(0);
133
134         if (Character.isUpperCase(ch) &&
135             (fieldName.length() == 1 ||
136              Character.isLowerCase(fieldName.charAt(1)))) {
137           fieldName = Character.toLowerCase(ch) + fieldName.substring(1);
138         }
139       }
140
141       configure(initList, method, fieldName, param[0]);
142     }
143   }
144
145   public static void
146     configureClassResources(ArrayList JavaDoc<BuilderProgram> initList,
147                             Class JavaDoc type)
148     throws ConfigException
149   {
150     Resources resources = (Resources) type.getAnnotation(Resources.class);
151     if (resources != null) {
152       for (Resource resource : resources.value()) {
153         introspectClassResource(initList, type, resource);
154       }
155     }
156
157     Resource resource = (Resource) type.getAnnotation(Resource.class);
158     if (resource != null) {
159       introspectClassResource(initList, type, resource);
160     }
161
162     for (Field JavaDoc field : type.getDeclaredFields()) {
163       configure(initList, field, field.getName(), field.getType());
164     }
165   }
166
167   private static void
168     introspectClassResource(ArrayList JavaDoc<BuilderProgram> initList,
169                             Class JavaDoc type,
170                             Resource resource)
171     throws ConfigException
172   {
173     String JavaDoc name = resource.name();
174
175     Field JavaDoc field = findField(type, name);
176
177     if (field != null) {
178       initList.add(configureResource(field, field.getName(), field.getType(),
179                                      resource.name(),
180                                      resource.type().getName(),
181                                      resource.name()));
182
183       return;
184     }
185
186     Method JavaDoc method = findMethod(type, name);
187
188     if (method != null) {
189       initList.add(configureResource(method, method.getName(),
190                                      method.getParameterTypes()[0],
191                                      resource.name(),
192                                      resource.type().getName(),
193                                      resource.name()));
194
195       return;
196     }
197   }
198
199   private static Field JavaDoc findField(Class JavaDoc type, String JavaDoc name)
200   {
201     for (Field JavaDoc field : type.getDeclaredFields()) {
202       if (field.getName().equals(name))
203         return field;
204     }
205
206     return null;
207   }
208
209   private static Method JavaDoc findMethod(Class JavaDoc type, String JavaDoc name)
210   {
211     for (Method JavaDoc method : type.getDeclaredMethods()) {
212       if (method.getParameterTypes().length != 1)
213         continue;
214
215       String JavaDoc methodName = method.getName();
216       if (! methodName.startsWith("set"))
217         continue;
218
219       methodName = Introspector.decapitalize(methodName.substring(3));
220
221       if (name.equals(methodName))
222         return method;
223     }
224
225     return null;
226   }
227
228   public static void configure(ArrayList JavaDoc<BuilderProgram> initList,
229                                AccessibleObject JavaDoc field,
230                                String JavaDoc fieldName,
231                                Class JavaDoc fieldType)
232     throws ConfigException
233   {
234     if (field.isAnnotationPresent(Resource.class))
235       configureResource(initList, field, fieldName, fieldType);
236     else if (field.isAnnotationPresent(EJB JavaDoc.class))
237       configureEJB(initList, field, fieldName, fieldType);
238     else if (field.isAnnotationPresent(PersistenceUnit.class))
239       configurePersistenceUnit(initList, field, fieldName, fieldType);
240     else if (field.isAnnotationPresent(PersistenceContext.class))
241       configurePersistenceContext(initList, field, fieldName, fieldType);
242     else if (field.isAnnotationPresent(WebServiceRef.class))
243       configureWebServiceRef(initList, field, fieldName, fieldType);
244   }
245
246   private static void configureResource(ArrayList JavaDoc<BuilderProgram> initList,
247                                         AccessibleObject JavaDoc field,
248                                         String JavaDoc fieldName,
249                                         Class JavaDoc fieldType)
250     throws ConfigException
251   {
252     Resource resource = field.getAnnotation(Resource.class);
253
254     initList.add(configureResource(field,
255                                    fieldName, fieldType,
256                                    resource.name(),
257                                    resource.type().getName(),
258                                    resource.name()));
259   }
260
261   public static BuilderProgram
262     introspectResource(AccessibleObject JavaDoc field,
263                        String JavaDoc fieldName,
264                        Class JavaDoc fieldType)
265     throws ConfigException
266   {
267     Resource resource = field.getAnnotation(Resource.class);
268
269     if (resource != null)
270       return configureResource(field,
271                                fieldName, fieldType,
272                                resource.name(),
273                                resource.type().getName(),
274                                resource.name());
275     else
276       return null;
277   }
278
279   private static void configureEJB(ArrayList JavaDoc<BuilderProgram> initList,
280                                    AccessibleObject JavaDoc field,
281                                    String JavaDoc fieldName,
282                                    Class JavaDoc fieldType)
283     throws ConfigException
284   {
285     EJB JavaDoc ejb = (EJB JavaDoc) field.getAnnotation(javax.ejb.EJB JavaDoc.class);
286
287     initList.add(configureResource(field, fieldName, fieldType,
288                                    ejb.beanName(),
289                                    "javax.ejb.EJBLocalObject",
290                                    ejb.name()));
291   }
292
293   private static void
294     configureWebServiceRef(ArrayList JavaDoc<BuilderProgram> initList,
295                            AccessibleObject JavaDoc field,
296                            String JavaDoc fieldName,
297                            Class JavaDoc fieldType)
298     throws ConfigException
299   {
300     WebServiceRef ref
301       = (WebServiceRef) field.getAnnotation(WebServiceRef.class);
302
303     String JavaDoc name = ref.name();
304     name = ref.name();
305
306     if ("".equals(name))
307       name = fieldName;
308
309     name = toFullName(name);
310     // XXX: types
311

312     AccessibleInject inject;
313
314     if (field instanceof Field JavaDoc)
315       inject = new FieldInject((Field JavaDoc) field);
316     else
317       inject = new PropertyInject((Method JavaDoc) field);
318
319     BuilderProgram program;
320
321     if (Service.class.isAssignableFrom(fieldType)) {
322       program = new ServiceInjectProgram(name,
323                                          fieldType,
324                                          inject);
325     }
326     else {
327       program = new ServiceProxyInjectProgram(name,
328                                               fieldType,
329                                               inject);
330     }
331
332     initList.add(program);
333   }
334
335   private static void configurePersistenceUnit(ArrayList JavaDoc<BuilderProgram> initList,
336                                                AccessibleObject JavaDoc field,
337                                                String JavaDoc fieldName,
338                                                Class JavaDoc fieldType)
339     throws ConfigException
340   {
341     PersistenceUnit pUnit = field.getAnnotation(PersistenceUnit.class);
342
343     String JavaDoc jndiPrefix = "java:comp/env/persistence/_amber_PersistenceUnit";
344
345     String JavaDoc jndiName = null;
346     String JavaDoc unitName = pUnit.unitName();
347
348     try {
349       if (! unitName.equals(""))
350         jndiName = jndiPrefix + '/' + unitName;
351       else {
352         InitialContext JavaDoc ic = new InitialContext JavaDoc();
353
354         NamingEnumeration JavaDoc<NameClassPair JavaDoc> iter = ic.list(jndiPrefix);
355
356         if (iter == null) {
357           log.warning("Can't find configured PersistenceUnit");
358           return; // XXX: error?
359
}
360
361         String JavaDoc ejbJndiName = null;
362         while (iter.hasMore()) {
363           NameClassPair JavaDoc pair = iter.next();
364
365           if (pair.getName().equals("resin-ejb"))
366             ejbJndiName = jndiPrefix + '/' + pair.getName();
367           else {
368             jndiName = jndiPrefix + '/' + pair.getName();
369             break;
370           }
371         }
372
373         if (jndiName == null)
374           jndiName = ejbJndiName;
375       }
376
377       initList.add(configureResource(field, fieldName, fieldType,
378                                      unitName,
379                                      "javax.persistence.EntityManagerFactory",
380                                      jndiName));
381     } catch (Throwable JavaDoc e) {
382       log.log(Level.WARNING, e.toString(), e);
383     }
384   }
385
386   private static void configurePersistenceContext(ArrayList JavaDoc<BuilderProgram> initList,
387                                                   AccessibleObject JavaDoc field,
388                                                   String JavaDoc fieldName,
389                                                   Class JavaDoc fieldType)
390     throws ConfigException
391   {
392     PersistenceContext pContext = field.getAnnotation(PersistenceContext.class);
393
394     String JavaDoc jndiPrefix = "java:comp/env/persistence";
395
396     String JavaDoc jndiName = null;
397     String JavaDoc unitName = pContext.unitName();
398
399     try {
400       if (! unitName.equals(""))
401         jndiName = jndiPrefix + '/' + unitName;
402       else {
403         InitialContext JavaDoc ic = new InitialContext JavaDoc();
404
405         NamingEnumeration JavaDoc<NameClassPair JavaDoc> iter = ic.list(jndiPrefix);
406
407         if (iter == null) {
408           log.warning("Can't find configured PersistenceContext");
409           return; // XXX: error?
410
}
411
412         String JavaDoc ejbJndiName = null;
413         while (iter.hasMore()) {
414           NameClassPair JavaDoc pair = iter.next();
415
416           // Skip reserved prefixes.
417
// See com.caucho.amber.manager.AmberContainer
418
if (pair.getName().startsWith("_amber"))
419             continue;
420
421           if (pair.getName().equals("resin-ejb"))
422             ejbJndiName = jndiPrefix + '/' + pair.getName();
423           else {
424             jndiName = jndiPrefix + '/' + pair.getName();
425             break;
426           }
427         }
428
429         if (jndiName == null)
430           jndiName = ejbJndiName;
431       }
432
433       initList.add(configureResource(field, fieldName, fieldType,
434                                      unitName,
435                                      "javax.persistence.EntityManager",
436                                      jndiName));
437     } catch (Throwable JavaDoc e) {
438       log.log(Level.WARNING, e.toString(), e);
439     }
440   }
441
442   private static
443     BuilderProgram configureResource(AccessibleObject JavaDoc field,
444                                      String JavaDoc fieldName,
445                                      Class JavaDoc fieldType,
446                                      String JavaDoc name,
447                                      String JavaDoc resourceType,
448                                      String JavaDoc jndiName)
449     throws ConfigException
450   {
451     String JavaDoc prefix = "";
452
453     if (name.equals(""))
454       name = fieldName;
455
456     if (resourceType.equals("") || resourceType.equals("java.lang.Object"))
457       resourceType = fieldType.getName();
458
459     if (resourceType.equals("javax.sql.DataSource"))
460       prefix = "jdbc/";
461     else if (resourceType.startsWith("javax.jms."))
462       prefix = "jms/";
463     else if (resourceType.startsWith("javax.mail."))
464       prefix = "mail/";
465     else if (resourceType.equals("java.net.URL"))
466       prefix = "url/";
467     else if (resourceType.startsWith("javax.ejb."))
468       prefix = "ejb/";
469
470     if (! jndiName.equals("")) {
471     }
472     else if (UserTransaction JavaDoc.class.equals(fieldType)) {
473       jndiName = "java:comp/UserTransaction";
474     }
475     else if ("java.util.concurrent.Executor".equals(resourceType)) {
476       jndiName = "java:comp/ThreadPool";
477     }
478     else {
479       jndiName = prefix + name;
480     }
481
482     int colon = jndiName.indexOf(':');
483     int slash = jndiName.indexOf('/');
484
485     if (colon < 0 || slash > 0 && slash < colon)
486       jndiName = "java:comp/env/" + jndiName;
487
488     BuilderProgram program;
489
490     if (field instanceof Method JavaDoc)
491       program = new JndiInjectProgram(jndiName, (Method JavaDoc) field);
492     else
493       program = new JndiFieldInjectProgram(jndiName, (Field JavaDoc) field);
494
495     if (log.isLoggable(Level.FINEST))
496       log.log(Level.FINEST, String.valueOf(program));
497
498     return program;
499   }
500
501   private static String JavaDoc toFullName(String JavaDoc jndiName)
502   {
503     int colon = jndiName.indexOf(':');
504     int slash = jndiName.indexOf('/');
505
506     if (colon < 0 || slash > 0 && slash < colon)
507       jndiName = "java:comp/env/" + jndiName;
508
509     return jndiName;
510   }
511 }
512
Popular Tags