package tc.oc.commons.core.reflect;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import com.google.common.collect.ForwardingSet;
import com.google.common.reflect.TypeToken;
/**
* A {@link Set} of {@link TypeToken}s with the property that no member is
* assignable to any other member of the set.
*
* Exactly how this property is maintained depends on the {@link #prune(TypeToken)}
* method, which subclasses must implement.
*/
public abstract class MinimalTypeSet<T extends TypeToken<?>, C extends Class<?>> extends ForwardingSet<T> {
private final Set<T> types = new HashSet<>();
@Override protected Set<T> delegate() { return types; }
protected abstract boolean prune(T type);
@Override
public boolean add(T type) {
if(types.contains(type)) return false;
if(!prune(type)) return false;
types.add(type);
return true;
}
public boolean add(C type) {
return add((T) TypeToken.of(type));
}
public boolean add(Type type) {
return add((T) TypeToken.of(type));
}
@Override
public boolean addAll(Collection<? extends T> types) {
boolean changed = false;
for(T t : types) {
if(add(t)) changed = true;
}
return changed;
}
public Set<C> toClassSet() {
return types.stream()
.map(t -> (C) t.getRawType())
.collect(Collectors.toSet());
}
}