Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.molgenis.data.support;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Streams.stream;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Map;
import java.util.stream.Collectors;
import org.molgenis.data.Entity;
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.data.util.EntityTypeUtils;
import org.molgenis.util.UnexpectedEnumException;
/**
* Class for entities not defined in pre-existing Java classes
*
* @see StaticEntity
*/
public class DynamicEntity implements Entity {
/** Entity meta data */
private final EntityType entityType;
/** Maps attribute names to values. Value class types are determined by attribute data type. */
private final Map values;
/**
* Constructs an entity with the given entity meta data.
*
* @param entityType entity meta
*/
public DynamicEntity(EntityType entityType) {
this.entityType = requireNonNull(entityType);
this.values = newHashMap();
}
/**
* Constructs an entity with the given entity meta data and initialized the entity with the given
* data.
*
* @param entityType entity meta
* @param values map with attribute name-value pairs
*/
public DynamicEntity(EntityType entityType, Map values) {
this(entityType);
values.forEach(this::set);
}
public EntityType getEntityType() {
return entityType;
}
@Override
public Iterable getAttributeNames() {
return stream(entityType.getAtomicAttributes()).map(Attribute::getName)::iterator;
}
@Override
public Object getIdValue() {
// abstract entities might not have an id attribute
Attribute idAttr = entityType.getIdAttribute();
return idAttr != null ? get(idAttr.getName()) : null;
}
@Override
public void setIdValue(Object id) {
Attribute idAttr = entityType.getIdAttribute();
if (idAttr == null) {
throw new IllegalArgumentException(
format("Entity [%s] doesn't have an id attribute", entityType.getId()));
}
set(idAttr.getName(), id);
}
@Override
public Object getLabelValue() {
// abstract entities might not have an label attribute
Attribute labelAttr = entityType.getLabelAttribute();
return labelAttr != null ? get(labelAttr.getName()) : null;
}
@Override
public Object get(String attrName) {
return values.get(attrName);
}
@Override
public String getString(String attrName) {
return (String) get(attrName);
}
@Override
public Integer getInt(String attrName) {
return (Integer) get(attrName);
}
@Override
public Long getLong(String attrName) {
return (Long) get(attrName);
}
@Override
public Boolean getBoolean(String attrName) {
return (Boolean) get(attrName);
}
@Override
public Double getDouble(String attrName) {
return (Double) get(attrName);
}
@Override
public Instant getInstant(String attrName) {
return (Instant) get(attrName);
}
@Override
public LocalDate getLocalDate(String attrName) {
return (LocalDate) get(attrName);
}
@Override
public Entity getEntity(String attrName) {
return (Entity) get(attrName);
}
@SuppressWarnings("unchecked")
@Override
public E getEntity(String attrName, Class clazz) {
return (E) get(attrName);
}
@SuppressWarnings("unchecked")
@Override
public Iterable getEntities(String attrName) {
Object value = get(attrName);
return value != null ? (Iterable) value : emptyList();
}
@SuppressWarnings("unchecked")
@Override
public Iterable getEntities(String attrName, Class clazz) {
Object value = get(attrName);
return value != null ? (Iterable) value : emptyList();
}
@Override
public void set(String attrName, Object value) {
validateValueType(attrName, value);
values.put(attrName, value);
}
@Override
public void set(Entity values) {
values.getAttributeNames().forEach(attrName -> set(attrName, values.get(attrName)));
}
/**
* Validate is value is of the type defined by the attribute data type.
*
* @param attrName attribute name
* @param value value (must be of the type defined by the attribute data type.)
*/
protected void validateValueType(String attrName, Object value) {
if (value == null) {
return;
}
Attribute attr = entityType.getAttribute(attrName);
if (attr == null) {
throw new UnknownAttributeException(entityType, attrName);
}
AttributeType dataType = attr.getDataType();
switch (dataType) {
case BOOL:
if (!(value instanceof Boolean)) {
throw new MolgenisDataException(
format(
"Value [%s] is of type [%s] instead of [%s] for attribute: [%s]",
value.toString(),
value.getClass().getSimpleName(),
Boolean.class.getSimpleName(),
attrName));
}
break;
case CATEGORICAL:
// expected type is FileMeta. validation is not possible because molgenis-data does not
// depend on molgenis-file
case FILE:
case XREF:
if (!(value instanceof Entity)) {
throw new MolgenisDataException(
format(
"Value [%s] is of type [%s] instead of [%s] for attribute: [%s]",
value.toString(),
value.getClass().getSimpleName(),
Entity.class.getSimpleName(),
attrName));
}
break;
case CATEGORICAL_MREF:
case MREF:
case ONE_TO_MANY:
if (!(value instanceof Iterable)) {
throw new MolgenisDataException(
format(
"Value [%s] is of type [%s] instead of [%s] for attribute: [%s]",
value.toString(),
value.getClass().getSimpleName(),
Iterable.class.getSimpleName(),
attrName));
}
break;
case COMPOUND:
throw new IllegalArgumentException(
format("Unexpected data type [%s] for attribute: [%s]", dataType.toString(), attrName));
case DATE:
if (!(value instanceof LocalDate)) {
throw new MolgenisDataException(
format(
"Value [%s] is of type [%s] instead of [%s] for attribute: [%s]",
value.toString(),
value.getClass().getSimpleName(),
LocalDate.class.getSimpleName(),
attrName));
}
break;
case DATE_TIME:
if (!(value instanceof Instant)) {
throw new MolgenisDataException(
format(
"Value [%s] is of type [%s] instead of [%s] for attribute: [%s]",
value.toString(),
value.getClass().getSimpleName(),
Instant.class.getSimpleName(),
attrName));
}
break;
case DECIMAL:
if (!(value instanceof Double)) {
throw new MolgenisDataException(
format(
"Value [%s] is of type [%s] instead of [%s] for attribute: [%s]",
value.toString(),
value.getClass().getSimpleName(),
Double.class.getSimpleName(),
attrName));
}
if (((Double) value).isNaN()) {
throw new MolgenisDataException(
format(
"Value [%s] for type [%s] is not allowed for attribute: [%s]",
value.toString(), Double.class.getSimpleName(), attrName));
}
break;
case EMAIL:
case ENUM:
case HTML:
case HYPERLINK:
case SCRIPT:
case STRING:
case TEXT:
if (!(value instanceof String)) {
throw new MolgenisDataException(
format(
"Value [%s] is of type [%s] instead of [%s] for attribute: [%s]",
value.toString(),
value.getClass().getSimpleName(),
String.class.getSimpleName(),
attrName));
}
break;
case INT:
if (!(value instanceof Integer)) {
throw new MolgenisDataException(
format(
"Value [%s] is of type [%s] instead of [%s] for attribute: [%s]",
value.toString(),
value.getClass().getSimpleName(),
Integer.class.getSimpleName(),
attrName));
}
break;
case LONG:
if (!(value instanceof Long)) {
throw new MolgenisDataException(
format(
"Value [%s] is of type [%s] instead of [%s] for attribute: [%s]",
value.toString(),
value.getClass().getSimpleName(),
Long.class.getSimpleName(),
attrName));
}
break;
default:
throw new UnexpectedEnumException(dataType);
}
}
@Override
public String toString() {
StringBuilder strBuilder = new StringBuilder(entityType.getId()).append('{');
strBuilder.append(
stream(entityType.getAtomicAttributes())
.map(
attr -> {
StringBuilder attrStrBuilder = new StringBuilder(attr.getName()).append('=');
if (EntityTypeUtils.isSingleReferenceType(attr)) {
Entity refEntity = getEntity(attr.getName());
attrStrBuilder.append(refEntity != null ? refEntity.getIdValue() : null);
} else if (EntityTypeUtils.isMultipleReferenceType(attr)) {
attrStrBuilder
.append('[')
.append(
stream(getEntities(attr.getName()))
.map(Entity::getIdValue)
.map(Object::toString)
.collect(joining(",")))
.append(']');
} else {
attrStrBuilder.append(get(attr.getName()));
}
return attrStrBuilder.toString();
})
.collect(Collectors.joining("&")));
strBuilder.append('}');
return strBuilder.toString();
}
}