1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jdo.impl.model.java;
18
19 import java.security.AccessController;
20 import java.security.PrivilegedAction;
21 import java.lang.reflect.Field;
22
23 import org.apache.jdo.model.ModelFatalException;
24 import org.apache.jdo.model.java.JavaField;
25 import org.apache.jdo.model.java.JavaType;
26 import org.apache.jdo.model.jdo.JDOField;
27 import org.apache.jdo.util.I18NHelper;
28
29 /***
30 * This class provides a basic JavaField implementation using a reflection
31 * Field instance. The implementation supports lazy initialization of the
32 * wrapped reflection field instance (see
33 * {@link #BaseReflectionJavaField(String fieldName, JavaType declaringClass)}.
34 * <p>
35 * Note, this implementation is not connected to a JavaModelFactory, thus
36 * it can only support predefined types as field types.
37 * @see PredefinedType
38 * @author Michael Bouschen
39 * @since JDO 1.1
40 * @version JDO 2.0
41 */
42 public class BaseReflectionJavaField
43 extends AbstractJavaMember
44 implements JavaField
45 {
46 /*** The wrapped java.lang.reflect.Field instance. */
47 private Field field;
48
49 /*** The type of the field. */
50 protected JavaType type;
51
52 /*** I18N support */
53 private final static I18NHelper msg =
54 I18NHelper.getInstance(BaseReflectionJavaField.class);
55
56 /***
57 * Constructor taking a reflection field representation. The specifie
58 * field must not be <code>null</code>.
59 * @param field the java.lang.reflect.Field instance
60 * @param declaringClass the JavaType of the declaring class or interface.
61 */
62 protected BaseReflectionJavaField(Field field, JavaType declaringClass)
63 {
64 super((field == null) ? null : field.getName(), declaringClass);
65 if (field == null)
66 throw new ModelFatalException(msg.msg(
67 "ERR_InvalidNullFieldInstance", "BaseReflectionJavaField.<init>"));
68 this.field = field;
69 }
70
71 /***
72 * Constructor taking the field name. This constructor allows lazy
73 * initialization of the field reference.
74 * @param fieldName the name of the field.
75 * @param declaringClass the JavaType of the declaring class or interface.
76 */
77 protected BaseReflectionJavaField(String fieldName, JavaType declaringClass)
78 {
79 super(fieldName, declaringClass);
80 }
81
82
83
84 /***
85 * Returns the environment specific instance wrapped by this JavaModel
86 * element. This implementation returns the
87 * <code>java.lang.reflect.Field</code> instance for this JavaField.
88 * @return the environment specific instance wrapped by this JavaModel
89 * element.
90 */
91 public Object getUnderlyingObject()
92 {
93 return getField();
94 }
95
96
97
98 /***
99 * Returns the Java language modifiers for the field represented by
100 * this JavaField, as an integer. The java.lang.reflect.Modifier class
101 * should be used to decode the modifiers.
102 * @return the Java language modifiers for this JavaField
103 * @see java.lang.reflect.Modifier
104 */
105 public int getModifiers()
106 {
107 ensureInitializedField();
108 return field.getModifiers();
109 }
110
111
112
113 /***
114 * Returns the JavaType representation of the field type.
115 * @return field type
116 */
117 public JavaType getType()
118 {
119 if (type == null) {
120 ensureInitializedField();
121 String typeName = field.getType().getName();
122
123 type = PredefinedType.getPredefinedType(typeName);
124 }
125 return type;
126 }
127
128
129
130 /***
131 * Returns the java.lang.reflect.Field that is wrapped by this
132 * JavaField.
133 * @return the java.lang.reflect.Field instance.
134 */
135 protected Field getField()
136 {
137 ensureInitializedField();
138 return this.field;
139 }
140
141 /***
142 * Helper method to retrieve the java.lang.reflect.Field for the specified
143 * field name.
144 * @param clazz the Class instance of the declaring class or interface
145 * @param fieldName the field name
146 * @return the java.lang.reflect.Field for the specified field name.
147 */
148 public static Field getDeclaredFieldPrivileged(final Class clazz,
149 final String fieldName)
150 {
151 if ((clazz == null) || (fieldName == null))
152 return null;
153
154 return (Field) AccessController.doPrivileged(
155 new PrivilegedAction() {
156 public Object run () {
157 try {
158 return clazz.getDeclaredField(fieldName);
159 }
160 catch (SecurityException ex) {
161 throw new ModelFatalException(
162 msg.msg("EXC_CannotGetDeclaredField",
163 clazz.getName()), ex);
164 }
165 catch (NoSuchFieldException ex) {
166 return null;
167 }
168 }
169 }
170 );
171 }
172
173 /***
174 * Helper method to retrieve the declared java.lang.reflect.Field
175 * instances for the specified class.
176 * @param clazz the Class instance of the declaring class or interface
177 * @return the java.lang.reflect.Field instances for the declared fields
178 * of the specified class.
179 */
180 public static Field[] getDeclaredFieldsPrivileged(final Class clazz)
181 {
182 if (clazz == null)
183 return null;
184
185 return (Field[]) AccessController.doPrivileged(
186 new PrivilegedAction() {
187 public Object run () {
188 try {
189 return clazz.getDeclaredFields();
190 }
191 catch (SecurityException ex) {
192 throw new ModelFatalException(
193 msg.msg("EXC_CannotGetDeclaredFields",
194 clazz.getName()), ex);
195 }
196 }
197 }
198 );
199 }
200
201
202
203 /***
204 * This method makes sure the reflection field is set.
205 */
206 protected void ensureInitializedField()
207 {
208 if (this.field == null) {
209 this.field = getDeclaredFieldPrivileged(
210 ((BaseReflectionJavaType)getDeclaringClass()).getJavaClass(),
211 getName());
212 if (field == null) {
213 throw new ModelFatalException(msg.msg(
214 "ERR_MissingFieldInstance",
215 "BaseReflectionJavaField.ensureInitializedField", getName()));
216 }
217 }
218 }
219
220 }