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