/* * Copied from Gentyref project http://code.google.com/p/gentyref/ * Reformatted and moved to fit package structure */ package com.google.sitebricks.conversion.generics; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; /** * Wrapper around {@link Type}. * * You can use this to create instances of Type for a type known at compile * time. * * For example, to get the Type that represents List<String>: * <code>Type listOfString = new TypeToken<List<String>>(){}.getType();</code> * * @author Wouter Coekaerts <wouter@coekaerts.be> * * @param <T> * The type represented by this TypeToken. */ public abstract class TypeToken<T> { private final Type type; /** * Constructs a type token. */ protected TypeToken() { this.type = extractType(); } private TypeToken(Type type) { this.type = type; } public Type getType() { return type; } private Type extractType() { Type t = getClass().getGenericSuperclass(); if (!(t instanceof ParameterizedType)) { throw new RuntimeException("Invalid TypeToken; must specify type parameters"); } ParameterizedType pt = (ParameterizedType) t; if (pt.getRawType() != TypeToken.class) { throw new RuntimeException("Invalid TypeToken; must directly extend TypeToken"); } return pt.getActualTypeArguments()[0]; } /** * Gets type token for the given {@code Class} instance. */ public static <T> TypeToken<T> get(Class<T> type) { return new SimpleTypeToken<T>(type); } /** * Gets type token for the given {@code Type} instance. */ public static TypeToken<?> get(Type type) { return new SimpleTypeToken<Object>(type); } private static class SimpleTypeToken<T> extends TypeToken<T> { public SimpleTypeToken(Type type) { super(type); } } @Override public boolean equals(Object obj) { return (obj instanceof TypeToken<?>) && type.equals(((TypeToken<?>) obj).type); } @Override public int hashCode() { return type.hashCode(); } }