package org.molgenis.data.support;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import org.molgenis.data.Entity;
import org.molgenis.data.Range;
import org.molgenis.data.Sort;
import org.molgenis.data.meta.AttributeType;
import org.molgenis.data.meta.model.Attribute;
import org.molgenis.data.meta.model.EntityType;
import org.molgenis.data.meta.model.Tag;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class MapOfStringsExpressionEvaluator implements ExpressionEvaluator
{
private final Attribute targetAttribute;
private Map<String, ExpressionEvaluator> evaluators;
/**
* Constructs a new expression evaluator for an attribute whose expression is a simple string.
*
* @param attribute attribute meta data
* @param entityType entity meta data
*/
public MapOfStringsExpressionEvaluator(Attribute attribute, EntityType entityType)
{
targetAttribute = attribute;
String expression = attribute.getExpression();
if (expression == null)
{
throw new NullPointerException("Attribute has no expression.");
}
EntityType refEntity = attribute.getRefEntity();
if (refEntity == null)
{
throw new NullPointerException("refEntity not specified.");
}
Gson gson = new Gson();
try
{
@SuppressWarnings("unchecked") Map<String, String> attributeExpressions = gson
.fromJson(expression, Map.class);
ImmutableMap.Builder<String, ExpressionEvaluator> builder = ImmutableMap.builder();
for (Entry<String, String> entry : attributeExpressions.entrySet())
{
Attribute targetAttribute = refEntity.getAttribute(entry.getKey());
if (targetAttribute == null)
{
throw new IllegalArgumentException("Unknown target attribute: " + entry.getKey() + '.');
}
Attribute amd = new AttributeWithJsonExpression(targetAttribute, entry.getValue());
StringExpressionEvaluator evaluator = new StringExpressionEvaluator(amd, entityType);
builder.put(entry.getKey(), evaluator);
}
evaluators = builder.build();
}
catch (ClassCastException ex)
{
throw new IllegalArgumentException(
"Nested expressions not supported, expression must be Map<String,String>.");
}
}
@Override
public Object evaluate(Entity entity)
{
Entity result = new DynamicEntity(targetAttribute.getRefEntity());
for (Entry<String, ExpressionEvaluator> entry : evaluators.entrySet())
{
result.set(entry.getKey(), entry.getValue().evaluate(entity));
}
return result;
}
private static class AttributeWithJsonExpression extends Attribute
{
private final Attribute attr;
private final String expression;
public AttributeWithJsonExpression(Attribute attr, String expression)
{
super(attr.getEntityType());
this.attr = attr;
this.expression = expression;
}
@Override
public String getExpression()
{
return expression;
}
@Override
public Object get(String attributeName)
{
return attr.get(attributeName);
}
@Override
public Iterable<String> getAttributeNames()
{
return attr.getAttributeNames();
}
@Override
public Boolean getBoolean(String attributeName)
{
return attr.getBoolean(attributeName);
}
@Override
public Date getDate(String attributeName)
{
return attr.getDate(attributeName);
}
@Override
public Double getDouble(String attributeName)
{
return attr.getDouble(attributeName);
}
@Override
public Iterable<Entity> getEntities(String attributeName)
{
return attr.getEntities(attributeName);
}
@Override
public <E extends Entity> Iterable<E> getEntities(String attributeName, Class<E> clazz)
{
return attr.getEntities(attributeName, clazz);
}
@Override
public Entity getEntity(String attributeName)
{
return attr.getEntity(attributeName);
}
@Override
public <E extends Entity> E getEntity(String attributeName, Class<E> clazz)
{
return attr.getEntity(attributeName, clazz);
}
@Override
public EntityType getEntityType()
{
return attr.getEntityType();
}
@Override
public Object getIdValue()
{
return attr.getIdValue();
}
@Override
public Integer getInt(String attributeName)
{
return attr.getInt(attributeName);
}
@Override
public Object getLabelValue()
{
return attr.getLabelValue();
}
@Override
public Long getLong(String attributeName)
{
return attr.getLong(attributeName);
}
@Override
public String getString(String attributeName)
{
return attr.getString(attributeName);
}
@Override
public Timestamp getTimestamp(String attributeName)
{
return attr.getTimestamp(attributeName);
}
@Override
public java.util.Date getUtilDate(String attributeName)
{
return attr.getUtilDate(attributeName);
}
@Override
public String getIdentifier()
{
return attr.getIdentifier();
}
@Override
public String getName()
{
return attr.getName();
}
@Override
public Integer getSequenceNumber()
{
return attr.getSequenceNumber();
}
@Override
public EntityType getEntity()
{
return attr.getEntity();
}
@Override
public boolean isIdAttribute()
{
return attr.isIdAttribute();
}
@Override
public boolean isLabelAttribute()
{
return attr.isLabelAttribute();
}
@Override
public Integer getLookupAttributeIndex()
{
return attr.getLookupAttributeIndex();
}
@Override
public String getLabel()
{
return attr.getLabel();
}
@Override
public String getLabel(String languageCode)
{
return attr.getLabel(languageCode);
}
@Override
public String getDescription()
{
return attr.getDescription();
}
@Override
public String getDescription(String languageCode)
{
return attr.getDescription(languageCode);
}
@Override
public AttributeType getDataType()
{
return attr.getDataType();
}
@Override
public Iterable<Attribute> getChildren()
{
return attr.getChildren();
}
@Override
public EntityType getRefEntity()
{
return attr.getRefEntity();
}
@Override
public Attribute getMappedBy()
{
return attr.getMappedBy();
}
@Override
public boolean isMappedBy()
{
return attr.isMappedBy();
}
@Override
public Sort getOrderBy()
{
return attr.getOrderBy();
}
@Override
public boolean hasExpression()
{
return attr.hasExpression();
}
@Override
public boolean isNillable()
{
return attr.isNillable();
}
@Override
public boolean isAuto()
{
return attr.isAuto();
}
@Override
public boolean isVisible()
{
return attr.isVisible();
}
@Override
public boolean isAggregatable()
{
return attr.isAggregatable();
}
@Override
public List<String> getEnumOptions()
{
return attr.getEnumOptions();
}
@Override
public Long getRangeMin()
{
return attr.getRangeMin();
}
@Override
public Long getRangeMax()
{
return attr.getRangeMax();
}
@Override
public boolean isReadOnly()
{
return attr.isReadOnly();
}
@Override
public boolean isUnique()
{
return attr.isUnique();
}
@Override
public String getVisibleExpression()
{
return attr.getVisibleExpression();
}
@Override
public String getValidationExpression()
{
return attr.getValidationExpression();
}
@Override
public String getDefaultValue()
{
return attr.getDefaultValue();
}
@Override
public Range getRange()
{
return attr.getRange();
}
@Override
public Attribute getParent()
{
return attr.getParent();
}
@Override
public Attribute getChild(String attrName)
{
return attr.getChild(attrName);
}
@Override
public Iterable<Tag> getTags()
{
return attr.getTags();
}
@Override
public String toString()
{
return attr.toString();
}
@Override
public Attribute getInversedBy()
{
return attr.getInversedBy();
}
@Override
public boolean isInversedBy()
{
return attr.isInversedBy();
}
}
}