package org.activityinfo.model.formTree; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import org.activityinfo.model.resource.ResourceId; import java.util.Iterator; import java.util.List; /** * Describes a path of nested fields */ public class FieldPath { private final List<ResourceId> path; public FieldPath(ResourceId rootFieldId, FieldPath relativePath) { path = Lists.newArrayList(rootFieldId); path.addAll(relativePath.path); } public FieldPath(FieldPath prefix, ResourceId key) { path = Lists.newArrayList(); if(prefix != null) { path.addAll(prefix.path); } path.add(key); } public FieldPath(FieldPath parent, FieldPath relativePath) { this.path = Lists.newArrayList(); this.path.addAll(parent.path); this.path.addAll(relativePath.path); } public FieldPath(List<ResourceId> fieldIds) { path = Lists.newArrayList(fieldIds); } public FieldPath(ResourceId... fieldIds) { path = Lists.newArrayList(fieldIds); } public boolean isNested() { return path.size() > 1; } public int getDepth() { return path.size(); } public FieldPath relativeTo(ResourceId rootFieldId) { Preconditions.checkArgument(path.get(0).equals(rootFieldId)); return new FieldPath(path.subList(1, path.size())); } public ResourceId getLeafId() { return path.get(path.size()-1); } /** * Creates a new FieldPath that describes the nth ancestor of this * path. n=1 is the direct parent, n=2, grand parent, etc. */ public FieldPath ancestor(int n) { return new FieldPath(path.subList(0, path.size()-n)); } public ResourceId getRoot() { return path.get(0); } public boolean isDescendantOf(ResourceId fieldId) { return path.get(0).equals(fieldId); } public List<ResourceId> getPath() { return path; } @Override public String toString() { StringBuilder s = new StringBuilder(); for(ResourceId fieldId : path) { if(s.length() > 0) { s.append("."); } s.append(fieldId.asString()); } return s.toString(); } @Override public int hashCode() { return path.hashCode(); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (!(obj instanceof FieldPath)) { return false; } FieldPath otherPath = (FieldPath) obj; return path.equals(otherPath.path); } public Iterator<ResourceId> iterator() { return path.iterator(); } }