package org.molgenis.data.populate; import org.molgenis.data.Entity; import org.molgenis.data.EntityReferenceCreator; import org.molgenis.data.meta.AttributeType; import org.molgenis.data.meta.model.Attribute; import org.molgenis.data.meta.model.EntityType; import org.molgenis.util.ListEscapeUtils; import org.molgenis.util.MolgenisDateFormat; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.text.ParseException; import java.util.Date; import java.util.List; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; import static java.lang.String.format; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toList; import static org.molgenis.util.EntityUtils.asStream; import static org.molgenis.util.MolgenisDateFormat.getDateFormat; import static org.molgenis.util.MolgenisDateFormat.getDateTimeFormat; /** * Populate entity values for attributes with default values */ @Component public class DefaultValuePopulator { private final EntityReferenceCreator entityReferenceCreator; @Autowired public DefaultValuePopulator(EntityReferenceCreator entityReferenceCreator) { this.entityReferenceCreator = requireNonNull(entityReferenceCreator); } /** * Populates an entity with default values * * @param entity populated entity */ public void populate(Entity entity) { asStream(entity.getEntityType().getAllAttributes()).filter(Attribute::hasDefaultValue) .forEach(attr -> populateDefaultValues(entity, attr)); } private void populateDefaultValues(Entity entity, Attribute attr) { Object defaultValueAsString = getDefaultValue(attr); entity.set(attr.getName(), defaultValueAsString); } private Object getDefaultValue(Attribute attr) { String valueAsString = attr.getDefaultValue(); return convertToTypedValue(attr, valueAsString); } private Object convertToTypedValue(Attribute attr, String valueAsString) { AttributeType attrType = attr.getDataType(); switch (attrType) { case BOOL: return convertBool(attr, valueAsString); case CATEGORICAL: case FILE: case XREF: return convertRef(attr, valueAsString); case CATEGORICAL_MREF: case MREF: case ONE_TO_MANY: return convertMref(attr, valueAsString); case DATE: return convertDate(attr, valueAsString); case DATE_TIME: return convertDateTime(attr, valueAsString); case DECIMAL: return convertDecimal(valueAsString); case EMAIL: case ENUM: case HTML: case HYPERLINK: case SCRIPT: case STRING: case TEXT: return valueAsString; case INT: return convertInt(valueAsString); case LONG: return convertLong(valueAsString); case COMPOUND: throw new RuntimeException(format("Illegal attribute type [%s]", attrType.toString())); default: throw new RuntimeException(format("Unknown attribute type [%s]", attrType.toString())); } } private static Long convertLong(String valueAsString) { return Long.valueOf(valueAsString); } private static Integer convertInt(String valueAsString) { return Integer.valueOf(valueAsString); } private static Double convertDecimal(String valueAsString) { return Double.valueOf(valueAsString); } private static Date convertDate(Attribute attr, String valueAsString) { try { return getDateFormat().parse(valueAsString); } catch (ParseException e) { throw new RuntimeException( format("Attribute [%s] value [%s] does not match date format [%s]", attr.getName(), valueAsString, MolgenisDateFormat.getDateFormat().toPattern())); } } private static Date convertDateTime(Attribute attr, String valueAsString) { try { return getDateTimeFormat().parse(valueAsString); } catch (ParseException e) { throw new RuntimeException( format("Attribute [%s] value [%s] does not match date format [%s]", attr.getName(), valueAsString, MolgenisDateFormat.getDateTimeFormat().toPattern())); } } private static Boolean convertBool(Attribute attr, String valueAsString) { if (valueAsString.equalsIgnoreCase(TRUE.toString())) { return true; } else if (valueAsString.equalsIgnoreCase(FALSE.toString())) { return false; } else { throw new RuntimeException( format("Attribute [%s] value [%s] cannot be converter to type [%s]", attr.getName(), valueAsString, Boolean.class.getSimpleName())); } } private Entity convertRef(Attribute attr, String idValueAsString) { EntityType refEntityType = attr.getRefEntity(); Object idValue = convertToTypedValue(refEntityType.getIdAttribute(), idValueAsString); return entityReferenceCreator.getReference(refEntityType, idValue); } private List<Entity> convertMref(Attribute attr, String idValuesAsString) { List<String> valuesAsString = ListEscapeUtils.toList(idValuesAsString); return valuesAsString.stream().map(refValueAsString -> convertRef(attr, refValueAsString)).collect(toList()); } }