• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
populateFromList(String fieldListName)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
add(HeaderField field)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      */
checkConsistency()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
contains(Object o)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
iterator()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
size()110     public int size() {
111         return fieldsByName.size();
112     }
113 
getFieldByName(String name)114     public HeaderField getFieldByName(String name) {
115         assert fieldsByName.containsKey(name) : name;
116         return fieldsByName.get(name);
117     }
118 
getFieldBySqlName(String sqlName)119     public HeaderField getFieldBySqlName(String sqlName) {
120         assert fieldsBySqlName.containsKey(sqlName) : sqlName;
121         return fieldsBySqlName.get(sqlName);
122     }
123 
containsName(String name)124     public boolean containsName(String name) {
125         return fieldsByName.containsKey(name);
126     }
127 
containsSqlName(String sqlName)128     public boolean containsSqlName(String sqlName) {
129         return fieldsBySqlName.containsKey(sqlName);
130     }
131 
132     /**
133      * Note this is O(n).
134      */
135     @Override
remove(Object o)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