package org.molgenis.util; import com.google.gson.*; import org.molgenis.data.Entity; import org.molgenis.data.meta.AttributeType; import org.molgenis.data.meta.model.Attribute; import java.lang.reflect.Type; import java.util.Date; import static java.lang.String.format; /** * Serializer for concrete Entity subclasses. This allows you to return Entities in your Controllers, without having to * create DTO's with explicit fields for {@link Gson} serialization. */ public class EntitySerializer implements JsonSerializer<Entity> { private JsonElement serializeReference(Entity entity, JsonSerializationContext context) { JsonObject result = new JsonObject(); result.addProperty("__entityName", entity.getEntityType().getName()); result.add("__idValue", context.serialize(entity.getIdValue())); result.add("__labelValue", context.serialize(entity.getLabelValue())); return result; } @Override public JsonElement serialize(Entity entity, Type type, JsonSerializationContext context) { JsonObject result = new JsonObject(); result.addProperty("__entityName", entity.getEntityType().getName()); for (Attribute attr : entity.getEntityType().getAtomicAttributes()) { String attributeName = attr.getName(); Object value = entity.get(attributeName); if (value != null) { AttributeType attrType = attr.getDataType(); switch (attrType) { case BOOL: result.addProperty(attributeName, entity.getBoolean(attributeName)); break; case CATEGORICAL: case XREF: case FILE: Entity refEntity = entity.getEntity(attributeName); result.add(attributeName, serializeReference(refEntity, context)); break; case CATEGORICAL_MREF: case MREF: case ONE_TO_MANY: JsonArray jsonArray = new JsonArray(); entity.getEntities(attributeName).forEach(e -> jsonArray.add(serializeReference(e, context))); result.add(attributeName, jsonArray); break; case DATE: case DATE_TIME: Date dateValue = entity.getUtilDate(attributeName); result.add(attributeName, context.serialize(dateValue)); break; case DECIMAL: result.addProperty(attributeName, entity.getDouble(attributeName)); break; case INT: result.addProperty(attributeName, entity.getInt(attributeName)); break; case LONG: result.addProperty(attributeName, entity.getLong(attributeName)); break; case ENUM: case HTML: case HYPERLINK: case SCRIPT: case EMAIL: case STRING: case TEXT: result.addProperty(attributeName, value.toString()); break; case COMPOUND: throw new RuntimeException(format("Illegal attribute type [%s]", attrType.toString())); default: throw new RuntimeException(format("Unknown attribute type [%s]", attrType.toString())); } } } return result; } }