blob: 03ba14728730529028767a187b41e8e18969bbf3 [file] [log] [blame]
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<HeaderField> {
private Map<String, HeaderField> fieldsByName = new HashMap<String, HeaderField>();
private Map<String, HeaderField> fieldsBySqlName = new HashMap<String, HeaderField>();
private List<HeaderField> orderedFields = new ArrayList<HeaderField>();
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<HeaderField> iterator() {
final Iterator<HeaderField> baseIterator = orderedFields.iterator();
return new Iterator<HeaderField>() {
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;
}
}