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 org.apache.harmony.lang.reflect.parser;
0019:
0020: import java.io.Serializable;
0021: import java.lang.reflect.Constructor;
0022: import java.lang.reflect.Field;
0023: import java.lang.reflect.GenericDeclaration;
0024: import java.lang.reflect.GenericSignatureFormatError;
0025: import java.lang.reflect.Method;
0026: import java.lang.reflect.ParameterizedType;
0027: import java.lang.reflect.Type;
0028: import java.lang.reflect.TypeVariable;
0029:
0030: import org.apache.harmony.lang.reflect.implementation.ParameterizedTypeImpl;
0031: import org.apache.harmony.lang.reflect.implementation.TypeVariableImpl;
0032: import org.apache.harmony.lang.reflect.repository.ParameterizedTypeRepository;
0033: import org.apache.harmony.lang.reflect.repository.TypeVariableRepository;
0034: import org.apache.harmony.lang.reflect.support.AuxiliaryChecker;
0035: import org.apache.harmony.lang.reflect.support.AuxiliaryCreator;
0036: import org.apache.harmony.lang.reflect.support.AuxiliaryFinder;
0037: import org.apache.harmony.lang.reflect.support.AuxiliaryLoader;
0038: import org.apache.harmony.lang.reflect.support.AuxiliaryUtil;
0039:
0040: /**
0041: * @author Serguei S. Zapreyev
0042: * @version $Revision: 1.1.2.1 $
0043: */
0044: public class Parser {
0045:
0046: public static enum SignatureKind {
0047: FIELD_SIGNATURE(2), METHOD_SIGNATURE(3), CONSTRUCTOR_SIGNATURE(
0048: 4), CLASS_SIGNATURE(1);
0049: SignatureKind(int value) {
0050: this .value = value;
0051: }
0052:
0053: private final int value;
0054:
0055: public int value() {
0056: return value;
0057: }
0058: }
0059:
0060: public static InterimGenericDeclaration parseSignature(
0061: String signature, SignatureKind kind,
0062: java.lang.reflect.GenericDeclaration startPoint)
0063: throws GenericSignatureFormatError {
0064: return SignatureParser.parseSignature(signature, kind.value());
0065: }
0066:
0067: //TODO: generic warning
0068: /**
0069: * ################################################################################
0070: * for j.l.r.Constructor
0071: * ################################################################################
0072: */
0073: //TODO: synchronization on constructor?
0074: /**
0075: * initializes generalized exeptions
0076: */
0077: public static Type[] getGenericExceptionTypes(
0078: Constructor constructor, String signature) {
0079: Type[] genericExceptionTypes = null;
0080: //So, here it can be ParameterizedType or TypeVariable or ordinary reference class type elements.
0081: Object startPoint = constructor;
0082: //FIXME: Performance enhancement
0083: String constrSignature = AuxiliaryUtil.toUTF8(signature); // getting this method signature
0084: if (constrSignature == null) {
0085: //FIXME: Performance enhancement
0086: return constructor.getExceptionTypes();
0087: }
0088: // constrSignature&constrGenDecl is also the "hard" way to rethrow GenericSignatureFormatError each time for a while
0089: InterimConstructorGenericDecl constrGenDecl = (InterimConstructorGenericDecl) Parser
0090: .parseSignature(constrSignature,
0091: SignatureKind.CONSTRUCTOR_SIGNATURE,
0092: (GenericDeclaration) startPoint); // GenericSignatureFormatError can be thrown here
0093: InterimType[] throwns = constrGenDecl.throwns;
0094: if (throwns == null) {
0095: //FIXME: Performance enhancement
0096: return constructor.getExceptionTypes();
0097: }
0098: int l = throwns.length;
0099: genericExceptionTypes = new Type[l];
0100: for (int i = 0; i < l; i++) {
0101: if (throwns[i] instanceof InterimParameterizedType) {
0102: ParameterizedType pType = ParameterizedTypeRepository
0103: .findParameterizedType(
0104: (InterimParameterizedType) throwns[i],
0105: ((InterimParameterizedType) throwns[i]).signature,
0106: startPoint);
0107: if (pType == null) {
0108: try {
0109: AuxiliaryFinder
0110: .findGenericClassDeclarationForParameterizedType(
0111: (InterimParameterizedType) throwns[i],
0112: startPoint);
0113: } catch (Throwable e) {
0114: throw new TypeNotPresentException(
0115: ((InterimParameterizedType) throwns[i]).rawType.classTypeName
0116: .substring(1).replace('/', '.'),
0117: e);
0118: }
0119: //check the correspondence of the formal parameter number and the actual argument number:
0120: AuxiliaryChecker.checkArgsNumber(
0121: (InterimParameterizedType) throwns[i],
0122: startPoint); // the MalformedParameterizedTypeException may raise here
0123: try {
0124: pType = new ParameterizedTypeImpl(
0125: AuxiliaryCreator
0126: .createTypeArgs(
0127: (InterimParameterizedType) throwns[i],
0128: startPoint),
0129: AuxiliaryCreator
0130: .createRawType(
0131: (InterimParameterizedType) throwns[i],
0132: startPoint),
0133: AuxiliaryCreator
0134: .createOwnerType(
0135: (InterimParameterizedType) throwns[i],
0136: startPoint));
0137: } catch (ClassNotFoundException e) {
0138: throw new TypeNotPresentException(e
0139: .getMessage(), e);
0140: }
0141: ParameterizedTypeRepository
0142: .registerParameterizedType(
0143: pType,
0144: (InterimParameterizedType) throwns[i],
0145: ((InterimParameterizedType) throwns[i]).signature,
0146: startPoint);
0147: }
0148: genericExceptionTypes[i] = (Type) pType;
0149: } else if (throwns[i] instanceof InterimClassType) {
0150: try {
0151: genericExceptionTypes[i] = (Type) AuxiliaryLoader
0152: .findClass(
0153: ((InterimClassType) throwns[i]).classTypeName
0154: .substring(1).replace('/',
0155: '.'), startPoint); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one?
0156: } catch (ClassNotFoundException e) {
0157: throw new TypeNotPresentException(
0158: ((InterimClassType) throwns[i]).classTypeName
0159: .substring(1).replace('/', '.'), e);
0160: } catch (ExceptionInInitializerError e) {
0161: } catch (LinkageError e) {
0162: }
0163: } else if (throwns[i] instanceof InterimTypeVariable) {
0164: String tvName = ((InterimTypeVariable) throwns[i]).typeVariableName;
0165: TypeVariable variable = TypeVariableRepository
0166: .findTypeVariable(tvName, startPoint);
0167:
0168: if (variable == null) {
0169: variable = AuxiliaryFinder.findTypeVariable(tvName,
0170: startPoint);
0171: if (variable == null) {
0172: genericExceptionTypes[i] = (Type) null;
0173: break;
0174: }
0175: }
0176: genericExceptionTypes[i] = (Type) variable;
0177: } else {
0178: // Internal Error
0179: }
0180: }
0181: return genericExceptionTypes;
0182: }
0183:
0184: /**
0185: * initializes type parameters
0186: */
0187: @SuppressWarnings("unchecked")
0188: public static TypeVariable<? extends Constructor>[] getTypeParameters(
0189: Constructor constructor, String signature) {
0190: //So, here it can be only TypeVariable elements.
0191:
0192: TypeVariable<Constructor>[] typeParameters = null;
0193: Object startPoint = constructor;
0194:
0195: //FIXME: performance enhancement
0196: String constrSignature = AuxiliaryUtil.toUTF8(signature); // getting this method signature
0197:
0198: if (constrSignature == null) {
0199: return new TypeVariable[0]; // can't use <generic> for arrays...
0200: }
0201:
0202: //FIXME: performance enhancement
0203: InterimConstructorGenericDecl constrGenDecl = (InterimConstructorGenericDecl) Parser
0204: .parseSignature(constrSignature,
0205: SignatureKind.CONSTRUCTOR_SIGNATURE,
0206: (GenericDeclaration) startPoint); // GenericSignatureFormatError
0207: // can be
0208: // thrown
0209: // here
0210: InterimTypeParameter[] pTypeParameters = constrGenDecl.typeParameters;
0211:
0212: if (pTypeParameters == null) {
0213: return new TypeVariable[0]; // can't use <generic> for arrays...
0214: }
0215: int l = pTypeParameters.length;
0216: typeParameters = new TypeVariable[l]; // can't use <generic> for arrays...
0217:
0218: for (int i = 0; i < l; i++) {
0219: String tvName = pTypeParameters[i].typeParameterName;
0220: TypeVariable variable = new TypeVariableImpl(
0221: (GenericDeclaration) constructor, tvName,
0222: pTypeParameters[i]);
0223: TypeVariableRepository.registerTypeVariable(variable,
0224: tvName, startPoint);
0225: typeParameters[i] = variable;
0226: }
0227: return typeParameters;
0228: }
0229:
0230: /**
0231: * initializes generalized parameters
0232: */
0233: public static synchronized Type[] getGenericParameterTypes(
0234: Constructor constructor, String signature) {
0235: //So, here it can be ParameterizedType or TypeVariable or ordinary reference class type elements.
0236: Type[] genericParameterTypes = null;
0237: Object startPoint = constructor;
0238: //FIXME: performance enhancement
0239: String constrSignature = AuxiliaryUtil.toUTF8(signature); // getting this method
0240: if (constrSignature == null) {
0241: //FIXME: performance enhancement
0242: return constructor.getParameterTypes();
0243: }
0244:
0245: // GenericSignatureFormatError can be thrown here
0246: //FIXME: performance enhancement
0247: InterimConstructorGenericDecl constrGenDecl = (InterimConstructorGenericDecl) Parser
0248: .parseSignature(constrSignature,
0249: SignatureKind.CONSTRUCTOR_SIGNATURE,
0250: (GenericDeclaration) startPoint);
0251:
0252: InterimType[] methodParameters = constrGenDecl.methodParameters;
0253: if (methodParameters == null) {
0254: return new Type[0];
0255: }
0256: int l = methodParameters.length;
0257: genericParameterTypes = new Type[l];
0258: for (int i = 0; i < l; i++) {
0259: if (methodParameters[i] instanceof InterimParameterizedType) {
0260: ParameterizedType pType = ParameterizedTypeRepository
0261: .findParameterizedType(
0262: (InterimParameterizedType) methodParameters[i],
0263: ((InterimParameterizedType) methodParameters[i]).signature,
0264: startPoint);
0265: if (pType == null) {
0266: try {
0267: AuxiliaryFinder
0268: .findGenericClassDeclarationForParameterizedType(
0269: (InterimParameterizedType) methodParameters[i],
0270: startPoint);
0271: } catch (Throwable e) {
0272: throw new TypeNotPresentException(
0273: ((InterimParameterizedType) methodParameters[i]).rawType.classTypeName
0274: .substring(1).replace('/', '.'),
0275: e);
0276: }
0277: // check the correspondence of the formal parameter
0278: // number and the actual argument number:
0279: AuxiliaryChecker
0280: .checkArgsNumber(
0281: (InterimParameterizedType) methodParameters[i],
0282: startPoint); // the
0283: // MalformedParameterizedTypeException
0284: // may raise here
0285: try {
0286: pType = new ParameterizedTypeImpl(
0287: AuxiliaryCreator
0288: .createTypeArgs(
0289: (InterimParameterizedType) methodParameters[i],
0290: startPoint),
0291: AuxiliaryCreator
0292: .createRawType(
0293: (InterimParameterizedType) methodParameters[i],
0294: startPoint),
0295: AuxiliaryCreator
0296: .createOwnerType(
0297: (InterimParameterizedType) methodParameters[i],
0298: startPoint));
0299: } catch (ClassNotFoundException e) {
0300: throw new TypeNotPresentException(e
0301: .getMessage(), e);
0302: }
0303: ParameterizedTypeRepository
0304: .registerParameterizedType(
0305: pType,
0306: (InterimParameterizedType) methodParameters[i],
0307: ((InterimParameterizedType) methodParameters[i]).signature,
0308: startPoint);
0309: }
0310: genericParameterTypes[i] = (Type) pType;
0311: } else if (methodParameters[i] instanceof InterimClassType) {
0312: try {
0313: genericParameterTypes[i] = (Type) AuxiliaryLoader
0314: .findClass(
0315: ((InterimClassType) methodParameters[i]).classTypeName
0316: .substring(
0317: (((InterimClassType) methodParameters[i]).classTypeName
0318: .charAt(0) == 'L' ? 1
0319: : 0))
0320: .replace('/', '.'),
0321: startPoint); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one?
0322: } catch (ClassNotFoundException e) {
0323: throw new TypeNotPresentException(
0324: ((InterimClassType) methodParameters[i]).classTypeName
0325: .substring(
0326: (((InterimClassType) methodParameters[i]).classTypeName
0327: .charAt(0) == 'L' ? 1
0328: : 0)).replace('/',
0329: '.'), e);
0330: } catch (ExceptionInInitializerError e) {
0331: } catch (LinkageError e) {
0332: }
0333: } else if (methodParameters[i] instanceof InterimTypeVariable) {
0334: String tvName = ((InterimTypeVariable) methodParameters[i]).typeVariableName;
0335: TypeVariable variable = TypeVariableRepository
0336: .findTypeVariable(tvName, startPoint);
0337: if (variable == null) {
0338: variable = AuxiliaryFinder.findTypeVariable(tvName,
0339: startPoint);
0340: if (variable == null) {
0341: genericParameterTypes[i] = (Type) null;
0342: continue;
0343: }
0344: }
0345: genericParameterTypes[i] = (Type) variable;
0346: } else if (methodParameters[i] instanceof InterimGenericArrayType) {
0347: genericParameterTypes[i] = AuxiliaryCreator
0348: .createGenericArrayType(
0349: (InterimGenericArrayType) methodParameters[i],
0350: startPoint);
0351: } else {
0352: // Internal Error
0353: }
0354: }
0355: return genericParameterTypes;
0356: }
0357:
0358: /**
0359: * ################################################################################
0360: * for j.l.r.Field
0361: * ################################################################################
0362: */
0363: public static Type parseFieldGenericType(Field field,
0364: String rawSignature) throws GenericSignatureFormatError {
0365: Object startPoint = field.getDeclaringClass();
0366: String signature = AuxiliaryUtil.toUTF8(rawSignature);
0367: if (signature == null) {
0368: return field.getType();
0369: }
0370: InterimFieldGenericDecl decl = (InterimFieldGenericDecl) Parser
0371: .parseSignature(signature,
0372: SignatureKind.FIELD_SIGNATURE,
0373: (GenericDeclaration) startPoint);
0374: InterimGenericType fldType = decl.fieldType;
0375: if (fldType instanceof InterimTypeVariable) {
0376: String tvName = ((InterimTypeVariable) fldType).typeVariableName;
0377: TypeVariable variable = TypeVariableRepository
0378: .findTypeVariable(tvName, startPoint);
0379: if (variable == null) {
0380: variable = AuxiliaryFinder.findTypeVariable(tvName,
0381: startPoint);
0382: if (variable == null) {
0383: return (Type) null;
0384: }
0385: }
0386: return (Type) variable;
0387: } else if (fldType instanceof InterimParameterizedType) {
0388: ParameterizedType pType = ParameterizedTypeRepository
0389: .findParameterizedType(
0390: (InterimParameterizedType) fldType,
0391: ((InterimParameterizedType) fldType).signature,
0392: startPoint);
0393: if (pType == null) {
0394: try {
0395: AuxiliaryFinder
0396: .findGenericClassDeclarationForParameterizedType(
0397: (InterimParameterizedType) fldType,
0398: startPoint);
0399: } catch (Throwable e) {
0400: throw new TypeNotPresentException(
0401: ((InterimParameterizedType) fldType).rawType.classTypeName
0402: .substring(1).replace('/', '.'), e);
0403: }
0404: // check the correspondence of the formal parameter number
0405: // and the actual argument number:
0406: AuxiliaryChecker.checkArgsNumber(
0407: (InterimParameterizedType) fldType, startPoint); // the
0408: // MalformedParameterizedTypeException
0409: // may
0410: // raise
0411: // here
0412: try {
0413: pType = new ParameterizedTypeImpl(AuxiliaryCreator
0414: .createTypeArgs(
0415: (InterimParameterizedType) fldType,
0416: startPoint), AuxiliaryCreator
0417: .createRawType(
0418: (InterimParameterizedType) fldType,
0419: startPoint), AuxiliaryCreator
0420: .createOwnerType(
0421: (InterimParameterizedType) fldType,
0422: startPoint));
0423: } catch (ClassNotFoundException e) {
0424: throw new TypeNotPresentException(e.getMessage(), e);
0425: }
0426: ParameterizedTypeRepository.registerParameterizedType(
0427: pType, (InterimParameterizedType) fldType,
0428: ((InterimParameterizedType) fldType).signature,
0429: startPoint);
0430: }
0431: return pType;
0432: } else if (fldType instanceof InterimGenericArrayType) {
0433: return AuxiliaryCreator.createGenericArrayType(
0434: (InterimGenericArrayType) fldType, startPoint);
0435: } else {
0436: return field.getType();
0437: }
0438: }
0439:
0440: /**
0441: * ################################################################################
0442: * for j.l.r.Method
0443: * ################################################################################
0444: */
0445:
0446: /**
0447: * initializes type parameters
0448: */
0449: @SuppressWarnings("unchecked")
0450: public static TypeVariable[] getTypeParameters(Method method,
0451: String signature) {
0452: // So, here it can be only TypeVariable elements.
0453: TypeVariable[] typeParameters;
0454: Object startPoint = method;
0455: // FIXME: performance enhancement
0456: String methSignature = AuxiliaryUtil.toUTF8(signature); // getting this
0457: // method
0458: // FIXME: performance enhancement // signature
0459: if (methSignature == null) {
0460: return new TypeVariable[0];
0461: }
0462: // FIXME: performance enhancement
0463: InterimMethodGenericDecl methGenDecl = (InterimMethodGenericDecl) Parser
0464: .parseSignature(methSignature,
0465: SignatureKind.METHOD_SIGNATURE,
0466: (GenericDeclaration) startPoint); // GenericSignatureFormatError
0467: // can be thrown
0468: // here
0469: InterimTypeParameter[] pTypeParameters = methGenDecl.typeParameters;
0470: if (pTypeParameters == null) {
0471: return new TypeVariable[0];
0472: }
0473: int l = pTypeParameters.length;
0474: typeParameters = new TypeVariable[l];
0475: for (int i = 0; i < l; i++) {
0476: String tvName = pTypeParameters[i].typeParameterName;
0477: TypeVariable variable = new TypeVariableImpl(
0478: (GenericDeclaration) method, tvName,
0479: methGenDecl.typeParameters[i]);
0480: TypeVariableRepository.registerTypeVariable(variable,
0481: tvName, startPoint);
0482: typeParameters[i] = variable;
0483: }
0484: return typeParameters;
0485: }
0486:
0487: public static Type getGenericReturnTypeImpl(Method method,
0488: String signature) throws GenericSignatureFormatError {
0489: Object startPoint = method;
0490: // FIXME: performance enhancement
0491: String methSignature;
0492: methSignature = AuxiliaryUtil.toUTF8(signature);
0493: if (methSignature == null) {
0494: // FIXME: performance enhancement
0495: return (Type) method.getReturnType();
0496: }
0497: // FIXME: performance enhancement
0498: InterimMethodGenericDecl methGenDecl = (InterimMethodGenericDecl) Parser
0499: .parseSignature(methSignature,
0500: SignatureKind.METHOD_SIGNATURE,
0501: (GenericDeclaration) startPoint);
0502: InterimType mthdType = methGenDecl.returnValue;
0503: if (mthdType instanceof InterimTypeVariable) {
0504: String tvName = ((InterimTypeVariable) mthdType).typeVariableName;
0505: TypeVariable variable = TypeVariableRepository
0506: .findTypeVariable(tvName, startPoint);
0507: if (variable == null) {
0508: variable = AuxiliaryFinder.findTypeVariable(tvName,
0509: startPoint);
0510: if (variable == null) {
0511: return (Type) null; // compatible behaviour
0512: }
0513: }
0514: return (Type) variable;
0515: } else if (mthdType instanceof InterimParameterizedType) {
0516: ParameterizedType pType = ParameterizedTypeRepository
0517: .findParameterizedType(
0518: (InterimParameterizedType) mthdType,
0519: ((InterimParameterizedType) mthdType).signature,
0520: startPoint);
0521: if (pType == null) {
0522: try {
0523: AuxiliaryFinder
0524: .findGenericClassDeclarationForParameterizedType(
0525: (InterimParameterizedType) mthdType,
0526: startPoint);
0527: } catch (Throwable e) {
0528: throw new TypeNotPresentException(
0529: ((InterimParameterizedType) mthdType).rawType.classTypeName
0530: .substring(1).replace('/', '.'), e);
0531: }
0532: // check the correspondence of the formal parameter number and
0533: // the actual argument number:
0534: AuxiliaryChecker
0535: .checkArgsNumber(
0536: (InterimParameterizedType) mthdType,
0537: startPoint); // the
0538: // MalformedParameterizedTypeException
0539: // may
0540: // raise
0541: // here
0542: try {
0543: pType = new ParameterizedTypeImpl(
0544: AuxiliaryCreator
0545: .createTypeArgs(
0546: (InterimParameterizedType) mthdType,
0547: startPoint),
0548: AuxiliaryCreator
0549: .createRawType(
0550: (InterimParameterizedType) mthdType,
0551: startPoint),
0552: AuxiliaryCreator
0553: .createOwnerType(
0554: (InterimParameterizedType) mthdType,
0555: startPoint));
0556: } catch (ClassNotFoundException e) {
0557: throw new TypeNotPresentException(e.getMessage(), e);
0558: }
0559: ParameterizedTypeRepository
0560: .registerParameterizedType(
0561: pType,
0562: (InterimParameterizedType) mthdType,
0563: ((InterimParameterizedType) mthdType).signature,
0564: startPoint);
0565: }
0566: return (Type) pType;
0567: } else if (mthdType instanceof InterimGenericArrayType) {
0568: return AuxiliaryCreator.createGenericArrayType(
0569: (InterimGenericArrayType) mthdType, startPoint);
0570: } else {
0571: return method.getReturnType();
0572: }
0573: }
0574:
0575: /**
0576: * initializes generalized exeptions
0577: */
0578: public static Type[] getGenericExceptionTypes(Method method,
0579: String signature) {
0580: // So, here it can be ParameterizedType or TypeVariable or ordinary
0581: // reference class type elements.
0582: Type[] genericExceptionTypes = null;
0583: Object startPoint = method;
0584: // FIXME: performance enhancement
0585: String methSignature = AuxiliaryUtil.toUTF8(signature); // getting
0586: // this
0587: // method
0588: // FIXME: performance enhancement // signature
0589: if (methSignature == null) {
0590: return method.getExceptionTypes();
0591: }
0592: // FIXME: performance enhancement
0593: InterimMethodGenericDecl methGenDecl = (InterimMethodGenericDecl) Parser
0594: .parseSignature(methSignature,
0595: SignatureKind.METHOD_SIGNATURE,
0596: (GenericDeclaration) startPoint); // GenericSignatureFormatError
0597: // can be thrown here
0598: InterimType[] throwns = methGenDecl.throwns;
0599: if (throwns == null) {
0600: return method.getExceptionTypes();
0601: }
0602: int l = throwns.length;
0603: genericExceptionTypes = new Type[l];
0604: for (int i = 0; i < l; i++) {
0605: if (throwns[i] instanceof InterimParameterizedType) {
0606: ParameterizedType pType = ParameterizedTypeRepository
0607: .findParameterizedType(
0608: (InterimParameterizedType) throwns[i],
0609: ((InterimParameterizedType) throwns[i]).signature,
0610: startPoint);
0611: if (pType == null) {
0612: try {
0613: AuxiliaryFinder
0614: .findGenericClassDeclarationForParameterizedType(
0615: (InterimParameterizedType) throwns[i],
0616: startPoint);
0617: } catch (Throwable e) {
0618: throw new TypeNotPresentException(
0619: ((InterimParameterizedType) throwns[i]).rawType.classTypeName
0620: .substring(1).replace('/', '.'),
0621: e);
0622: }
0623: // check the correspondence of the formal parameter
0624: // number and the actual argument number:
0625: AuxiliaryChecker.checkArgsNumber(
0626: (InterimParameterizedType) throwns[i],
0627: startPoint); // the
0628: // MalformedParameterizedTypeException
0629: // may raise here
0630: try {
0631: pType = new ParameterizedTypeImpl(
0632: AuxiliaryCreator
0633: .createTypeArgs(
0634: (InterimParameterizedType) throwns[i],
0635: startPoint),
0636: AuxiliaryCreator
0637: .createRawType(
0638: (InterimParameterizedType) throwns[i],
0639: startPoint),
0640: AuxiliaryCreator
0641: .createOwnerType(
0642: (InterimParameterizedType) throwns[i],
0643: startPoint));
0644: } catch (ClassNotFoundException e) {
0645: throw new TypeNotPresentException(e
0646: .getMessage(), e);
0647: }
0648: ParameterizedTypeRepository
0649: .registerParameterizedType(
0650: pType,
0651: (InterimParameterizedType) throwns[i],
0652: ((InterimParameterizedType) throwns[i]).signature,
0653: startPoint);
0654: }
0655: genericExceptionTypes[i] = (Type) pType;
0656: } else if (throwns[i] instanceof InterimClassType) {
0657: try {
0658: genericExceptionTypes[i] = (Type) AuxiliaryLoader
0659: .findClass(
0660: ((InterimClassType) throwns[i]).classTypeName
0661: .substring(
0662: (((InterimClassType) throwns[i]).classTypeName
0663: .charAt(0) == 'L' ? 1
0664: : 0))
0665: .replace('/', '.'),
0666: startPoint); // XXX:
0667: // should
0668: // we
0669: // propagate
0670: // the
0671: // class
0672: // loader
0673: // of
0674: // initial
0675: // user's
0676: // request
0677: // (Field.getGenericType())
0678: // or
0679: // use
0680: // this
0681: // one?
0682: } catch (ClassNotFoundException e) {
0683: throw new TypeNotPresentException(
0684: ((InterimClassType) throwns[i]).classTypeName
0685: .substring(
0686: (((InterimClassType) throwns[i]).classTypeName
0687: .charAt(0) == 'L' ? 1
0688: : 0)).replace('/',
0689: '.'), e);
0690: } catch (ExceptionInInitializerError e) {
0691: } catch (LinkageError e) {
0692: }
0693: } else if (throwns[i] instanceof InterimTypeVariable) {
0694: String tvName = ((InterimTypeVariable) throwns[i]).typeVariableName;
0695: TypeVariable variable = TypeVariableRepository
0696: .findTypeVariable(tvName, startPoint);
0697: if (variable == null) {
0698: variable = AuxiliaryFinder.findTypeVariable(tvName,
0699: startPoint);
0700: if (variable == null) {
0701: genericExceptionTypes[i] = (Type) null;
0702: break;
0703: }
0704: }
0705: genericExceptionTypes[i] = (Type) variable;
0706: } else {
0707: // Internal Error
0708: }
0709:
0710: }
0711: return genericExceptionTypes;
0712: }
0713:
0714: /**
0715: * initializes generalized parameters
0716: */
0717: public static Type[] getGenericParameterTypes(Method method,
0718: String signature) {
0719: // So, here it can be ParameterizedType or TypeVariable or ordinary
0720: // reference class type elements.
0721: Type[] genericParameterTypes = null;
0722: Object startPoint = method;
0723: String methSignature = AuxiliaryUtil.toUTF8(signature); // getting this
0724: // method
0725: // signature
0726: if (methSignature == null) {
0727: return method.getParameterTypes();
0728: }
0729: InterimMethodGenericDecl methGenDecl = (InterimMethodGenericDecl) Parser
0730: .parseSignature(methSignature,
0731: SignatureKind.METHOD_SIGNATURE,
0732: (GenericDeclaration) startPoint); // GenericSignatureFormatError
0733: // can be thrown
0734: // here
0735: InterimType[] methodParameters = methGenDecl.methodParameters;
0736: if (methodParameters == null) {
0737: return new Type[0];
0738: }
0739: int l = methodParameters.length;
0740: genericParameterTypes = new Type[l];
0741: for (int i = 0; i < l; i++) {
0742: if (methodParameters[i] instanceof InterimParameterizedType) {
0743: ParameterizedType pType = ParameterizedTypeRepository
0744: .findParameterizedType(
0745: (InterimParameterizedType) methodParameters[i],
0746: ((InterimParameterizedType) methodParameters[i]).signature,
0747: startPoint);
0748: if (pType == null) {
0749: try {
0750: AuxiliaryFinder
0751: .findGenericClassDeclarationForParameterizedType(
0752: (InterimParameterizedType) methodParameters[i],
0753: startPoint);
0754: } catch (Throwable e) {
0755: throw new TypeNotPresentException(
0756: ((InterimParameterizedType) methodParameters[i]).rawType.classTypeName
0757: .substring(1).replace('/', '.'),
0758: e);
0759: }
0760: // check the correspondence of the formal parameter number
0761: // and the actual argument number:
0762: AuxiliaryChecker
0763: .checkArgsNumber(
0764: (InterimParameterizedType) methodParameters[i],
0765: startPoint); // the
0766: // MalformedParameterizedTypeException
0767: // may raise here
0768: try {
0769: pType = new ParameterizedTypeImpl(
0770: AuxiliaryCreator
0771: .createTypeArgs(
0772: (InterimParameterizedType) methodParameters[i],
0773: startPoint),
0774: AuxiliaryCreator
0775: .createRawType(
0776: (InterimParameterizedType) methodParameters[i],
0777: startPoint),
0778: AuxiliaryCreator
0779: .createOwnerType(
0780: (InterimParameterizedType) methodParameters[i],
0781: startPoint));
0782: } catch (ClassNotFoundException e) {
0783: throw new TypeNotPresentException(e
0784: .getMessage(), e);
0785: }
0786: ParameterizedTypeRepository
0787: .registerParameterizedType(
0788: pType,
0789: (InterimParameterizedType) methodParameters[i],
0790: ((InterimParameterizedType) methodParameters[i]).signature,
0791: startPoint);
0792: }
0793: genericParameterTypes[i] = (Type) pType;
0794: } else if (methodParameters[i] instanceof InterimClassType) {
0795: try {
0796: genericParameterTypes[i] = (Type) AuxiliaryLoader
0797: .findClass(
0798: ((InterimClassType) methodParameters[i]).classTypeName
0799: .substring(
0800: (((InterimClassType) methodParameters[i]).classTypeName
0801: .charAt(0) == 'L' ? 1
0802: : 0))
0803: .replace('/', '.'),
0804: startPoint); // XXX: should we
0805: // propagate the
0806: // class loader of
0807: // initial user's
0808: // request
0809: // (Field.getGenericType())
0810: // or use this one?
0811: } catch (ClassNotFoundException e) {
0812: throw new TypeNotPresentException(
0813: ((InterimClassType) methodParameters[i]).classTypeName
0814: .substring(
0815: (((InterimClassType) methodParameters[i]).classTypeName
0816: .charAt(0) == 'L' ? 1
0817: : 0)).replace('/',
0818: '.'), e);
0819: } catch (ExceptionInInitializerError e) {
0820: } catch (LinkageError e) {
0821: }
0822: } else if (methodParameters[i] instanceof InterimTypeVariable) {
0823: String tvName = ((InterimTypeVariable) methodParameters[i]).typeVariableName;
0824: TypeVariable variable = TypeVariableRepository
0825: .findTypeVariable(tvName, startPoint);
0826: if (variable == null) {
0827: variable = AuxiliaryFinder.findTypeVariable(tvName,
0828: startPoint);
0829: if (variable == null) {
0830: genericParameterTypes[i] = (Type) null;
0831: continue;
0832: }
0833: }
0834: genericParameterTypes[i] = (Type) variable;
0835: } else if (methodParameters[i] instanceof InterimGenericArrayType) {
0836: genericParameterTypes[i] = AuxiliaryCreator
0837: .createGenericArrayType(
0838: (InterimGenericArrayType) methodParameters[i],
0839: startPoint);
0840: } else {
0841: // Internal Error
0842: }
0843: }
0844: return genericParameterTypes;
0845: }
0846:
0847: /**
0848: * ################################################################################
0849: * for j.l.Class
0850: * ################################################################################
0851: */
0852: @SuppressWarnings("unchecked")
0853: public static TypeVariable[] getTypeParameters(Class c,
0854: String rawSignature) {
0855: TypeVariable[] typeParameters = null;
0856: //So, here it can be only TypeVariable elements.
0857: Object startPoint = c;
0858: String signature = AuxiliaryUtil.toUTF8(rawSignature); // getting this class signature
0859: if (signature == null) {
0860: return typeParameters = new TypeVariable[0];
0861: }
0862: InterimClassGenericDecl decl = (InterimClassGenericDecl) Parser
0863: .parseSignature(signature,
0864: SignatureKind.CLASS_SIGNATURE,
0865: (GenericDeclaration) startPoint); // GenericSignatureFormatError can be thrown here
0866: InterimTypeParameter[] pTypeParameters = decl.typeParameters;
0867: if (pTypeParameters == null) {
0868: return typeParameters = new TypeVariable[0];
0869: }
0870: int l = pTypeParameters.length;
0871: typeParameters = new TypeVariable[l];
0872: for (int i = 0; i < l; i++) {
0873: String tvName = pTypeParameters[i].typeParameterName;
0874: TypeVariable variable = new TypeVariableImpl(
0875: (GenericDeclaration) c, tvName,
0876: decl.typeParameters[i]);
0877: TypeVariableRepository.registerTypeVariable(variable,
0878: tvName, startPoint);
0879: typeParameters[i] = variable;
0880: }
0881: return typeParameters;
0882: }
0883:
0884: public static Type getGenericSuperClass(Class c, String rawSignature) {
0885: Type genericSuperclass = null;
0886: Object startPoint = (Object) c; // It should be this class itself
0887: // because, for example, superclass may
0888: // be a parameterized type with
0889: // parameters which are the generic
0890: // parameters of this class
0891: String signature = AuxiliaryUtil.toUTF8(rawSignature); // getting this class signature
0892: if (signature == null) {
0893: return genericSuperclass = c.getSuperclass();
0894: }
0895: InterimClassGenericDecl decl = (InterimClassGenericDecl) Parser
0896: .parseSignature(signature,
0897: SignatureKind.CLASS_SIGNATURE,
0898: (GenericDeclaration) startPoint); // GenericSignatureFormatError
0899: // can be thrown
0900: // here
0901: InterimType super ClassType = decl.super Class;
0902: if (super ClassType == null) {
0903: return genericSuperclass = c.getSuperclass();
0904: }
0905: if (super ClassType instanceof InterimParameterizedType) {
0906: ParameterizedType pType = ParameterizedTypeRepository
0907: .findParameterizedType(
0908: (InterimParameterizedType) super ClassType,
0909: ((InterimParameterizedType) super ClassType).signature,
0910: startPoint);
0911: if (pType == null) {
0912: try {
0913: AuxiliaryFinder
0914: .findGenericClassDeclarationForParameterizedType(
0915: (InterimParameterizedType) super ClassType,
0916: startPoint);
0917: } catch (Throwable e) {
0918: throw new TypeNotPresentException(
0919: ((InterimParameterizedType) super ClassType).rawType.classTypeName
0920: .substring(1).replace('/', '.'), e);
0921: }
0922: // check the correspondence of the formal parameter number and
0923: // the actual argument number:
0924: AuxiliaryChecker.checkArgsNumber(
0925: (InterimParameterizedType) super ClassType,
0926: startPoint); // the
0927: // MalformedParameterizedTypeException
0928: // may
0929: // raise
0930: // here
0931: try {
0932: pType = new ParameterizedTypeImpl(
0933: AuxiliaryCreator
0934: .createTypeArgs(
0935: (InterimParameterizedType) super ClassType,
0936: startPoint),
0937: AuxiliaryCreator
0938: .createRawType(
0939: (InterimParameterizedType) super ClassType,
0940: startPoint),
0941: AuxiliaryCreator
0942: .createOwnerType(
0943: (InterimParameterizedType) super ClassType,
0944: startPoint));
0945: } catch (ClassNotFoundException e) {
0946: throw new TypeNotPresentException(e.getMessage(), e);
0947: }
0948: ParameterizedTypeRepository.registerParameterizedType(
0949: pType,
0950: (InterimParameterizedType) super ClassType,
0951: signature, startPoint);
0952: }
0953: genericSuperclass = (Type) pType;
0954: } else if (super ClassType instanceof InterimClassType) {
0955: try {
0956: genericSuperclass = (Type) c
0957: .getClass()
0958: .getClassLoader()
0959: //FIXME: any potential issue to change findClass->loadClass
0960: .loadClass(
0961: AuxiliaryFinder
0962: .transform(((InterimClassType) super ClassType).classTypeName
0963: .substring(1).replace(
0964: '/', '.'))); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one?
0965: } catch (ClassNotFoundException e) {
0966: throw new TypeNotPresentException(
0967: ((InterimClassType) super ClassType).classTypeName
0968: .substring(1).replace('/', '.'), e);
0969: } catch (ExceptionInInitializerError e) {
0970: } catch (LinkageError e) {
0971: }
0972: } else {
0973: // Internal Error
0974: }
0975: return genericSuperclass;
0976: }
0977:
0978: @SuppressWarnings("unchecked")
0979: public static Type[] getGenericInterfaces(Class c,
0980: String rawSignature) {
0981:
0982: Type[] genericInterfaces = null;
0983:
0984: //So, here it can be only ParameterizedType or ordinary reference class type elements.
0985: if (c.isArray()) {
0986: return genericInterfaces = new Type[] { Cloneable.class,
0987: Serializable.class };
0988: }
0989: if (genericInterfaces == null) {
0990: Object startPoint = c; // It should be this class itself because, for example, an interface may be a parameterized type with parameters which are the generic parameters of this class
0991: String signature = AuxiliaryUtil.toUTF8(rawSignature); // getting this class signature
0992: if (signature == null) {
0993: return genericInterfaces = c.getInterfaces();
0994: }
0995: InterimClassGenericDecl decl = (InterimClassGenericDecl) Parser
0996: .parseSignature(signature,
0997: SignatureKind.CLASS_SIGNATURE,
0998: (GenericDeclaration) startPoint); //GenericSignatureFormatError can be thrown here
0999: InterimType[] super Interfaces = decl.super Interfaces;
1000: if (super Interfaces == null) {
1001: return genericInterfaces = c.getInterfaces();
1002: }
1003: int l = super Interfaces.length;
1004: genericInterfaces = new Type[l];
1005: for (int i = 0; i < l; i++) {
1006: if (super Interfaces[i] instanceof InterimParameterizedType) {
1007: ParameterizedType pType = ParameterizedTypeRepository
1008: .findParameterizedType(
1009: (InterimParameterizedType) super Interfaces[i],
1010: ((InterimParameterizedType) super Interfaces[i]).signature,
1011: startPoint);
1012: if (pType == null) {
1013: try {
1014: AuxiliaryFinder
1015: .findGenericClassDeclarationForParameterizedType(
1016: (InterimParameterizedType) super Interfaces[i],
1017: startPoint);
1018: } catch (Throwable e) {
1019: throw new TypeNotPresentException(
1020: ((InterimParameterizedType) super Interfaces[i]).rawType.classTypeName
1021: .substring(1).replace('/',
1022: '.'), e);
1023: }
1024: //check the correspondence of the formal parameter number and the actual argument number:
1025: AuxiliaryChecker
1026: .checkArgsNumber(
1027: (InterimParameterizedType) super Interfaces[i],
1028: startPoint); // the MalformedParameterizedTypeException may raise here
1029: try {
1030: pType = new ParameterizedTypeImpl(
1031: AuxiliaryCreator
1032: .createTypeArgs(
1033: (InterimParameterizedType) super Interfaces[i],
1034: startPoint),
1035: AuxiliaryCreator
1036: .createRawType(
1037: (InterimParameterizedType) super Interfaces[i],
1038: startPoint),
1039: AuxiliaryCreator
1040: .createOwnerType(
1041: (InterimParameterizedType) super Interfaces[i],
1042: startPoint));
1043: } catch (ClassNotFoundException e) {
1044: throw new TypeNotPresentException(e
1045: .getMessage(), e);
1046: }
1047: ParameterizedTypeRepository
1048: .registerParameterizedType(
1049: pType,
1050: (InterimParameterizedType) super Interfaces[i],
1051: signature, startPoint);
1052: }
1053: genericInterfaces[i] = (Type) pType;
1054: } else if (super Interfaces[i] instanceof InterimClassType) {
1055: try {
1056: if (c.getClass().getClassLoader() != null) {
1057: //FIXME: any potential issue to change findClass->loadClass
1058: genericInterfaces[i] = (Type) c
1059: .getClass()
1060: .getClassLoader()
1061: .loadClass(
1062: AuxiliaryFinder
1063: .transform(((InterimClassType) super Interfaces[i]).classTypeName
1064: .substring(
1065: 1)
1066: .replace(
1067: '/',
1068: '.'))); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one?
1069: } else {
1070: genericInterfaces[i] = (Type) AuxiliaryLoader
1071: .findClass(
1072: AuxiliaryFinder
1073: .transform(((InterimClassType) super Interfaces[i]).classTypeName
1074: .substring(
1075: 1)
1076: .replace(
1077: '/',
1078: '.')),
1079: startPoint); // XXX: should we propagate the class loader of initial user's request (Field.getGenericType()) or use this one?
1080: }
1081: } catch (ClassNotFoundException e) {
1082: throw new TypeNotPresentException(
1083: ((InterimClassType) super Interfaces[i]).classTypeName
1084: .substring(1).replace('/', '.'),
1085: e);
1086: } catch (ExceptionInInitializerError e) {
1087: } catch (LinkageError e) {
1088: }
1089: } else {
1090: // Internal Error
1091: }
1092: }
1093: }
1094: return genericInterfaces;
1095: }
1096: }
|