{
String intf = intfs[ifId];
if (addedInterfaces.contains(intf)) throw new Exception("2 mixins are implementing the same interfaces " + intf);
if (implementedInterfaces.contains(intf)) throw new Exception("Attempting to mixin interface already used by class " + intf);
CtClass intfClass = pool.get(intf);
CtMethod[] methods = intfClass.getMethods();
HashSet<Long> mixinMethods = new HashSet<Long>();
for (int m = 0; m < methods.length; m++)
{
if (methods[m].getDeclaringClass().getName().equals("java.lang.Object")) continue;
Long hash = new Long(JavassistMethodHashing.methodHash(methods[m]));
if (mixinMethods.contains(hash)) continue;
if (addedMethods.contains(hash)) throw new Exception("More than one mixin has same method");
mixinMethods.add(hash);
addedMethods.add(hash);
String aopReturnStr = (methods[m].getReturnType().equals(CtClass.voidType)) ? "" : "return ($r)";
String returnStr = (methods[m].getReturnType().equals(CtClass.voidType)) ? "" : "return ";
String args = "null";
if (methods[m].getParameterTypes().length > 0) args = "$args";
String code = "{ " +
" try{" +
" " + intf + " mixin = (" + intf + ")mixins[" + mixinId + "];" +
" org.jboss.aop.MethodInfo mi = currentAdvisor.getMethodInfo(" + hash.longValue() + "L); " +
" org.jboss.aop.advice.Interceptor[] interceptors = mi.getInterceptors();" +
" if (mi != null && interceptors != (Object[])null && interceptors.length > 0) { " +
" org.jboss.aop.proxy.container.ContainerProxyMethodInvocation invocation = new org.jboss.aop.proxy.container.ContainerProxyMethodInvocation(mi, interceptors, this); " +
" invocation.setArguments(" + args + "); " +
" invocation.setTargetObject(mixin); " +
" invocation.setMetaData(metadata);" +
" " + aopReturnStr + " invocation.invokeNext(); " +
" } else { " +
" " + returnStr + " mixin." + methods[m].getName() + "($$);" +
" } " +
" }finally{" +
" }" +
"}";
CtMethod newMethod = CtNewMethod.make(methods[m].getReturnType(), methods[m].getName(), methods[m].getParameterTypes(), methods[m].getExceptionTypes(), code, proxy);
newMethod.setModifiers(Modifier.PUBLIC);
proxy.addMethod(newMethod);
copySignature(methods[m], newMethod);
}
proxy.addInterface(intfClass);
addedInterfaces.add(intfClass.getName());
}
}
}