package org.activityinfo.model.type.enumerated; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.activityinfo.model.resource.IsRecord; import org.activityinfo.model.resource.Record; import org.activityinfo.model.resource.ResourceId; import org.activityinfo.model.type.FieldTypeClass; import org.activityinfo.model.type.FieldValue; import org.activityinfo.model.type.HasSetFieldValue; import java.util.Collections; import java.util.List; import java.util.Set; public class EnumValue implements FieldValue, IsRecord, HasSetFieldValue { public static final EnumValue EMPTY = new EnumValue(Collections.<ResourceId>emptySet()); private final Set<ResourceId> valueIds; public EnumValue(ResourceId valueId) { this.valueIds = ImmutableSet.of(valueId); } public EnumValue(ResourceId... valueIds) { this.valueIds = ImmutableSet.copyOf(valueIds); } public EnumValue(Iterable<ResourceId> valueIds) { this.valueIds = ImmutableSet.copyOf(valueIds); } public Set<ResourceId> getResourceIds() { return valueIds; } public ResourceId getValueId() { Preconditions.checkState(valueIds.size() == 1); return valueIds.iterator().next(); } @Override public Record asRecord() { Record record = new Record(); record.set(TYPE_CLASS_FIELD_NAME, EnumType.TYPE_CLASS.getId()); if(valueIds.size() == 1) { record.set("value", valueIds.iterator().next().asString()); } else if(valueIds.size() > 1) { record.set("value", toStringList(valueIds)); } return record; } public Set<EnumItem> getValuesAsItems(EnumType enumType) { Set<EnumItem> items = Sets.newHashSet(); for (final ResourceId resourceId : getResourceIds()) { for (EnumItem enumItem : enumType.getValues()) { if (enumItem.getId().equals(resourceId)) { items.add(enumItem); } } } return items; } private List<String> toStringList(Set<ResourceId> resourceIds) { List<String> strings = Lists.newArrayList(); for(ResourceId resourceId : resourceIds) { strings.add(resourceId.asString()); } return strings; } public static EnumValue fromRecord(Record record) { String id = record.isString("value"); if(id != null) { return new EnumValue(ResourceId.valueOf(id)); } id = record.isString("id"); // ugly workaround for inconsistent data that appears on production db if(id != null) { return new EnumValue(ResourceId.valueOf(id)); } List<String> strings = record.getStringList("value"); Set<ResourceId> ids = Sets.newHashSet(); for(String string : strings) { ids.add(ResourceId.valueOf(string)); } return new EnumValue(ids); } @Override public FieldTypeClass getTypeClass() { return EnumType.TYPE_CLASS; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } EnumValue that = (EnumValue) o; if (!valueIds.equals(that.valueIds)) { return false; } return true; } @Override public int hashCode() { return valueIds.hashCode(); } @Override public String toString() { return "EnumValue[" + Joiner.on(", ").join(valueIds) + "]"; } }