package autotest.tko; import autotest.tko.TkoUtils.FieldInfo; import java.util.AbstractCollection; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * A modifiable, ordered Collection of unique HeaderFields indexed by both field name and field SQL * name. */ public class HeaderFieldCollection extends AbstractCollection { private Map fieldsByName = new HashMap(); private Map fieldsBySqlName = new HashMap(); private List orderedFields = new ArrayList(); public void populateFromList(String fieldListName) { for (FieldInfo fieldInfo : TkoUtils.getFieldList(fieldListName)) { HeaderField field = new SimpleHeaderField(fieldInfo.name, fieldInfo.field); add(field); } } @Override public boolean add(HeaderField field) { if (contains(field)) { return false; } orderedFields.add(field); fieldsByName.put(field.getName(), field); fieldsBySqlName.put(field.getSqlName(), field); assert checkConsistency(); return true; } /** * Called only within an assertion. */ public boolean checkConsistency() { assert fieldsByName.size() == fieldsBySqlName.size(); assert fieldsByName.size() == orderedFields.size(); for (HeaderField field : fieldsByName.values()) { assert fieldsByName.get(field.getName()) == field; assert fieldsBySqlName.get(field.getSqlName()) == field; assert orderedFields.contains(field); } return true; } /** * We perform strict input checking here, and both add() and remove() use this. */ @Override public boolean contains(Object o) { if (o == null || !(o instanceof HeaderField)) { return false; } HeaderField field = (HeaderField) o; boolean containsName = fieldsByName.containsKey(field.getName()); boolean containsSqlName = fieldsBySqlName.containsKey(field.getSqlName()); if (containsName && containsSqlName) { return true; } if (!containsName && containsSqlName) { throw new IllegalArgumentException("Duplicate SQL name: " + field + ", " + fieldsBySqlName.get(field.getSqlName())); } if (containsName && !containsSqlName) { throw new IllegalArgumentException("Duplicate name: " + field + ", " + fieldsByName.get(field.getName())); } return false; } @Override public Iterator iterator() { final Iterator baseIterator = orderedFields.iterator(); return new Iterator() { HeaderField lastElement; @Override public boolean hasNext() { return baseIterator.hasNext(); } @Override public HeaderField next() { lastElement = baseIterator.next(); return lastElement; } @Override public void remove() { baseIterator.remove(); fieldsByName.remove(lastElement.getName()); fieldsBySqlName.remove(lastElement.getSqlName()); assert checkConsistency(); } }; } @Override public int size() { return fieldsByName.size(); } public HeaderField getFieldByName(String name) { assert fieldsByName.containsKey(name) : name; return fieldsByName.get(name); } public HeaderField getFieldBySqlName(String sqlName) { assert fieldsBySqlName.containsKey(sqlName) : sqlName; return fieldsBySqlName.get(sqlName); } public boolean containsName(String name) { return fieldsByName.containsKey(name); } public boolean containsSqlName(String sqlName) { return fieldsBySqlName.containsKey(sqlName); } /** * Note this is O(n). */ @Override public boolean remove(Object o) { if (!contains(o)) { return false; } HeaderField field = (HeaderField) o; orderedFields.remove(field); fieldsByName.remove(field.getName()); fieldsBySqlName.remove(field.getSqlName()); return true; } }