com.wizzardo.tools.reflection.Fields Maven / Gradle / Ivy
package com.wizzardo.tools.reflection;
import com.wizzardo.tools.interfaces.Consumer;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* Created by wizzardo on 31/05/16.
*/
public class Fields implements Iterable {
protected static final int SYNTHETIC = 0x00001000;
protected static final FieldReflectionFactory FIELD_REFLECTION_FACTORY = new FieldReflectionFactory();
protected static final FieldMapper DEFAULT_MAPPER = new FieldMapper() {
@Override
public FieldInfo map(Field field, Generic generic) {
return new FieldInfo(field, FIELD_REFLECTION_FACTORY.create(field), generic.types);
}
};
public interface FieldMapper {
R map(Field field, G generic);
}
protected final Map map;
protected final T[] array;
public Fields(Map map) {
this.map = new HashMap(map.size(), 1);
this.map.putAll(map);
array = fill(map.values(), createArray(map.size()));
}
public Fields(Class clazz) {
this(clazz, (FieldMapper) DEFAULT_MAPPER);
}
public Fields(Class clazz, FieldMapper mapper) {
this(Generic.of(clazz), mapper);
}
public Fields(Generic generic) {
this(generic, (FieldMapper) DEFAULT_MAPPER);
}
public Fields(G g, FieldMapper mapper) {
Map fields = readFields(g, new LinkedHashMap(), mapper);
this.map = new LinkedHashMap(fields.size(), 1);
this.map.putAll(fields);
array = fill(map.values(), createArray(map.size()));
}
protected T[] createArray(int size) {
return (T[]) new FieldInfo[size];
}
protected T[] fill(Collection c, T[] array) {
int i = 0;
for (T fieldInfo : c) {
array[i++] = fieldInfo;
}
return array;
}
@Override
public Iterator iterator() {
return new Iterator() {
int position = 0;
@Override
public boolean hasNext() {
return position < array.length;
}
@Override
public T next() {
return array[position++];
}
@Override
public void remove() {
throw new UnsupportedOperationException("Cannot remove an element of an array.");
}
};
}
public void each(Consumer consumer) {
for (FieldInfo fieldInfo : array) {
consumer.consume(fieldInfo);
}
}
public T get(String name) {
return map.get(name);
}
public int size() {
return map.size();
}
public boolean containsKey(String name) {
return map.containsKey(name);
}
public static Fields getFields(Class clazz) {
return getFields(clazz, DEFAULT_MAPPER);
}
public static Fields of(Class clazz) {
return getFields(clazz, DEFAULT_MAPPER);
}
public static Fields getFields(Class clazz, FieldMapper mapper) {
return new Fields(clazz, mapper);
}
protected Map readFields(G generic, Map fields, FieldMapper mapper) {
if (generic == null)
return fields;
readFields((G) generic.parent, fields, mapper);
Field[] ff = generic.clazz.getDeclaredFields();
for (Field field : ff) {
if (!Modifier.isTransient(field.getModifiers())
&& !Modifier.isStatic(field.getModifiers())
&& (field.getModifiers() & SYNTHETIC) == 0
// && !Modifier.isFinal(field.getModifiers())
// && !Modifier.isPrivate(field.getModifiers())
// && !Modifier.isProtected(field.getModifiers())
) {
field.setAccessible(true);
fields.put(field.getName(), mapper.map(field, generic));
}
}
return fields;
}
}