View Javadoc

1   /*
2    * Copyright 2008-2009 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.entropysoft.transmorph.signature;
17  
18  import java.lang.reflect.GenericArrayType;
19  import java.lang.reflect.Type;
20  import java.util.HashMap;
21  import java.util.Map;
22  
23  import net.entropysoft.transmorph.type.GenericArrayTypeImpl;
24  import net.entropysoft.transmorph.type.ParameterizedTypeImpl;
25  import net.entropysoft.transmorph.type.WildcardTypeImpl;
26  
27  public class TypeFactory {
28  	private static Map<Character, Class<?>> primitiveTypesMap = new HashMap<Character, Class<?>>();
29  
30  	static {
31  		primitiveTypesMap.put(PrimitiveTypeSignature.PRIMITIVE_BOOLEAN,
32  				Boolean.TYPE);
33  		primitiveTypesMap.put(PrimitiveTypeSignature.PRIMITIVE_BYTE, Byte.TYPE);
34  		primitiveTypesMap.put(PrimitiveTypeSignature.PRIMITIVE_CHAR,
35  				Character.TYPE);
36  		primitiveTypesMap.put(PrimitiveTypeSignature.PRIMITIVE_DOUBLE,
37  				Double.TYPE);
38  		primitiveTypesMap.put(PrimitiveTypeSignature.PRIMITIVE_FLOAT,
39  				Float.TYPE);
40  		primitiveTypesMap.put(PrimitiveTypeSignature.PRIMITIVE_INT,
41  				Integer.TYPE);
42  		primitiveTypesMap.put(PrimitiveTypeSignature.PRIMITIVE_LONG, Long.TYPE);
43  		primitiveTypesMap.put(PrimitiveTypeSignature.PRIMITIVE_SHORT,
44  				Short.TYPE);
45  	}
46  
47  	private ClassLoader classLoader;
48  
49  	public TypeFactory(ClassLoader classLoader) {
50  		this.classLoader = classLoader;
51  	}
52  
53  	public ClassLoader getClassLoader() {
54  		return classLoader;
55  	}
56  
57  	public Type getType(FullTypeSignature typeSignature)
58  			throws ClassNotFoundException {
59  		if (typeSignature.isPrimitiveType()) {
60  			return getType((PrimitiveTypeSignature) typeSignature);
61  		}
62  		if (typeSignature.isArrayType()) {
63  			return getType((ArrayTypeSignature) typeSignature);
64  		}
65  		if (typeSignature.isClassType()) {
66  			return getType((ClassTypeSignature) typeSignature);
67  		}
68  		if (typeSignature.isTypeVar()) {
69  			throw new ClassNotFoundException("Type variable not supported");
70  		}
71  		throw new ClassNotFoundException("Signature type not supported");
72  	}
73  
74  	public Type getType(PrimitiveTypeSignature primitiveTypeSignature) {
75  		return primitiveTypesMap.get(primitiveTypeSignature
76  				.getPrimitiveTypeChar());
77  	}
78  
79  	public GenericArrayType getType(ArrayTypeSignature arrayTypeSignature)
80  			throws ClassNotFoundException {
81  		Type componentType = getType(arrayTypeSignature
82  				.getComponentTypeSignature());
83  		return new GenericArrayTypeImpl(componentType);
84  	}
85  
86  	public Type getType(ClassTypeSignature classTypeSignature)
87  			throws ClassNotFoundException {
88  		TypeArgSignature[] typeArgSignatures = classTypeSignature
89  				.getTypeArgSignatures();
90  		if (typeArgSignatures.length == 0) {
91  			return getClass(classTypeSignature);
92  		}
93  		Class<?> rawType = (Class<?>)getType(classTypeSignature.getTypeErasureSignature());
94  		Type ownerType;
95  		if (classTypeSignature.getOwnerTypeSignature() == null) {
96  			ownerType = null;
97  		} else {
98  			ownerType = getType(classTypeSignature.getOwnerTypeSignature());
99  		}
100 
101 		Type[] actualTypeArguments = new Type[typeArgSignatures.length];
102 		for (int i = 0; i < actualTypeArguments.length; i++) {
103 			actualTypeArguments[i] = getType(typeArgSignatures[i]);
104 		}
105 		return new ParameterizedTypeImpl(rawType, actualTypeArguments,
106 				ownerType);
107 	}
108 
109 	private Class<?> getClass(ClassTypeSignature typeErasureSignature)
110 			throws ClassNotFoundException {
111 		String className = typeErasureSignature.getClassName();
112 		return Class.forName(className, true, classLoader);
113 	}
114 
115 	private Type getType(TypeArgSignature typeArgSignature)
116 			throws ClassNotFoundException {
117 		char wildcard = typeArgSignature.getWildcard();
118 		if (wildcard == TypeArgSignature.NO_WILDCARD) {
119 			return getType(typeArgSignature.getFieldTypeSignature());
120 		}
121 		if (wildcard == TypeArgSignature.UNBOUNDED_WILDCARD) {
122 			return new WildcardTypeImpl(new Type[] { Object.class },
123 					new Type[0]);
124 		}
125 		if (wildcard == TypeArgSignature.LOWERBOUND_WILDCARD) {
126 			return new WildcardTypeImpl(new Type[] { Object.class },
127 					new Type[] { getType(typeArgSignature
128 							.getFieldTypeSignature()) });
129 		}
130 		if (wildcard == TypeArgSignature.UPPERBOUND_WILDCARD) {
131 			return new WildcardTypeImpl(new Type[] { getType(typeArgSignature
132 					.getFieldTypeSignature()) }, new Type[0]);
133 		}
134 		throw new ClassNotFoundException(
135 				"Invalid wildcard in type arg signature");
136 	}
137 }