View Javadoc

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