package io.robe.convert.common;
import io.robe.convert.common.annotation.Convert;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
/**
* Abstract Converter class to include common concepts and util methods
*/
public abstract class Converter {
/**
* Holds the class of data type.
*/
private final Class dataClass;
public Converter(Class dataClass) {
this.dataClass = dataClass;
}
/**
* Returns the class of data type which was given at constructor.
*
* @return data class.
*/
public Class getDataClass() {
return dataClass;
}
protected final boolean isSuitable(Convert ann) {
return ((ann != null) && !ann.ignore());
}
/**
* Returns an ordered list of the fields which belongs to the given class.
*
* @param clazz class to get types.
* @return ordered list of fields.
*/
protected final Collection<FieldEntry> getFields(Class clazz) {
LinkedList<FieldEntry> fieldList = getAllFields(clazz);
Collections.sort(fieldList, new Comparator<FieldEntry>() {
public int compare(FieldEntry o1, FieldEntry o2) {
return o1.compareTo(o2);
}
});
return fieldList;
}
protected final LinkedList<FieldEntry> getAllFields(Class clazz) {
LinkedList<FieldEntry> fieldList = new LinkedList<>();
if (clazz.getSuperclass() != null) {
fieldList = getAllFields(clazz.getSuperclass());
}
for (Field field : clazz.getDeclaredFields()) {
Convert cfAnn = field.getAnnotation(Convert.class);
if (isSuitable(cfAnn)) {
fieldList.add(new FieldEntry(cfAnn.order(), field));
}
}
return fieldList;
}
/**
* Returns a map of the fields which belongs to the given class with field name as key.
*
* @param clazz class to get types.
* @return ordered list of fields.
*/
protected final Map<String, Field> getFieldMap(Class clazz) {
Map<String, Field> fieldList = new HashMap<String, Field>();
for (FieldEntry entry : getAllFields(clazz)) {
Field field = entry.getValue();
fieldList.put(field.getName(), field);
}
return fieldList;
}
public static class FieldEntry implements Map.Entry<Integer, Field>, Comparable<FieldEntry> {
private Integer key = null;
private Field value = null;
public FieldEntry(Integer key, Field value) {
this.key = key;
this.value = value;
}
@Override
public Integer getKey() {
return this.key;
}
@Override
public Field getValue() {
return this.value;
}
@Override
public Field setValue(Field value) {
this.value = value;
return value;
}
@Override
public int compareTo(FieldEntry o) {
return this.getKey().compareTo(o.getKey());
}
}
}