1495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert/* GENERATED SOURCE. DO NOT MODIFY. */ 2495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert// © 2017 and later: Unicode, Inc. and others. 3495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 4495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertpackage android.icu.impl.locale; 5495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 6495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.io.BufferedReader; 7495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.io.File; 8495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.io.InputStream; 9495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.io.InputStreamReader; 10495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.net.URL; 11495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.nio.charset.Charset; 12495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Arrays; 13495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Collection; 14495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Collections; 15495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.HashMap; 16495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.HashSet; 17495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Iterator; 18495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.LinkedHashMap; 19495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.LinkedHashSet; 20495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.List; 21495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Map; 22495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Map.Entry; 23495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.Set; 24495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.TreeMap; 25495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.TreeSet; 26495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.regex.Matcher; 27495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport java.util.regex.Pattern; 28495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 29495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport android.icu.util.ICUException; 30495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertimport android.icu.util.ICUUncheckedIOException; 31495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 32495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert/** 33495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * Stub class to make migration easier until we get either Guava or a higher level of Java. 34495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * @hide Only a subset of ICU is exposed in Android 35495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert */ 36495cb271e305cfb399d463f32210a371198f0abfFredrik Roubertpublic class XCldrStub { 37495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 38495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class Multimap<K, V> { 39495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private final Map<K,Set<V>> map; 40495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private final Class<Set<V>> setClass; 41495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 42495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @SuppressWarnings("unchecked") 43495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private Multimap(Map<K,Set<V>> map, Class<?> setClass) { 44495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert this.map = map; 45495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert this.setClass = (Class<Set<V>>) (setClass != null 46495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert ? setClass 47495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert : HashSet.class); 48495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 49495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Multimap<K, V> putAll(K key, V... values) { 50495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (values.length != 0) { 51495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert createSetIfMissing(key).addAll(Arrays.asList(values)); 52495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 53495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return this; 54495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 55495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public void putAll(K key, Collection<V> values) { 56495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (!values.isEmpty()) { 57495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert createSetIfMissing(key).addAll(values); 58495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 59495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 60495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public void putAll(Collection<K> keys, V value) { 61495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for (K key : keys) { 62495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert put(key, value); 63495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 64495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 65495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public void putAll(Multimap<K, V> source) { 66495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for (Entry<K, Set<V>> entry : source.map.entrySet()) { 67495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert putAll(entry.getKey(), entry.getValue()); 68495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 69495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 70495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public void put(K key, V value) { 71495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert createSetIfMissing(key).add(value); 72495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 73495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private Set<V> createSetIfMissing(K key) { 74495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert Set<V> old = map.get(key); 75495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (old == null) { 76495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert map.put(key, old = getInstance()); 77495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 78495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return old; 79495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 80495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private Set<V> getInstance() { 81495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert try { 82495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return setClass.newInstance(); 83495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } catch (Exception e) { 84495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert throw new ICUException(e); 85495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 86495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 87495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Set<V> get(K key) { 88495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert Set<V> result = map.get(key); 89495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return result; // == null ? Collections.<V>emptySet() : result; 90495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 91495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Set<K> keySet() { 92495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return map.keySet(); 93495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 94495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Map<K, Set<V>> asMap() { 95495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return map; 96495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 97495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Set<V> values() { 98495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert Collection<Set<V>> values = map.values(); 99495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (values.size() == 0) { 100495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return Collections.<V>emptySet(); 101495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 102495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert Set<V> result = getInstance(); 103495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for ( Set<V> valueSet : values) { 104495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert result.addAll(valueSet); 105495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 106495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return result; 107495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 108495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public int size() { 109495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return map.size(); 110495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 111495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Iterable<Entry<K, V>> entries() { 112495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return new MultimapIterator<K, V>(map); 113495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 114495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @Override 115495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public boolean equals(Object obj) { 116495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return this == obj || 117495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert (obj != null 118495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert && obj.getClass() == this.getClass() 119495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert && map.equals(((Multimap<?,?>) obj).map)); 120495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 121495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 122495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @Override 123495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public int hashCode() { 124495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return map.hashCode(); 125495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 126495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 127495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 128495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class Multimaps { 129495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <K, V, R extends Multimap<K, V>> R invertFrom(Multimap<V, K> source, R target) { 130495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for (Entry<V, Set<K>> entry : source.asMap().entrySet()) { 131495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert target.putAll(entry.getValue(), entry.getKey()); 132495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 133495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return target; 134495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 135495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <K, V, R extends Multimap<K, V>> R invertFrom(Map<V, K> source, R target) { 136495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for (Entry<V, K> entry : source.entrySet()) { 137495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert target.put(entry.getValue(), entry.getKey()); 138495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 139495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return target; 140495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 141495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert /** 142495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * Warning, not functionally the same as Guava; only for use in invertFrom. 143495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert */ 144495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <K, V> Map<K,V> forMap(Map<K,V> map) { 145495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return map; 146495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 147495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 148495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 149495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private static class MultimapIterator<K,V> implements Iterator<Entry<K,V>>, Iterable<Entry<K,V>> { 150495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private final Iterator<Entry<K, Set<V>>> it1; 151495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private Iterator<V> it2 = null; 152495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private final ReusableEntry<K,V> entry = new ReusableEntry<K,V>(); 153495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 154495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private MultimapIterator(Map<K,Set<V>> map) { 155495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert it1 = map.entrySet().iterator(); 156495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 157495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @Override 158495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public boolean hasNext() { 159495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return it1.hasNext() || it2 != null && it2.hasNext(); 160495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 161495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @Override 162495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Entry<K, V> next() { 163495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (it2 != null && it2.hasNext()) { 164495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert entry.value = it2.next(); 165495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } else { 166495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert Entry<K, Set<V>> e = it1.next(); 167495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert entry.key = e.getKey(); 168495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert it2 = e.getValue().iterator(); 169495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 170495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return entry; 171495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 172495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @Override 173495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Iterator<Entry<K, V>> iterator() { 174495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return this; 175495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 176495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @Override 177495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public void remove() { 178495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert throw new UnsupportedOperationException(); 179495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 180495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 181495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 182495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private static class ReusableEntry<K,V> implements Entry<K,V> { 183495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert K key; 184495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert V value; 185495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @Override 186495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public K getKey() { 187495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return key; 188495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 189495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @Override 190495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public V getValue() { 191495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return value; 192495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 193495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert @Override 194495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public V setValue(V value) { 195495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert throw new UnsupportedOperationException(); 196495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 197495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 198495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 199495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class HashMultimap<K, V> extends Multimap<K, V> { 200495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private HashMultimap() { 201495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert super(new HashMap<K, Set<V>>(), HashSet.class); 202495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 203495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <K, V> HashMultimap<K, V> create() { 204495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return new HashMultimap<K, V>(); 205495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 206495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 207495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 208495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class TreeMultimap<K, V> extends Multimap<K, V> { 209495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private TreeMultimap() { 210495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert super(new TreeMap<K, Set<V>>(), TreeSet.class); 211495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 212495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <K, V> TreeMultimap<K, V> create() { 213495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return new TreeMultimap<K, V>(); 214495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 215495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 216495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 217495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class LinkedHashMultimap<K, V> extends Multimap<K, V> { 218495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private LinkedHashMultimap() { 219495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert super(new LinkedHashMap<K, Set<V>>(), LinkedHashSet.class); 220495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 221495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <K, V> LinkedHashMultimap<K, V> create() { 222495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return new LinkedHashMultimap<K, V>(); 223495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 224495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 225495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 226495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 227495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // public static class Counter<T> implements Iterable<T>{ 228495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // private Map<T,Long> data; 229495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // @Override 230495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // public Iterator<T> iterator() { 231495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // return data.keySet().iterator(); 232495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // } 233495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // public long get(T s) { 234495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // Long result = data.get(s); 235495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // return result != null ? result : 0L; 236495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // } 237495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // public void add(T item, int count) { 238495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // Long result = data.get(item); 239495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // data.put(item, result == null ? count : result + count); 240495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // } 241495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // } 242495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 243495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <T> String join(T[] source, String separator) { 244495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert StringBuilder result = new StringBuilder(); 245495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for (int i = 0; i < source.length; ++i) { 246495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (i != 0) result.append(separator); 247495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert result.append(source[i]); 248495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 249495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return result.toString(); 250495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 251495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 252495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <T> String join(Iterable<T> source, String separator) { 253495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert StringBuilder result = new StringBuilder(); 254495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert boolean first = true; 255495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for (T item : source) { 256495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (!first) result.append(separator); 257495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert else first = false; 258495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert result.append(item.toString()); 259495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 260495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return result.toString(); 261495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 262495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 263495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class CollectionUtilities { 264495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <T, U extends Iterable<T>> String join(U source, String separator) { 265495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return XCldrStub.join(source, separator); 266495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 267495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 268495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 269495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class Joiner { 270495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private final String separator; 271495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert private Joiner(String separator) { 272495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert this.separator = separator; 273495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 274495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static final Joiner on(String separator) { 275495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return new Joiner(separator); 276495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 277495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public <T> String join(T[] source) { 278495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return XCldrStub.join(source, separator); 279495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 280495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public <T> String join(Iterable<T> source) { 281495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return XCldrStub.join(source, separator); 282495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 283495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 284495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 285495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class Splitter { 286495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert Pattern pattern; 287495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert boolean trimResults = false; 288495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Splitter(char c) { 289495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert this(Pattern.compile("\\Q" + c + "\\E")); 290495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 291495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Splitter(Pattern p) { 292495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert pattern = p; 293495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 294495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static Splitter on(char c) { 295495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return new Splitter(c); 296495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 297495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static Splitter on(Pattern p) { 298495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return new Splitter(p); 299495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 300495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public List<String> splitToList(String input) { 301495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert String[] items = pattern.split(input); 302495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (trimResults) { 303495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for (int i = 0; i < items.length; ++i) { 304495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert items[i] = items[i].trim(); 305495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 306495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 307495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return Arrays.asList(items); 308495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 309495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Splitter trimResults() { 310495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert trimResults = true; 311495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return this; 312495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 313495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public Iterable<String> split(String input) { 314495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return splitToList(input); 315495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 316495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 317495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 318495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class ImmutableSet { 319495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <T> Set<T> copyOf(Set<T> values) { 320495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return Collections.unmodifiableSet(new LinkedHashSet<T>(values)); // copy set for safety, preserve order 321495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 322495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 323495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class ImmutableMap { 324495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <K,V> Map<K,V> copyOf(Map<K,V> values) { 325495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return Collections.unmodifiableMap(new LinkedHashMap<K,V>(values)); // copy set for safety, preserve order 326495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 327495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 328495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class ImmutableMultimap { 329495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static <K,V> Multimap<K,V> copyOf(Multimap<K,V> values) { 330495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert LinkedHashMap<K, Set<V>> temp = new LinkedHashMap<K,Set<V>>(); // semi-deep copy, preserve order 331495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for (Entry<K, Set<V>> entry : values.asMap().entrySet()) { 332495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert Set<V> value = entry.getValue(); 333495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert temp.put(entry.getKey(), value.size() == 1 334495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert ? Collections.singleton(value.iterator().next()) 335495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert : Collections.unmodifiableSet(new LinkedHashSet<V>(value))); 336495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 337495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return new Multimap<K,V>(Collections.unmodifiableMap(temp), null); 338495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 339495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 340495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 341495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static class FileUtilities { 342495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static final Charset UTF8 = Charset.forName("utf-8"); 343495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 344495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static BufferedReader openFile(Class<?> class1, String file) { 345495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return openFile(class1, file, UTF8); 346495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 347495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 348495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static BufferedReader openFile(Class<?> class1, String file, Charset charset) { 349495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // URL path = null; 350495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert // String externalForm = null; 351495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert try { 352495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert final InputStream resourceAsStream = class1.getResourceAsStream(file); 353495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (charset == null) { 354495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert charset = UTF8; 355495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 356495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert InputStreamReader reader = new InputStreamReader(resourceAsStream, charset); 357495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert BufferedReader bufferedReader = new BufferedReader(reader, 1024 * 64); 358495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return bufferedReader; 359495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } catch (Exception e) { 360495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert String className = class1 == null ? null : class1.getCanonicalName(); 361495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert String canonicalName = null; 362495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert try { 363495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert String relativeFileName = getRelativeFileName(class1, "../util/"); 364495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert canonicalName = new File(relativeFileName).getCanonicalPath(); 365495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } catch (Exception e1) { 366495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert throw new ICUUncheckedIOException("Couldn't open file: " + file + "; relative to class: " 367495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert + className, e); 368495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 369495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert throw new ICUUncheckedIOException("Couldn't open file " + file + "; in path " + canonicalName + "; relative to class: " 370495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert + className, e); 371495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 372495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 373495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static String getRelativeFileName(Class<?> class1, String filename) { 374495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert URL resource = class1 == null ? 375495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert FileUtilities.class.getResource(filename) : class1.getResource(filename); 376495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert String resourceString = resource.toString(); 377495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (resourceString.startsWith("file:")) { 378495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return resourceString.substring(5); 379495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } else if (resourceString.startsWith("jar:file:")) { 380495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return resourceString.substring(9); 381495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } else { 382495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert throw new ICUUncheckedIOException("File not found: " + resourceString); 383495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 384495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 385495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 386495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 387495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert static public class RegexUtilities { 388495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static int findMismatch(Matcher m, CharSequence s) { 389495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert int i; 390495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert for (i = 1; i < s.length(); ++i) { 391495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert boolean matches = m.reset(s.subSequence(0, i)).matches(); 392495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert if (!matches && !m.hitEnd()) { 393495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert break; 394495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 395495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 396495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return i - 1; 397495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 398495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public static String showMismatch(Matcher m, CharSequence s) { 399495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert int failPoint = findMismatch(m, s); 400495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert String show = s.subSequence(0, failPoint) + "☹" + s.subSequence(failPoint, s.length()); 401495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert return show; 402495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 403495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 404495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert 405495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert public interface Predicate<T> { 406495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert /** 407495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * Evaluates this predicate on the given argument. 408495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * 409495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * @param t the input argument 410495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * @return {@code true} if the input argument matches the predicate, 411495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert * otherwise {@code false} 412495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert */ 413495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert boolean test(T t); 414495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert } 415495cb271e305cfb399d463f32210a371198f0abfFredrik Roubert}