2020-01-16 10:06:28 +00:00
|
|
|
package com.terraforged.core.util.serialization.serializer;
|
|
|
|
|
|
|
|
import com.terraforged.core.util.serialization.annotation.Comment;
|
|
|
|
import com.terraforged.core.util.serialization.annotation.Range;
|
|
|
|
import com.terraforged.core.util.serialization.annotation.Serializable;
|
|
|
|
|
|
|
|
import java.lang.reflect.Array;
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
import java.lang.reflect.Modifier;
|
|
|
|
|
|
|
|
public class Serializer {
|
|
|
|
|
|
|
|
public void serialize(Object object, Writer writer) throws IllegalAccessException {
|
|
|
|
if (object.getClass().isArray()) {
|
|
|
|
writer.beginArray();
|
|
|
|
int length = Array.getLength(object);
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
Object element = Array.get(object, i);
|
|
|
|
serialize(element, writer);
|
|
|
|
}
|
|
|
|
writer.endArray();
|
|
|
|
} else if (!object.getClass().isPrimitive()) {
|
|
|
|
int order = 0;
|
|
|
|
writer.beginObject();
|
|
|
|
for (Field field : object.getClass().getFields()) {
|
|
|
|
if (Serializer.isSerializable(field)) {
|
|
|
|
field.setAccessible(true);
|
|
|
|
write(object, field, order, writer);
|
|
|
|
order++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
writer.endObject();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void write(Object object, Field field, int order, Writer writer) throws IllegalAccessException {
|
|
|
|
if (field.getType() == int.class) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name(field.getName());
|
2020-01-16 10:06:28 +00:00
|
|
|
writer.beginObject();
|
|
|
|
writer.name("value").value((int) field.get(object));
|
|
|
|
writeMeta(field, order, writer);
|
|
|
|
writer.endObject();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (field.getType() == float.class) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name(field.getName());
|
2020-01-16 10:06:28 +00:00
|
|
|
writer.beginObject();
|
|
|
|
writer.name("value").value((float) field.get(object));
|
|
|
|
writeMeta(field, order, writer);
|
|
|
|
writer.endObject();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (field.getType() == String.class) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name(field.getName());
|
2020-01-16 10:06:28 +00:00
|
|
|
writer.beginObject();
|
|
|
|
writer.name("value").value((String) field.get(object));
|
|
|
|
writeMeta(field, order, writer);
|
|
|
|
writer.endObject();
|
|
|
|
return;
|
|
|
|
}
|
2020-02-24 12:30:13 +00:00
|
|
|
if (field.getType() == boolean.class) {
|
|
|
|
writer.name(field.getName());
|
|
|
|
writer.beginObject();
|
|
|
|
writer.name("value").value("" + (field.get(object)));
|
|
|
|
writeMeta(field, order, writer);
|
|
|
|
writer.endObject();
|
|
|
|
}
|
2020-01-16 10:06:28 +00:00
|
|
|
if (field.getType().isEnum()) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name(field.getName());
|
2020-01-16 10:06:28 +00:00
|
|
|
writer.beginObject();
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name("value").value(((Enum<?>) field.get(object)).name());
|
2020-01-16 10:06:28 +00:00
|
|
|
writeMeta(field, order, writer);
|
|
|
|
writer.endObject();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (field.getType().isArray()) {
|
|
|
|
if (field.getType().getComponentType().isAnnotationPresent(Serializable.class)) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name(field.getName());
|
2020-01-16 10:06:28 +00:00
|
|
|
writer.beginObject();
|
|
|
|
writer.name("value");
|
|
|
|
serialize(field.get(object), writer);
|
|
|
|
writeMeta(field, order, writer);
|
|
|
|
writer.endObject();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (field.getType().isAnnotationPresent(Serializable.class)) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name(field.getName());
|
2020-01-16 10:06:28 +00:00
|
|
|
writer.beginObject();
|
|
|
|
writer.name("value");
|
|
|
|
serialize(field.get(object), writer);
|
|
|
|
writeMeta(field, order, writer);
|
|
|
|
writer.endObject();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void writeMeta(Field field, int order, Writer writer) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name("#display").value(getName(field));
|
|
|
|
writer.name("#order").value(order);
|
2020-01-16 10:06:28 +00:00
|
|
|
|
|
|
|
Range range = field.getAnnotation(Range.class);
|
|
|
|
if (range != null) {
|
|
|
|
if (field.getType() == int.class) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name("#min").value((int) range.min());
|
|
|
|
writer.name("#max").value((int) range.max());
|
2020-01-16 10:06:28 +00:00
|
|
|
} else {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name("#min").value(range.min());
|
|
|
|
writer.name("#max").value(range.max());
|
2020-01-16 10:06:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Comment comment = field.getAnnotation(Comment.class);
|
|
|
|
if (comment != null) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name("#comment");
|
2020-01-16 10:06:28 +00:00
|
|
|
writer.beginArray();
|
|
|
|
for (String line : comment.value()) {
|
|
|
|
writer.value(line);
|
|
|
|
}
|
|
|
|
writer.endArray();
|
|
|
|
}
|
|
|
|
|
2020-02-24 12:30:13 +00:00
|
|
|
if (field.getType() == boolean.class) {
|
|
|
|
writer.name("#options");
|
|
|
|
writer.beginArray();
|
|
|
|
writer.value("true");
|
|
|
|
writer.value("false");
|
|
|
|
writer.endArray();
|
|
|
|
}
|
|
|
|
|
2020-01-16 10:06:28 +00:00
|
|
|
if (field.getType().isEnum()) {
|
2020-02-24 12:30:13 +00:00
|
|
|
writer.name("#options");
|
2020-01-16 10:06:28 +00:00
|
|
|
writer.beginArray();
|
2020-02-24 12:30:13 +00:00
|
|
|
for (Enum<?> o : field.getType().asSubclass(Enum.class).getEnumConstants()) {
|
2020-01-16 10:06:28 +00:00
|
|
|
writer.value(o.name());
|
|
|
|
}
|
|
|
|
writer.endArray();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static String getName(Field field) {
|
|
|
|
String name = field.getName();
|
|
|
|
StringBuilder sb = new StringBuilder(name.length() * 2);
|
|
|
|
for (int i = 0; i < name.length(); i++) {
|
|
|
|
char c = name.charAt(i);
|
2020-02-24 12:30:13 +00:00
|
|
|
if (i == 0) {
|
|
|
|
c = Character.toUpperCase(c);
|
|
|
|
} else if (Character.isUpperCase(c)) {
|
|
|
|
sb.append(' ');
|
2020-01-16 10:06:28 +00:00
|
|
|
}
|
2020-02-24 12:30:13 +00:00
|
|
|
|
|
|
|
sb.append(c);
|
2020-01-16 10:06:28 +00:00
|
|
|
}
|
|
|
|
return sb.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static boolean isSerializable(Field field) {
|
|
|
|
int modifiers = field.getModifiers();
|
|
|
|
return Modifier.isPublic(modifiers)
|
|
|
|
&& !Modifier.isFinal(modifiers)
|
|
|
|
&& !Modifier.isStatic(modifiers)
|
|
|
|
&& !Modifier.isTransient(modifiers);
|
|
|
|
}
|
|
|
|
}
|