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