Coverage Summary for Class: DummyProxy (com.google.common.testing)

Class Method, % Line, %
DummyProxy 100% (2/2) 100% (10/10)
DummyProxy$DummyHandler 100% (7/7) 94.4% (17/18)
Total 100% (9/9) 96.4% (27/28)


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.checkNotNull; 20 import static com.google.common.testing.NullPointerTester.isNullable; 21  22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.collect.ImmutableList; 24 import com.google.common.collect.Sets; 25 import com.google.common.reflect.AbstractInvocationHandler; 26 import com.google.common.reflect.Invokable; 27 import com.google.common.reflect.Parameter; 28 import com.google.common.reflect.TypeToken; 29 import java.io.Serializable; 30 import java.lang.reflect.Method; 31 import java.lang.reflect.Proxy; 32 import java.util.Set; 33  34 /** 35  * Generates a dummy interface proxy that simply returns a dummy value for each method. 36  * 37  * @author Ben Yu 38  */ 39 @GwtIncompatible 40 abstract class DummyProxy { 41  42  /** 43  * Returns a new proxy for {@code interfaceType}. Proxies of the same interface are equal to each 44  * other if the {@link DummyProxy} instance that created the proxies are equal. 45  */ 46  final <T> T newProxy(TypeToken<T> interfaceType) { 47  Set<Class<?>> interfaceClasses = Sets.newLinkedHashSet(); 48  interfaceClasses.addAll(interfaceType.getTypes().interfaces().rawTypes()); 49  // Make the proxy serializable to work with SerializableTester 50  interfaceClasses.add(Serializable.class); 51  Object dummy = 52  Proxy.newProxyInstance( 53  interfaceClasses.iterator().next().getClassLoader(), 54  interfaceClasses.toArray(new Class<?>[interfaceClasses.size()]), 55  new DummyHandler(interfaceType)); 56  @SuppressWarnings("unchecked") // interfaceType is T 57  T result = (T) dummy; 58  return result; 59  } 60  61  /** Returns the dummy return value for {@code returnType}. */ 62  abstract <R> R dummyReturnValue(TypeToken<R> returnType); 63  64  private class DummyHandler extends AbstractInvocationHandler implements Serializable { 65  private final TypeToken<?> interfaceType; 66  67  DummyHandler(TypeToken<?> interfaceType) { 68  this.interfaceType = interfaceType; 69  } 70  71  @Override 72  protected Object handleInvocation(Object proxy, Method method, Object[] args) { 73  Invokable<?, ?> invokable = interfaceType.method(method); 74  ImmutableList<Parameter> params = invokable.getParameters(); 75  for (int i = 0; i < args.length; i++) { 76  Parameter param = params.get(i); 77  if (!isNullable(param)) { 78  checkNotNull(args[i]); 79  } 80  } 81  return dummyReturnValue(interfaceType.resolveType(method.getGenericReturnType())); 82  } 83  84  @Override 85  public int hashCode() { 86  return identity().hashCode(); 87  } 88  89  @Override 90  public boolean equals(Object obj) { 91  if (obj instanceof DummyHandler) { 92  DummyHandler that = (DummyHandler) obj; 93  return identity().equals(that.identity()); 94  } else { 95  return false; 96  } 97  } 98  99  private DummyProxy identity() { 100  return DummyProxy.this; 101  } 102  103  @Override 104  public String toString() { 105  return "Dummy proxy for " + interfaceType; 106  } 107  108  // Since type variables aren't serializable, reduce the type down to raw type before 109  // serialization. 110  private Object writeReplace() { 111  return new DummyHandler(TypeToken.of(interfaceType.getRawType())); 112  } 113  } 114 }