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.log.Log;
25  
26  /**
27   * Injection
28   *
29   * Represents the injection of a resource into a target (method or field).
30   * The injection is performed by doing an ENC lookup using the jndi
31   * name provided, and setting the object obtained on the target.
32   *
33   */
34  public class Injection
35  {
36      private Class<?> _targetClass;
37      private String _jndiName;
38      private String _mappingName;
39      private Member _target;
40      private Class<?> _paramClass;
41      private Class<?> _resourceClass;
42  
43      
44      public Injection ()
45      {
46      }
47      
48  
49      /**
50       * @return the _className
51       */
52      public Class<?> getTargetClass()
53      {
54          return _targetClass;
55      }
56  
57      public Class<?> getParamClass ()
58      {
59          return _paramClass;
60      }
61     
62      public Class<?> getResourceClass ()
63      {
64          return _resourceClass;
65      }
66      
67      public boolean isField ()
68      {
69          return (_target != null && _target instanceof Field);
70      }
71      
72      public boolean isMethod ()
73      {
74          return (_target != null && _target instanceof Method);
75      }
76      
77      /**
78       * @return the jndiName
79       */
80      public String getJndiName()
81      {
82          return _jndiName;
83      }
84      /**
85       * @param jndiName the jndiName to set
86       */
87      public void setJndiName(String jndiName)
88      {
89          this._jndiName = jndiName;
90      }
91      /**
92       * @return the mappingName
93       */
94      public String getMappingName()
95      {
96          return _mappingName;
97      }
98      /**
99       * @param mappingName the mappingName to set
100      */
101     public void setMappingName(String mappingName)
102     {
103         this._mappingName = mappingName;
104     }
105     
106     /**
107      * @return the target
108      */
109     public Member getTarget()
110     {
111         return _target;
112     }
113     
114 
115     public void setTarget(Class<?> clazz, Field field, Class<?> resourceType)
116     {
117         _targetClass = clazz;
118         _target = field;
119         _resourceClass = resourceType;
120     }
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     public void setTarget (Class<?> clazz, String target, Class<?> resourceType)
131     {
132         _targetClass = clazz;
133         _resourceClass = resourceType;
134         
135         //first look for a javabeans style setter matching the targetName
136         String setter = "set"+target.substring(0,1).toUpperCase()+target.substring(1);
137         try
138         {
139             Log.debug("Looking for method for setter: "+setter+" with arg "+_resourceClass);
140             _target = IntrospectionUtil.findMethod(clazz, setter, new Class[] {_resourceClass}, true, false);
141             _targetClass = clazz;
142             _paramClass = _resourceClass;
143         }
144         catch (NoSuchMethodException me)
145         {
146             //try as a field
147             try
148             {
149                 _target = IntrospectionUtil.findField(clazz, target, resourceType, true, false);
150                 _targetClass = clazz;
151             }
152             catch (NoSuchFieldException fe)
153             {
154                 throw new IllegalArgumentException("No such field or method "+target+" on class "+_targetClass);
155             }
156         }
157 
158     }
159     
160     /**
161      * Inject a value for a Resource from JNDI into an object
162      * @param injectable
163      */
164     public void inject (Object injectable)
165     { 
166         if (_target != null)
167         {
168             if (_target instanceof Field)
169                 injectField((Field)_target, injectable);
170             else
171                 injectMethod((Method)_target, injectable);
172         }
173         else
174             throw new IllegalStateException ("No method or field to inject with "+getJndiName());
175     }
176 
177     
178     /**
179      * The Resource must already exist in the ENC of this webapp.
180      * @return the injected valud
181      * @throws NamingException
182      */
183     public Object lookupInjectedValue ()
184     throws NamingException
185     {
186         InitialContext context = new InitialContext();
187         return context.lookup("java:comp/env/"+getJndiName());
188     }
189     
190 
191 
192     /**
193      * Inject value from jndi into a field of an instance
194      * @param field
195      * @param injectable
196      */
197     protected void injectField (Field field, Object injectable)
198     {        
199         try
200         {
201             boolean accessibility = field.isAccessible();
202             field.setAccessible(true);
203             field.set(injectable, lookupInjectedValue());
204             field.setAccessible(accessibility);
205         }
206         catch (Exception e)
207         {
208             Log.warn(e);
209             throw new IllegalStateException("Inject failed for field "+field.getName());
210         }
211     }
212 
213     /**
214      * Inject value from jndi into a setter method of an instance
215      * @param method
216      * @param injectable
217      */
218     protected void injectMethod (Method method, Object injectable)
219     {
220         try
221         {
222             boolean accessibility = method.isAccessible();
223             method.setAccessible(true);
224             method.invoke(injectable, new Object[] {lookupInjectedValue()});
225             method.setAccessible(accessibility);
226         }
227         catch (Exception e)
228         {
229             Log.warn(e);
230             throw new IllegalStateException("Inject failed for method "+method.getName());
231         }
232     }
233    
234 }