1 19 20 package org.netbeans.test.stub.api; 21 22 import java.lang.reflect.InvocationHandler ; 23 import java.lang.reflect.InvocationTargetException ; 24 import java.lang.reflect.Method ; 25 import java.lang.reflect.Proxy ; 26 import java.util.Arrays ; 27 import java.util.Map ; 28 import java.util.WeakHashMap ; 29 import org.netbeans.test.stub.spi.StubImplementation; 30 import org.openide.util.Lookup; 31 32 36 public final class Stub { 37 38 private static StubImplementation IMPL; 39 40 static { 41 IMPL = (StubImplementation)Lookup.getDefault().lookup(StubImplementation.class); 42 if (IMPL == null) { 43 IMPL = new DefaultStubImplementation(); 44 } 45 } 46 47 public static Object create(Class intf) { 48 return create(new Class [] { intf }); 49 } 50 51 public static Object create(Class intfs[]) { 52 return IMPL.create(intfs); 53 } 54 55 public static Object create(Class intf, StubDelegate delegate) { 56 return create(new Class [] { intf }, delegate); 57 } 58 59 public static Object create(Class [] intfs, StubDelegate delegate) { 60 return IMPL.create(intfs, delegate); 61 } 62 63 public static Object getDelegate(Object stub) { 64 return IMPL.getDelegate(stub); 65 } 66 67 public static void setProperty(Object stub, Object key, Object value) { 68 IMPL.setProperty(stub, key, value); 69 } 70 71 private static final class DefaultStubImplementation implements StubImplementation { 72 73 private static final Map STUB_TO_DELEGATE = new WeakHashMap (); 74 75 public Object create(Class [] intfs) { 76 return create(intfs, new DefaultInvocationHandler()); 77 } 78 79 public Object create(Class [] intfs, StubDelegate delegate) { 80 Object stub = create(intfs, new MethodDelegatingInvocationHandler(delegate)); 81 STUB_TO_DELEGATE.put(stub, delegate); 82 return stub; 83 } 84 85 private Object create(Class [] intfs, InvocationHandler handler) { 86 return Proxy.newProxyInstance(Stub.class.getClassLoader(), intfs, handler); 87 } 88 89 public Object getDelegate(Object stub) { 90 StubDelegate delegate = (StubDelegate)STUB_TO_DELEGATE.get(stub); 91 if (delegate == null) { 92 throw new IllegalArgumentException ("No delegate for this stub. Is " + stub + " a stub?"); 93 } 94 return delegate; 95 } 96 97 public void setProperty(Object stub, Object key, Object value) { 98 ((StubDelegate)getDelegate(stub)).setProperty(key, value); 99 } 100 } 101 102 105 private static final class MethodDelegatingInvocationHandler implements InvocationHandler { 106 107 public Object delegate; 108 109 public MethodDelegatingInvocationHandler(Object delegate) { 110 this.delegate = delegate; 111 } 112 113 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable { 114 try { 115 Method delegateMethod = delegate.getClass().getMethod(method.getName(), method.getParameterTypes()); 116 return delegateMethod.invoke(delegate, args); 117 } catch (InvocationTargetException e) { 118 throw e.getCause(); 119 } catch (NoSuchMethodException e) { 120 throw new RuntimeException ("No method " + method.getName() + " with params " + Arrays.asList(method.getParameterTypes())); 123 } 124 } 125 } 126 127 130 private static final class DefaultInvocationHandler implements InvocationHandler { 131 132 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable { 133 String methodName = method.getName(); 134 Class [] paramTypes = method.getParameterTypes(); 135 136 if ("hashCode".equals(methodName)) { 137 return new Integer (System.identityHashCode(proxy)); 138 } else if ("equals".equals(methodName) && paramTypes.length == 1 && paramTypes[0] == Object .class) { 139 return Boolean.valueOf(args[0] == proxy); 140 } 141 142 Class retClass = method.getReturnType(); 143 144 if (retClass.isPrimitive()) { 145 if (retClass == Byte.TYPE) { 146 return new Byte ((byte)0); 147 } else if (retClass == Short.TYPE) { 148 return new Short ((short)0); 149 } else if (retClass == Integer.TYPE) { 150 return new Integer (0); 151 } else if (retClass == Long.TYPE) { 152 return new Long (0L); 153 } else if (retClass == Float.TYPE) { 154 return new Float (0); 155 } else if (retClass == Double.TYPE) { 156 return new Double (0.0); 157 } else if (retClass == Character.TYPE) { 158 return new Character ('\0'); 159 } else if (retClass == Boolean.TYPE) { 160 return Boolean.FALSE; 161 } 162 } 163 164 return null; 165 } 166 } 167 } 168 | Popular Tags |