diff options
Diffstat (limited to 'guava-testlib/src/com/google/common/testing/ArbitraryInstances.java')
-rw-r--r-- | guava-testlib/src/com/google/common/testing/ArbitraryInstances.java | 440 |
1 files changed, 0 insertions, 440 deletions
diff --git a/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java b/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java deleted file mode 100644 index 4ebcc9a..0000000 --- a/guava-testlib/src/com/google/common/testing/ArbitraryInstances.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) 2012 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.testing; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.annotations.Beta; -import com.google.common.base.CharMatcher; -import com.google.common.base.Charsets; -import com.google.common.base.Defaults; -import com.google.common.base.Equivalence; -import com.google.common.base.Joiner; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.base.Splitter; -import com.google.common.base.Ticker; -import com.google.common.collect.BiMap; -import com.google.common.collect.ClassToInstanceMap; -import com.google.common.collect.Constraint; -import com.google.common.collect.Constraints; -import com.google.common.collect.ImmutableBiMap; -import com.google.common.collect.ImmutableClassToInstanceMap; -import com.google.common.collect.ImmutableCollection; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableListMultimap; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableMultiset; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSetMultimap; -import com.google.common.collect.ImmutableSortedMap; -import com.google.common.collect.ImmutableSortedMultiset; -import com.google.common.collect.ImmutableSortedSet; -import com.google.common.collect.ImmutableTable; -import com.google.common.collect.Iterators; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.MapConstraint; -import com.google.common.collect.MapConstraints; -import com.google.common.collect.MapDifference; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; -import com.google.common.collect.Multiset; -import com.google.common.collect.Ordering; -import com.google.common.collect.PeekingIterator; -import com.google.common.collect.Range; -import com.google.common.collect.RowSortedTable; -import com.google.common.collect.SetMultimap; -import com.google.common.collect.Sets; -import com.google.common.collect.SortedMapDifference; -import com.google.common.collect.SortedMultiset; -import com.google.common.collect.SortedSetMultimap; -import com.google.common.collect.Table; -import com.google.common.collect.Tables; -import com.google.common.collect.TreeBasedTable; -import com.google.common.collect.TreeMultimap; -import com.google.common.primitives.Primitives; -import com.google.common.primitives.UnsignedInteger; -import com.google.common.primitives.UnsignedLong; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.Reader; -import java.io.Serializable; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.GenericDeclaration; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.DoubleBuffer; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.LongBuffer; -import java.nio.ShortBuffer; -import java.nio.charset.Charset; -import java.util.ArrayDeque; -import java.util.Collection; -import java.util.Comparator; -import java.util.Currency; -import java.util.Deque; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Locale; -import java.util.Map; -import java.util.NavigableMap; -import java.util.NavigableSet; -import java.util.Queue; -import java.util.Random; -import java.util.Set; -import java.util.SortedMap; -import java.util.SortedSet; -import java.util.concurrent.BlockingDeque; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ConcurrentNavigableMap; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.MatchResult; -import java.util.regex.Pattern; - -import javax.annotation.Nullable; - -/** - * Supplies an arbitrary "default" instance for a wide range of types, often useful in testing - * utilities. - * - * <p>Covers common types defined in {@code java.lang}, {@code java.lang.reflect}, {@code java.io}, - * {@code java.nio}, {@code java.math}, {@code java.util}, {@code java.util.concurrent}, - * {@code java.util.regex}, {@code com.google.common.base}, {@code com.google.common.collect} - * and {@code com.google.common.primitives}. In addition, any public class that exposes a public - * parameter-less constructor will be "new"d and returned. - * - * <p>All default instances returned by {@link #get} are generics-safe. Clients won't get type - * errors for using {@code get(Comparator.class)} as a {@code Comparator<Foo>}, for example. - * Immutable empty instances are returned for collection types; {@code ""} for string; - * {@code 0} for number types; reasonable default instance for other stateless types. For mutable - * types, a fresh instance is created each time {@code get()} is called. - * - * @author Kevin Bourrillion - * @author Ben Yu - * @since 12.0 - */ -@Beta -public final class ArbitraryInstances { - - private static final ClassToInstanceMap<Object> DEFAULTS = ImmutableClassToInstanceMap.builder() - // primitives - .put(Object.class, "") - .put(Number.class, 0) - .put(UnsignedInteger.class, UnsignedInteger.ZERO) - .put(UnsignedLong.class, UnsignedLong.ZERO) - .put(BigInteger.class, BigInteger.ZERO) - .put(BigDecimal.class, BigDecimal.ZERO) - .put(CharSequence.class, "") - .put(String.class, "") - .put(Pattern.class, Pattern.compile("")) - .put(MatchResult.class, Pattern.compile("").matcher("").toMatchResult()) - .put(TimeUnit.class, TimeUnit.SECONDS) - .put(Charset.class, Charsets.UTF_8) - .put(Currency.class, Currency.getInstance(Locale.US)) - .put(Locale.class, Locale.US) - // common.base - .put(CharMatcher.class, CharMatcher.NONE) - .put(Joiner.class, Joiner.on(',')) - .put(Splitter.class, Splitter.on(',')) - .put(Optional.class, Optional.absent()) - .put(Predicate.class, Predicates.alwaysTrue()) - .put(Equivalence.class, Equivalence.equals()) - .put(Ticker.class, Ticker.systemTicker()) - // io types - .put(InputStream.class, new ByteArrayInputStream(new byte[0])) - .put(ByteArrayInputStream.class, new ByteArrayInputStream(new byte[0])) - .put(Readable.class, new StringReader("")) - .put(Reader.class, new StringReader("")) - .put(StringReader.class, new StringReader("")) - .put(Buffer.class, ByteBuffer.allocate(0)) - .put(CharBuffer.class, CharBuffer.allocate(0)) - .put(ByteBuffer.class, ByteBuffer.allocate(0)) - .put(ShortBuffer.class, ShortBuffer.allocate(0)) - .put(IntBuffer.class, IntBuffer.allocate(0)) - .put(LongBuffer.class, LongBuffer.allocate(0)) - .put(FloatBuffer.class, FloatBuffer.allocate(0)) - .put(DoubleBuffer.class, DoubleBuffer.allocate(0)) - .put(File.class, new File("")) - // All collections are immutable empty. So safe for any type parameter. - .put(Iterator.class, Iterators.emptyIterator()) - .put(PeekingIterator.class, Iterators.peekingIterator(Iterators.emptyIterator())) - .put(ListIterator.class, ImmutableList.of().listIterator()) - .put(Iterable.class, ImmutableSet.of()) - .put(Collection.class, ImmutableList.of()) - .put(ImmutableCollection.class, ImmutableList.of()) - .put(List.class, ImmutableList.of()) - .put(ImmutableList.class, ImmutableList.of()) - .put(Set.class, ImmutableSet.of()) - .put(ImmutableSet.class, ImmutableSet.of()) - .put(SortedSet.class, ImmutableSortedSet.of()) - .put(ImmutableSortedSet.class, ImmutableSortedSet.of()) - .put(NavigableSet.class, Sets.unmodifiableNavigableSet(Sets.newTreeSet())) - .put(Map.class, ImmutableMap.of()) - .put(ImmutableMap.class, ImmutableMap.of()) - .put(SortedMap.class, ImmutableSortedMap.of()) - .put(ImmutableSortedMap.class, ImmutableSortedMap.of()) - .put(NavigableMap.class, Maps.unmodifiableNavigableMap(Maps.newTreeMap())) - .put(Multimap.class, ImmutableMultimap.of()) - .put(ImmutableMultimap.class, ImmutableMultimap.of()) - .put(ListMultimap.class, ImmutableListMultimap.of()) - .put(ImmutableListMultimap.class, ImmutableListMultimap.of()) - .put(SetMultimap.class, ImmutableSetMultimap.of()) - .put(ImmutableSetMultimap.class, ImmutableSetMultimap.of()) - .put(SortedSetMultimap.class, Multimaps.unmodifiableSortedSetMultimap(TreeMultimap.create())) - .put(Multiset.class, ImmutableMultiset.of()) - .put(ImmutableMultiset.class, ImmutableMultiset.of()) - .put(SortedMultiset.class, ImmutableSortedMultiset.of()) - .put(ImmutableSortedMultiset.class, ImmutableSortedMultiset.of()) - .put(BiMap.class, ImmutableBiMap.of()) - .put(ImmutableBiMap.class, ImmutableBiMap.of()) - .put(Table.class, ImmutableTable.of()) - .put(ImmutableTable.class, ImmutableTable.of()) - .put(RowSortedTable.class, Tables.unmodifiableRowSortedTable(TreeBasedTable.create())) - .put(ClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build()) - .put(ImmutableClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build()) - .put(Comparable.class, ByToString.INSTANCE) - .put(Comparator.class, AlwaysEqual.INSTANCE) - .put(Ordering.class, AlwaysEqual.INSTANCE) - .put(Range.class, Range.all()) - .put(Constraint.class, Constraints.notNull()) - .put(MapConstraint.class, MapConstraints.notNull()) - .put(MapDifference.class, Maps.difference(ImmutableMap.of(), ImmutableMap.of())) - .put(SortedMapDifference.class, - Maps.difference(ImmutableSortedMap.of(), ImmutableSortedMap.of())) - // reflect - .put(AnnotatedElement.class, Object.class) - .put(GenericDeclaration.class, Object.class) - .put(Type.class, Object.class) - .build(); - - /** - * type -> implementation. Inherently mutable interfaces and abstract classes are mapped to their - * default implementations and are "new"d upon get(). - */ - private static final ConcurrentMap<Class<?>, Class<?>> implementations = Maps.newConcurrentMap(); - - private static <T> void setImplementation(Class<T> type, Class<? extends T> implementation) { - checkArgument(type != implementation, "Don't register %s to itself!", type); - checkArgument(!DEFAULTS.containsKey(type), - "A default value was already registered for %s", type); - checkArgument(implementations.put(type, implementation) == null, - "Implementation for %s was already registered", type); - } - - static { - setImplementation(Appendable.class, StringBuilder.class); - setImplementation(BlockingQueue.class, LinkedBlockingDeque.class); - setImplementation(BlockingDeque.class, LinkedBlockingDeque.class); - setImplementation(ConcurrentMap.class, ConcurrentHashMap.class); - setImplementation(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class); - setImplementation(CountDownLatch.class, Dummies.DummyCountDownLatch.class); - setImplementation(Deque.class, ArrayDeque.class); - setImplementation(OutputStream.class, ByteArrayOutputStream.class); - setImplementation(PrintStream.class, Dummies.InMemoryPrintStream.class); - setImplementation(PrintWriter.class, Dummies.InMemoryPrintWriter.class); - setImplementation(Queue.class, ArrayDeque.class); - setImplementation(Random.class, Dummies.DeterministicRandom.class); - setImplementation(ScheduledThreadPoolExecutor.class, - Dummies.DummyScheduledThreadPoolExecutor.class); - setImplementation(ThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class); - setImplementation(Writer.class, StringWriter.class); - setImplementation(Runnable.class, Dummies.DummyRunnable.class); - setImplementation(ThreadFactory.class, Dummies.DummyThreadFactory.class); - setImplementation(Executor.class, Dummies.DummyExecutor.class); - } - - @SuppressWarnings("unchecked") // it's a subtype map - @Nullable - private static <T> Class<? extends T> getImplementation(Class<T> type) { - return (Class<? extends T>) implementations.get(type); - } - - private static final Logger logger = Logger.getLogger(ArbitraryInstances.class.getName()); - - /** - * Returns an arbitrary value for {@code type} as the null value, or {@code null} if empty-ness is - * unknown for the type. - */ - @Nullable public static <T> T get(Class<T> type) { - T defaultValue = DEFAULTS.getInstance(type); - if (defaultValue != null) { - return defaultValue; - } - Class<? extends T> implementation = getImplementation(type); - if (implementation != null) { - return get(implementation); - } - if (type.isEnum()) { - T[] enumConstants = type.getEnumConstants(); - return (enumConstants.length == 0) - ? null - : enumConstants[0]; - } - if (type.isArray()) { - return createEmptyArray(type); - } - T jvmDefault = Defaults.defaultValue(Primitives.unwrap(type)); - if (jvmDefault != null) { - return jvmDefault; - } - if (Modifier.isAbstract(type.getModifiers()) || !Modifier.isPublic(type.getModifiers())) { - return null; - } - final Constructor<T> constructor; - try { - constructor = type.getConstructor(); - } catch (NoSuchMethodException e) { - return null; - } - constructor.setAccessible(true); // accessibility check is too slow - try { - return constructor.newInstance(); - } catch (InstantiationException impossible) { - throw new AssertionError(impossible); - } catch (IllegalAccessException impossible) { - throw new AssertionError(impossible); - } catch (InvocationTargetException e) { - logger.log(Level.WARNING, "Exception while invoking default constructor.", e.getCause()); - return null; - } - } - - @SuppressWarnings("unchecked") // same component type means same array type - private static <T> T createEmptyArray(Class<T> arrayType) { - return (T) Array.newInstance(arrayType.getComponentType(), 0); - } - - // Internal implementations of some classes, with public default constructor that get() needs. - private static final class Dummies { - - public static final class InMemoryPrintStream extends PrintStream { - public InMemoryPrintStream() { - super(new ByteArrayOutputStream()); - } - } - - public static final class InMemoryPrintWriter extends PrintWriter { - public InMemoryPrintWriter() { - super(new StringWriter()); - } - } - - public static final class DeterministicRandom extends Random { - @SuppressWarnings("unused") // invoked by reflection - public DeterministicRandom() { - super(0); - } - } - - public static final class DummyScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { - public DummyScheduledThreadPoolExecutor() { - super(1); - } - } - - public static final class DummyCountDownLatch extends CountDownLatch { - public DummyCountDownLatch() { - super(0); - } - } - - public static final class DummyRunnable implements Runnable, Serializable { - @Override public void run() {} - } - - public static final class DummyThreadFactory implements ThreadFactory, Serializable { - @Override public Thread newThread(Runnable r) { - return new Thread(r); - } - } - - public static final class DummyExecutor implements Executor, Serializable { - @Override public void execute(Runnable command) {} - } - } - - // Compare by toString() to satisfy 2 properties: - // 1. compareTo(null) should throw NullPointerException - // 2. the order is deterministic and easy to understand, for debugging purpose. - private static final class ByToString implements Comparable<Object>, Serializable { - private static final ByToString INSTANCE = new ByToString(); - - @Override public int compareTo(Object o) { - return toString().compareTo(o.toString()); - } - - @Override public String toString() { - return "BY_TO_STRING"; - } - - private Object readResolve() { - return INSTANCE; - } - } - - // Always equal is a valid total ordering. And it works for any Object. - private static final class AlwaysEqual extends Ordering<Object> implements Serializable { - private static final AlwaysEqual INSTANCE = new AlwaysEqual(); - - @Override public int compare(Object o1, Object o2) { - return 0; - } - - @Override public String toString() { - return "ALWAYS_EQUAL"; - } - - private Object readResolve() { - return INSTANCE; - } - } - - private ArbitraryInstances() {} -} |