package tc.oc.commons.core.reflect;
import java.lang.reflect.TypeVariable;
import com.google.common.cache.LoadingCache;
import com.google.common.reflect.TypeToken;
import com.google.inject.TypeLiteral;
import tc.oc.commons.core.util.CacheUtils;
public class TypeParameterCache<D, V> {
private final LoadingCache<Class<? extends D>, TypeToken<V>> cache;
public TypeParameterCache(Class<D> decl, String name) {
this(Types.typeVariable(decl, name));
}
public TypeParameterCache(TypeVariable<Class<D>> typeVariable) {
cache = CacheUtils.newCache(
context -> (TypeToken<V>) Types.assertFullySpecified(TypeToken.of(context).resolveType(typeVariable))
);
}
public TypeToken<V> resolve(Class<? extends D> context) {
return cache.getUnchecked(context);
}
public TypeToken<V> resolve(TypeToken<? extends D> context) {
return cache.getUnchecked((Class<? extends D>) context.getRawType());
}
public TypeLiteral<V> resolve(TypeLiteral<? extends D> context) {
return Types.toLiteral(cache.getUnchecked((Class<? extends D>) context.getRawType()));
}
public Class<V> resolveRaw(Class<? extends D> context) {
return (Class<V>) resolve(context).getRawType();
}
}