View Javadoc
1 /* 2 * Nanning Aspects 3 * 4 * Distributable under LGPL license. 5 * See terms of license at gnu.org. 6 */ 7 package org.codehaus.nanning; 8 9 import java.io.Serializable; 10 import java.lang.reflect.InvocationTargetException; 11 import java.lang.reflect.Method; 12 import java.util.*; 13 14 /*** 15 * A mixin consists of an interface, a target and a number of interceptors intercepting calls to methods, a mixin 16 * can also be a concrete class (no interface/implementation-separation) but at most one mixins with conrete classes 17 * per AspectInstance is supported. 18 * Create a mixin with interface and target: 19 * <pre><code> 20 new MixinInstance(Interface.class, new Target()); 21 </code></pre> 22 * Create a mixin with a concrete class: 23 * <pre><code> 24 new MixinInstance(Target.class); 25 </code></pre> 26 * Add interceptor to method: 27 * <pre><code> 28 Method method = Target.class.getMethod("method", null); 29 MixinInstance mixin = new MixinInstance(Target.class); 30 mixin.addInterceptor(method, new MethodInterceptor() { 31 public Object invoke(Invocation invocation) { 32 return invocation.invokeNext(); 33 } 34 } 35 </code></pre> 36 * 37 * <!-- $Id: Mixin.java,v 1.1 2003/07/12 16:48:16 lecando Exp $ --> 38 * 39 * @author $Author: lecando $ 40 * @version $Revision: 1.1 $ 41 */ 42 public class Mixin implements Serializable { 43 static final long serialVersionUID = 7386027290257587762L; 44 45 private Class interfaceClass; 46 private Object target; 47 48 private transient Map methodInterceptors = new HashMap(); 49 50 public Mixin() { 51 } 52 53 public Mixin(Class interfaceClass, Object target) { 54 setInterfaceClass(interfaceClass); 55 setTarget(target); 56 } 57 58 public void setInterfaceClass(Class interfaceClass) { 59 this.interfaceClass = interfaceClass; 60 } 61 62 public void setTarget(Object target) { 63 assert !(target instanceof Mixin); 64 this.target = target; 65 } 66 67 public Class getInterfaceClass() { 68 return interfaceClass; 69 } 70 71 public Set getAllInterceptors() { 72 Set allInterceptors = new HashSet(); 73 if (methodInterceptors != null) { 74 for (Iterator methodIterator = methodInterceptors.values().iterator(); methodIterator.hasNext();) { 75 List interceptors = (List) methodIterator.next(); 76 for (Iterator interceptorIterator = interceptors.iterator(); interceptorIterator.hasNext();) { 77 Interceptor interceptor = (Interceptor) interceptorIterator.next(); 78 allInterceptors.add(interceptor); 79 } 80 } 81 } 82 return allInterceptors; 83 } 84 85 public Object getTarget() { 86 return target; 87 } 88 89 public List getInterceptorsForMethod(Method method) { 90 if (methodInterceptors == null) { 91 methodInterceptors = new HashMap(); 92 } 93 List interceptors = (List) methodInterceptors.get(method); 94 if (interceptors == null) { 95 interceptors = new ArrayList(); 96 methodInterceptors.put(method, interceptors); 97 } 98 return interceptors; 99 } 100 101 protected class InvocationImpl implements Invocation { 102 protected Object proxy; 103 protected final Method method; 104 protected final Object[] args; 105 protected ListIterator interceptors; 106 107 public InvocationImpl(Object proxy, Method method, Object[] args) { 108 this.proxy = proxy; 109 this.method = method; 110 this.args = args; 111 interceptors = getInterceptorsForMethod(method).listIterator(); 112 } 113 114 public Object invokeNext() throws Throwable { 115 if (interceptors.hasNext()) { 116 return ((MethodInterceptor) interceptors.next()).invoke(this); 117 } else { 118 try { 119 return method.invoke(getTarget(), args); 120 } catch (InvocationTargetException e) { 121 throwRealException(e); 122 throw e; 123 } 124 } 125 } 126 127 private void throwRealException(InvocationTargetException e) throws Exception { 128 Throwable realException = e.getTargetException(); 129 if (realException instanceof Error) { 130 throw (Error) realException; 131 } else if (realException instanceof RuntimeException) { 132 throw (RuntimeException) realException; 133 } else { 134 throw (Exception) realException; 135 } 136 } 137 138 public Interceptor getInterceptor(int index) { 139 return (Interceptor) getInterceptorsForMethod(method).get(index); 140 } 141 142 public Class getTargetInterface() { 143 return getInterfaceClass(); 144 } 145 146 public AspectInstance getAspectInstance() { 147 return Aspects.getAspectInstance(getProxy()); 148 } 149 150 public int getArgumentCount() { 151 return args.length; 152 } 153 154 public Object getArgument(int arg) { 155 return args[arg]; 156 } 157 158 public Object getTarget() { 159 return Mixin.this.target; 160 } 161 162 public void setTarget(Object target) { 163 Mixin.this.setTarget(target); 164 } 165 166 public Object getProxy() { 167 return proxy; 168 } 169 170 public int getCurrentIndex() { 171 return interceptors.previousIndex(); 172 } 173 174 public int getfInterceptorCount() { 175 return getInterceptorsForMethod(method).size(); 176 } 177 178 public Method getMethod() { 179 return method; 180 } 181 182 public Object[] getArgs() { 183 return args; 184 } 185 } 186 187 public Class getMainClass() { 188 return getInterfaceClass(); 189 } 190 191 public Object invokeMethod(Object proxy, Method method, Object[] args) 192 throws Throwable { 193 Invocation invocation = new InvocationImpl(proxy, method, args); 194 Object returnValue = invocation.invokeNext(); 195 return returnValue; 196 } 197 198 public boolean isMainMixin() { 199 return !getInterfaceClass().isInterface(); 200 } 201 202 /*** 203 * Add interceptor to all methods of the mixin. 204 * @param interceptor 205 */ 206 public void addInterceptor(MethodInterceptor interceptor) { 207 Method[] methods = getAllMethods(); 208 for (int i = 0; i < methods.length; i++) { 209 Method method = methods[i]; 210 addInterceptor(method, interceptor); 211 } 212 } 213 214 public boolean equals(Object o) { 215 if (this == o) return true; 216 if (!(o instanceof Mixin)) return false; 217 218 final Mixin mixinInstance = (Mixin) o; 219 220 if (interfaceClass != null ? !interfaceClass.equals(mixinInstance.interfaceClass) : mixinInstance.interfaceClass != null) return false; 221 if (target != null ? !target.equals(mixinInstance.target) : mixinInstance.target != null) return false; 222 223 return true; 224 } 225 226 public int hashCode() { 227 int result; 228 result = (interfaceClass != null ? interfaceClass.hashCode() : 0); 229 result = 29 * result + (target != null ? target.hashCode() : 0); 230 return result; 231 } 232 233 /*** 234 * Add interceptor to specified method. 235 * @param method 236 * @param interceptor 237 */ 238 public void addInterceptor(Method method, MethodInterceptor interceptor) { 239 getInterceptorsForMethod(method).add(interceptor); 240 } 241 242 public Method[] getAllMethods() { 243 return interfaceClass.getMethods(); 244 } 245 246 public String toString() { 247 return "mixin{" + getTarget() + "}"; 248 } 249 }

This page was automatically generated by Maven