1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.util.AbstractList; 25 import java.util.ArrayList; 26 import java.util.Collection; 27 import java.util.Collections; 28 import java.util.HashMap; 29 import java.util.Iterator; 30 import java.util.LinkedHashMap; 31 import java.util.List; 32 import java.util.Map; 33 import java.util.RandomAccess; 34 import java.util.Spliterator; 35 import java.util.function.Consumer; 36 import java.util.function.Function; 37 import java.util.function.Supplier; 38 39 class SpliteratorLateBindingFailFastHelper { 40 41 interface Source<T> { 42 Spliterator<T> spliterator(); 43 44 void update(); 45 46 default boolean bindOnCharacteristics() { 47 return false; 48 } 49 } 50 51 static class IntSource<T> implements Source<Integer> { 52 final T b; 53 final Function<? super T, Spliterator.OfInt> toSpliterator; 54 final Consumer<T> updater; 55 final boolean bindOnCharacteristics; 56 57 public IntSource(T b, Function<? super T, Spliterator.OfInt> toSpliterator, 58 Consumer<T> updater) { 59 this(b, toSpliterator, updater, false); 60 } 61 62 public IntSource(T b, Function<? super T, Spliterator.OfInt> toSpliterator, 63 Consumer<T> updater, boolean bindOnCharacteristics) { 64 this.b = b; 65 this.toSpliterator = toSpliterator; 66 this.updater = updater; 67 this.bindOnCharacteristics = bindOnCharacteristics; 68 } 69 70 @Override 71 public Spliterator.OfInt spliterator() { 72 return toSpliterator.apply(b); 73 } 74 75 @Override 76 public void update() { 77 updater.accept(b); 78 } 79 80 @Override 81 public boolean bindOnCharacteristics() { 82 return bindOnCharacteristics; 83 } 84 } 85 86 static class SpliteratorDataBuilder<T> { 87 final List<Object[]> data; 88 89 final T newValue; 90 91 final List<T> exp; 92 93 final Map<T, T> mExp; 94 95 SpliteratorDataBuilder(List<Object[]> data, T newValue, List<T> exp) { 96 this.data = data; 97 this.newValue = newValue; 98 this.exp = exp; 99 this.mExp = createMap(exp); 100 } 101 102 Map<T, T> createMap(List<T> l) { 103 Map<T, T> m = new LinkedHashMap<>(); 104 for (T t : l) { 105 m.put(t, t); 106 } 107 return m; 108 } 109 110 void add(String description, Supplier<Source<?>> s) { 111 data.add(new Object[]{description, s}); 112 } 113 114 void addCollection(Function<Collection<T>, ? extends Collection<T>> f) { 115 class CollectionSource implements Source<T> { 116 final Collection<T> c = f.apply(exp); 117 118 final Consumer<Collection<T>> updater; 119 120 CollectionSource(Consumer<Collection<T>> updater) { 121 this.updater = updater; 122 } 123 124 @Override 125 public Spliterator<T> spliterator() { 126 return c.spliterator(); 127 } 128 129 @Override 130 public void update() { 131 updater.accept(c); 132 } 133 } 134 135 String description = "new " + f.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator() "; 136 add(description + "ADD", () -> new CollectionSource(c -> c.add(newValue))); 137 add(description + "REMOVE", () -> new CollectionSource(c -> c.remove(c.iterator().next()))); 138 } 139 140 void addList(Function<Collection<T>, ? extends List<T>> l) { 141 addCollection(l); 142 addCollection(l.andThen(list -> list.subList(0, list.size()))); 143 } 144 145 void addMap(Function<Map<T, T>, ? extends Map<T, T>> mapConstructor) { 146 class MapSource<U> implements Source<U> { 147 final Map<T, T> m = mapConstructor.apply(mExp); 148 149 final Collection<U> c; 150 151 final Consumer<Map<T, T>> updater; 152 153 MapSource(Function<Map<T, T>, Collection<U>> f, Consumer<Map<T, T>> updater) { 154 this.c = f.apply(m); 155 this.updater = updater; 156 } 157 158 @Override 159 public Spliterator<U> spliterator() { 160 return c.spliterator(); 161 } 162 163 @Override 164 public void update() { 165 updater.accept(m); 166 } 167 } 168 169 Map<String, Consumer<Map<T, T>>> actions = new HashMap<>(); 170 actions.put("ADD", m -> m.put(newValue, newValue)); 171 actions.put("REMOVE", m -> m.remove(m.keySet().iterator().next())); 172 173 String description = "new " + mapConstructor.apply(Collections.<T, T>emptyMap()).getClass().getName(); 174 for (Map.Entry<String, Consumer<Map<T, T>>> e : actions.entrySet()) { 175 add(description + ".keySet().spliterator() " + e.getKey(), 176 () -> new MapSource<>(m -> m.keySet(), e.getValue())); 177 add(description + ".values().spliterator() " + e.getKey(), 178 () -> new MapSource<>(m -> m.values(), e.getValue())); 179 add(description + ".entrySet().spliterator() " + e.getKey(), 180 () -> new MapSource<>(m -> m.entrySet(), e.getValue())); 181 } 182 } 183 } 184 185 static class AbstractRandomAccessListImpl extends AbstractList<Integer> implements RandomAccess { 186 List<Integer> l; 187 188 AbstractRandomAccessListImpl(Collection<Integer> c) { 189 this.l = new ArrayList<>(c); 190 } 191 192 @Override 193 public boolean add(Integer integer) { 194 modCount++; 195 return l.add(integer); 196 } 197 198 @Override 199 public Iterator<Integer> iterator() { 200 return l.iterator(); 201 } 202 203 @Override 204 public Integer get(int index) { 205 return l.get(index); 206 } 207 208 @Override 209 public boolean remove(Object o) { 210 modCount++; 211 return l.remove(o); 212 } 213 214 @Override 215 public int size() { 216 return l.size(); 217 } 218 219 @Override 220 public List<Integer> subList(int fromIndex, int toIndex) { 221 return l.subList(fromIndex, toIndex); 222 } 223 } 224 }