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