1ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistpackage com.android.hotspot2.omadm;
2ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
3ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.ArrayList;
4ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Collection;
5ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Iterator;
6ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.LinkedHashMap;
7ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.List;
8ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Map;
9ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
10ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistpublic class MultiValueMap<T> {
11ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    private final Map<String, ArrayList<T>> mMap = new LinkedHashMap<>();
12ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
13ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public void put(String key, T value) {
14ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        key = key.toLowerCase();
15ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        ArrayList<T> values = mMap.get(key);
16ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        if (values == null) {
17ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            values = new ArrayList<>();
18ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            mMap.put(key, values);
19ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
20ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        values.add(value);
21ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
22ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
23ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public T get(String key) {
24ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        key = key.toLowerCase();
25ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        List<T> values = mMap.get(key);
26ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        if (values == null) {
27ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            return null;
28ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        } else if (values.size() == 1) {
29ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            return values.get(0);
30ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        } else {
31ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            throw new IllegalArgumentException("Cannot do get on multi-value");
32ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
33ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
34ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
35ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public T replace(String key, T oldValue, T newValue) {
36ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        key = key.toLowerCase();
37ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        List<T> values = mMap.get(key);
38ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        if (values == null) {
39ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            return null;
40ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
41ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
42ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        for (int n = 0; n < values.size(); n++) {
43ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            T value = values.get(n);
44ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            if (value == oldValue) {
45ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                values.set(n, newValue);
46ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                return value;
47ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            }
48ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
49ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return null;
50ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
51ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
52ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public T remove(String key, T value) {
53ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        key = key.toLowerCase();
54ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        List<T> values = mMap.get(key);
55ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        if (values == null) {
56ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            return null;
57ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
58ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
59ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        T result = null;
60ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        Iterator<T> valueIterator = values.iterator();
61ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        while (valueIterator.hasNext()) {
62ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            if (valueIterator.next() == value) {
63ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                valueIterator.remove();
64ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                result = value;
65ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                break;
66ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            }
67ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
68ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        if (values.isEmpty()) {
69ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            mMap.remove(key);
70ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
71ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return result;
72ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
73ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
74ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public T remove(T value) {
75ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        T result = null;
76ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        Iterator<Map.Entry<String, ArrayList<T>>> iterator = mMap.entrySet().iterator();
77ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        while (iterator.hasNext()) {
78ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            ArrayList<T> values = iterator.next().getValue();
79ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            Iterator<T> valueIterator = values.iterator();
80ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            while (valueIterator.hasNext()) {
81ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                if (valueIterator.next() == value) {
82ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                    valueIterator.remove();
83ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                    result = value;
84ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                    break;
85ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                }
86ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            }
87ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            if (result != null) {
88ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                if (values.isEmpty()) {
89ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                    iterator.remove();
90ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                }
91ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                break;
92ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            }
93ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
94ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return result;
95ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
96ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
97ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public Collection<T> values() {
98ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        List<T> allValues = new ArrayList<>(mMap.size());
99ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        for (List<T> values : mMap.values()) {
100ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            for (T value : values) {
101ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist                allValues.add(value);
102ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            }
103ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
104ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return allValues;
105ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
106ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist
107ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    public T getSingletonValue() {
108ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        if (mMap.size() != 1) {
109ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            throw new IllegalArgumentException("Map is not a single entry map");
110ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
111ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        List<T> values = mMap.values().iterator().next();
112ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        if (values.size() != 1) {
113ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist            throw new IllegalArgumentException("Map is not a single entry map");
114ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        }
115ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist        return values.iterator().next();
116ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist    }
117ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist}
118