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_BRIDGE;
023: import static org.apache.harmony.vm.ClassFormat.ACC_SYNTHETIC;
024: import static org.apache.harmony.vm.ClassFormat.ACC_VARARGS;
025:
026: import java.lang.annotation.Annotation;
027: import java.util.Arrays;
028:
029: import org.apache.harmony.lang.reflect.parser.Parser;
030: import org.apache.harmony.vm.VMGenericsAndAnnotations;
031: import org.apache.harmony.vm.VMStack;
032:
033: /**
034: * @com.intel.drl.spec_ref
035: */
036: public final class Method extends AccessibleObject implements Member,
037: GenericDeclaration {
038:
039: /**
040: * @com.intel.drl.spec_ref
041: */
042: public boolean isBridge() {
043: return (getModifiers() & ACC_BRIDGE) != 0;
044: }
045:
046: /**
047: * @com.intel.drl.spec_ref
048: */
049: public boolean isVarArgs() {
050: return (getModifiers() & ACC_VARARGS) != 0;
051: }
052:
053: /**
054: * @com.intel.drl.spec_ref
055: */
056: public Annotation[][] getParameterAnnotations() {
057: Annotation a[][] = data.getParameterAnnotations();
058: Annotation aa[][] = new Annotation[a.length][];
059: for (int i = 0; i < a.length; i++) {
060: aa[i] = new Annotation[a[i].length];
061: System.arraycopy(a[i], 0, aa[i], 0, a[i].length);
062: }
063: return aa;
064: }
065:
066: /**
067: * @com.intel.drl.spec_ref
068: */
069: public Annotation[] getDeclaredAnnotations() {
070: Annotation a[] = data.getDeclaredAnnotations();
071: Annotation aa[] = new Annotation[a.length];
072: System.arraycopy(a, 0, aa, 0, a.length);
073: return aa;
074: }
075:
076: /**
077: * @com.intel.drl.spec_ref
078: */
079: @SuppressWarnings("unchecked")
080: public <A extends Annotation> A getAnnotation(
081: Class<A> annotationClass) {
082: if (annotationClass == null) {
083: throw new NullPointerException();
084: }
085: for (Annotation aa : data.getDeclaredAnnotations()) {
086: if (aa.annotationType() == annotationClass) {
087:
088: return (A) aa;
089: }
090: }
091: return null;
092: }
093:
094: /**
095: * @com.intel.drl.spec_ref
096: */
097: public Type[] getGenericExceptionTypes()
098: throws GenericSignatureFormatError,
099: TypeNotPresentException,
100: MalformedParameterizedTypeException {
101: if (data.genericExceptionTypes == null) {
102: data.genericExceptionTypes = Parser
103: .getGenericExceptionTypes(this ,
104: VMGenericsAndAnnotations
105: .getSignature(data.vm_member_id));
106: }
107: return (Type[]) data.genericExceptionTypes.clone();
108: }
109:
110: /**
111: * @com.intel.drl.spec_ref
112: */
113: public Type[] getGenericParameterTypes()
114: throws GenericSignatureFormatError,
115: TypeNotPresentException,
116: MalformedParameterizedTypeException {
117: if (data.genericParameterTypes == null) {
118: data.genericParameterTypes = Parser
119: .getGenericParameterTypes(this ,
120: VMGenericsAndAnnotations
121: .getSignature(data.vm_member_id));
122: }
123:
124: return (Type[]) data.genericParameterTypes.clone();
125: }
126:
127: /**
128: * @com.intel.drl.spec_ref
129: */
130: public Type getGenericReturnType()
131: throws GenericSignatureFormatError,
132: TypeNotPresentException,
133: MalformedParameterizedTypeException {
134: if (data.genericReturnType == null) {
135: data.genericReturnType = Parser.getGenericReturnTypeImpl(
136: this , VMGenericsAndAnnotations
137: .getSignature(data.vm_member_id));
138: }
139: return data.genericReturnType;
140: }
141:
142: /**
143: * @com.intel.drl.spec_ref
144: */
145: @SuppressWarnings("unchecked")
146: public TypeVariable<Method>[] getTypeParameters()
147: throws GenericSignatureFormatError {
148: if (data.typeParameters == null) {
149: data.typeParameters = Parser.getTypeParameters(this ,
150: VMGenericsAndAnnotations
151: .getSignature(data.vm_member_id));
152: }
153: return (TypeVariable<Method>[]) data.typeParameters.clone();
154: }
155:
156: /**
157: * @com.intel.drl.spec_ref
158: */
159: public String toGenericString() {
160: StringBuilder sb = new StringBuilder(80);
161: // data initialization
162: if (data.genericParameterTypes == null) {
163: data.genericParameterTypes = Parser
164: .getGenericParameterTypes(this ,
165: VMGenericsAndAnnotations
166: .getSignature(data.vm_member_id));
167: }
168: if (data.genericExceptionTypes == null) {
169: data.genericExceptionTypes = Parser
170: .getGenericExceptionTypes(this ,
171: VMGenericsAndAnnotations
172: .getSignature(data.vm_member_id));
173: }
174: // append modifiers if any
175: int modifier = getModifiers();
176: if (modifier != 0) {
177: sb.append(
178: Modifier.toString(modifier
179: & ~(ACC_BRIDGE + ACC_VARARGS))).append(' ');
180: }
181: // append type parameters
182: if (data.typeParameters != null
183: && data.typeParameters.length > 0) {
184: sb.append('<');
185: for (int i = 0; i < data.typeParameters.length; i++) {
186: appendGenericType(sb, data.typeParameters[i]);
187: if (i < data.typeParameters.length - 1) {
188: sb.append(", ");
189: }
190: }
191: sb.append("> ");
192: }
193: // append return type
194: appendGenericType(sb, getGenericReturnType());
195: sb.append(' ');
196: // append method name
197: appendArrayType(sb, getDeclaringClass());
198: sb.append("." + getName());
199: // append parameters
200: sb.append('(');
201: appendArrayGenericType(sb, data.genericParameterTypes);
202: sb.append(')');
203: // append exeptions if any
204: if (data.genericExceptionTypes.length > 0) {
205: sb.append(" throws ");
206: appendArrayGenericType(sb, data.genericExceptionTypes);
207: }
208: return sb.toString();
209: }
210:
211: /**
212: * @com.intel.drl.spec_ref
213: */
214: public boolean isSynthetic() {
215: return (getModifiers() & ACC_SYNTHETIC) != 0;
216: }
217:
218: /**
219: * @com.intel.drl.spec_ref
220: */
221: public Object getDefaultValue() {
222: return VMGenericsAndAnnotations
223: .getDefaultValue(data.vm_member_id);
224: }
225:
226: /**
227: * cache of the method data
228: */
229: private final MethodData data;
230:
231: /**
232: * Copy constructor
233: *
234: * @param m original method
235: */
236: Method(Method m) {
237: data = m.data;
238: isAccessible = m.isAccessible;
239: }
240:
241: /**
242: * Only VM should call this constructor.
243: * String parameters must be interned.
244: * @api2vm
245: */
246: Method(long id, Class clss, String name, String desc, int m) {
247: data = new MethodData(id, clss, name, desc, m);
248: }
249:
250: /**
251: * Called by VM to obtain this method's handle.
252: *
253: * @return handle for this method
254: * @api2vm
255: */
256: long getId() {
257: return data.vm_member_id;
258: }
259:
260: /**
261: * @com.intel.drl.spec_ref
262: */
263: public boolean equals(Object obj) {
264: if (obj instanceof Method) {
265: Method another = (Method) obj;
266: if (data.vm_member_id == another.data.vm_member_id) {
267: assert getDeclaringClass() == another
268: .getDeclaringClass()
269: && getName() == another.getName()
270: && getReturnType() == another.getReturnType()
271: && Arrays.equals(getParameterTypes(), another
272: .getParameterTypes());
273: return true;
274: }
275: }
276: return false;
277: }
278:
279: /**
280: * @com.intel.drl.spec_ref
281: */
282: public Class<?> getDeclaringClass() {
283: return data.declaringClass;
284: }
285:
286: /**
287: * @com.intel.drl.spec_ref
288: */
289: public Class<?>[] getExceptionTypes() {
290: return (Class[]) data.getExceptionTypes().clone();
291: }
292:
293: /**
294: * @com.intel.drl.spec_ref
295: */
296: public int getModifiers() {
297: return data.modifiers;
298: }
299:
300: /**
301: * @com.intel.drl.spec_ref
302: */
303: public String getName() {
304: return data.name;
305: }
306:
307: /**
308: * @com.intel.drl.spec_ref
309: */
310: public Class<?>[] getParameterTypes() {
311: return (Class[]) data.getParameterTypes().clone();
312: }
313:
314: /**
315: * @com.intel.drl.spec_ref
316: */
317: public Class<?> getReturnType() {
318: return data.getReturnType();
319: }
320:
321: /**
322: * @com.intel.drl.spec_ref
323: */
324: public int hashCode() {
325: return getDeclaringClass().getName().hashCode()
326: ^ getName().hashCode();
327: }
328:
329: /**
330: * @com.intel.drl.spec_ref
331: */
332: public Object invoke(Object obj, Object... args)
333: throws IllegalAccessException, IllegalArgumentException,
334: InvocationTargetException {
335:
336: obj = checkObject(getDeclaringClass(), getModifiers(), obj);
337:
338: // check parameter validity
339: checkInvokationArguments(data.getParameterTypes(), args);
340:
341: if (!isAccessible) {
342: reflectExporter.checkMemberAccess(
343: VMStack.getCallerClass(0), getDeclaringClass(),
344: obj == null ? getDeclaringClass() : obj.getClass(),
345: getModifiers());
346: }
347: return VMReflection.invokeMethod(data.vm_member_id, obj, args);
348: }
349:
350: /**
351: * @com.intel.drl.spec_ref
352: */
353: public String toString() {
354: StringBuilder sb = new StringBuilder();
355: // append modifiers if any
356: int modifier = getModifiers();
357: if (modifier != 0) {
358: // BRIDGE & VARARGS recognized incorrectly
359: final int MASK = ~(ACC_BRIDGE + ACC_VARARGS);
360: sb.append(Modifier.toString(modifier & MASK)).append(' ');
361: }
362: // append return type
363: appendArrayType(sb, getReturnType());
364: sb.append(' ');
365: // append full method name
366: sb.append(getDeclaringClass().getName()).append('.').append(
367: getName());
368: // append parameters
369: sb.append('(');
370: appendArrayType(sb, data.getParameterTypes());
371: sb.append(')');
372: // append exeptions if any
373: Class[] exn = data.getExceptionTypes();
374: if (exn.length > 0) {
375: sb.append(" throws ");
376: appendSimpleType(sb, exn);
377: }
378: return sb.toString();
379: }
380:
381: /* NON API SECTION */
382:
383: /**
384: * This method is required by serialization mechanism.
385: *
386: * @return the signature of the method
387: */
388: String getSignature() {
389: return data.descriptor;
390: }
391:
392: /**
393: * Keeps an information about this method
394: */
395: private class MethodData {
396:
397: /**
398: * method handle which is used to retrieve all necessary information
399: * about this method object
400: */
401: final long vm_member_id;
402:
403: Annotation[] declaredAnnotations;
404:
405: final Class<?> declaringClass;
406:
407: private Class<?>[] exceptionTypes;
408:
409: Type[] genericExceptionTypes;
410:
411: Type[] genericParameterTypes;
412:
413: Type genericReturnType;
414:
415: String methSignature;
416:
417: final int modifiers;
418:
419: final String name;
420:
421: final String descriptor;
422:
423: /**
424: * declared method annotations
425: */
426: Annotation[][] parameterAnnotations;
427:
428: /**
429: * method parameters
430: */
431: Class<?>[] parameterTypes;
432:
433: /**
434: * method return type
435: */
436: private Class<?> returnType;
437:
438: /**
439: * method type parameters
440: */
441: TypeVariable<Method>[] typeParameters;
442:
443: /**
444: * @param obj method handler
445: */
446: public MethodData(long vm_id, Class clss, String name,
447: String desc, int mods) {
448: vm_member_id = vm_id;
449: declaringClass = clss;
450: this .name = name;
451: modifiers = mods;
452: descriptor = desc;
453: }
454:
455: public Annotation[] getDeclaredAnnotations() {
456: if (declaredAnnotations == null) {
457: declaredAnnotations = VMGenericsAndAnnotations
458: .getDeclaredAnnotations(vm_member_id);
459: }
460: return declaredAnnotations;
461: }
462:
463: /**
464: * initializes exeptions
465: */
466: public Class<?>[] getExceptionTypes() {
467: if (exceptionTypes == null) {
468: exceptionTypes = VMReflection
469: .getExceptionTypes(vm_member_id);
470: }
471: return exceptionTypes;
472: }
473:
474: public Annotation[][] getParameterAnnotations() {
475: if (parameterAnnotations == null) {
476: parameterAnnotations = VMGenericsAndAnnotations
477: .getParameterAnnotations(vm_member_id);
478: }
479: return parameterAnnotations;
480: }
481:
482: /**
483: * initializes parameters
484: */
485: public Class[] getParameterTypes() {
486: if (parameterTypes == null) {
487: parameterTypes = VMReflection
488: .getParameterTypes(vm_member_id);
489: }
490: return parameterTypes;
491: }
492:
493: /**
494: * initializes return type
495: */
496: public Class<?> getReturnType() {
497: if (returnType == null) {
498: returnType = VMReflection
499: .getMethodReturnType(vm_member_id);
500: }
501: return returnType;
502: }
503: }
504: }
|