Home | History | Annotate | Download | only in tko
      1 package autotest.tko;
      2 
      3 import autotest.tko.TkoUtils.FieldInfo;
      4 
      5 import java.util.AbstractCollection;
      6 import java.util.ArrayList;
      7 import java.util.HashMap;
      8 import java.util.Iterator;
      9 import java.util.List;
     10 import java.util.Map;
     11 
     12 /**
     13  * A modifiable, ordered Collection of unique HeaderFields indexed by both field name and field SQL
     14  * name.
     15  */
     16 public class HeaderFieldCollection extends AbstractCollection<HeaderField> {
     17     private Map<String, HeaderField> fieldsByName = new HashMap<String, HeaderField>();
     18     private Map<String, HeaderField> fieldsBySqlName = new HashMap<String, HeaderField>();
     19     private List<HeaderField> orderedFields = new ArrayList<HeaderField>();
     20 
     21     public void populateFromList(String fieldListName) {
     22         for (FieldInfo fieldInfo : TkoUtils.getFieldList(fieldListName)) {
     23             HeaderField field = new SimpleHeaderField(fieldInfo.name, fieldInfo.field);
     24             add(field);
     25         }
     26     }
     27 
     28     @Override
     29     public boolean add(HeaderField field) {
     30         if (contains(field)) {
     31             return false;
     32         }
     33 
     34         orderedFields.add(field);
     35         fieldsByName.put(field.getName(), field);
     36         fieldsBySqlName.put(field.getSqlName(), field);
     37         assert checkConsistency();
     38         return true;
     39     }
     40 
     41     /**
     42      * Called only within an assertion.
     43      */
     44     public boolean checkConsistency() {
     45         assert fieldsByName.size() == fieldsBySqlName.size();
     46         assert fieldsByName.size() == orderedFields.size();
     47         for (HeaderField field : fieldsByName.values()) {
     48             assert fieldsByName.get(field.getName()) == field;
     49             assert fieldsBySqlName.get(field.getSqlName()) == field;
     50             assert orderedFields.contains(field);
     51         }
     52         return true;
     53     }
     54 
     55     /**
     56      * We perform strict input checking here, and both add() and remove() use this.
     57      */
     58     @Override
     59     public boolean contains(Object o) {
     60         if (o == null || !(o instanceof HeaderField)) {
     61             return false;
     62         }
     63 
     64         HeaderField field = (HeaderField) o;
     65         boolean containsName = fieldsByName.containsKey(field.getName());
     66         boolean containsSqlName = fieldsBySqlName.containsKey(field.getSqlName());
     67 
     68         if (containsName && containsSqlName) {
     69             return true;
     70         }
     71         if (!containsName && containsSqlName) {
     72             throw new IllegalArgumentException("Duplicate SQL name: " + field + ", "
     73                                                + fieldsBySqlName.get(field.getSqlName()));
     74         }
     75         if (containsName && !containsSqlName) {
     76             throw new IllegalArgumentException("Duplicate name: " + field + ", "
     77                                                + fieldsByName.get(field.getName()));
     78         }
     79         return false;
     80     }
     81 
     82     @Override
     83     public Iterator<HeaderField> iterator() {
     84         final Iterator<HeaderField> baseIterator = orderedFields.iterator();
     85         return new Iterator<HeaderField>() {
     86             HeaderField lastElement;
     87 
     88             @Override
     89             public boolean hasNext() {
     90                 return baseIterator.hasNext();
     91             }
     92 
     93             @Override
     94             public HeaderField next() {
     95                 lastElement = baseIterator.next();
     96                 return lastElement;
     97             }
     98 
     99             @Override
    100             public void remove() {
    101                 baseIterator.remove();
    102                 fieldsByName.remove(lastElement.getName());
    103                 fieldsBySqlName.remove(lastElement.getSqlName());
    104                 assert checkConsistency();
    105             }
    106         };
    107     }
    108 
    109     @Override
    110     public int size() {
    111         return fieldsByName.size();
    112     }
    113 
    114     public HeaderField getFieldByName(String name) {
    115         assert fieldsByName.containsKey(name) : name;
    116         return fieldsByName.get(name);
    117     }
    118 
    119     public HeaderField getFieldBySqlName(String sqlName) {
    120         assert fieldsBySqlName.containsKey(sqlName) : sqlName;
    121         return fieldsBySqlName.get(sqlName);
    122     }
    123 
    124     public boolean containsName(String name) {
    125         return fieldsByName.containsKey(name);
    126     }
    127 
    128     public boolean containsSqlName(String sqlName) {
    129         return fieldsBySqlName.containsKey(sqlName);
    130     }
    131 
    132     /**
    133      * Note this is O(n).
    134      */
    135     @Override
    136     public boolean remove(Object o) {
    137         if (!contains(o)) {
    138             return false;
    139         }
    140 
    141         HeaderField field = (HeaderField) o;
    142         orderedFields.remove(field);
    143         fieldsByName.remove(field.getName());
    144         fieldsBySqlName.remove(field.getSqlName());
    145         return true;
    146     }
    147 }
    148