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