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