/*
* Beanfabrics Framework Copyright (C) by Michael Karneim, beanfabrics.org
* Use is subject to license terms. See license.txt.
*/
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.Collection;
import org.beanfabrics.model.MapPM;
import org.beanfabrics.model.OperationPM;
import org.beanfabrics.model.PresentationModel;
public class DumpGenericTypeDemo {
static abstract class Foo<X extends Foo<X>> implements Comparable<X> {
}
static abstract class Bar<X extends Foo<X>, Z extends X> extends Foo<X> implements Iterable<Z> {
}
private static interface IGelb<G> {
G getG();
}
private static interface IBlau<B> {
B getB();
}
private static class MapCell2<G1, K1, V1 extends PresentationModel> extends MapPM<K1, V1> implements IGelb<G1> {
public G1 getG() {
return null;
}
}
private static class MyMap2 extends MapCell2<Integer, String, OperationPM> {
}
public static void main(String[] args) {
// System.out.println(dump(Foo.class));
// System.out.println(dump(Bar.class));
System.out.println(dump(Iterable.class));
System.out.println(dump(Collection.class));
// System.out.println(dump(MyMap2.class));
// System.out.println(dump(MapCell2.class));
// System.out.println(dump(MapPM.class));
// System.out.println(dump(IMapPM.class));
// System.out.println(dump(IListPM.class));
}
private static <T> String dump(Class<T> clz) {
StringBuilder sb = new StringBuilder();
dump(sb, clz);
return sb.toString();
}
private static <T> void dump(StringBuilder sb, Class<T> clz) {
sb.append(clz.getSimpleName());
dumpTypeParameters(sb, clz.getTypeParameters());
if (clz.getSuperclass() != null) {
sb.append(" extends ");
dumpType(sb, clz.getGenericSuperclass());
}
if (clz.getInterfaces().length > 0) {
sb.append(" implements ");
Type[] interfaces = clz.getGenericInterfaces();
dumpType(sb, interfaces[0]);
for (int i = 1; i < interfaces.length; i++) {
sb.append(", ");
dumpType(sb, interfaces[i]);
}
}
}
private static <T> void dumpTypeParameters(StringBuilder sb, TypeVariable<Class<T>>[] tva) {
if (tva.length > 0) {
sb.append("<");
if (tva.length > 0) {
dumpTypeVariableDefinition(sb, tva[0]);
for (int i = 1; i < tva.length; i++) {
sb.append(", ");
dumpTypeVariableDefinition(sb, tva[i]);
}
}
sb.append(">");
}
}
private static void dumpTypeArguments(StringBuilder sb, Type[] ta) {
if (ta.length > 0) {
sb.append("<");
dumpType(sb, ta[0]);
for (int i = 1; i < ta.length; i++) {
sb.append(", ");
dumpType(sb, ta[i]);
}
sb.append(">");
}
}
private static <T> void dumpTypeVariableDefinition(StringBuilder sb, TypeVariable<Class<T>> tv) {
sb.append(tv.getName());
Type[] ba = tv.getBounds();
if (ba.length > 0) {
if ((ba.length > 1) || !Object.class.equals(ba[0])) {
sb.append(" extends ");
dumpType(sb, ba[0]);
for (int i = 1; i < ba.length; i++) {
sb.append(" & ");
dumpType(sb, ba[i]);
}
}
}
}
private static <T> void dumpType(StringBuilder sb, Type type) {
if (type instanceof WildcardType) {
dumpWildcardType(sb, (WildcardType)type);
} else if (type instanceof ParameterizedType) {
dumpParameterizedType(sb, (ParameterizedType)type);
} else if (type instanceof GenericArrayType) {
dumpGenericArrayType(sb, (GenericArrayType)type);
} else if (type instanceof TypeVariable) {
dumpTypeVariableReference(sb, (TypeVariable)type);
} else if (type instanceof Class) {
sb.append(((Class)type).getSimpleName());
} else {
throw new RuntimeException("unknown type: " + type + " := " + type.getClass());
}
}
private static void dumpWildcardType(StringBuilder sb, WildcardType wildcardType) {
throw new UnsupportedOperationException("Not yet implemented");
}
private static void dumpParameterizedType(StringBuilder sb, ParameterizedType parameterizedType) {
dumpType(sb, parameterizedType.getRawType());
dumpTypeArguments(sb, parameterizedType.getActualTypeArguments());
}
private static void dumpGenericArrayType(StringBuilder sb, GenericArrayType genericArrayType) {
throw new UnsupportedOperationException("Not yet implemented");
}
private static void dumpTypeVariableReference(StringBuilder sb, TypeVariable typeVariable) {
sb.append(typeVariable.getName());
}
}