package org.molgenis.data.elasticsearch.converter;
import org.molgenis.data.Entity;
import org.molgenis.data.EntityManager;
import org.molgenis.data.MolgenisDataException;
import org.molgenis.data.UnknownAttributeException;
import org.molgenis.data.meta.AttributeType;
import org.molgenis.data.meta.model.Attribute;
import org.molgenis.data.meta.model.EntityType;
import org.molgenis.util.MolgenisDateFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.stream.StreamSupport;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static org.molgenis.data.EntityManager.CreationMode.NO_POPULATE;
@Component
public class SourceToEntityConverter
{
private final EntityManager entityManager;
@Autowired
public SourceToEntityConverter(EntityManager entityManager)
{
this.entityManager = requireNonNull(entityManager);
}
public Entity convert(Map<String, Object> source, EntityType entityType)
{
Entity entity = entityManager.create(entityType, NO_POPULATE);
source.entrySet().forEach(entry ->
{
String attrName = entry.getKey();
Attribute attr = entityType.getAttribute(attrName);
if (attr == null)
{
throw new UnknownAttributeException(
"Unknown attribute [" + attrName + "] of entity [" + entityType.getName());
}
Object sourceValue = entry.getValue();
Object entityValue;
if (sourceValue != null)
{
AttributeType attrType = attr.getDataType();
switch (attr.getDataType())
{
case BOOL:
case DECIMAL:
case EMAIL:
case ENUM:
case HTML:
case HYPERLINK:
case INT:
case LONG:
case SCRIPT:
case STRING:
case TEXT:
entityValue = sourceValue;
break;
case CATEGORICAL:
case FILE:
case XREF:
// TODO store id for xrefs
if (sourceValue instanceof Map<?, ?>)
{
@SuppressWarnings("unchecked")
Map<String, Object> sourceRefEntity = (Map<String, Object>) sourceValue;
EntityType refEntity = attr.getRefEntity();
String refIdAttrName = refEntity.getIdAttribute().getName();
Object sourceRefEntityId = sourceRefEntity.get(refIdAttrName);
entityValue = entityManager.getReference(refEntity, sourceRefEntityId);
}
else
{
throw new RuntimeException("Unexpected type [" + sourceValue.getClass().getSimpleName()
+ "], expected [Map<String, Object]");
}
break;
case CATEGORICAL_MREF:
case MREF:
if (sourceValue instanceof Iterable<?>)
{
// TODO store list of ids for mrefs
@SuppressWarnings("unchecked")
Iterable<Map<String, Object>> sourceRefEntities = (Iterable<Map<String, Object>>) sourceValue;
EntityType refEntity = attr.getRefEntity();
String refIdAttrName = refEntity.getIdAttribute().getName();
Iterable<Object> sourceRefEntityIds = () -> StreamSupport
.stream(sourceRefEntities.spliterator(), false)
.map(sourceRefEntity -> sourceRefEntity.get(refIdAttrName)).iterator();
entityValue = entityManager.getReferences(refEntity, sourceRefEntityIds);
}
else
{
throw new RuntimeException("Unexpected type [" + sourceValue.getClass().getSimpleName()
+ "], expected [Iterable<Map<String, Object>>]");
}
break;
case COMPOUND:
throw new RuntimeException("Compound attribute is not an atomic attribute");
case DATE:
try
{
entityValue = MolgenisDateFormat.getDateFormat().parse((String) sourceValue);
}
catch (Exception e)
{
throw new MolgenisDataException(e);
}
break;
case DATE_TIME:
try
{
entityValue = MolgenisDateFormat.getDateTimeFormat().parse((String) sourceValue);
}
catch (Exception e)
{
throw new MolgenisDataException(e);
}
break;
default:
throw new RuntimeException(format("Unknown data type [%s]", attrType.toString()));
}
}
else
{
entityValue = null;
}
entity.set(attrName, entityValue);
});
return entity;
}
}