1 /* 2 * Copyright (C) 2012 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.testing; 18 19 import static com.google.common.base.Preconditions.checkArgument; 20 21 import com.google.common.annotations.GwtIncompatible; 22 import com.google.common.base.CharMatcher; 23 import com.google.common.base.Charsets; 24 import com.google.common.base.Defaults; 25 import com.google.common.base.Equivalence; 26 import com.google.common.base.Joiner; 27 import com.google.common.base.Predicate; 28 import com.google.common.base.Predicates; 29 import com.google.common.base.Splitter; 30 import com.google.common.base.Stopwatch; 31 import com.google.common.base.Ticker; 32 import com.google.common.collect.BiMap; 33 import com.google.common.collect.ClassToInstanceMap; 34 import com.google.common.collect.ImmutableBiMap; 35 import com.google.common.collect.ImmutableClassToInstanceMap; 36 import com.google.common.collect.ImmutableCollection; 37 import com.google.common.collect.ImmutableList; 38 import com.google.common.collect.ImmutableListMultimap; 39 import com.google.common.collect.ImmutableMap; 40 import com.google.common.collect.ImmutableMultimap; 41 import com.google.common.collect.ImmutableMultiset; 42 import com.google.common.collect.ImmutableSet; 43 import com.google.common.collect.ImmutableSetMultimap; 44 import com.google.common.collect.ImmutableSortedMap; 45 import com.google.common.collect.ImmutableSortedMultiset; 46 import com.google.common.collect.ImmutableSortedSet; 47 import com.google.common.collect.ImmutableTable; 48 import com.google.common.collect.Iterators; 49 import com.google.common.collect.ListMultimap; 50 import com.google.common.collect.MapDifference; 51 import com.google.common.collect.Maps; 52 import com.google.common.collect.Multimap; 53 import com.google.common.collect.Multimaps; 54 import com.google.common.collect.Multiset; 55 import com.google.common.collect.Ordering; 56 import com.google.common.collect.PeekingIterator; 57 import com.google.common.collect.Range; 58 import com.google.common.collect.RowSortedTable; 59 import com.google.common.collect.SetMultimap; 60 import com.google.common.collect.Sets; 61 import com.google.common.collect.SortedMapDifference; 62 import com.google.common.collect.SortedMultiset; 63 import com.google.common.collect.SortedSetMultimap; 64 import com.google.common.collect.Table; 65 import com.google.common.collect.Tables; 66 import com.google.common.collect.TreeBasedTable; 67 import com.google.common.collect.TreeMultimap; 68 import com.google.common.io.ByteSink; 69 import com.google.common.io.ByteSource; 70 import com.google.common.io.ByteStreams; 71 import com.google.common.io.CharSink; 72 import com.google.common.io.CharSource; 73 import com.google.common.primitives.Primitives; 74 import com.google.common.primitives.UnsignedInteger; 75 import com.google.common.primitives.UnsignedLong; 76 import com.google.errorprone.annotations.Keep; 77 import java.io.ByteArrayInputStream; 78 import java.io.ByteArrayOutputStream; 79 import java.io.File; 80 import java.io.InputStream; 81 import java.io.OutputStream; 82 import java.io.PrintStream; 83 import java.io.PrintWriter; 84 import java.io.Reader; 85 import java.io.Serializable; 86 import java.io.StringReader; 87 import java.io.StringWriter; 88 import java.io.Writer; 89 import java.lang.reflect.AnnotatedElement; 90 import java.lang.reflect.Array; 91 import java.lang.reflect.Constructor; 92 import java.lang.reflect.Field; 93 import java.lang.reflect.GenericDeclaration; 94 import java.lang.reflect.InvocationTargetException; 95 import java.lang.reflect.Modifier; 96 import java.lang.reflect.Type; 97 import java.math.BigDecimal; 98 import java.math.BigInteger; 99 import java.nio.Buffer; 100 import java.nio.ByteBuffer; 101 import java.nio.CharBuffer; 102 import java.nio.DoubleBuffer; 103 import java.nio.FloatBuffer; 104 import java.nio.IntBuffer; 105 import java.nio.LongBuffer; 106 import java.nio.ShortBuffer; 107 import java.nio.charset.Charset; 108 import java.util.ArrayDeque; 109 import java.util.Arrays; 110 import java.util.Collection; 111 import java.util.Comparator; 112 import java.util.Currency; 113 import java.util.Deque; 114 import java.util.Iterator; 115 import java.util.List; 116 import java.util.ListIterator; 117 import java.util.Locale; 118 import java.util.Map; 119 import java.util.NavigableMap; 120 import java.util.NavigableSet; 121 import java.util.Queue; 122 import java.util.Random; 123 import java.util.Set; 124 import java.util.SortedMap; 125 import java.util.SortedSet; 126 import java.util.UUID; 127 import java.util.concurrent.BlockingDeque; 128 import java.util.concurrent.BlockingQueue; 129 import java.util.concurrent.ConcurrentHashMap; 130 import java.util.concurrent.ConcurrentMap; 131 import java.util.concurrent.ConcurrentNavigableMap; 132 import java.util.concurrent.ConcurrentSkipListMap; 133 import java.util.concurrent.CountDownLatch; 134 import java.util.concurrent.Executor; 135 import java.util.concurrent.LinkedBlockingDeque; 136 import java.util.concurrent.ScheduledThreadPoolExecutor; 137 import java.util.concurrent.ThreadFactory; 138 import java.util.concurrent.ThreadPoolExecutor; 139 import java.util.concurrent.TimeUnit; 140 import java.util.logging.Level; 141 import java.util.logging.Logger; 142 import java.util.regex.MatchResult; 143 import java.util.regex.Matcher; 144 import java.util.regex.Pattern; 145 import javax.annotation.CheckForNull; 146 147 /** 148 * Supplies an arbitrary "default" instance for a wide range of types, often useful in testing 149 * utilities. 150 * 151 * <p>Covers arrays, enums and common types defined in {@code java.lang}, {@code java.lang.reflect}, 152 * {@code java.io}, {@code java.nio}, {@code java.math}, {@code java.util}, {@code 153 * java.util.concurrent}, {@code java.util.regex}, {@code com.google.common.base}, {@code 154 * com.google.common.collect} and {@code com.google.common.primitives}. In addition, if the type 155 * exposes at least one public static final constant of the same type, one of the constants will be 156 * used; or if the class exposes a public parameter-less constructor then it will be "new"d and 157 * returned. 158 * 159 * <p>All default instances returned by {@link #get} are generics-safe. Clients won't get type 160 * errors for using {@code get(Comparator.class)} as a {@code Comparator<Foo>}, for example. 161 * Immutable empty instances are returned for collection types; {@code ""} for string; {@code 0} for 162 * number types; reasonable default instance for other stateless types. For mutable types, a fresh 163 * instance is created each time {@code get()} is called. 164 * 165 * @author Kevin Bourrillion 166 * @author Ben Yu 167 * @since 12.0 168 */ 169 @GwtIncompatible 170 public final class ArbitraryInstances { 171 172 private static final Ordering<Field> BY_FIELD_NAME = 173 new Ordering<Field>() { 174 @Override 175 public int compare(Field left, Field right) { 176 return left.getName().compareTo(right.getName()); 177 } 178 }; 179 180 /** 181 * Returns a new {@code MatchResult} that corresponds to a successful match. Apache Harmony (used 182 * in Android) requires a successful match in order to generate a {@code MatchResult}: 183 * http://goo.gl/5VQFmC 184 */ newMatchResult()185 private static MatchResult newMatchResult() { 186 Matcher matcher = Pattern.compile(".").matcher("X"); 187 matcher.find(); 188 return matcher.toMatchResult(); 189 } 190 191 private static final ClassToInstanceMap<Object> DEFAULTS = 192 ImmutableClassToInstanceMap.builder() 193 // primitives 194 .put(Object.class, "") 195 .put(Number.class, 0) 196 .put(UnsignedInteger.class, UnsignedInteger.ZERO) 197 .put(UnsignedLong.class, UnsignedLong.ZERO) 198 .put(BigInteger.class, BigInteger.ZERO) 199 .put(BigDecimal.class, BigDecimal.ZERO) 200 .put(CharSequence.class, "") 201 .put(String.class, "") 202 .put(Pattern.class, Pattern.compile("")) 203 .put(MatchResult.class, newMatchResult()) 204 .put(TimeUnit.class, TimeUnit.SECONDS) 205 .put(Charset.class, Charsets.UTF_8) 206 .put(Currency.class, Currency.getInstance(Locale.US)) 207 .put(Locale.class, Locale.US) 208 .put(UUID.class, UUID.randomUUID()) 209 // common.base 210 .put(CharMatcher.class, CharMatcher.none()) 211 .put(Joiner.class, Joiner.on(',')) 212 .put(Splitter.class, Splitter.on(',')) 213 .put(com.google.common.base.Optional.class, com.google.common.base.Optional.absent()) 214 .put(Predicate.class, Predicates.alwaysTrue()) 215 .put(Equivalence.class, Equivalence.equals()) 216 .put(Ticker.class, Ticker.systemTicker()) 217 .put(Stopwatch.class, Stopwatch.createUnstarted()) 218 // io types 219 .put(InputStream.class, new ByteArrayInputStream(new byte[0])) 220 .put(ByteArrayInputStream.class, new ByteArrayInputStream(new byte[0])) 221 .put(Readable.class, new StringReader("")) 222 .put(Reader.class, new StringReader("")) 223 .put(StringReader.class, new StringReader("")) 224 .put(Buffer.class, ByteBuffer.allocate(0)) 225 .put(CharBuffer.class, CharBuffer.allocate(0)) 226 .put(ByteBuffer.class, ByteBuffer.allocate(0)) 227 .put(ShortBuffer.class, ShortBuffer.allocate(0)) 228 .put(IntBuffer.class, IntBuffer.allocate(0)) 229 .put(LongBuffer.class, LongBuffer.allocate(0)) 230 .put(FloatBuffer.class, FloatBuffer.allocate(0)) 231 .put(DoubleBuffer.class, DoubleBuffer.allocate(0)) 232 .put(File.class, new File("")) 233 .put(ByteSource.class, ByteSource.empty()) 234 .put(CharSource.class, CharSource.empty()) 235 .put(ByteSink.class, NullByteSink.INSTANCE) 236 .put(CharSink.class, NullByteSink.INSTANCE.asCharSink(Charsets.UTF_8)) 237 // All collections are immutable empty. So safe for any type parameter. 238 .put(Iterator.class, ImmutableSet.of().iterator()) 239 .put(PeekingIterator.class, Iterators.peekingIterator(ImmutableSet.of().iterator())) 240 .put(ListIterator.class, ImmutableList.of().listIterator()) 241 .put(Iterable.class, ImmutableSet.of()) 242 .put(Collection.class, ImmutableList.of()) 243 .put(ImmutableCollection.class, ImmutableList.of()) 244 .put(List.class, ImmutableList.of()) 245 .put(ImmutableList.class, ImmutableList.of()) 246 .put(Set.class, ImmutableSet.of()) 247 .put(ImmutableSet.class, ImmutableSet.of()) 248 .put(SortedSet.class, ImmutableSortedSet.of()) 249 .put(ImmutableSortedSet.class, ImmutableSortedSet.of()) 250 .put(NavigableSet.class, Sets.unmodifiableNavigableSet(Sets.newTreeSet())) 251 .put(Map.class, ImmutableMap.of()) 252 .put(ImmutableMap.class, ImmutableMap.of()) 253 .put(SortedMap.class, ImmutableSortedMap.of()) 254 .put(ImmutableSortedMap.class, ImmutableSortedMap.of()) 255 .put(NavigableMap.class, Maps.unmodifiableNavigableMap(Maps.newTreeMap())) 256 .put(Multimap.class, ImmutableMultimap.of()) 257 .put(ImmutableMultimap.class, ImmutableMultimap.of()) 258 .put(ListMultimap.class, ImmutableListMultimap.of()) 259 .put(ImmutableListMultimap.class, ImmutableListMultimap.of()) 260 .put(SetMultimap.class, ImmutableSetMultimap.of()) 261 .put(ImmutableSetMultimap.class, ImmutableSetMultimap.of()) 262 .put( 263 SortedSetMultimap.class, 264 Multimaps.unmodifiableSortedSetMultimap(TreeMultimap.create())) 265 .put(Multiset.class, ImmutableMultiset.of()) 266 .put(ImmutableMultiset.class, ImmutableMultiset.of()) 267 .put(SortedMultiset.class, ImmutableSortedMultiset.of()) 268 .put(ImmutableSortedMultiset.class, ImmutableSortedMultiset.of()) 269 .put(BiMap.class, ImmutableBiMap.of()) 270 .put(ImmutableBiMap.class, ImmutableBiMap.of()) 271 .put(Table.class, ImmutableTable.of()) 272 .put(ImmutableTable.class, ImmutableTable.of()) 273 .put(RowSortedTable.class, Tables.unmodifiableRowSortedTable(TreeBasedTable.create())) 274 .put(ClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build()) 275 .put(ImmutableClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build()) 276 .put(Comparable.class, ByToString.INSTANCE) 277 .put(Comparator.class, AlwaysEqual.INSTANCE) 278 .put(Ordering.class, AlwaysEqual.INSTANCE) 279 .put(Range.class, Range.all()) 280 .put(MapDifference.class, Maps.difference(ImmutableMap.of(), ImmutableMap.of())) 281 .put( 282 SortedMapDifference.class, 283 Maps.difference(ImmutableSortedMap.of(), ImmutableSortedMap.of())) 284 // reflect 285 .put(AnnotatedElement.class, Object.class) 286 .put(GenericDeclaration.class, Object.class) 287 .put(Type.class, Object.class) 288 .build(); 289 290 /** 291 * type → implementation. Inherently mutable interfaces and abstract classes are mapped to their 292 * default implementations and are "new"d upon get(). 293 */ 294 private static final ConcurrentMap<Class<?>, Class<?>> implementations = Maps.newConcurrentMap(); 295 setImplementation(Class<T> type, Class<? extends T> implementation)296 private static <T> void setImplementation(Class<T> type, Class<? extends T> implementation) { 297 checkArgument(type != implementation, "Don't register %s to itself!", type); 298 checkArgument( 299 !DEFAULTS.containsKey(type), "A default value was already registered for %s", type); 300 checkArgument( 301 implementations.put(type, implementation) == null, 302 "Implementation for %s was already registered", 303 type); 304 } 305 306 static { setImplementation(Appendable.class, StringBuilder.class)307 setImplementation(Appendable.class, StringBuilder.class); setImplementation(BlockingQueue.class, LinkedBlockingDeque.class)308 setImplementation(BlockingQueue.class, LinkedBlockingDeque.class); setImplementation(BlockingDeque.class, LinkedBlockingDeque.class)309 setImplementation(BlockingDeque.class, LinkedBlockingDeque.class); setImplementation(ConcurrentMap.class, ConcurrentHashMap.class)310 setImplementation(ConcurrentMap.class, ConcurrentHashMap.class); setImplementation(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class)311 setImplementation(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class); setImplementation(CountDownLatch.class, Dummies.DummyCountDownLatch.class)312 setImplementation(CountDownLatch.class, Dummies.DummyCountDownLatch.class); setImplementation(Deque.class, ArrayDeque.class)313 setImplementation(Deque.class, ArrayDeque.class); setImplementation(OutputStream.class, ByteArrayOutputStream.class)314 setImplementation(OutputStream.class, ByteArrayOutputStream.class); setImplementation(PrintStream.class, Dummies.InMemoryPrintStream.class)315 setImplementation(PrintStream.class, Dummies.InMemoryPrintStream.class); setImplementation(PrintWriter.class, Dummies.InMemoryPrintWriter.class)316 setImplementation(PrintWriter.class, Dummies.InMemoryPrintWriter.class); setImplementation(Queue.class, ArrayDeque.class)317 setImplementation(Queue.class, ArrayDeque.class); setImplementation(Random.class, Dummies.DeterministicRandom.class)318 setImplementation(Random.class, Dummies.DeterministicRandom.class); setImplementation( ScheduledThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class)319 setImplementation( 320 ScheduledThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class); setImplementation(ThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class)321 setImplementation(ThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class); setImplementation(Writer.class, StringWriter.class)322 setImplementation(Writer.class, StringWriter.class); setImplementation(Runnable.class, Dummies.DummyRunnable.class)323 setImplementation(Runnable.class, Dummies.DummyRunnable.class); setImplementation(ThreadFactory.class, Dummies.DummyThreadFactory.class)324 setImplementation(ThreadFactory.class, Dummies.DummyThreadFactory.class); setImplementation(Executor.class, Dummies.DummyExecutor.class)325 setImplementation(Executor.class, Dummies.DummyExecutor.class); 326 } 327 328 @SuppressWarnings("unchecked") // it's a subtype map 329 @CheckForNull getImplementation(Class<T> type)330 private static <T> Class<? extends T> getImplementation(Class<T> type) { 331 return (Class<? extends T>) implementations.get(type); 332 } 333 334 private static final Logger logger = Logger.getLogger(ArbitraryInstances.class.getName()); 335 336 /** 337 * Returns an arbitrary instance for {@code type}, or {@code null} if no arbitrary instance can be 338 * determined. 339 */ 340 @CheckForNull get(Class<T> type)341 public static <T> T get(Class<T> type) { 342 T defaultValue = DEFAULTS.getInstance(type); 343 if (defaultValue != null) { 344 return defaultValue; 345 } 346 Class<? extends T> implementation = getImplementation(type); 347 if (implementation != null) { 348 return get(implementation); 349 } 350 if (type.isEnum()) { 351 T[] enumConstants = type.getEnumConstants(); 352 return (enumConstants.length == 0) ? null : enumConstants[0]; 353 } 354 if (type.isArray()) { 355 return createEmptyArray(type); 356 } 357 T jvmDefault = Defaults.defaultValue(Primitives.unwrap(type)); 358 if (jvmDefault != null) { 359 return jvmDefault; 360 } 361 if (Modifier.isAbstract(type.getModifiers()) || !Modifier.isPublic(type.getModifiers())) { 362 return arbitraryConstantInstanceOrNull(type); 363 } 364 final Constructor<T> constructor; 365 try { 366 constructor = type.getConstructor(); 367 } catch (NoSuchMethodException e) { 368 return arbitraryConstantInstanceOrNull(type); 369 } 370 constructor.setAccessible(true); // accessibility check is too slow 371 try { 372 return constructor.newInstance(); 373 /* 374 * Do not merge the 2 catch blocks below. javac would infer a type of 375 * ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of 376 * Android don't *seem* to mind, but there might be edge cases of which we're unaware.) 377 */ 378 } catch (InstantiationException impossible) { 379 throw new AssertionError(impossible); 380 } catch (IllegalAccessException impossible) { 381 throw new AssertionError(impossible); 382 } catch (InvocationTargetException e) { 383 logger.log(Level.WARNING, "Exception while invoking default constructor.", e.getCause()); 384 return arbitraryConstantInstanceOrNull(type); 385 } 386 } 387 388 @CheckForNull arbitraryConstantInstanceOrNull(Class<T> type)389 private static <T> T arbitraryConstantInstanceOrNull(Class<T> type) { 390 Field[] fields = type.getDeclaredFields(); 391 Arrays.sort(fields, BY_FIELD_NAME); 392 for (Field field : fields) { 393 if (Modifier.isPublic(field.getModifiers()) 394 && Modifier.isStatic(field.getModifiers()) 395 && Modifier.isFinal(field.getModifiers())) { 396 if (field.getGenericType() == field.getType() && type.isAssignableFrom(field.getType())) { 397 field.setAccessible(true); 398 try { 399 T constant = type.cast(field.get(null)); 400 if (constant != null) { 401 return constant; 402 } 403 } catch (IllegalAccessException impossible) { 404 throw new AssertionError(impossible); 405 } 406 } 407 } 408 } 409 return null; 410 } 411 createEmptyArray(Class<T> arrayType)412 private static <T> T createEmptyArray(Class<T> arrayType) { 413 return arrayType.cast(Array.newInstance(arrayType.getComponentType(), 0)); 414 } 415 416 // Internal implementations of some classes, with public default constructor that get() needs. 417 private static final class Dummies { 418 419 public static final class InMemoryPrintStream extends PrintStream { InMemoryPrintStream()420 public InMemoryPrintStream() { 421 super(new ByteArrayOutputStream()); 422 } 423 } 424 425 public static final class InMemoryPrintWriter extends PrintWriter { InMemoryPrintWriter()426 public InMemoryPrintWriter() { 427 super(new StringWriter()); 428 } 429 } 430 431 public static final class DeterministicRandom extends Random { 432 @Keep DeterministicRandom()433 public DeterministicRandom() { 434 super(0); 435 } 436 } 437 438 public static final class DummyScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { DummyScheduledThreadPoolExecutor()439 public DummyScheduledThreadPoolExecutor() { 440 super(1); 441 } 442 } 443 444 public static final class DummyCountDownLatch extends CountDownLatch { DummyCountDownLatch()445 public DummyCountDownLatch() { 446 super(0); 447 } 448 } 449 450 public static final class DummyRunnable implements Runnable, Serializable { 451 @Override run()452 public void run() {} 453 } 454 455 public static final class DummyThreadFactory implements ThreadFactory, Serializable { 456 @Override newThread(Runnable r)457 public Thread newThread(Runnable r) { 458 return new Thread(r); 459 } 460 } 461 462 public static final class DummyExecutor implements Executor, Serializable { 463 @Override execute(Runnable command)464 public void execute(Runnable command) {} 465 } 466 } 467 468 private static final class NullByteSink extends ByteSink implements Serializable { 469 private static final NullByteSink INSTANCE = new NullByteSink(); 470 471 @Override openStream()472 public OutputStream openStream() { 473 return ByteStreams.nullOutputStream(); 474 } 475 } 476 477 // Compare by toString() to satisfy 2 properties: 478 // 1. compareTo(null) should throw NullPointerException 479 // 2. the order is deterministic and easy to understand, for debugging purpose. 480 @SuppressWarnings("ComparableType") 481 private static final class ByToString implements Comparable<Object>, Serializable { 482 private static final ByToString INSTANCE = new ByToString(); 483 484 @Override compareTo(Object o)485 public int compareTo(Object o) { 486 return toString().compareTo(o.toString()); 487 } 488 489 @Override toString()490 public String toString() { 491 return "BY_TO_STRING"; 492 } 493 readResolve()494 private Object readResolve() { 495 return INSTANCE; 496 } 497 } 498 499 // Always equal is a valid total ordering. And it works for any Object. 500 private static final class AlwaysEqual extends Ordering<Object> implements Serializable { 501 private static final AlwaysEqual INSTANCE = new AlwaysEqual(); 502 503 @Override compare(Object o1, Object o2)504 public int compare(Object o1, Object o2) { 505 return 0; 506 } 507 508 @Override toString()509 public String toString() { 510 return "ALWAYS_EQUAL"; 511 } 512 readResolve()513 private Object readResolve() { 514 return INSTANCE; 515 } 516 } 517 ArbitraryInstances()518 private ArbitraryInstances() {} 519 } 520