package org.apache.beehive.wsm.processor.apt;
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Header:$
*/
import com.sun.mirror.type.ArrayType;
import com.sun.mirror.type.PrimitiveType;
import com.sun.mirror.type.TypeMirror;
import com.sun.mirror.type.VoidType;
public class TypeMirrorUtil {
// returns a class object of the specified type.
public static Class classForName(TypeMirror type) throws ClassNotFoundException {
Class clazz = null;
try {
if (type instanceof PrimitiveType) {
clazz = getPrimitiveClass(((PrimitiveType) type).getKind());
}
else if (type instanceof VoidType) {
clazz = void.class;
}
else if (type instanceof ArrayType) {
Object[] typeOfArray = new Object[]{new Object()};
int arrayDepth = arrayDepth((ArrayType) type, 0, typeOfArray);
StringBuffer className = new StringBuffer();
for (int i = 0; i < arrayDepth; i++) {
className.append("[");
}
TypeMirror mirrorTypeOfArray = (TypeMirror) typeOfArray[0];
if (mirrorTypeOfArray instanceof PrimitiveType) {
// e.g. an array of int will be "[I".
className.append(getTypeSignatureOfPrimitiveType(((PrimitiveType) mirrorTypeOfArray).getKind()));
}
else {
// e.g. an array of String will be "[Ljava.lang.String;".
className.append("L").append(((TypeMirror) typeOfArray[0]).toString()).append(";");
}
clazz = findClass(className.toString());
}
else {
clazz = findClass(type.toString());
}
}
catch (ClassNotFoundException e) {
throw new ClassNotFoundException(type.toString());
}
return clazz;
}
private static Class getPrimitiveClass(PrimitiveType.Kind kind) throws ClassNotFoundException {
// todo: change order of the cases for better performance.
switch (kind) {
case BOOLEAN:
return boolean.class;
case BYTE:
return byte.class;
case CHAR:
return char.class;
case DOUBLE:
return double.class;
case FLOAT:
return float.class;
case INT:
return int.class;
case LONG:
return long.class;
case SHORT:
return short.class;
}
throw new ClassNotFoundException();
}
private static String getTypeSignatureOfPrimitiveType(PrimitiveType.Kind kind) throws ClassNotFoundException {
// todo: change order of the cases for better performance.
switch (kind) {
case BOOLEAN:
return "Z";
case BYTE:
return "B";
case CHAR:
return "C";
case DOUBLE:
return "D";
case FLOAT:
return "F";
case INT:
return "I";
case LONG:
return "J";
case SHORT:
return "S";
}
throw new ClassNotFoundException();
}
private static int arrayDepth(ArrayType type, int depth, Object[] typeOfArray) {
if (type.getComponentType() instanceof ArrayType) {
return arrayDepth((ArrayType) type.getComponentType(), ++depth, typeOfArray);
} else {
typeOfArray[0] = type.getComponentType();
}
return ++depth;
}
/**
* Since we work using the Mirror API, we need to look for inner classes
* ourselves. This method assumes that the class we're looking for is
* readily available through the class loader.
* @param className
* @return
* @throws ClassNotFoundException
*/
private static Class findClass(String className) throws ClassNotFoundException {
Class clazz = null;
int idx = className.lastIndexOf('.');
if (-1 == idx) {
clazz = Class.forName(className);
}
else {
try {
clazz = Class.forName(className);
}
catch (ClassNotFoundException e) {
char[] chars = className.toCharArray();
for (int i = chars.length - 1; i >= 0 ; i--) {
if ('.' == chars[i]) {
chars[i] = '$';
break;
}
}
clazz = findClass(new String(chars));
}
}
return clazz;
}
}