package openmods.utils;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Ints;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public abstract class FieldsSelector {
public static class FieldEntry implements Comparable<FieldEntry> {
public final Field field;
public final int rank;
public FieldEntry(Field field, int rank) {
this.field = field;
this.rank = rank;
}
@Override
public int compareTo(FieldEntry o) {
int result = Ints.compare(this.rank, o.rank);
if (result != 0) return result;
return this.field.getName().compareTo(o.field.getName());
}
}
private final CachedFactory<Class<?>, Collection<Field>> cache = new CachedFactory<Class<?>, Collection<Field>>() {
@Override
protected Collection<Field> create(Class<?> key) {
return scanForFields(key);
}
};
protected abstract List<FieldEntry> listFields(Class<?> cls);
private Collection<Field> scanForFields(Class<?> cls) {
final List<FieldEntry> entries = listFields(cls);
Collections.sort(entries);
ImmutableList.Builder<Field> result = ImmutableList.builder();
for (FieldEntry entry : entries) {
final Field field = entry.field;
result.add(field);
field.setAccessible(true);
}
return result.build();
}
public Collection<Field> getFields(Class<?> cls) {
synchronized (cache) {
return cache.getOrCreate(cls);
}
}
}