KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > injection > ResourceHandler


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.injection;
23
24 import org.jboss.ejb3.Container;
25 import org.jboss.logging.Logger;
26 import org.jboss.metamodel.descriptor.EnvEntry;
27 import org.jboss.metamodel.descriptor.EnvironmentRefGroup;
28 import org.jboss.metamodel.descriptor.MessageDestinationRef;
29 import org.jboss.metamodel.descriptor.ResourceEnvRef;
30 import org.jboss.metamodel.descriptor.ResourceRef;
31 import org.jboss.reflect.plugins.ValueConvertor;
32
33 import javax.annotation.Resource;
34 import javax.annotation.Resources;
35 import javax.ejb.EJBContext JavaDoc;
36 import javax.ejb.TimerService JavaDoc;
37 import javax.transaction.UserTransaction JavaDoc;
38 import javax.xml.ws.WebServiceContext;
39
40 import java.lang.reflect.AccessibleObject JavaDoc;
41 import java.lang.reflect.Field JavaDoc;
42 import java.lang.reflect.Method JavaDoc;
43 import java.util.Collection JavaDoc;
44 import java.util.Map JavaDoc;
45 import java.net.URL JavaDoc;
46 import java.net.MalformedURLException JavaDoc;
47
48 /**
49  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
50  * @version $Revision: 58502 $
51  */

