package org.molgenis.data.rest.v2; import org.molgenis.data.Entity; import org.molgenis.data.meta.model.Attribute; import org.molgenis.data.meta.model.EntityType; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; /** * An AttributeFilter represents the value of the attrs parameter in a REST query. * <p> * The AttributeFilter allows you to specify which attributes should be fetched for each {@link Entity} that is * retrieved. * <p> * By default, the top level entity will always be fetched with all attributes, but you can also specify a list of * attribute names. Those will be added to the ID and label attributes, which will always be fetched. * <p> * Referenced entities will always be fetched using ID and label, but you can also specify a list of attribute names. * Those will be added to the ID and label attributes, which will always be fetched. You can also specify the special * selector `*` which will fetch all attributes for a referenced entity. */ class AttributeFilter implements Iterable<Entry<String, AttributeFilter>> { private final Map<String, AttributeFilter> attributes; private boolean includeAllAttrs; private boolean includeIdAttr; private boolean includeLabelAttr; private AttributeFilter idAttrFilter; private AttributeFilter labelAttrFilter; public AttributeFilter() { this.attributes = new LinkedHashMap<String, AttributeFilter>(); } public boolean isIncludeAllAttrs() { return includeAllAttrs; } /** * Indicates if this filter is {@link #includeAllAttrs}, and NO other attributes are selected. */ public boolean isStar() { return includeAllAttrs && (attributes == null || attributes.keySet().isEmpty()); } AttributeFilter setIncludeAllAttrs(boolean includeAllAttrs) { this.includeAllAttrs = includeAllAttrs; return this; } public boolean isIncludeIdAttr() { return includeIdAttr; } public AttributeFilter setIncludeIdAttr(boolean includeIdAttr) { return setIncludeIdAttr(includeIdAttr, null); } public AttributeFilter setIncludeIdAttr(boolean includeIdAttr, AttributeFilter idAttrFilter) { this.includeIdAttr = includeIdAttr; this.idAttrFilter = idAttrFilter; return this; } public boolean isIncludeLabelAttr() { return includeLabelAttr; } public AttributeFilter setIncludeLabelAttr(boolean includeLabelAttr) { return setIncludeLabelAttr(includeLabelAttr, null); } public AttributeFilter setIncludeLabelAttr(boolean includeLabelAttr, AttributeFilter labelAttrFilter) { this.includeLabelAttr = includeLabelAttr; this.labelAttrFilter = labelAttrFilter; return this; } public AttributeFilter getAttributeFilter(EntityType entityType, Attribute attr) { if (idAttrFilter != null && attr.equals(entityType.getIdAttribute())) { return idAttrFilter; } else if (labelAttrFilter != null && attr.equals(entityType.getLabelAttribute())) { return labelAttrFilter; } else { return attributes.get(normalize(attr.getName())); } } @Override public Iterator<Entry<String, AttributeFilter>> iterator() { return Collections.unmodifiableMap(attributes).entrySet().iterator(); } public AttributeFilter add(String name) { return add(name, null); } public AttributeFilter add(String name, AttributeFilter attributeSelection) { attributes.put(normalize(name), attributeSelection); return this; } private String normalize(String name) { return name;//.toLowerCase(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((attributes == null) ? 0 : attributes.hashCode()); result = prime * result + (includeAllAttrs ? 1231 : 1237); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; AttributeFilter other = (AttributeFilter) obj; if (attributes == null) { if (other.attributes != null) return false; } else if (!attributes.equals(other.attributes)) return false; if (includeAllAttrs != other.includeAllAttrs) return false; return true; } @Override public String toString() { return "AttributeFilter [attributes=" + attributes + ", includeAllAttrs=" + includeAllAttrs + "]"; } }