com.thegoate.utils.fill.serialize.model.ModelBuilder Maven / Gradle / Ivy
package com.thegoate.utils.fill.serialize.model;
import com.thegoate.annotations.AnnotationFactory;
import com.thegoate.reflection.GoateReflection;
import com.thegoate.utils.fill.serialize.Cereal;
import com.thegoate.utils.fill.serialize.DefaultSource;
import com.thegoate.utils.fill.serialize.Serializer;
import com.thegoate.utils.fill.serialize.collections.ListType;
import com.thegoate.utils.fill.serialize.collections.MapKeyType;
import com.thegoate.utils.fill.serialize.collections.MapType;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
public class ModelBuilder extends Cereal {
Class klass;
Class source = DefaultSource.class;
private List genericType = new ArrayList<>();
public ModelBuilder(Class klass) {
this.klass = klass;
}
public ModelBuilder source(Class source) {
this.source = source;
return this;
}
public ModelBuilder T(Class varType) {
genericType.add(varType);
return this;
}
public T build(Class blueprint) {
T model = null;
M definition = (M) assemble(klass);
if (definition != null) {
model = (T) new Serializer<>(definition, source).includeNulls().asSourced(true).to(blueprint);
}
return model;
}
private A assemble(Class klass) {
A definition = null;
try {
definition = (A) new AnnotationFactory().constructor(null).build(klass);
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
LOG.debug("Problem instantiating the pojo, while try casting instead (" + klass.getName() + "): " + e.getMessage(), e);
try {
definition = (A) doCast(definition, Object.class, klass);
} catch (InstantiationException | IllegalAccessException castException) {
LOG.error("failed to even cast to pojo, Goate cannot build a model of this properly: " + klass.getName(), castException);
}
}
GoateReflection gr = new GoateReflection();
if (definition == null) {
definition = (A) gr.getDefaultPrimitive(klass);
}
if (definition != null) {
if(!gr.isPrimitive(klass)) {
Map fields = gr.findFields(klass);
for (Map.Entry field : fields.entrySet()) {
Object value = gr.getFieldValue(definition, field.getValue());
if (value == null) {
boolean accessible = field.getValue().isAccessible();
field.getValue().setAccessible(true);
try {
if (gr.classIsNumber(field.getValue().getType())) {
field.getValue().set(definition, doCast("0", field.getValue().getType()));
} else if (gr.isBoolean(value)) {
field.getValue().set(definition, true);
} else if (gr.isPrimitiveOrNumerical(value)) {
field.getValue().set(value, doCast("", field.getValue().getType()));
} else if (field.getValue().getType().isArray()) { //check if array before checking if collection.
field.getValue().set(definition, buildArray(field.getValue(), field.getValue().getType()));
} else if (gr.isCollectionOrMap(field.getValue())) {
field.getValue().set(definition, buildCollection(field.getValue(), field.getValue().getType()));
} else {
Object val = assemble(field.getValue().getType());
field.getValue().set(definition, val);
}
} catch (IllegalAccessException | InstantiationException e) {
LOG.debug("problem modeling field: " + field.getKey() + ". " + e.getMessage(), e);
}
field.getValue().setAccessible(accessible);
}
}
}
}
return definition;
}
private Z buildCollection(Field field, Class zType) {
Z collection = null;
if (Collection.class.isAssignableFrom(field.getType())
|| Set.class.isAssignableFrom(field.getType())) {
ListType type = field.getAnnotation(ListType.class);
List