KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > beans > factory > config > FieldRetrievingFactoryBean


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.beans.factory.config;
18
19 import java.lang.reflect.Field JavaDoc;
20 import java.lang.reflect.Modifier JavaDoc;
21
22 import org.springframework.beans.factory.BeanClassLoaderAware;
23 import org.springframework.beans.factory.BeanFactoryUtils;
24 import org.springframework.beans.factory.BeanNameAware;
25 import org.springframework.beans.factory.FactoryBean;
26 import org.springframework.beans.factory.FactoryBeanNotInitializedException;
27 import org.springframework.beans.factory.InitializingBean;
28 import org.springframework.util.ClassUtils;
29 import org.springframework.util.StringUtils;
30
31 /**
32  * FactoryBean which retrieves a static or non-static field value.
33  *
34  * <p>Typically used for retrieving public static final constants. Usage example:
35  *
36  * <pre class="code">// standard definition for exposing a static field, specifying the "staticField" property
37  * &lt;bean id="myField" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"&gt;
38  * &lt;property name="staticField" value="java.sql.Connection.TRANSACTION_SERIALIZABLE"/&gt;
39  * &lt;/bean&gt;
40  *
41  * // convenience version that specifies a static field pattern as bean name
42  * &lt;bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
43  * class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/&gt;</pre>
44  * </pre>
45  *
46  * <p>If you are using Spring 2.0, you can also use the following style of configuration for
47  * public static fields.
48  *
49  * <pre class="code">&lt;util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/&gt;</pre>
50  *
51  * @author Juergen Hoeller
52  * @since 1.1
53  * @see #setStaticField
54  */

55 public class FieldRetrievingFactoryBean implements FactoryBean, BeanNameAware, BeanClassLoaderAware, InitializingBean {
56
57     private Class JavaDoc targetClass;
58
59     private Object JavaDoc targetObject;
60
61     private String JavaDoc targetField;
62
63     private String JavaDoc staticField;
64
65     private String JavaDoc beanName;
66
67     private ClassLoader JavaDoc beanClassLoader = ClassUtils.getDefaultClassLoader();
68
69     // the field we will retrieve
70
private Field JavaDoc fieldObject;
71
72
73     /**
74      * Set the target class on which the field is defined.
75      * Only necessary when the target field is static; else,
76      * a target object needs to be specified anyway.
77      * @see #setTargetObject
78      * @see #setTargetField
79      */

80     public void setTargetClass(Class JavaDoc targetClass) {
81         this.targetClass = targetClass;
82     }
83
84     /**
85      * Return the target class on which the field is defined.
86      */

87     public Class JavaDoc getTargetClass() {
88         return targetClass;
89     }
90
91     /**
92      * Set the target object on which the field is defined.
93      * Only necessary when the target field is not static;
94      * else, a target class is sufficient.
95      * @see #setTargetClass
96      * @see #setTargetField
97      */

98     public void setTargetObject(Object JavaDoc targetObject) {
99         this.targetObject = targetObject;
100     }
101
102     /**
103      * Return the target object on which the field is defined.
104      */

105     public Object JavaDoc getTargetObject() {
106         return this.targetObject;
107     }
108
109     /**
110      * Set the name of the field to be retrieved.
111      * Refers to either a static field or a non-static field,
112      * depending on a target object being set.
113      * @see #setTargetClass
114      * @see #setTargetObject
115      */

116     public void setTargetField(String JavaDoc targetField) {
117         this.targetField = StringUtils.trimAllWhitespace(targetField);
118     }
119
120     /**
121      * Return the name of the field to be retrieved.
122      */

123     public String JavaDoc getTargetField() {
124         return this.targetField;
125     }
126
127     /**
128      * Set a fully qualified static field name to retrieve,
129      * e.g. "example.MyExampleClass.MY_EXAMPLE_FIELD".
130      * Convenient alternative to specifying targetClass and targetField.
131      * @see #setTargetClass
132      * @see #setTargetField
133      */

134     public void setStaticField(String JavaDoc staticField) {
135         this.staticField = StringUtils.trimAllWhitespace(staticField);
136     }
137
138     /**
139      * The bean name of this FieldRetrievingFactoryBean will be interpreted
140      * as "staticField" pattern, if neither "targetClass" nor "targetObject"
141      * nor "targetField" have been specified.
142      * This allows for concise bean definitions with just an id/name.
143      */

144     public void setBeanName(String JavaDoc beanName) {
145         this.beanName = StringUtils.trimAllWhitespace(BeanFactoryUtils.originalBeanName(beanName));
146     }
147
148     public void setBeanClassLoader(ClassLoader JavaDoc classLoader) {
149         this.beanClassLoader = classLoader;
150     }
151
152
153     public void afterPropertiesSet() throws ClassNotFoundException JavaDoc, NoSuchFieldException JavaDoc {
154         if (this.targetClass != null && this.targetObject != null) {
155             throw new IllegalArgumentException JavaDoc("Specify either targetClass or targetObject, not both");
156         }
157
158         if (this.targetClass == null && this.targetObject == null) {
159             if (this.targetField != null) {
160                 throw new IllegalArgumentException JavaDoc(
161                     "Specify targetClass or targetObject in combination with targetField");
162             }
163
164             // If no other property specified, consider bean name as static field expression.
165
if (this.staticField == null) {
166                 this.staticField = this.beanName;
167             }
168
169             // Try to parse static field into class and field.
170
int lastDotIndex = this.staticField.lastIndexOf('.');
171             if (lastDotIndex == -1 || lastDotIndex == this.staticField.length()) {
172                 throw new IllegalArgumentException JavaDoc(
173                         "staticField must be a fully qualified class plus method name: " +
174                         "e.g. 'example.MyExampleClass.MY_EXAMPLE_FIELD'");
175             }
176             String JavaDoc className = this.staticField.substring(0, lastDotIndex);
177             String JavaDoc fieldName = this.staticField.substring(lastDotIndex + 1);
178             this.targetClass = ClassUtils.forName(className, this.beanClassLoader);
179             this.targetField = fieldName;
180         }
181
182         else if (this.targetField == null) {
183             // Either targetClass or targetObject specified.
184
throw new IllegalArgumentException JavaDoc("targetField is required");
185         }
186
187         // Try to get the exact method first.
188
Class JavaDoc targetClass = (this.targetObject != null) ? this.targetObject.getClass() : this.targetClass;
189         this.fieldObject = targetClass.getField(this.targetField);
190     }
191
192
193     public Object JavaDoc getObject() throws IllegalAccessException JavaDoc {
194         if (this.fieldObject == null) {
195             throw new FactoryBeanNotInitializedException();
196         }
197
198         if (!Modifier.isPublic(this.fieldObject.getModifiers()) ||
199                 !Modifier.isPublic(this.fieldObject.getDeclaringClass().getModifiers())) {
200             this.fieldObject.setAccessible(true);
201         }
202
203         if (this.targetObject != null) {
204             // instance field
205
return this.fieldObject.get(this.targetObject);
206         }
207         else{
208             // class field
209
return this.fieldObject.get(null);
210         }
211     }
212
213     public Class JavaDoc getObjectType() {
214         return (this.fieldObject != null ? this.fieldObject.getType() : null);
215     }
216
217     public boolean isSingleton() {
218         return false;
219     }
220
221 }
222
Popular Tags