11d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvistpackage com.android.server.wifi.hotspot2.omadm; 21d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 31d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvistimport java.util.ArrayList; 41d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvistimport java.util.Collection; 51d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvistimport java.util.Iterator; 61d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvistimport java.util.LinkedHashMap; 71d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvistimport java.util.List; 81d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvistimport java.util.Map; 91d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 101d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvistpublic class MultiValueMap<T> { 111d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist private final Map<String, ArrayList<T>> mMap = new LinkedHashMap<>(); 121d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 131d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist public void put(String key, T value) { 141d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist key = key.toLowerCase(); 151d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist ArrayList<T> values = mMap.get(key); 161d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (values == null) { 171d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist values = new ArrayList<>(); 181d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist mMap.put(key, values); 191d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 201d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist values.add(value); 211d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 221d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 231d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist public T get(String key) { 241d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist key = key.toLowerCase(); 251d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist List<T> values = mMap.get(key); 261d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (values == null) { 271d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return null; 281d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 291d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist else if (values.size() == 1) { 301d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return values.get(0); 311d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 321d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist else { 331d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist throw new IllegalArgumentException("Cannot do get on multi-value"); 341d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 351d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 361d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 371d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist public T replace(String key, T oldValue, T newValue) { 381d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist key = key.toLowerCase(); 391d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist List<T> values = mMap.get(key); 401d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (values == null) { 411d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return null; 421d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 431d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 441d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist for (int n = 0; n < values.size(); n++) { 451d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist T value = values.get(n); 461d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (value == oldValue) { 471d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist values.set(n, newValue); 481d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return value; 491d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 501d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 511d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return null; 521d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 531d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 541d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist public T remove(String key, T value) { 551d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist key = key.toLowerCase(); 561d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist List<T> values = mMap.get(key); 571d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (values == null) { 581d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return null; 591d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 601d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 611d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist T result = null; 621d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist Iterator<T> valueIterator = values.iterator(); 631d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist while (valueIterator.hasNext()) { 641d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (valueIterator.next() == value) { 651d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist valueIterator.remove(); 661d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist result = value; 671d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist break; 681d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 691d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 701d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (values.isEmpty()) { 711d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist mMap.remove(key); 721d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 731d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return result; 741d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 751d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 761d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist public T remove(T value) { 771d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist T result = null; 781d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist Iterator<Map.Entry<String, ArrayList<T>>> iterator = mMap.entrySet().iterator(); 791d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist while (iterator.hasNext()) { 801d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist ArrayList<T> values = iterator.next().getValue(); 811d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist Iterator<T> valueIterator = values.iterator(); 821d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist while (valueIterator.hasNext()) { 831d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (valueIterator.next() == value) { 841d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist valueIterator.remove(); 851d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist result = value; 861d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist break; 871d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 881d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 891d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (result != null) { 901d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (values.isEmpty()) { 911d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist iterator.remove(); 921d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 931d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist break; 941d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 951d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 961d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return result; 971d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 981d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 991d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist public Collection<T> values() { 1001d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist List<T> allValues = new ArrayList<>(mMap.size()); 1011d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist for (List<T> values : mMap.values()) { 1021d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist for (T value : values) { 1031d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist allValues.add(value); 1041d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 1051d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 1061d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return allValues; 1071d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 1081d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist 1091d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist public T getSingletonValue() { 1101d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (mMap.size() != 1) { 1111d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist throw new IllegalArgumentException("Map is not a single entry map"); 1121d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 1131d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist List<T> values = mMap.values().iterator().next(); 1141d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist if (values.size() != 1) { 1151d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist throw new IllegalArgumentException("Map is not a single entry map"); 1161d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 1171d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist return values.iterator().next(); 1181d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist } 1191d5cd3938f9191184cd9aea3059a3b62bf3a0372Jan Nordqvist} 120