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