52 public class ResourceHandler implements InjectionHandler
53 {
54    private static final Logger log = Logger.getLogger(ResourceHandler.class);
55
56    private static void loadEnvEntry(InjectionContainer container, Collection JavaDoc<EnvEntry> envEntries)
57    {
58       for (EnvEntry envEntry : envEntries)
59       {
60          String JavaDoc encName = "env/" + envEntry.getEnvEntryName();
61          InjectionUtil.injectionTarget(encName, envEntry, container, container.getEncInjections());
62          if (container.getEncInjectors().containsKey(encName)) continue;
63          log.trace("adding env-entry injector " + encName);
64          container.getEncInjectors().put(encName, new EnvEntryEncInjector(encName, envEntry.getEnvEntryType(), envEntry.getEnvEntryValue()));
65       }
66    }
67
68    private static void loadXmlResourceRefs(InjectionContainer container, Collection JavaDoc<ResourceRef> refs)
69    {
70       for (ResourceRef envRef : refs)
71       {
72          String JavaDoc encName = "env/" + envRef.getResRefName();
73          if (container.getEncInjectors().containsKey(encName)) continue;
74          if (envRef.getMappedName() == null || envRef.getMappedName().equals(""))
75          {
76             if (envRef.getResUrl() != null)
77             {
78                try
79                {
80                   container.getEncInjectors().put(encName, new ValueEncInjector(encName, new URL JavaDoc(envRef.getResUrl().trim()), "<resource-ref>"));
81                }
82                catch (MalformedURLException JavaDoc e)
83                {
84                   throw new RuntimeException JavaDoc(e);
85                }
86             }
87             else
88             {
89                throw new RuntimeException JavaDoc("mapped-name is required for " + envRef.getResRefName() + " of deployment " + container.getIdentifier());
90             }
91          }
92          else
93          {
94             container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, envRef.getMappedName(), "<resource-ref>"));
95          }
96          InjectionUtil.injectionTarget(encName, envRef, container, container.getEncInjections());
97       }
98    }
99
100    private static void loadXmlResourceEnvRefs(InjectionContainer container, Collection JavaDoc<ResourceEnvRef> refs)
101    {
102       for (ResourceEnvRef envRef : refs)
103       {
104          String JavaDoc encName = "env/" + envRef.getResRefName();
105          if (container.getEncInjectors().containsKey(encName)) continue;
106          if (envRef.getMappedName() == null || envRef.getMappedName().equals(""))
107          {
108             throw new RuntimeException JavaDoc("mapped-name is required for " + envRef.getResRefName() + " of deployment " + container.getIdentifier());
109          }
110          container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, envRef.getMappedName(), "<resource-ref>"));
111          InjectionUtil.injectionTarget(encName, envRef, container, container.getEncInjections());
112       }
113    }
114
115    private static void loadXmlMessageDestinationRefs(InjectionContainer container, Collection JavaDoc<MessageDestinationRef> refs)
116    {
117       for (MessageDestinationRef envRef : refs)
118       {
119          String JavaDoc encName = "env/" + envRef.getMessageDestinationRefName();
120          if (container.getEncInjectors().containsKey(encName)) continue;
121          if (envRef.getMappedName() == null || envRef.getMappedName().equals(""))
122          {
123             // Look for a message-destination-link
124
String JavaDoc link = envRef.getMessageDestinationLink();
125             if( link != null )
126             {
127                // TODO: Resolve the link...
128
}
129             throw new RuntimeException JavaDoc("mapped-name is required for " + envRef.getMessageDestinationRefName() + " of deployment " + container.getIdentifier());
130          }
131          container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, envRef.getMappedName(), "<message-destination-ref>"));
132          InjectionUtil.injectionTarget(encName, envRef, container, container.getEncInjections());
133       }
134    }
135
136    public void loadXml(EnvironmentRefGroup xml, InjectionContainer container)
137    {
138       if (xml == null) return;
139       if (xml.getMessageDestinationRefs() != null) loadXmlMessageDestinationRefs(container, xml.getMessageDestinationRefs());
140       if (xml.getResourceEnvRefs() != null) loadXmlResourceEnvRefs(container, xml.getResourceEnvRefs());
141       if (xml.getResourceRefs() != null) loadXmlResourceRefs(container, xml.getResourceRefs());
142       if (xml.getEnvEntries() != null) loadEnvEntry(container, xml.getEnvEntries());
143    }
144
145    public void handleClassAnnotations(Class JavaDoc clazz, InjectionContainer container)
146    {
147       Resources resources = container.getAnnotation(Resources.class, clazz);
148       if (resources != null)
149       {
150       for (Resource ref : resources.value())
151       {
152          handleClassAnnotation(ref, container, clazz);
153       }
154       }
155       Resource res = container.getAnnotation(Resource.class, clazz);
156       if (res != null) handleClassAnnotation(res, container, clazz);
157    }
158
159    private void handleClassAnnotation(Resource ref, InjectionContainer container, Class JavaDoc clazz)
160    {
161       String JavaDoc encName = ref.name();
162       if (encName == null || encName.equals(""))
163       {
164          throw new RuntimeException JavaDoc("JBoss requires name() for class level @Resource");
165       }
166       encName = "env/" + ref.name();
167       if (container.getEncInjectors().containsKey(encName)) return;
168
169       String JavaDoc mappedName = ref.mappedName();
170       if (mappedName == null || mappedName.equals(""))
171       {
172          throw new RuntimeException JavaDoc("You did not specify a @Resource.mappedName() for name: "
173                +ref.name()+", class: " + clazz.getName() + " and there is no binding for that enc name in XML");
174       }
175
176       if (ref.type() == URL JavaDoc.class)
177       {
178          // Create a URL from the mappedName
179
try
180          {
181             URL JavaDoc url = new URL JavaDoc(ref.mappedName().trim());
182             container.getEncInjectors().put(encName, new ValueEncInjector(encName, url, "@Resource"));
183          }
184          catch (MalformedURLException JavaDoc e)
185          {
186             throw new RuntimeException JavaDoc(e);
187          }
188       }
189       else
190       {
191          container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, ref.mappedName(), "@Resource"));
192       }
193    }
194
195    public void handleMethodAnnotations(Method JavaDoc method, InjectionContainer container, Map JavaDoc<AccessibleObject JavaDoc, Injector> injectors)
196    {
197       Resource ref = method.getAnnotation(Resource.class);
198       if (ref == null) return;
199
200       String JavaDoc encName = ref.name();
201       if (encName == null || encName.equals(""))
202       {
203          encName = InjectionUtil.getEncName(method);
204       }
205       else
206       {
207          encName = "env/" + encName;
208       }
209
210       method.setAccessible(true);
211
212       if (!method.getName().startsWith("set"))
213          throw new RuntimeException JavaDoc("@Resource can only be used with a set method: " + method);
214       if (method.getParameterTypes().length != 1)
215          throw new RuntimeException JavaDoc("@Resource can only be used with a set method of one parameter: " + method);
216
217       Class JavaDoc type = method.getParameterTypes()[0];
218       if (!ref.type().equals(Object JavaDoc.class))
219       {
220          type = ref.type();
221       }
222       if (type.equals(UserTransaction JavaDoc.class))
223       {
224          injectors.put(method, new UserTransactionMethodInjector(method, container));
225       }
226       else if (type.equals(TimerService JavaDoc.class))
227       {
228          injectors.put(method, new TimerServiceMethodInjector(method, (Container) container)); // only EJBs
229
}
230       else if (EJBContext JavaDoc.class.isAssignableFrom(type))
231       {
232          injectors.put(method, new EJBContextMethodInjector(method));
233       }
234       else if (type.equals(WebServiceContext.class))
235       {
236          // FIXME: For now we skip it, and rely on the WS stack to perform the injection
237
}
238       else if (type.equals(String JavaDoc.class)
239               || type.equals(Character JavaDoc.class)
240               || type.equals(Byte JavaDoc.class)
241               || type.equals(Short JavaDoc.class)
242               || type.equals(Integer JavaDoc.class)
243               || type.equals(Long JavaDoc.class)
244               || type.equals(Boolean JavaDoc.class)
245               || type.equals(Double JavaDoc.class)
246               || type.equals(Float JavaDoc.class)
247               || type.isPrimitive()
248               )
249       {
250
251          // don't add an injector if no XML <env-entry is present as there will be no value to inject
252
if (container.getEncInjectors().containsKey(encName))
253          {
254             injectors.put(method, new JndiMethodInjector(method, encName, container.getEnc()));
255          }
256          else if (ref.mappedName() != null && ref.mappedName().length() > 0)
257          {
258             // Use the mappedName as the string value
259
String JavaDoc s = ref.mappedName().trim();
260             try
261             {
262                Object JavaDoc value = ValueConvertor.convertValue(type, s);
263                container.getEncInjectors().put(encName, new ValueEncInjector(encName, value, "@Resource"));
264                injectors.put(method, new JndiMethodInjector(method, encName, container.getEnc()));
265             }
266             catch(Throwable JavaDoc t)
267             {
268                throw new RuntimeException JavaDoc("Failed to convert: "+ref.mappedName()+" to type:"+type, t);
269             }
270          }
271       }
272       else
273       {
274          if (!container.getEncInjectors().containsKey(encName))
275          {
276             String JavaDoc mappedName = ref.mappedName();
277             if (mappedName == null || mappedName.equals(""))
278             {
279               throw new RuntimeException JavaDoc("You did not specify a @Resource.mappedName() on " + method + " and there is no binding for that enc name in XML");
280             }
281             container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, ref.mappedName(), "@Resource"));
282          }
283          injectors.put(method, new JndiMethodInjector(method, encName, container.getEnc()));
284       }
285    }
286    public void handleFieldAnnotations(Field JavaDoc field, InjectionContainer container, Map JavaDoc<AccessibleObject JavaDoc, Injector> injectors)
287    {
288       Resource ref = field.getAnnotation(Resource.class);
289       if (ref == null) return;
290
291       log.trace("field " + field + " has @Resource");
292       
293       String JavaDoc encName = ref.name();
294       if (encName == null || encName.equals(""))
295       {
296          encName = InjectionUtil.getEncName(field);
297       }
298       else
299       {
300          encName = "env/" + encName;
301       }
302
303       field.setAccessible(true);
304
305       Class JavaDoc type = field.getType();
306       if (!ref.type().equals(Object JavaDoc.class))
307       {
308          type = ref.type();
309       }
310       if (type.equals(UserTransaction JavaDoc.class))
311       {
312          injectors.put(field, new UserTransactionFieldInjector(field, container));
313       }
314       else if (type.equals(TimerService JavaDoc.class))
315       {
316          injectors.put(field, new TimerServiceFieldInjector(field, (Container) container)); // only EJBs
317
}
318       else if (EJBContext JavaDoc.class.isAssignableFrom(type))
319       {
320          injectors.put(field, new EJBContextFieldInjector(field));
321       }
322       else if (type.equals(WebServiceContext.class))
323       {
324          // FIXME: For now we skip it, and rely on the WS stack to perform the injection
325
}
326       else if (type.equals(String JavaDoc.class)
327               || type.equals(Character JavaDoc.class)
328               || type.equals(Byte JavaDoc.class)
329               || type.equals(Short JavaDoc.class)
330               || type.equals(Integer JavaDoc.class)
331               || type.equals(Long JavaDoc.class)
332               || type.equals(Boolean JavaDoc.class)
333               || type.equals(Double JavaDoc.class)
334               || type.equals(Float JavaDoc.class)
335               || type.isPrimitive()
336               )
337       {
338          // don't add an injector if no XML <env-entry is present as there will be no value to inject
339
if (container.getEncInjectors().containsKey(encName))
340          {
341             injectors.put(field, new JndiFieldInjector(field, encName, container.getEnc()));
342          }
343          else if (ref.mappedName() != null && ref.mappedName().length() > 0)
344          {
345             // Use the mappedName as the string value
346
String JavaDoc s = ref.mappedName().trim();
347             try
348             {
349                Object JavaDoc value = ValueConvertor.convertValue(type, s);
350                container.getEncInjectors().put(encName, new ValueEncInjector(encName, value, "@Resource"));
351                injectors.put(field, new JndiFieldInjector(field, encName, container.getEnc()));
352             }
353             catch(Throwable JavaDoc t)
354             {
355                throw new RuntimeException JavaDoc("Failed to convert: "+ref.mappedName()+" to type:"+type, t);
356             }
357          }
358          else
359          {
360             log.warn("Not injecting " + field.getName() + ", no matching enc injector " + encName + " found");
361          }
362       }
363       else
364       {
365          if (!container.getEncInjectors().containsKey(encName))
366          {
367             String JavaDoc mappedName = ref.mappedName();
368             if (mappedName == null || mappedName.equals(""))
369             {
370               throw new RuntimeException JavaDoc("You did not specify a @Resource.mappedName() on " + field + " and there is no binding for enc name " + encName + " in XML");
371             }
372             container.getEncInjectors().put(encName, new LinkRefEncInjector(encName, ref.mappedName(), "@Resource"));
373          }
374          injectors.put(field, new JndiFieldInjector(field, encName, container.getEnc()));
375       }
376    }
377
378
379 }
380
Popular Tags