View Javadoc

1   // ========================================================================
2   // Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.plus.annotation;
15  
16  import java.lang.reflect.Field;
17  import java.lang.reflect.Member;
18  import java.lang.reflect.Method;
19  
20  import javax.naming.InitialContext;
21  import javax.naming.NamingException;
22  
23  import org.eclipse.jetty.util.IntrospectionUtil;
24  import org.eclipse.jetty.util.Loader;
25  import org.eclipse.jetty.util.TypeUtil;
26  import org.eclipse.jetty.util.log.Log;
27  
28  /**
29   * Injection
30   *
31   * Represents the injection of a resource into a target (method or field).
32   * The injection is performed by doing an ENC lookup using the jndi
33   * name provided, and setting the object obtained on the target.
34   *
35   */
36  public class Injection
37  {
38      private Class _targetClass;
39      private String _jndiName;
40      private String _mappingName;
41      private Member _target;
42      private Class _paramClass;
43      private Class _resourceClass;
44  
45      
46      public Injection ()
47      {}
48      
49  
50      /**
51       * @return the _className
52       */
53      public Class getTargetClass()
54      {
55          return _targetClass;
56      }
57  
58      public Class getParamClass ()
59      {
60          return _paramClass;
61      }
62     
63      public Class getResourceClass ()
64      {
65          return _resourceClass;
66      }
67      
68      public boolean isField ()
69      {
70          return (_target != null && _target instanceof Field);
71      }
72      
73      public boolean isMethod ()
74      {
75          return (_target != null && _target instanceof Method);
76      }
77      
78      /**
79       * @return the jndiName
80       */
81      public String getJndiName()
82      {
83          return _jndiName;
84      }
85      /**
86       * @param jndiName the jndiName to set
87       */
88      public void setJndiName(String jndiName)
89      {
90          this._jndiName = jndiName;
91      }
92      /**
93       * @return the mappingName
94       */
95      public String getMappingName()
96      {
97          return _mappingName;
98      }
99      /**
100      * @param mappingName the mappingName to set
101      */
102     public void setMappingName(String mappingName)
103     {
104         this._mappingName = mappingName;
105     }
106     
107     /**
108      * @return the target
109      */
110     public Member getTarget()
111     {
112         return _target;
113     }
114     
115 
116     public void setTarget(Class clazz, Field field, Class resourceType)
117     {
118         _targetClass = clazz;
119         _target = field;
120         _resourceClass = resourceType;
121     }
122     public void setTarget(Class clazz, Method method, Class arg, Class resourceType)
123     {
124         _targetClass = clazz;
125         _target = method;
126         _resourceClass = resourceType;
127         _paramClass = arg;
128     }
129     
130    
131     public void setTarget (Class clazz, String target, Class resourceType)
132     {
133         _targetClass = clazz;
134         _resourceClass = resourceType;
135         
136         //first look for a javabeans style setter matching the targetName
137         String setter = "set"+target.substring(0,1).toUpperCase()+target.substring(1);
138         try
139         {
140             Log.debug("Looking for method for setter: "+setter+" with arg "+_resourceClass);
141             _target = IntrospectionUtil.findMethod(clazz, setter, new Class[] {_resourceClass}, true, false);
142             _targetClass = clazz;
143             _paramClass = _resourceClass;
144         }
145         catch (NoSuchMethodException me)
146         {
147             //try as a field
148             try
149             {
150                 _target = IntrospectionUtil.findField(clazz, target, resourceType, true, false);
151                 _targetClass = clazz;
152             }
153             catch (NoSuchFieldException fe)
154             {
155                 throw new IllegalArgumentException("No such field or method "+target+" on class "+_targetClass);
156             }
157         }
158 
159     }
160     
161     /**
162      * Inject a value for a Resource from JNDI into an object
163      * @param injectable
164      */
165     public void inject (Object injectable)
166     { 
167         if (_target != null)
168         {
169             if (_target instanceof Field)
170                 injectField((Field)_target, injectable);
171             else
172                 injectMethod((Method)_target, injectable);
173         }
174         else
175             throw new IllegalStateException ("No method or field to inject with "+getJndiName());
176     }
177 
178     
179     /**
180      * The Resource must already exist in the ENC of this webapp.
181      * @return the injected valud
182      * @throws NamingException
183      */
184     public Object lookupInjectedValue ()
185     throws NamingException
186     {
187         InitialContext context = new InitialContext();
188         return context.lookup("java:comp/env/"+getJndiName());
189     }
190     
191 
192 
193     /**
194      * Inject value from jndi into a field of an instance
195      * @param field
196      * @param injectable
197      */
198     protected void injectField (Field field, Object injectable)
199     {        
200         try
201         {
202             boolean accessibility = field.isAccessible();
203             field.setAccessible(true);
204             field.set(injectable, lookupInjectedValue());
205             field.setAccessible(accessibility);
206         }
207         catch (Exception e)
208         {
209             Log.warn(e);
210             throw new IllegalStateException("Inject failed for field "+field.getName());
211         }
212     }
213 
214     /**
215      * Inject value from jndi into a setter method of an instance
216      * @param method
217      * @param injectable
218      */
219     protected void injectMethod (Method method, Object injectable)
220     {
221         try
222         {
223             boolean accessibility = method.isAccessible();
224             method.setAccessible(true);
225             method.invoke(injectable, new Object[] {lookupInjectedValue()});
226             method.setAccessible(accessibility);
227         }
228         catch (Exception e)
229         {
230             Log.warn(e);
231             throw new IllegalStateException("Inject failed for method "+method.getName());
232         }
233     }
234    
235 }