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.Beta; 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.base.CharMatcher; 24 import com.google.common.base.Charsets; 25 import com.google.common.base.Defaults; 26 import com.google.common.base.Equivalence; 27 import com.google.common.base.Joiner; 28 import com.google.common.base.Predicate; 29 import com.google.common.base.Predicates; 30 import com.google.common.base.Splitter; 31 import com.google.common.base.Stopwatch; 32 import com.google.common.base.Ticker; 33 import com.google.common.collect.BiMap; 34 import com.google.common.collect.ClassToInstanceMap; 35 import com.google.common.collect.ImmutableBiMap; 36 import com.google.common.collect.ImmutableClassToInstanceMap; 37 import com.google.common.collect.ImmutableCollection; 38 import com.google.common.collect.ImmutableList; 39 import com.google.common.collect.ImmutableListMultimap; 40 import com.google.common.collect.ImmutableMap; 41 import com.google.common.collect.ImmutableMultimap; 42 import com.google.common.collect.ImmutableMultiset; 43 import com.google.common.collect.ImmutableSet; 44 import com.google.common.collect.ImmutableSetMultimap; 45 import com.google.common.collect.ImmutableSortedMap; 46 import com.google.common.collect.ImmutableSortedMultiset; 47 import com.google.common.collect.ImmutableSortedSet; 48 import com.google.common.collect.ImmutableTable; 49 import com.google.common.collect.Iterators; 50 import com.google.common.collect.ListMultimap; 51 import com.google.common.collect.MapDifference; 52 import com.google.common.collect.Maps; 53 import com.google.common.collect.Multimap; 54 import com.google.common.collect.Multimaps; 55 import com.google.common.collect.Multiset; 56 import com.google.common.collect.Ordering; 57 import com.google.common.collect.PeekingIterator; 58 import com.google.common.collect.Range; 59 import com.google.common.collect.RowSortedTable; 60 import com.google.common.collect.SetMultimap; 61 import com.google.common.collect.Sets; 62 import com.google.common.collect.SortedMapDifference; 63 import com.google.common.collect.SortedMultiset; 64 import com.google.common.collect.SortedSetMultimap; 65 import com.google.common.collect.Table; 66 import com.google.common.collect.Tables; 67 import com.google.common.collect.TreeBasedTable; 68 import com.google.common.collect.TreeMultimap; 69 import com.google.common.io.ByteSink; 70 import com.google.common.io.ByteSource; 71 import com.google.common.io.ByteStreams; 72 import com.google.common.io.CharSink; 73 import com.google.common.io.CharSource; 74 import com.google.common.primitives.Primitives; 75 import com.google.common.primitives.UnsignedInteger; 76 import com.google.common.primitives.UnsignedLong; 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 org.checkerframework.checker.nullness.compatqual.NullableDecl; 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 @Beta 170 @GwtIncompatible 171 public final class ArbitraryInstances { 172 173 private static final Ordering<Field> BY_FIELD_NAME = 174 new Ordering<Field>() { 175 @Override 176 public int compare(Field left, Field right) { 177 return left.getName().compareTo(right.getName()); 178 } 179 }; 180 181 /** 182 * Returns a new {@code MatchResult} that corresponds to a successful match. Apache Harmony (used 183 * in Android) requires a successful match in order to generate a {@code MatchResult}: 184 * http://goo.gl/5VQFmC 185 */ newMatchResult()186 private static MatchResult newMatchResult() { 187 Matcher matcher = Pattern.compile(".").matcher("X"); 188 matcher.find(); 189 return matcher.toMatchResult(); 190 } 191 192 private static final ClassToInstanceMap<Object> DEFAULTS = 193 ImmutableClassToInstanceMap.builder() 194 // primitives 195 .put(Object.class, "") 196 .put(Number.class, 0) 197 .put(UnsignedInteger.class, UnsignedInteger.ZERO) 198 .put(UnsignedLong.class, UnsignedLong.ZERO) 199 .put(BigInteger.class, BigInteger.ZERO) 200 .put(BigDecimal.class, BigDecimal.ZERO) 201 .put(CharSequence.class, "") 202 .put(String.class, "") 203 .put(Pattern.class, Pattern.compile("")) 204 .put(MatchResult.class, newMatchResult()) 205 .put(TimeUnit.class, TimeUnit.SECONDS) 206 .put(Charset.class, Charsets.UTF_8) 207 .put(Currency.class, Currency.getInstance(Locale.US)) 208 .put(Locale.class, Locale.US) 209 .put(UUID.class, UUID.randomUUID()) 210 // common.base 211 .put(CharMatcher.class, CharMatcher.none()) 212 .put(Joiner.class, Joiner.on(',')) 213 .put(Splitter.class, Splitter.on(',')) 214 .put(com.google.common.base.Optional.class, com.google.common.base.Optional.absent()) 215 .put(Predicate.class, Predicates.alwaysTrue()) 216 .put(Equivalence.class, Equivalence.equals()) 217 .put(Ticker.class, Ticker.systemTicker()) 218 .put(Stopwatch.class, Stopwatch.createUnstarted()) 219 // io types 220 .put(InputStream.class, new ByteArrayInputStream(new byte[0])) 221 .put(ByteArrayInputStream.class, new ByteArrayInputStream(new byte[0])) 222 .put(Readable.class, new StringReader("")) 223 .put(Reader.class, new StringReader("")) 224 .put(StringReader.class, new StringReader("")) 225 .put(Buffer.class, ByteBuffer.allocate(0)) 226 .put(CharBuffer.class, CharBuffer.allocate(0)) 227 .put(ByteBuffer.class, ByteBuffer.allocate(0)) 228 .put(ShortBuffer.class, ShortBuffer.allocate(0)) 229 .put(IntBuffer.class, IntBuffer.allocate(0)) 230 .put(LongBuffer.class, LongBuffer.allocate(0)) 231 .put(FloatBuffer.class, FloatBuffer.allocate(0)) 232 .put(DoubleBuffer.class, DoubleBuffer.allocate(0)) 233 .put(File.class, new File("")) 234 .put(ByteSource.class, ByteSource.empty()) 235 .put(CharSource.class, CharSource.empty()) 236 .put(ByteSink.class, NullByteSink.INSTANCE) 237 .put(CharSink.class, NullByteSink.INSTANCE.asCharSink(Charsets.UTF_8)) 238 // All collections are immutable empty. So safe for any type parameter. 239 .put(Iterator.class, ImmutableSet.of().iterator()) 240 .put(PeekingIterator.class, Iterators.peekingIterator(ImmutableSet.of().iterator())) 241 .put(ListIterator.class, ImmutableList.of().listIterator()) 242 .put(Iterable.class, ImmutableSet.of()) 243 .put(Collection.class, ImmutableList.of()) 244 .put(ImmutableCollection.class, ImmutableList.of()) 245 .put(List.class, ImmutableList.of()) 246 .put(ImmutableList.class, ImmutableList.of()) 247 .put(Set.class, ImmutableSet.of()) 248 .put(ImmutableSet.class, ImmutableSet.of()) 249 .put(SortedSet.class, ImmutableSortedSet.of()) 250 .put(ImmutableSortedSet.class, ImmutableSortedSet.of()) 251 .put(NavigableSet.class, Sets.unmodifiableNavigableSet(Sets.newTreeSet())) 252 .put(Map.class, ImmutableMap.of()) 253 .put(ImmutableMap.class, ImmutableMap.of()) 254 .put(SortedMap.class, ImmutableSortedMap.of()) 255 .put(ImmutableSortedMap.class, ImmutableSortedMap.of()) 256 .put(NavigableMap.class, Maps.unmodifiableNavigableMap(Maps.newTreeMap())) 257 .put(Multimap.class, ImmutableMultimap.of()) 258 .put(ImmutableMultimap.class, ImmutableMultimap.of()) 259 .put(ListMultimap.class, ImmutableListMultimap.of()) 260 .put(ImmutableListMultimap.class, ImmutableListMultimap.of()) 261 .put(SetMultimap.class, ImmutableSetMultimap.of()) 262 .put(ImmutableSetMultimap.class, ImmutableSetMultimap.of()) 263 .put( 264 SortedSetMultimap.class, 265 Multimaps.unmodifiableSortedSetMultimap(TreeMultimap.create())) 266 .put(Multiset.class, ImmutableMultiset.of()) 267 .put(ImmutableMultiset.class, ImmutableMultiset.of()) 268 .put(SortedMultiset.class, ImmutableSortedMultiset.of()) 269 .put(ImmutableSortedMultiset.class, ImmutableSortedMultiset.of()) 270 .put(BiMap.class, ImmutableBiMap.of()) 271 .put(ImmutableBiMap.class, ImmutableBiMap.of()) 272 .put(Table.class, ImmutableTable.of()) 273 .put(ImmutableTable.class, ImmutableTable.of()) 274 .put(RowSortedTable.class, Tables.unmodifiableRowSortedTable(TreeBasedTable.create())) 275 .put(ClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build()) 276 .put(ImmutableClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build()) 277 .put(Comparable.class, ByToString.INSTANCE) 278 .put(Comparator.class, AlwaysEqual.INSTANCE) 279 .put(Ordering.class, AlwaysEqual.INSTANCE) 280 .put(Range.class, Range.all()) 281 .put(MapDifference.class, Maps.difference(ImmutableMap.of(), ImmutableMap.of())) 282 .put( 283 SortedMapDifference.class, 284 Maps.difference(ImmutableSortedMap.of(), ImmutableSortedMap.of())) 285 // reflect 286 .put(AnnotatedElement.class, Object.class) 287 .put(GenericDeclaration.class, Object.class) 288 .put(Type.class, Object.class) 289 .build(); 290 291 /** 292 * type → implementation. Inherently mutable interfaces and abstract classes are mapped to their 293 * default implementations and are "new"d upon get(). 294 */ 295 private static final ConcurrentMap<Class<?>, Class<?>> implementations = Maps.newConcurrentMap(); 296 setImplementation(Class<T> type, Class<? extends T> implementation)297 private static <T> void setImplementation(Class<T> type, Class<? extends T> implementation) { 298 checkArgument(type != implementation, "Don't register %s to itself!", type); 299 checkArgument( 300 !DEFAULTS.containsKey(type), "A default value was already registered for %s", type); 301 checkArgument( 302 implementations.put(type, implementation) == null, 303 "Implementation for %s was already registered", 304 type); 305 } 306 307 static { setImplementation(Appendable.class, StringBuilder.class)308 setImplementation(Appendable.class, StringBuilder.class); setImplementation(BlockingQueue.class, LinkedBlockingDeque.class)309 setImplementation(BlockingQueue.class, LinkedBlockingDeque.class); setImplementation(BlockingDeque.class, LinkedBlockingDeque.class)310 setImplementation(BlockingDeque.class, LinkedBlockingDeque.class); setImplementation(ConcurrentMap.class, ConcurrentHashMap.class)311 setImplementation(ConcurrentMap.class, ConcurrentHashMap.class); setImplementation(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class)312 setImplementation(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class); setImplementation(CountDownLatch.class, Dummies.DummyCountDownLatch.class)313 setImplementation(CountDownLatch.class, Dummies.DummyCountDownLatch.class); setImplementation(Deque.class, ArrayDeque.class)314 setImplementation(Deque.class, ArrayDeque.class); setImplementation(OutputStream.class, ByteArrayOutputStream.class)315 setImplementation(OutputStream.class, ByteArrayOutputStream.class); setImplementation(PrintStream.class, Dummies.InMemoryPrintStream.class)316 setImplementation(PrintStream.class, Dummies.InMemoryPrintStream.class); setImplementation(PrintWriter.class, Dummies.InMemoryPrintWriter.class)317 setImplementation(PrintWriter.class, Dummies.InMemoryPrintWriter.class); setImplementation(Queue.class, ArrayDeque.class)318 setImplementation(Queue.class, ArrayDeque.class); setImplementation(Random.class, Dummies.DeterministicRandom.class)319 setImplementation(Random.class, Dummies.DeterministicRandom.class); setImplementation( ScheduledThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class)320 setImplementation( 321 ScheduledThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class); setImplementation(ThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class)322 setImplementation(ThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class); setImplementation(Writer.class, StringWriter.class)323 setImplementation(Writer.class, StringWriter.class); setImplementation(Runnable.class, Dummies.DummyRunnable.class)324 setImplementation(Runnable.class, Dummies.DummyRunnable.class); setImplementation(ThreadFactory.class, Dummies.DummyThreadFactory.class)325 setImplementation(ThreadFactory.class, Dummies.DummyThreadFactory.class); setImplementation(Executor.class, Dummies.DummyExecutor.class)326 setImplementation(Executor.class, Dummies.DummyExecutor.class); 327 } 328 329 @SuppressWarnings("unchecked") // it's a subtype map 330 @NullableDecl getImplementation(Class<T> type)331 private static <T> Class<? extends T> getImplementation(Class<T> type) { 332 return (Class<? extends T>) implementations.get(type); 333 } 334 335 private static final Logger logger = Logger.getLogger(ArbitraryInstances.class.getName()); 336 337 /** 338 * Returns an arbitrary instance for {@code type}, or {@code null} if no arbitrary instance can be 339 * determined. 340 */ 341 @NullableDecl get(Class<T> type)342 public static <T> T get(Class<T> type) { 343 T defaultValue = DEFAULTS.getInstance(type); 344 if (defaultValue != null) { 345 return defaultValue; 346 } 347 Class<? extends T> implementation = getImplementation(type); 348 if (implementation != null) { 349 return get(implementation); 350 } 351 if (type.isEnum()) { 352 T[] enumConstants = type.getEnumConstants(); 353 return (enumConstants.length == 0) ? null : enumConstants[0]; 354 } 355 if (type.isArray()) { 356 return createEmptyArray(type); 357 } 358 T jvmDefault = Defaults.defaultValue(Primitives.unwrap(type)); 359 if (jvmDefault != null) { 360 return jvmDefault; 361 } 362 if (Modifier.isAbstract(type.getModifiers()) || !Modifier.isPublic(type.getModifiers())) { 363 return arbitraryConstantInstanceOrNull(type); 364 } 365 final Constructor<T> constructor; 366 try { 367 constructor = type.getConstructor(); 368 } catch (NoSuchMethodException e) { 369 return arbitraryConstantInstanceOrNull(type); 370 } 371 constructor.setAccessible(true); // accessibility check is too slow 372 try { 373 return constructor.newInstance(); 374 /* 375 * Do not merge the 2 catch blocks below. javac would infer a type of 376 * ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of 377 * Android don't *seem* to mind, but there might be edge cases of which we're unaware.) 378 */ 379 } catch (InstantiationException impossible) { 380 throw new AssertionError(impossible); 381 } catch (IllegalAccessException impossible) { 382 throw new AssertionError(impossible); 383 } catch (InvocationTargetException e) { 384 logger.log(Level.WARNING, "Exception while invoking default constructor.", e.getCause()); 385 return arbitraryConstantInstanceOrNull(type); 386 } 387 } 388 389 @NullableDecl arbitraryConstantInstanceOrNull(Class<T> type)390 private static <T> T arbitraryConstantInstanceOrNull(Class<T> type) { 391 Field[] fields = type.getDeclaredFields(); 392 Arrays.sort(fields, BY_FIELD_NAME); 393 for (Field field : fields) { 394 if (Modifier.isPublic(field.getModifiers()) 395 && Modifier.isStatic(field.getModifiers()) 396 && Modifier.isFinal(field.getModifiers())) { 397 if (field.getGenericType() == field.getType() && type.isAssignableFrom(field.getType())) { 398 field.setAccessible(true); 399 try { 400 T constant = type.cast(field.get(null)); 401 if (constant != null) { 402 return constant; 403 } 404 } catch (IllegalAccessException impossible) { 405 throw new AssertionError(impossible); 406 } 407 } 408 } 409 } 410 return null; 411 } 412 createEmptyArray(Class<T> arrayType)413 private static <T> T createEmptyArray(Class<T> arrayType) { 414 return arrayType.cast(Array.newInstance(arrayType.getComponentType(), 0)); 415 } 416 417 // Internal implementations of some classes, with public default constructor that get() needs. 418 private static final class Dummies { 419 420 public static final class InMemoryPrintStream extends PrintStream { InMemoryPrintStream()421 public InMemoryPrintStream() { 422 super(new ByteArrayOutputStream()); 423 } 424 } 425 426 public static final class InMemoryPrintWriter extends PrintWriter { InMemoryPrintWriter()427 public InMemoryPrintWriter() { 428 super(new StringWriter()); 429 } 430 } 431 432 public static final class DeterministicRandom extends Random { 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