001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Evgueni Brevnov, Serguei S. Zapreyev, Alexey V. Varlamov
019: * @version $Revision: 1.1.2.2.4.4 $
020: */package java.lang.reflect;
021:
022: import static org.apache.harmony.vm.ClassFormat.ACC_ENUM;
023: import static org.apache.harmony.vm.ClassFormat.ACC_SYNTHETIC;
024:
025: import java.lang.annotation.Annotation;
026:
027: import org.apache.harmony.lang.reflect.parser.Parser;
028: import org.apache.harmony.vm.VMGenericsAndAnnotations;
029: import org.apache.harmony.vm.VMStack;
030:
031: /**
032: * @com.intel.drl.spec_ref
033: */
034: public final class Field extends AccessibleObject implements Member {
035:
036: /**
037: * @com.intel.drl.spec_ref
038: */
039: public Annotation[] getDeclaredAnnotations() {
040: Annotation a[] = data.getAnnotations();
041: Annotation aa[] = new Annotation[a.length];
042: System.arraycopy(a, 0, aa, 0, a.length);
043: return aa;
044: }
045:
046: /**
047: * @com.intel.drl.spec_ref
048: */
049: @SuppressWarnings("unchecked")
050: public <T extends Annotation> T getAnnotation(
051: Class<T> annotationClass) {
052: if (annotationClass == null) {
053: throw new NullPointerException();
054: }
055: for (Annotation aa : data.getAnnotations()) {
056: if (aa.annotationType() == annotationClass) {
057: return (T) aa;
058: }
059: }
060: return null;
061: }
062:
063: /**
064: * @com.intel.drl.spec_ref
065: */
066: public Type getGenericType() throws GenericSignatureFormatError,
067: TypeNotPresentException,
068: MalformedParameterizedTypeException {
069: if (data.genericType == null) {
070: data.genericType = Parser.parseFieldGenericType(this ,
071: VMGenericsAndAnnotations
072: .getSignature(data.vm_member_id));
073: }
074: return data.genericType;
075: }
076:
077: /**
078: * @com.intel.drl.spec_ref
079: */
080: public String toGenericString() {
081: StringBuilder sb = new StringBuilder(80);
082: // append modifiers if any
083: int modifier = getModifiers();
084: if (modifier != 0) {
085: sb.append(Modifier.toString(modifier)).append(' ');
086: }
087: // append generic type
088: appendGenericType(sb, getGenericType());
089: sb.append(' ');
090: // append full field name
091: sb.append(getDeclaringClass().getName()).append('.').append(
092: getName());
093: return sb.toString();
094: }
095:
096: /**
097: * @com.intel.drl.spec_ref
098: */
099: public boolean isSynthetic() {
100: return (getModifiers() & ACC_SYNTHETIC) != 0;
101: }
102:
103: /**
104: * @com.intel.drl.spec_ref
105: */
106: public boolean isEnumConstant() {
107: return (getModifiers() & ACC_ENUM) != 0;
108: }
109:
110: /**
111: * cache of the field data
112: */
113: private final FieldData data;
114:
115: /**
116: * Copy constructor
117: *
118: * @param f original field
119: */
120: Field(Field f) {
121: data = f.data;
122: isAccessible = f.isAccessible;
123: }
124:
125: /**
126: * Only VM should call this constructor.
127: * String parameters must be interned.
128: * @api2vm
129: */
130: Field(long id, Class clss, String name, String desc, int m) {
131: data = new FieldData(id, clss, name, desc, m);
132: }
133:
134: /**
135: * Called by VM to obtain this field's handle.
136: *
137: * @return handle for this field
138: * @api2vm
139: */
140: long getId() {
141: return data.vm_member_id;
142: }
143:
144: /**
145: * @com.intel.drl.spec_ref
146: */
147: public boolean equals(Object obj) {
148: if (obj instanceof Field) {
149: Field that = (Field) obj;
150: if (data.vm_member_id == that.data.vm_member_id) {
151: assert getDeclaringClass() == that.getDeclaringClass()
152: && getName() == that.getName();
153: return true;
154: }
155: }
156: return false;
157: }
158:
159: /**
160: * @com.intel.drl.spec_ref
161: */
162: public Object get(Object obj) throws IllegalArgumentException,
163: IllegalAccessException {
164: obj = checkGet(VMStack.getCallerClass(0), obj);
165: return VMField.getObject(obj, data.vm_member_id);
166: }
167:
168: /**
169: * @com.intel.drl.spec_ref
170: */
171: public boolean getBoolean(Object obj)
172: throws IllegalArgumentException, IllegalAccessException {
173: obj = checkGet(VMStack.getCallerClass(0), obj);
174: return VMField.getBoolean(obj, data.vm_member_id);
175: }
176:
177: /**
178: * @com.intel.drl.spec_ref
179: */
180: public byte getByte(Object obj) throws IllegalArgumentException,
181: IllegalAccessException {
182: obj = checkGet(VMStack.getCallerClass(0), obj);
183: return VMField.getByte(obj, data.vm_member_id);
184: }
185:
186: /**
187: * @com.intel.drl.spec_ref
188: */
189: public char getChar(Object obj) throws IllegalArgumentException,
190: IllegalAccessException {
191: obj = checkGet(VMStack.getCallerClass(0), obj);
192: return VMField.getChar(obj, data.vm_member_id);
193: }
194:
195: /**
196: * @com.intel.drl.spec_ref
197: */
198: public Class<?> getDeclaringClass() {
199: return data.declaringClass;
200: }
201:
202: /**
203: * @com.intel.drl.spec_ref
204: */
205: public double getDouble(Object obj)
206: throws IllegalArgumentException, IllegalAccessException {
207: obj = checkGet(VMStack.getCallerClass(0), obj);
208: return VMField.getDouble(obj, data.vm_member_id);
209: }
210:
211: /**
212: * @com.intel.drl.spec_ref
213: */
214: public float getFloat(Object obj) throws IllegalArgumentException,
215: IllegalAccessException {
216: obj = checkGet(VMStack.getCallerClass(0), obj);
217: return VMField.getFloat(obj, data.vm_member_id);
218: }
219:
220: /**
221: * @com.intel.drl.spec_ref
222: */
223: public int getInt(Object obj) throws IllegalArgumentException,
224: IllegalAccessException {
225: obj = checkGet(VMStack.getCallerClass(0), obj);
226: return VMField.getInt(obj, data.vm_member_id);
227: }
228:
229: /**
230: * @com.intel.drl.spec_ref
231: */
232: public long getLong(Object obj) throws IllegalArgumentException,
233: IllegalAccessException {
234: obj = checkGet(VMStack.getCallerClass(0), obj);
235: return VMField.getLong(obj, data.vm_member_id);
236: }
237:
238: /**
239: * @com.intel.drl.spec_ref
240: */
241: public int getModifiers() {
242: return data.modifiers;
243: }
244:
245: /**
246: * @com.intel.drl.spec_ref
247: */
248: public String getName() {
249: return data.name;
250: }
251:
252: /**
253: * @com.intel.drl.spec_ref
254: */
255: public short getShort(Object obj) throws IllegalArgumentException,
256: IllegalAccessException {
257: obj = checkGet(VMStack.getCallerClass(0), obj);
258: return VMField.getShort(obj, data.vm_member_id);
259: }
260:
261: /**
262: * @com.intel.drl.spec_ref
263: */
264: public Class<?> getType() {
265: return data.getType();
266: }
267:
268: /**
269: * @com.intel.drl.spec_ref
270: */
271: public int hashCode() {
272: return getDeclaringClass().getName().hashCode()
273: ^ getName().hashCode();
274: }
275:
276: /**
277: * @com.intel.drl.spec_ref
278: */
279: public void set(Object obj, Object value)
280: throws IllegalArgumentException, IllegalAccessException {
281: obj = checkSet(VMStack.getCallerClass(0), obj);
282: VMField.setObject(obj, data.vm_member_id, value);
283: }
284:
285: /**
286: * @com.intel.drl.spec_ref
287: */
288: public void setBoolean(Object obj, boolean value)
289: throws IllegalArgumentException, IllegalAccessException {
290: obj = checkSet(VMStack.getCallerClass(0), obj);
291: VMField.setBoolean(obj, data.vm_member_id, value);
292: }
293:
294: /**
295: * @com.intel.drl.spec_ref
296: */
297: public void setByte(Object obj, byte value)
298: throws IllegalArgumentException, IllegalAccessException {
299: obj = checkSet(VMStack.getCallerClass(0), obj);
300: VMField.setByte(obj, data.vm_member_id, value);
301: }
302:
303: /**
304: * @com.intel.drl.spec_ref
305: */
306: public void setChar(Object obj, char value)
307: throws IllegalArgumentException, IllegalAccessException {
308: obj = checkSet(VMStack.getCallerClass(0), obj);
309: VMField.setChar(obj, data.vm_member_id, value);
310: }
311:
312: /**
313: * @com.intel.drl.spec_ref
314: */
315: public void setDouble(Object obj, double value)
316: throws IllegalArgumentException, IllegalAccessException {
317: obj = checkSet(VMStack.getCallerClass(0), obj);
318: VMField.setDouble(obj, data.vm_member_id, value);
319: }
320:
321: /**
322: * @com.intel.drl.spec_ref
323: */
324: public void setFloat(Object obj, float value)
325: throws IllegalArgumentException, IllegalAccessException {
326: obj = checkSet(VMStack.getCallerClass(0), obj);
327: VMField.setFloat(obj, data.vm_member_id, value);
328: }
329:
330: /**
331: * @com.intel.drl.spec_ref
332: */
333: public void setInt(Object obj, int value)
334: throws IllegalArgumentException, IllegalAccessException {
335: obj = checkSet(VMStack.getCallerClass(0), obj);
336: VMField.setInt(obj, data.vm_member_id, value);
337: }
338:
339: /**
340: * @com.intel.drl.spec_ref
341: */
342: public void setLong(Object obj, long value)
343: throws IllegalArgumentException, IllegalAccessException {
344: obj = checkSet(VMStack.getCallerClass(0), obj);
345: VMField.setLong(obj, data.vm_member_id, value);
346: }
347:
348: /**
349: * @com.intel.drl.spec_ref
350: */
351: public void setShort(Object obj, short value)
352: throws IllegalArgumentException, IllegalAccessException {
353: obj = checkSet(VMStack.getCallerClass(0), obj);
354: VMField.setShort(obj, data.vm_member_id, value);
355: }
356:
357: /**
358: * @com.intel.drl.spec_ref
359: */
360: public String toString() {
361: StringBuilder sb = new StringBuilder(80);
362: // append modifiers if any
363: int modifier = getModifiers();
364: if (modifier != 0) {
365: sb.append(Modifier.toString(modifier)).append(' ');
366: }
367: // append return type
368: appendArrayType(sb, getType());
369: sb.append(' ');
370: // append full field name
371: sb.append(getDeclaringClass().getName()).append('.').append(
372: getName());
373: return sb.toString();
374: }
375:
376: /* NON API SECTION */
377:
378: /**
379: * Checks that the specified obj is valid object for a getXXX operation.
380: *
381: * @param callerClass caller class of a getXXX method
382: * @param obj object to check
383: * @return null if this field is static, otherwise obj one
384: * @throws IllegalArgumentException if obj argument is not valid
385: * @throws IllegalAccessException if caller doesn't have access permission
386: */
387: private Object checkGet(Class callerClass, Object obj)
388: throws IllegalArgumentException, IllegalAccessException {
389: obj = checkObject(getDeclaringClass(), getModifiers(), obj);
390: if (!isAccessible) {
391: reflectExporter.checkMemberAccess(callerClass,
392: getDeclaringClass(),
393: obj == null ? getDeclaringClass() : obj.getClass(),
394: getModifiers());
395: }
396: return obj;
397: }
398:
399: /**
400: * Checks that the specified obj is valid object for a setXXX operation.
401: *
402: * @param callerClass caller class of a setXXX method
403: * @param obj object to check
404: * @return null if this field is static, otherwise obj
405: * @throws IllegalArgumentException if obj argument is not valid one
406: * @throws IllegalAccessException if caller doesn't have access permission
407: * or this field is final
408: */
409: private Object checkSet(Class callerClass, Object obj)
410: throws IllegalArgumentException, IllegalAccessException {
411: obj = checkObject(getDeclaringClass(), getModifiers(), obj);
412: if (Modifier.isFinal(getModifiers())
413: && !(isAccessible && obj != null)) {
414: throw new IllegalAccessException(
415: "Can not assign new value to the field with final modifier");
416: }
417: if (!isAccessible) {
418: reflectExporter.checkMemberAccess(callerClass,
419: getDeclaringClass(),
420: obj == null ? getDeclaringClass() : obj.getClass(),
421: getModifiers());
422: }
423: return obj;
424: }
425:
426: /**
427: * This method is used by serialization mechanism.
428: *
429: * @return the signature of the field
430: */
431: String getSignature() {
432: return data.descriptor;
433: }
434:
435: /**
436: * Keeps an information about this field
437: */
438: private static class FieldData {
439:
440: final String name;
441: final Class declaringClass;
442: final int modifiers;
443: private Class<?> type;
444: private Annotation[] declaredAnnotations;
445: Type genericType;
446: final String descriptor;
447:
448: /**
449: * field handle which is used to retrieve all necessary information
450: * about this field object
451: */
452: final long vm_member_id;
453:
454: FieldData(long vm_id, Class clss, String name, String desc,
455: int mods) {
456: vm_member_id = vm_id;
457: declaringClass = clss;
458: this .name = name;
459: modifiers = mods;
460: descriptor = desc;
461: }
462:
463: Annotation[] getAnnotations() {
464: if (declaredAnnotations == null) {
465: declaredAnnotations = VMGenericsAndAnnotations
466: .getDeclaredAnnotations(vm_member_id);
467: }
468: return declaredAnnotations;
469: }
470:
471: Class<?> getType() {
472: if (type == null) {
473: type = VMReflection.getFieldType(vm_member_id);
474: }
475: return type;
476: }
477: }
478:
479: }
|