0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package java.lang;
0019:
0020: import static org.apache.harmony.vm.ClassFormat.ACC_ANNOTATION;
0021: import static org.apache.harmony.vm.ClassFormat.ACC_ENUM;
0022: import static org.apache.harmony.vm.ClassFormat.ACC_INTERFACE;
0023: import static org.apache.harmony.vm.ClassFormat.ACC_SYNTHETIC;
0024:
0025: import java.io.InputStream;
0026: import java.io.Serializable;
0027: import java.lang.annotation.Annotation;
0028: import java.lang.annotation.Inherited;
0029: import java.lang.ref.SoftReference;
0030: import java.lang.reflect.AnnotatedElement;
0031: import java.lang.reflect.Constructor;
0032: import java.lang.reflect.Field;
0033: import java.lang.reflect.GenericDeclaration;
0034: import java.lang.reflect.GenericSignatureFormatError;
0035: import java.lang.reflect.InvocationTargetException;
0036: import java.lang.reflect.MalformedParameterizedTypeException;
0037: import java.lang.reflect.Member;
0038: import java.lang.reflect.Method;
0039: import java.lang.reflect.Modifier;
0040: import java.lang.reflect.Type;
0041: import java.lang.reflect.TypeVariable;
0042: import java.net.URL;
0043: import java.security.AccessController;
0044: import java.security.AllPermission;
0045: import java.security.Permissions;
0046: import java.security.PrivilegedAction;
0047: import java.security.ProtectionDomain;
0048: import java.util.ArrayList;
0049: import java.util.Collection;
0050: import java.util.LinkedHashSet;
0051: import java.util.Map;
0052:
0053: import org.apache.harmony.lang.RuntimePermissionCollection;
0054: import org.apache.harmony.lang.reflect.Reflection;
0055: import org.apache.harmony.lang.reflect.parser.Parser;
0056: import org.apache.harmony.vm.VMGenericsAndAnnotations;
0057: import org.apache.harmony.vm.VMStack;
0058:
0059: /**
0060: * @com.intel.drl.spec_ref
0061: *
0062: * @author Evgueni Brevnov, Serguei S. Zapreyev, Alexey V. Varlamov
0063: * @version $Revision: 1.1.2.2.4.5 $
0064: */
0065: //public final class Class implements Serializable {
0066: public final class Class<T> implements Serializable, AnnotatedElement,
0067: GenericDeclaration, Type {
0068:
0069: private static final long serialVersionUID = 3206093459760846163L;
0070:
0071: static ProtectionDomain systemDomain;
0072:
0073: private transient ProtectionDomain domain;
0074:
0075: /** It is required for synchronization in newInstance method. */
0076: private boolean isDefaultConstructorInitialized;
0077:
0078: // TODO make it soft reference
0079: transient ReflectionData reflectionData;
0080: transient SoftReference<GACache> softCache;
0081:
0082: private GACache getCache() {
0083: GACache cache = null;
0084: if (softCache != null) {
0085: cache = softCache.get();
0086: }
0087: if (cache == null) {
0088: softCache = new SoftReference<GACache>(
0089: cache = new GACache());
0090: }
0091: return cache;
0092: }
0093:
0094: /**
0095: * Only VM can instantiate this class.
0096: */
0097: private Class() {
0098: }
0099:
0100: /**
0101: * @com.intel.drl.spec_ref
0102: */
0103: public static Class<?> forName(String name)
0104: throws ClassNotFoundException {
0105: return forName(name, true, VMClassRegistry
0106: .getClassLoader(VMStack.getCallerClass(0)));
0107: }
0108:
0109: /**
0110: * @com.intel.drl.spec_ref
0111: */
0112: public static Class<?> forName(String name, boolean initialize,
0113: ClassLoader classLoader) throws ClassNotFoundException {
0114: if (name == null) {
0115: throw new NullPointerException();
0116: }
0117: if (name.indexOf("/") != -1) {
0118: throw new ClassNotFoundException(name);
0119: }
0120:
0121: Class clazz = null;
0122:
0123: if (classLoader == null) {
0124: SecurityManager sc = System.getSecurityManager();
0125: if (sc != null
0126: && VMClassRegistry.getClassLoader(VMStack
0127: .getCallerClass(0)) != null) {
0128: sc
0129: .checkPermission(RuntimePermissionCollection.GET_CLASS_LOADER_PERMISSION);
0130: }
0131: clazz = VMClassRegistry.loadBootstrapClass(name);
0132: } else {
0133: int dims = 0;
0134: int len = name.length();
0135: while (dims < len && name.charAt(dims) == '[')
0136: dims++;
0137: if (dims > 0 && len > dims + 1 && name.charAt(dims) == 'L'
0138: && name.endsWith(";")) {
0139: /*
0140: * an array of a reference type is requested.
0141: * do not care of arrays of primitives as
0142: * they are perfectly loaded by bootstrap classloader.
0143: */
0144: try {
0145: clazz = classLoader.loadClass(name.substring(
0146: dims + 1, len - 1));
0147: } catch (ClassNotFoundException ignore) {
0148: }
0149: if (clazz != null) {
0150: clazz = VMClassRegistry.loadArray(clazz, dims);
0151: }
0152: } else {
0153: clazz = classLoader.loadClass(name);
0154: }
0155: }
0156: if (clazz == null) {
0157: throw new ClassNotFoundException(name);
0158: }
0159: if (classLoader != null) {
0160: // Although class loader may have had a chance to register
0161: // itself as initiating for requested class, there may occur
0162: // a classloader which overloads loadClass method (though it is
0163: // not recommended by J2SE specification).
0164: // Try to register initiating loader for clazz from here again
0165: classLoader.registerInitiatedClass(clazz);
0166: }
0167: if (initialize) {
0168: VMClassRegistry.initializeClass(clazz);
0169: } else {
0170: VMClassRegistry.linkClass(clazz);
0171: }
0172: return clazz;
0173: }
0174:
0175: /**
0176: * package private to access from the java.lang.ClassLoader class.
0177: */
0178: static volatile boolean disableAssertions = VMExecutionEngine
0179: .getAssertionStatus(null, false, 0) <= 0;
0180:
0181: /**
0182: * @com.intel.drl.spec_ref
0183: */
0184: public boolean desiredAssertionStatus() {
0185: if (disableAssertions) {
0186: return false;
0187: }
0188:
0189: ClassLoader loader = getClassLoaderImpl();
0190: if (loader == null) {
0191: // system class, status is controlled via cmdline only
0192: return VMExecutionEngine.getAssertionStatus(this , true, 0) > 0;
0193: }
0194:
0195: // First check exact class name
0196: String name = null;
0197: Map<String, Boolean> m = loader.classAssertionStatus;
0198: if (m != null && m.size() != 0) {
0199: name = getTopLevelClassName();
0200: Boolean status = m.get(name);
0201: if (status != null) {
0202: return status.booleanValue();
0203: }
0204: }
0205: if (!loader.clearAssertionStatus) {
0206: int systemStatus = VMExecutionEngine.getAssertionStatus(
0207: this , false, 0);
0208: if (systemStatus != 0) {
0209: return systemStatus > 0;
0210: }
0211: }
0212:
0213: // Next try (super)packages name(s) recursively
0214: m = loader.packageAssertionStatus;
0215: if (m != null && m.size() != 0) {
0216: if (name == null) {
0217: name = getName();
0218: }
0219: name = getParentName(name);
0220: // if this class is in the default package,
0221: // it is checked in the 1st iteration
0222: do {
0223: Boolean status = m.get(name);
0224: if (status != null) {
0225: return status.booleanValue();
0226: }
0227: } while ((name = getParentName(name)).length() > 0);
0228: }
0229: if (!loader.clearAssertionStatus) {
0230: int systemStatus = VMExecutionEngine.getAssertionStatus(
0231: this , true, loader.defaultAssertionStatus);
0232: if (systemStatus != 0) {
0233: return systemStatus > 0;
0234: }
0235: }
0236:
0237: // Finally check the default status
0238: return loader.defaultAssertionStatus > 0;
0239: }
0240:
0241: /**
0242: * @com.intel.drl.spec_ref
0243: *
0244: * Note: We don't check member access permission for each super class.
0245: * Java 1.5 API specification doesn't require this check.
0246: */
0247: public Class[] getClasses() {
0248: if (reflectionData == null) {
0249: initReflectionData();
0250: }
0251: checkMemberAccess(Member.PUBLIC);
0252: Class clss = this ;
0253: ArrayList<Class> classes = null;
0254: while (clss != null) {
0255: Class[] declared = VMClassRegistry.getDeclaredClasses(clss);
0256: if (declared.length != 0) {
0257: if (classes == null) {
0258: classes = new ArrayList<Class>();
0259: }
0260: for (Class c : declared) {
0261: if (Modifier.isPublic(c.getModifiers())) {
0262: classes.add(c);
0263: }
0264: }
0265: }
0266: clss = clss.getSuperclass();
0267: }
0268: if (classes == null) {
0269: return new Class[0];
0270: } else {
0271: return classes.toArray(new Class[classes.size()]);
0272: }
0273: }
0274:
0275: /**
0276: * @com.intel.drl.spec_ref
0277: */
0278: public ClassLoader getClassLoader() {
0279: ClassLoader loader = getClassLoaderImpl();
0280: SecurityManager sc = System.getSecurityManager();
0281: if (sc != null) {
0282: ClassLoader callerLoader = VMClassRegistry
0283: .getClassLoader(VMStack.getCallerClass(0));
0284: if (callerLoader != null
0285: && !callerLoader.isSameOrAncestor(loader)) {
0286: sc
0287: .checkPermission(RuntimePermissionCollection.GET_CLASS_LOADER_PERMISSION);
0288: }
0289: }
0290: return loader;
0291: }
0292:
0293: /**
0294: * @com.intel.drl.spec_ref
0295: */
0296: public Class<?> getComponentType() {
0297: if (!isArray())
0298: return null;
0299: return VMClassRegistry.getComponentType(this );
0300: }
0301:
0302: /**
0303: * @com.intel.drl.spec_ref
0304: */
0305: public Constructor<T> getConstructor(Class... argumentTypes)
0306: throws NoSuchMethodException {
0307: if (reflectionData == null) {
0308: initReflectionData();
0309: }
0310: checkMemberAccess(Member.PUBLIC);
0311: Constructor<T> ctors[] = reflectionData.getPublicConstructors();
0312: for (int i = 0; i < ctors.length; i++) {
0313: Constructor<T> c = ctors[i];
0314: try {
0315: if (isTypeMatches(argumentTypes, c.getParameterTypes())) {
0316: return Reflection.copyConstructor(c);
0317: }
0318: } catch (LinkageError ignore) {
0319: }
0320: }
0321: throw new NoSuchMethodException(getName()
0322: + printMethodSignature(argumentTypes));
0323:
0324: }
0325:
0326: /**
0327: * @com.intel.drl.spec_ref
0328: */
0329: public Constructor[] getConstructors() {
0330: if (reflectionData == null) {
0331: initReflectionData();
0332: }
0333: checkMemberAccess(Member.PUBLIC);
0334: return Reflection.copyConstructors(reflectionData
0335: .getPublicConstructors());
0336: }
0337:
0338: /**
0339: * @com.intel.drl.spec_ref
0340: */
0341: public Class[] getDeclaredClasses() {
0342: if (reflectionData == null) {
0343: initReflectionData();
0344: }
0345: checkMemberAccess(Member.DECLARED);
0346: return VMClassRegistry.getDeclaredClasses(this );
0347: }
0348:
0349: /**
0350: * @com.intel.drl.spec_ref
0351: */
0352: public Constructor<T> getDeclaredConstructor(Class... argumentTypes)
0353: throws NoSuchMethodException {
0354: if (reflectionData == null) {
0355: initReflectionData();
0356: }
0357: checkMemberAccess(Member.DECLARED);
0358: return Reflection
0359: .copyConstructor(getDeclaredConstructorInternal(argumentTypes));
0360: }
0361:
0362: /**
0363: * @com.intel.drl.spec_ref
0364: */
0365: public Constructor[] getDeclaredConstructors() {
0366: if (reflectionData == null) {
0367: initReflectionData();
0368: }
0369: checkMemberAccess(Member.DECLARED);
0370: if (reflectionData.declaredConstructors == null) {
0371: reflectionData.initDeclaredConstructors();
0372: }
0373: return Reflection
0374: .copyConstructors(reflectionData.declaredConstructors);
0375: }
0376:
0377: /**
0378: * @com.intel.drl.spec_ref
0379: */
0380: public Field getDeclaredField(String fieldName)
0381: throws NoSuchFieldException {
0382: if (reflectionData == null) {
0383: initReflectionData();
0384: }
0385: checkMemberAccess(Member.DECLARED);
0386: if (reflectionData.declaredFields == null) {
0387: reflectionData.initDeclaredFields();
0388: }
0389: for (int i = 0; i < reflectionData.declaredFields.length; i++) {
0390: Field f = reflectionData.declaredFields[i];
0391: if (fieldName.equals(f.getName())) {
0392: return Reflection.copyField(f);
0393: }
0394: }
0395: throw new NoSuchFieldException(fieldName.toString());
0396: }
0397:
0398: /**
0399: * @com.intel.drl.spec_ref
0400: */
0401: public Field[] getDeclaredFields() {
0402: if (reflectionData == null) {
0403: initReflectionData();
0404: }
0405: checkMemberAccess(Member.DECLARED);
0406: if (reflectionData.declaredFields == null) {
0407: reflectionData.initDeclaredFields();
0408: }
0409: return Reflection.copyFields(reflectionData.declaredFields);
0410: }
0411:
0412: /**
0413: * @com.intel.drl.spec_ref
0414: */
0415: public Method getDeclaredMethod(String methodName,
0416: Class... argumentTypes) throws NoSuchMethodException {
0417: if (reflectionData == null) {
0418: initReflectionData();
0419: }
0420: checkMemberAccess(Member.DECLARED);
0421: if (reflectionData.declaredMethods == null) {
0422: reflectionData.initDeclaredMethods();
0423: }
0424: return Reflection.copyMethod(findMatchingMethod(
0425: reflectionData.declaredMethods, methodName,
0426: argumentTypes));
0427: }
0428:
0429: /**
0430: * @com.intel.drl.spec_ref
0431: */
0432: public Method[] getDeclaredMethods() {
0433: if (reflectionData == null) {
0434: initReflectionData();
0435: }
0436: checkMemberAccess(Member.DECLARED);
0437: if (reflectionData.declaredMethods == null) {
0438: reflectionData.initDeclaredMethods();
0439: }
0440: return Reflection.copyMethods(reflectionData.declaredMethods);
0441: }
0442:
0443: /**
0444: * @com.intel.drl.spec_ref
0445: */
0446: public Class<?> getDeclaringClass() {
0447: return VMClassRegistry.getDeclaringClass(this );
0448: }
0449:
0450: /**
0451: * @com.intel.drl.spec_ref
0452: */
0453: public Field getField(String fieldName) throws NoSuchFieldException {
0454: if (reflectionData == null) {
0455: initReflectionData();
0456: }
0457: checkMemberAccess(Member.PUBLIC);
0458: Field[] ff = reflectionData.getPublicFields();
0459: for (Field f : ff) {
0460: if (fieldName.equals(f.getName())) {
0461: return Reflection.copyField(f);
0462: }
0463: }
0464: throw new NoSuchFieldException(fieldName.toString());
0465: }
0466:
0467: /**
0468: * @com.intel.drl.spec_ref
0469: */
0470: public Field[] getFields() {
0471: if (reflectionData == null) {
0472: initReflectionData();
0473: }
0474: checkMemberAccess(Member.PUBLIC);
0475: return Reflection.copyFields(reflectionData.getPublicFields());
0476: }
0477:
0478: /**
0479: * @com.intel.drl.spec_ref
0480: */
0481: public Class[] getInterfaces() {
0482: return VMClassRegistry.getInterfaces(this );
0483: }
0484:
0485: /**
0486: * @com.intel.drl.spec_ref
0487: */
0488: public Method getMethod(String methodName, Class... argumentTypes)
0489: throws NoSuchMethodException {
0490: if (reflectionData == null) {
0491: initReflectionData();
0492: }
0493: checkMemberAccess(Member.PUBLIC);
0494: return Reflection.copyMethod(findMatchingMethod(reflectionData
0495: .getPublicMethods(), methodName, argumentTypes));
0496: }
0497:
0498: /**
0499: * @com.intel.drl.spec_ref
0500: */
0501: public Method[] getMethods() {
0502: if (reflectionData == null) {
0503: initReflectionData();
0504: }
0505: checkMemberAccess(Member.PUBLIC);
0506: return Reflection
0507: .copyMethods(reflectionData.getPublicMethods());
0508: }
0509:
0510: /**
0511: * @com.intel.drl.spec_ref
0512: */
0513: public int getModifiers() {
0514: if (reflectionData == null) {
0515: initReflectionData();
0516: }
0517: int mods = reflectionData.modifiers;
0518: if (mods == -1) {
0519: mods = reflectionData.modifiers = VMClassRegistry
0520: .getModifiers(this );
0521: }
0522: return mods;
0523: }
0524:
0525: /**
0526: * @com.intel.drl.spec_ref
0527: */
0528: public String getName() {
0529: if (reflectionData == null) {
0530: initReflectionData();
0531: }
0532: return reflectionData.name;
0533: }
0534:
0535: /**
0536: * @com.intel.drl.spec_ref
0537: */
0538: public Package getPackage() {
0539: ClassLoader classLoader = getClassLoaderImpl();
0540: return classLoader == null ? ClassLoader.BootstrapLoader
0541: .getPackage(getPackageName()) : classLoader
0542: .getPackage(getPackageName());
0543: }
0544:
0545: /**
0546: * @com.intel.drl.spec_ref
0547: */
0548: public ProtectionDomain getProtectionDomain() {
0549: SecurityManager sc = System.getSecurityManager();
0550: if (sc != null) {
0551: sc
0552: .checkPermission(RuntimePermissionCollection.GET_PROTECTION_DOMAIN_PERMISSION);
0553: }
0554: if (domain == null) {
0555: if (systemDomain == null) {
0556: Permissions allPermissions = new Permissions();
0557: allPermissions.add(new AllPermission());
0558: systemDomain = new ProtectionDomain(null,
0559: allPermissions);
0560: }
0561: return systemDomain;
0562: }
0563: return domain;
0564: }
0565:
0566: /**
0567: * @com.intel.drl.spec_ref
0568: */
0569: public URL getResource(String resource) {
0570: resource = getAbsoluteResource(resource);
0571: ClassLoader classLoader = getClassLoaderImpl();
0572: return classLoader == null ? ClassLoader
0573: .getSystemResource(resource) : classLoader
0574: .getResource(resource);
0575: }
0576:
0577: /**
0578: * @com.intel.drl.spec_ref
0579: */
0580: public InputStream getResourceAsStream(String resource) {
0581: resource = getAbsoluteResource(resource);
0582: ClassLoader classLoader = getClassLoaderImpl();
0583: return classLoader == null ? ClassLoader
0584: .getSystemResourceAsStream(resource) : classLoader
0585: .getResourceAsStream(resource);
0586: }
0587:
0588: /**
0589: * @com.intel.drl.spec_ref
0590: */
0591: public Object[] getSigners() {
0592: try {
0593: Object[] signers = (Object[]) getClassLoaderImpl().classSigners
0594: .get(getName());
0595: return (Object[]) signers.clone();
0596: } catch (NullPointerException e) {
0597: }
0598: try {
0599: return (Object[]) domain.getCodeSource().getCertificates()
0600: .clone();
0601: } catch (NullPointerException e) {
0602: }
0603: return null;
0604: }
0605:
0606: /**
0607: * @com.intel.drl.spec_ref
0608: */
0609: public Class<? super T> getSuperclass() {
0610: return VMClassRegistry.getSuperclass(this );
0611: }
0612:
0613: /**
0614: * @com.intel.drl.spec_ref
0615: */
0616: public boolean isArray() {
0617: if (reflectionData == null) {
0618: initReflectionData();
0619: }
0620: return reflectionData.isArray;
0621: }
0622:
0623: /**
0624: * @com.intel.drl.spec_ref
0625: */
0626: public boolean isAssignableFrom(Class<?> clazz) {
0627: return VMClassRegistry.isAssignableFrom(this , clazz);
0628: }
0629:
0630: /**
0631: * @com.intel.drl.spec_ref
0632: */
0633: public boolean isInstance(Object obj) {
0634: return VMClassRegistry.isInstance(this , obj);
0635: }
0636:
0637: /**
0638: * @com.intel.drl.spec_ref
0639: */
0640: public boolean isInterface() {
0641: return (getModifiers() & ACC_INTERFACE) != 0;
0642: }
0643:
0644: /**
0645: * @com.intel.drl.spec_ref
0646: */
0647: public boolean isPrimitive() {
0648: return VMClassRegistry.isPrimitive(this );
0649: }
0650:
0651: /**
0652: * @com.intel.drl.spec_ref
0653: */
0654: public T newInstance() throws InstantiationException,
0655: IllegalAccessException {
0656: T newInstance = null;
0657: if (reflectionData == null) {
0658: initReflectionData();
0659: }
0660: SecurityManager sc = System.getSecurityManager();
0661: if (sc != null) {
0662: sc.checkMemberAccess(this , Member.PUBLIC);
0663: sc.checkPackageAccess(reflectionData.packageName);
0664: }
0665:
0666: /*
0667: * HARMONY-1930: The synchronization issue is possible here.
0668: *
0669: * The issues is caused by fact that:
0670: * - first thread starts defaultConstructor initialization, including
0671: * setting "isAccessible" flag to "true" for Constrcutor object
0672: * - another thread bypasses initialization and calls "newInstance"
0673: * for defaultConstructor (while isAccessible is "false" yet)
0674: * - so, for this "another" thread the Constructor.newInstance checks
0675: * the access rights by mistake and IllegalAccessException happens
0676: */
0677: while (!isDefaultConstructorInitialized) {
0678: synchronized (reflectionData) {
0679: if (isDefaultConstructorInitialized) {
0680: break; // non-first threads can be here - nothing to do
0681: }
0682:
0683: // only first thread can reach this point & do initialization
0684: try {
0685: reflectionData.initDefaultConstructor();
0686: } catch (NoSuchMethodException e) {
0687: throw new InstantiationException(e.getMessage()
0688: + " method not found");
0689: }
0690: final Constructor<T> c = reflectionData.defaultConstructor;
0691:
0692: try {
0693: AccessController
0694: .doPrivileged(new PrivilegedAction<Object>() {
0695: public Object run() {
0696: c.setAccessible(true);
0697: return null;
0698: }
0699: });
0700: } catch (SecurityException e) {
0701: // can't change accessibilty of the default constructor
0702: IllegalAccessException ex = new IllegalAccessException();
0703: ex.initCause(e);
0704: throw ex;
0705: }
0706:
0707: // default constructor is initialized, access flag is set
0708: isDefaultConstructorInitialized = true;
0709: break;
0710: }
0711: }
0712:
0713: // initialization is done, threads may work from here in any order
0714: Reflection.checkMemberAccess(VMStack.getCallerClass(0),
0715: reflectionData.defaultConstructor.getDeclaringClass(),
0716: reflectionData.defaultConstructor.getDeclaringClass(),
0717: reflectionData.defaultConstructor.getModifiers());
0718:
0719: try {
0720: newInstance = reflectionData.defaultConstructor
0721: .newInstance();
0722: } catch (InvocationTargetException e) {
0723: System.rethrow(e.getCause());
0724: }
0725: return newInstance;
0726: }
0727:
0728: /**
0729: * @com.intel.drl.spec_ref
0730: */
0731: public String toString() {
0732: return isPrimitive() ? getName()
0733: : (isInterface() ? "interface " : "class ") + getName();
0734: }
0735:
0736: /*
0737: * NON API SECTION
0738: */
0739:
0740: /**
0741: * Answers whether the arrays are equal
0742: */
0743: static boolean isTypeMatches(Class[] t1, Class[] t2) {
0744: if (t1 == null) {
0745: return t2 == null || t2.length == 0;
0746: }
0747: if (t2 == null) {
0748: return t1 == null || t1.length == 0;
0749: }
0750: if (t1.length != t2.length) {
0751: return false;
0752: }
0753: for (int i = 0; i < t2.length; i++) {
0754: if (t1[i] != t2[i]) {
0755: return false;
0756: }
0757: }
0758: return true;
0759: }
0760:
0761: /**
0762: * This is not time consume operation so we can do syncrhronization on this
0763: * class object. Note, this method has package private visibility in order
0764: * to increase performance.
0765: */
0766: synchronized void initReflectionData() {
0767: if (reflectionData == null) {
0768: reflectionData = new ReflectionData();
0769: }
0770: }
0771:
0772: String getPackageName() {
0773: if (reflectionData == null) {
0774: initReflectionData();
0775: }
0776: return reflectionData.packageName;
0777: }
0778:
0779: void setProtectionDomain(ProtectionDomain protectionDomain) {
0780: domain = protectionDomain;
0781: }
0782:
0783: static private Method findMatchingMethod(Method[] methods,
0784: String methodName, Class[] argumentTypes)
0785: throws NoSuchMethodException {
0786: Method matcher = null;
0787: for (int i = 0; i < methods.length; i++) {
0788: Method m = methods[i];
0789: if (matcher != null
0790: && matcher.getDeclaringClass() != m
0791: .getDeclaringClass()) {
0792: return matcher;
0793: }
0794: try {
0795: if (methodName.equals(m.getName())
0796: && isTypeMatches(argumentTypes, m
0797: .getParameterTypes())
0798: && (matcher == null || matcher.getReturnType()
0799: .isAssignableFrom(m.getReturnType()))) {
0800: matcher = m;
0801: }
0802: } catch (LinkageError ignore) {
0803: }
0804: }
0805: if (matcher == null) {
0806: throw new NoSuchMethodException(methodName.toString()
0807: + printMethodSignature(argumentTypes));
0808: }
0809: return matcher;
0810: }
0811:
0812: static private String getParentName(String name) {
0813: int dotPosition = name.lastIndexOf('.');
0814: return dotPosition == -1 ? "" : name.substring(0, dotPosition);
0815: }
0816:
0817: static private String printMethodSignature(Class[] types) {
0818: StringBuffer sb = new StringBuffer("(");
0819: if (types != null && types.length > 0) {
0820: sb.append(types[0] != null ? types[0].getName() : "null");
0821: for (int i = 1; i < types.length; i++) {
0822: sb.append(", ");
0823: sb.append(types[i] != null ? types[i].getName()
0824: : "null");
0825: }
0826: }
0827: sb.append(")");
0828: return sb.toString();
0829: }
0830:
0831: private void checkMemberAccess(int accessType) {
0832: SecurityManager sc = System.getSecurityManager();
0833: if (sc != null) {
0834: sc.checkMemberAccess(this , accessType);
0835: sc.checkPackageAccess(reflectionData.packageName);
0836: }
0837: }
0838:
0839: private String getAbsoluteResource(String resource) {
0840: if (resource.startsWith("/")) {
0841: return resource.substring(1);
0842: }
0843: String pkgName = getPackageName();
0844: if (pkgName.length() > 0) {
0845: resource = pkgName.replace('.', '/') + '/' + resource;
0846: }
0847: return resource;
0848: }
0849:
0850: private Constructor<T> getDeclaredConstructorInternal(
0851: Class[] argumentTypes) throws NoSuchMethodException {
0852: if (reflectionData.declaredConstructors == null) {
0853: reflectionData.initDeclaredConstructors();
0854: }
0855: for (int i = 0; i < reflectionData.declaredConstructors.length; i++) {
0856: Constructor<T> c = reflectionData.declaredConstructors[i];
0857: if (isTypeMatches(argumentTypes, c.getParameterTypes())) {
0858: return c;
0859: }
0860: }
0861: throw new NoSuchMethodException(getName()
0862: + printMethodSignature(argumentTypes));
0863: }
0864:
0865: private String getTopLevelClassName() {
0866: Class declaringClass = getDeclaringClass();
0867: return declaringClass == null ? getName() : declaringClass
0868: .getTopLevelClassName();
0869: }
0870:
0871: /* VMI SPECIFIC PART*/
0872:
0873: final ClassLoader getClassLoaderImpl() {
0874: assert (VMClassRegistry.getClassLoader0(this ) == definingLoader);
0875: return definingLoader;
0876: }
0877:
0878: static final Class[] getStackClasses(int maxDepth,
0879: boolean stopAtPrivileged) {
0880: return VMStack.getClasses(maxDepth, stopAtPrivileged);
0881: }
0882:
0883: /* END OF VMI SPECIFIC PART */
0884:
0885: /**
0886: *
0887: * @com.intel.drl.spec_ref
0888: *
0889: **/
0890: public Annotation[] getDeclaredAnnotations() {
0891: Annotation[] declared = getCache().getDeclaredAnnotations();
0892: Annotation aa[] = new Annotation[declared.length];
0893: System.arraycopy(declared, 0, aa, 0, declared.length);
0894: return aa;
0895: }
0896:
0897: /**
0898: *
0899: * @com.intel.drl.spec_ref
0900: *
0901: **/
0902: public Annotation[] getAnnotations() {
0903: Annotation[] all = getCache().getAllAnnotations();
0904: Annotation aa[] = new Annotation[all.length];
0905: System.arraycopy(all, 0, aa, 0, all.length);
0906: return aa;
0907: }
0908:
0909: /**
0910: *
0911: * @com.intel.drl.spec_ref
0912: *
0913: **/
0914: @SuppressWarnings("unchecked")
0915: public <A extends Annotation> A getAnnotation(
0916: Class<A> annotationClass) {
0917: if (annotationClass == null) {
0918: throw new NullPointerException();
0919: }
0920: for (Annotation aa : getCache().getAllAnnotations()) {
0921: if (annotationClass == aa.annotationType()) {
0922: return (A) aa;
0923: }
0924: }
0925: return null;
0926: }
0927:
0928: /**
0929: *
0930: * @com.intel.drl.spec_ref
0931: *
0932: **/
0933: public boolean isAnnotationPresent(
0934: Class<? extends Annotation> annotationClass) {
0935: if (annotationClass == null) {
0936: throw new NullPointerException();
0937: }
0938: for (Annotation aa : getCache().getAllAnnotations()) {
0939: if (annotationClass == aa.annotationType()) {
0940: return true;
0941: }
0942: }
0943: return false;
0944: }
0945:
0946: /**
0947: *
0948: * @com.intel.drl.spec_ref
0949: *
0950: **/
0951: @SuppressWarnings("unchecked")
0952: public T[] getEnumConstants() {
0953: if (isEnum()) {
0954: try {
0955: final Method values = getMethod("values");
0956: AccessController.doPrivileged(new PrivilegedAction() {
0957: public Object run() {
0958: values.setAccessible(true);
0959: return null;
0960: }
0961: });
0962: return (T[]) values.invoke(null);
0963: } catch (Exception ignore) {
0964: }
0965: }
0966: return null;
0967: }
0968:
0969: /**
0970: *
0971: * @com.intel.drl.spec_ref
0972: *
0973: **/
0974: public boolean isEnum() {
0975: // check for superclass is needed for compatibility
0976: // otherwise there are false positives on anonymous element classes
0977: return ((getModifiers() & ACC_ENUM) != 0 && getSuperclass() == Enum.class);
0978: }
0979:
0980: /**
0981: *
0982: * @com.intel.drl.spec_ref
0983: *
0984: **/
0985: public boolean isAnnotation() {
0986: return (getModifiers() & ACC_ANNOTATION) != 0;
0987: }
0988:
0989: /**
0990: *
0991: * @com.intel.drl.spec_ref
0992: *
0993: **/
0994: @SuppressWarnings("unchecked")
0995: public <U> Class<? extends U> asSubclass(Class<U> clazz)
0996: throws ClassCastException {
0997: if (!VMClassRegistry.isAssignableFrom(clazz, this )) {
0998: throw new ClassCastException(toString());
0999: }
1000:
1001: return (Class<? extends U>) this ;
1002: }
1003:
1004: /**
1005: *
1006: * @com.intel.drl.spec_ref
1007: *
1008: **/
1009: @SuppressWarnings("unchecked")
1010: public T cast(Object obj) throws ClassCastException {
1011: if (obj != null && !VMClassRegistry.isInstance(this , obj)) {
1012: throw new ClassCastException(obj.getClass().toString());
1013: }
1014: return (T) obj;
1015: }
1016:
1017: /**
1018: *
1019: * @com.intel.drl.spec_ref
1020: *
1021: **/
1022: public TypeVariable<Class<T>>[] getTypeParameters()
1023: throws GenericSignatureFormatError {
1024: return (TypeVariable<Class<T>>[]) getCache()
1025: .getTypeParameters().clone();
1026: }
1027:
1028: /**
1029: *
1030: * @com.intel.drl.spec_ref
1031: *
1032: **/
1033: public Method getEnclosingMethod() {
1034: Member m = VMClassRegistry.getEnclosingMember(this ); // see VMClassRegistry.getEnclosingMember() spec
1035: return m instanceof Method ? (Method) m : null;
1036: }
1037:
1038: /**
1039: *
1040: * @com.intel.drl.spec_ref
1041: *
1042: **/
1043: public Constructor<?> getEnclosingConstructor() {
1044: Member m = VMClassRegistry.getEnclosingMember(this ); // see VMClassRegistry.getEnclosingMember() spec
1045: return m instanceof Constructor ? (Constructor<?>) m : null;
1046: }
1047:
1048: /**
1049: *
1050: * @com.intel.drl.spec_ref
1051: *
1052: **/
1053: public Type[] getGenericInterfaces()
1054: throws GenericSignatureFormatError,
1055: TypeNotPresentException,
1056: MalformedParameterizedTypeException {
1057: if (isArray()) {
1058: return new Type[] { Cloneable.class, Serializable.class };
1059: }
1060: if (isPrimitive()) {
1061: return new Type[0];
1062: }
1063:
1064: return (Type[]) getCache().getGenericInterfaces().clone();
1065: }
1066:
1067: /**
1068: *
1069: * @com.intel.drl.spec_ref
1070: *
1071: **/
1072: public Type getGenericSuperclass()
1073: throws GenericSignatureFormatError,
1074: TypeNotPresentException,
1075: MalformedParameterizedTypeException {
1076: String tmp;
1077: if (isInterface()
1078: || ((tmp = getCanonicalName()) != null && tmp
1079: .equals("java.lang.Object")) || isPrimitive()) {
1080: return null;
1081: }
1082: if (isArray()) {
1083: return (Type) Object.class;
1084: }
1085:
1086: Class clazz = getSuperclass();
1087: if (clazz.getTypeParameters().length == 0) {
1088: return (Type) clazz;
1089: }
1090:
1091: return getCache().getGenericSuperclass();
1092: }
1093:
1094: /**
1095: *
1096: * @com.intel.drl.spec_ref
1097: *
1098: **/
1099: public Class<?> getEnclosingClass() {
1100: return VMClassRegistry.getEnclosingClass(this ); // see VMClassRegistry.getEnclosingClass() spec
1101: }
1102:
1103: /**
1104: *
1105: * @com.intel.drl.spec_ref
1106: *
1107: **/
1108: public boolean isMemberClass() {
1109: return getDeclaringClass() != null; // see Class.getDeclaringClass() spec
1110: }
1111:
1112: /**
1113: *
1114: * @com.intel.drl.spec_ref
1115: *
1116: **/
1117: public boolean isLocalClass() {
1118: return VMClassRegistry.getEnclosingMember(this ) != null
1119: && !isAnonymousClass(); // see CFF spec, #4.8.6, first paragraph and VMClassRegistry.getEnclosingMember() spec
1120: }
1121:
1122: /**
1123: *
1124: * @com.intel.drl.spec_ref
1125: *
1126: **/
1127: public boolean isAnonymousClass() {
1128: return getSimpleName().length() == 0;
1129: }
1130:
1131: /**
1132: *
1133: * @com.intel.drl.spec_ref
1134: *
1135: **/
1136: public boolean isSynthetic() {
1137: return (getModifiers() & ACC_SYNTHETIC) != 0;
1138: }
1139:
1140: /**
1141: *
1142: * @com.intel.drl.spec_ref
1143: *
1144: **/
1145: public String getCanonicalName() {
1146: if (isLocalClass() || isAnonymousClass()) {
1147: return null;
1148: }
1149: if (isArray()) {
1150: String res = getComponentType().getCanonicalName();
1151: return res != null ? res + "[]" : null;
1152: }
1153:
1154: StringBuffer sb = new StringBuffer(getPackageName());
1155: ArrayList<String> sympleNames = new ArrayList<String>();
1156: Class clss = this ;
1157: while ((clss = clss.getDeclaringClass()) != null) {
1158: if (clss.isLocalClass() || clss.isAnonymousClass()) {
1159: return null;
1160: }
1161: sympleNames.add(clss.getSimpleName());
1162: }
1163: if (sb.length() > 0) {
1164: sb.append(".");
1165: }
1166: for (int i = sympleNames.size() - 1; i > -1; i--) {
1167: sb.append(sympleNames.get(i)).append(".");
1168: }
1169: sb.append(getSimpleName());
1170:
1171: return sb.toString();
1172: }
1173:
1174: /**
1175: *
1176: * @com.intel.drl.spec_ref
1177: *
1178: **/
1179: public String getSimpleName() {
1180: // TODO: the method result should be reusible
1181: return VMClassRegistry.getSimpleName(this );
1182: }
1183:
1184: /**
1185: * Provides strong referencing between the classloader
1186: * and it's defined classes. Intended for class unloading implementation.
1187: * @see java.lang.ClassLoader#loadedClasses
1188: */
1189: ClassLoader definingLoader;
1190:
1191: private final class ReflectionData {
1192:
1193: String name;
1194:
1195: int modifiers = -1;
1196:
1197: boolean isArray;
1198:
1199: Constructor<T>[] declaredConstructors;
1200:
1201: Field[] declaredFields;
1202:
1203: Method[] declaredMethods;
1204:
1205: Constructor<T> defaultConstructor;
1206:
1207: String packageName;
1208:
1209: Constructor<T>[] publicConstructors;
1210:
1211: Field[] publicFields;
1212:
1213: Method[] publicMethods;
1214:
1215: public ReflectionData() {
1216: name = VMClassRegistry.getName(Class.this );
1217: isArray = VMClassRegistry.isArray(Class.this );
1218: packageName = Class.getParentName(name);
1219: }
1220:
1221: public void initDeclaredConstructors() {
1222: if (declaredConstructors == null) {
1223: declaredConstructors = VMClassRegistry
1224: .getDeclaredConstructors(Class.this );
1225: }
1226: }
1227:
1228: public void initDeclaredFields() {
1229: if (declaredFields == null) {
1230: declaredFields = VMClassRegistry
1231: .getDeclaredFields(Class.this );
1232: }
1233: }
1234:
1235: public void initDeclaredMethods() {
1236: if (declaredMethods == null) {
1237: declaredMethods = VMClassRegistry
1238: .getDeclaredMethods(Class.this );
1239: }
1240: }
1241:
1242: public void initDefaultConstructor()
1243: throws NoSuchMethodException {
1244: if (defaultConstructor == null) {
1245: defaultConstructor = Class.this
1246: .getDeclaredConstructorInternal(null);
1247: }
1248: }
1249:
1250: @SuppressWarnings("unchecked")
1251: public synchronized Constructor<T>[] getPublicConstructors() {
1252: if (publicConstructors != null) {
1253: return publicConstructors;
1254: }
1255: if (declaredConstructors == null) {
1256: initDeclaredConstructors();
1257: }
1258: ArrayList<Constructor<T>> constructors = new ArrayList<Constructor<T>>(
1259: declaredConstructors.length);
1260: for (int i = 0; i < declaredConstructors.length; i++) {
1261: Constructor<T> c = declaredConstructors[i];
1262: if (Modifier.isPublic(c.getModifiers())) {
1263: constructors.add(c);
1264: }
1265: }
1266: return publicConstructors = constructors
1267: .toArray(new Constructor[constructors.size()]);
1268: }
1269:
1270: /**
1271: * Stores public fields in order they should be searched by
1272: * getField(name) method.
1273: */
1274: public synchronized Field[] getPublicFields() {
1275: if (publicFields != null) {
1276: return publicFields;
1277: }
1278: if (declaredFields == null) {
1279: initDeclaredFields();
1280: }
1281:
1282: // initialize public fields of the super class
1283: int size = declaredFields.length;
1284: Class super Class = Class.this .getSuperclass();
1285: Field[] super Fields = null;
1286: if (super Class != null) {
1287: if (super Class.reflectionData == null) {
1288: super Class.initReflectionData();
1289: }
1290: super Fields = super Class.reflectionData
1291: .getPublicFields();
1292: size += super Fields.length;
1293: }
1294:
1295: // add public fields of this class
1296: Collection<Field> fields = new LinkedHashSet<Field>(size);
1297: for (Field f : declaredFields) {
1298: if (Modifier.isPublic(f.getModifiers())) {
1299: fields.add(f);
1300: }
1301: }
1302:
1303: // initialize and add fields of the super interfaces
1304: Class[] interfaces = Class.this .getInterfaces();
1305: for (Class ci : interfaces) {
1306: if (ci.reflectionData == null) {
1307: ci.initReflectionData();
1308: }
1309: Field[] fi = ci.reflectionData.getPublicFields();
1310: for (Field f : fi) {
1311: fields.add(f);
1312: }
1313: }
1314:
1315: // add public fields of the super class
1316: if (super Fields != null) {
1317: for (Field f : super Fields) {
1318: if (Modifier.isPublic(f.getModifiers())) {
1319: fields.add(f);
1320: }
1321: }
1322: }
1323:
1324: // maybe publicFields better be set atomically
1325: // instead of access synchronization?
1326: return publicFields = fields.toArray(new Field[fields
1327: .size()]);
1328: }
1329:
1330: public synchronized Method[] getPublicMethods() {
1331: if (publicMethods != null) {
1332: return publicMethods;
1333: }
1334: if (declaredMethods == null) {
1335: initDeclaredMethods();
1336: }
1337:
1338: // initialize public methods of the super class
1339: int size = declaredMethods.length;
1340: Class super Class = Class.this .getSuperclass();
1341: Method[] super Public = null;
1342: if (super Class != null) {
1343: if (super Class.reflectionData == null) {
1344: super Class.initReflectionData();
1345: }
1346: super Public = super Class.reflectionData
1347: .getPublicMethods();
1348: size += super Public.length;
1349: }
1350:
1351: // add methods of the super interfaces
1352: Class[] interfaces = Class.this .getInterfaces();
1353: Method[][] intf = null;
1354: if (interfaces.length != 0) {
1355: intf = new Method[interfaces.length][];
1356: for (int i = 0; i < interfaces.length; i++) {
1357: Class ci = interfaces[i];
1358: if (ci.reflectionData == null) {
1359: ci.initReflectionData();
1360: }
1361: intf[i] = ci.reflectionData.getPublicMethods();
1362: size += intf[i].length;
1363: }
1364: }
1365: // maybe publicMethods better be set atomically
1366: // instead of access synchronization?
1367: return publicMethods = Reflection.mergePublicMethods(
1368: declaredMethods, super Public, intf, size);
1369: }
1370: }
1371:
1372: private final class GACache {
1373:
1374: private Annotation[] allAnnotations;
1375: private Annotation[] declaredAnnotations;
1376: private Type[] genericInterfaces;
1377: private Type genericSuperclass;
1378: private TypeVariable<Class<T>>[] typeParameters;
1379:
1380: public synchronized Annotation[] getAllAnnotations() {
1381: if (allAnnotations != null) {
1382: return allAnnotations;
1383: }
1384: if (declaredAnnotations == null) {
1385: declaredAnnotations = VMGenericsAndAnnotations
1386: .getDeclaredAnnotations(Class.this );
1387: }
1388:
1389: // look for inherited annotations
1390: Class super Class = Class.this .getSuperclass();
1391: if (super Class != null) {
1392: Annotation[] sa = super Class.getCache()
1393: .getAllAnnotations();
1394: if (sa.length != 0) {
1395: final int size = declaredAnnotations.length;
1396: Annotation[] all = new Annotation[size + sa.length];
1397: System.arraycopy(declaredAnnotations, 0, all, 0,
1398: size);
1399: int pos = size;
1400: next: for (Annotation s : sa) {
1401: if (s.annotationType().isAnnotationPresent(
1402: Inherited.class)) {
1403: for (int i = 0; i < size; i++) {
1404: if (all[i].annotationType() == s
1405: .annotationType()) {
1406: // overriden by declared annotation
1407: continue next;
1408: }
1409: }
1410: all[pos++] = s;
1411: }
1412: }
1413: allAnnotations = new Annotation[pos];
1414: System.arraycopy(all, 0, allAnnotations, 0, pos);
1415: return allAnnotations;
1416: }
1417: }
1418: return allAnnotations = declaredAnnotations;
1419: }
1420:
1421: public Annotation[] getDeclaredAnnotations() {
1422: if (declaredAnnotations == null) {
1423: declaredAnnotations = VMGenericsAndAnnotations
1424: .getDeclaredAnnotations(Class.this );
1425: }
1426: return declaredAnnotations;
1427: }
1428:
1429: public synchronized Type[] getGenericInterfaces() {
1430: if (genericInterfaces == null) {
1431: genericInterfaces = Parser.getGenericInterfaces(
1432: Class.this , VMGenericsAndAnnotations
1433: .getSignature(Class.this ));
1434: }
1435: return genericInterfaces;
1436: }
1437:
1438: public Type getGenericSuperclass() {
1439: //So, here it can be only ParameterizedType or ordinary reference class type
1440: if (genericSuperclass == null) {
1441: genericSuperclass = Parser.getGenericSuperClass(
1442: Class.this , VMGenericsAndAnnotations
1443: .getSignature(Class.this ));
1444: }
1445: return genericSuperclass;
1446: }
1447:
1448: @SuppressWarnings("unchecked")
1449: public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
1450: if (typeParameters == null) {
1451: typeParameters = Parser.getTypeParameters(Class.this,
1452: VMGenericsAndAnnotations
1453: .getSignature(Class.this));
1454: }
1455: return typeParameters;
1456: }
1457: }
1458: }
|