Package org.jboss.aop.proxy.container

Source Code of org.jboss.aop.proxy.container.ContainerProxyFactory

/*     */ package org.jboss.aop.proxy.container;
/*     */
/*     */ import java.lang.reflect.Method;
/*     */ import java.security.ProtectionDomain;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Collection;
/*     */ import java.util.HashMap;
/*     */ import java.util.HashSet;
/*     */ import java.util.Iterator;
/*     */ import java.util.Map;
/*     */ import java.util.Map.Entry;
/*     */ import java.util.Set;
/*     */ import java.util.WeakHashMap;
/*     */ import javassist.CannotCompileException;
/*     */ import javassist.ClassPool;
/*     */ import javassist.CtClass;
/*     */ import javassist.CtConstructor;
/*     */ import javassist.CtField;
/*     */ import javassist.CtMethod;
/*     */ import javassist.CtNewConstructor;
/*     */ import javassist.CtNewMethod;
/*     */ import javassist.Modifier;
/*     */ import javassist.NotFoundException;
/*     */ import javassist.SerialVersionUID;
/*     */ import javassist.bytecode.AnnotationsAttribute;
/*     */ import javassist.bytecode.ClassFile;
/*     */ import javassist.bytecode.ParameterAnnotationsAttribute;
/*     */ import javassist.bytecode.SignatureAttribute;
/*     */ import javassist.bytecode.annotation.Annotation;
/*     */ import org.jboss.aop.Advised;
/*     */ import org.jboss.aop.Advisor;
/*     */ import org.jboss.aop.AspectManager;
/*     */ import org.jboss.aop.ClassContainer;
/*     */ import org.jboss.aop.InstanceAdvised;
/*     */ import org.jboss.aop.instrument.TransformerCommon;
/*     */ import org.jboss.aop.introduction.InterfaceIntroduction;
/*     */ import org.jboss.aop.introduction.InterfaceIntroduction.Mixin;
/*     */ import org.jboss.aop.util.JavassistMethodHashing;
/*     */
/*     */ public class ContainerProxyFactory
/*     */ {
/*  68 */   private static final String ADVISED = Advised.class.getName();
/*  69 */   private static final String INSTANCE_ADVISED = InstanceAdvised.class.getName();
/*  70 */   private static final CtClass[] EMPTY_CTCLASS_ARRAY = new CtClass[0];
/*     */   public static final String PROXY_NAME_PREFIX = "AOPContainerProxy$";
/*  73 */   private static Object maplock = new Object();
/*  74 */   private static WeakHashMap proxyCache = new WeakHashMap();
/*  75 */   private static volatile int counter = 0;
/*     */   private static CtMethod setDelegateMethod;
/*     */   private boolean objectAsSuper;
/*     */   private Advisor advisor;
/*     */   private Class clazz;
/*     */   private CtClass proxy;
/*     */   private ClassPool pool;
/*     */   private ArrayList mixins;
/*     */   private boolean isAdvised;
/*     */   private CtConstructor defaultCtor;
/*     */
/*     */   public static Class getProxyClass(Class clazz, AspectManager manager)
/*     */     throws Exception
/*     */   {
/* 105 */     ContainerProxyCacheKey key = new ContainerProxyCacheKey(clazz);
/* 106 */     ClassContainer container = getTempClassContainer(clazz, manager);
/* 107 */     return getProxyClass(false, key, container);
/*     */   }
/*     */
/*     */   public static Class getProxyClass(boolean objectAsSuper, ContainerProxyCacheKey key, Advisor advisor)
/*     */     throws Exception
/*     */   {
/* 113 */     Class clazz = key.getClazz();
/*     */
/* 115 */     if (Delegate.class.isAssignableFrom(clazz)) clazz = clazz.getSuperclass();
/*     */
/* 117 */     Class proxyClass = null;
/* 118 */     synchronized (maplock)
/*     */     {
/* 120 */       Map map = (Map)proxyCache.get(clazz);
/* 121 */       if (map == null)
/*     */       {
/* 123 */         map = new HashMap();
/* 124 */         proxyCache.put(clazz, map);
/*     */       }
/*     */       else
/*     */       {
/* 128 */         proxyClass = (Class)map.get(key);
/*     */       }
/*     */
/* 131 */       if (proxyClass == null)
/*     */       {
/* 133 */         proxyClass = generateProxy(objectAsSuper, clazz, advisor);
/* 134 */         map.put(key, proxyClass);
/*     */       }
/*     */     }
/* 137 */     return proxyClass;
/*     */   }
/*     */
/*     */   private static Class generateProxy(boolean objectAsSuper, Class clazz, Advisor advisor) throws Exception
/*     */   {
/* 142 */     ArrayList introductions = advisor.getInterfaceIntroductions();
/* 143 */     CtClass proxy = createProxyCtClass(objectAsSuper, introductions, clazz, advisor);
/* 144 */     ProtectionDomain pd = clazz.getProtectionDomain();
/* 145 */     Class proxyClass = TransformerCommon.toClass(proxy, pd);
/* 146 */     return proxyClass;
/*     */   }
/*     */
/*     */   private static ClassProxyContainer getTempClassContainer(Class clazz, AspectManager manager)
/*     */   {
/* 151 */     ClassProxyContainer container = new ClassProxyContainer("temp", manager);
/* 152 */     container.setClass(clazz);
/*     */
/* 154 */     Iterator it = container.getManager().getInterfaceIntroductions().values().iterator();
/* 155 */     while (it.hasNext())
/*     */     {
/* 157 */       InterfaceIntroduction intro = (InterfaceIntroduction)it.next();
/* 158 */       if (intro.matches(container, container.getClazz()))
/*     */       {
/* 160 */         container.addInterfaceIntroduction(intro);
/*     */       }
/*     */     }
/*     */
/* 164 */     return container;
/*     */   }
/*     */
/*     */   public static CtClass createProxyCtClass(boolean objectAsSuper, ArrayList mixins, Class clazz, Advisor advisor)
/*     */     throws Exception
/*     */   {
/* 170 */     ContainerProxyFactory factory = new ContainerProxyFactory(objectAsSuper, mixins, clazz, advisor);
/* 171 */     return factory.createProxyCtClass();
/*     */   }
/*     */
/*     */   private ContainerProxyFactory(boolean objectAsSuper, ArrayList mixins, Class clazz, Advisor advisor)
/*     */   {
/* 177 */     this.objectAsSuper = objectAsSuper;
/* 178 */     this.mixins = mixins;
/* 179 */     this.clazz = clazz;
/* 180 */     this.advisor = advisor;
/* 181 */     this.isAdvised = Advised.class.isAssignableFrom(clazz);
/*     */   }
/*     */
/*     */   private CtClass createProxyCtClass()
/*     */     throws Exception
/*     */   {
/* 187 */     this.pool = AspectManager.instance().findClassPool(this.clazz.getClassLoader());
/* 188 */     if (this.pool == null) throw new NullPointerException("Could not find ClassPool");
/*     */
/* 190 */     createBasics();
/* 191 */     addMethodsAndMixins();
/* 192 */     overrideSpecialMethods(this.clazz, this.proxy);
/*     */
/* 194 */     SerialVersionUID.setSerialVersionUID(this.proxy);
/*     */
/* 196 */     return this.proxy;
/*     */   }
/*     */
/*     */   private CtClass createBasics()
/*     */     throws Exception
/*     */   {
/* 202 */     Class proxySuper = this.objectAsSuper ? Object.class : this.clazz;
/* 203 */     String classname = getClassName();
/*     */
/* 205 */     CtClass template = this.pool.get("org.jboss.aop.proxy.container.ProxyTemplate");
/* 206 */     CtClass superclass = this.pool.get(proxySuper.getName());
/*     */
/* 208 */     this.proxy = TransformerCommon.makeClass(this.pool, classname, superclass);
/* 209 */     this.proxy.addInterface(this.pool.get("org.jboss.aop.instrument.Untransformable"));
/*     */
/* 212 */     Class[] interfaces = proxySuper.getInterfaces();
/* 213 */     for (int i = 0; i < interfaces.length; i++)
/*     */     {
/* 215 */       CtClass interfaze = this.pool.get(interfaces[i].getName());
/* 216 */       this.proxy.addInterface(interfaze);
/*     */     }
/*     */
/* 219 */     copyConstructors(superclass, this.proxy);
/* 220 */     addFieldFromTemplate(template, "mixins");
/*     */
/* 223 */     this.proxy.addInterface(this.pool.get("org.jboss.aop.proxy.container.Delegate"));
/*     */
/* 225 */     addFieldFromTemplate(template, "delegate", superclass);
/* 226 */     addMethodFromTemplate(template, "getDelegate", "{ return delegate; }");
/* 227 */     setDelegateMethod = addMethodFromTemplate(template, "setDelegate", "{ this.delegate = (" + proxySuper.getName() + ")$1; }");
/*     */
/* 230 */     this.proxy.addInterface(this.pool.get("org.jboss.aop.proxy.container.AspectManaged"));
/*     */
/* 232 */     addFieldFromTemplate(template, "currentAdvisor");
/* 233 */     addFieldFromTemplate(template, "classAdvisor");
/* 234 */     addMethodFromTemplate(template, "getAdvisor", "{return classAdvisor;}");
/* 235 */     addMethodFromTemplate(template, "setAdvisor", "{this.classAdvisor = $1;currentAdvisor = classAdvisor;}");
/*     */
/* 237 */     addFieldFromTemplate(template, "metadata");
/* 238 */     addMethodFromTemplate(template, "setMetadata", "{this.metadata = $1;}");
/*     */
/* 240 */     addFieldFromTemplate(template, "instanceAdvisor");
/* 241 */     addMethodFromTemplate(template, "setInstanceAdvisor", instanceAdvisorSetterBody());
/* 242 */     addMethodFromTemplate(template, "getInstanceAdvisor", instanceAdvisorGetterBody());
/*     */
/* 244 */     addMethodFromTemplate(template, "writeObject", writeObjectBody());
/* 245 */     addMethodFromTemplate(template, "readObject", readObjectBody(superclass));
/*     */
/* 247 */     if (this.objectAsSuper)
/*     */     {
/* 249 */       addMethodFromTemplate(template, "equals", equalsBody());
/* 250 */       addMethodFromTemplate(template, "hashCode", hashCodeBody());
/*     */     }
/*     */
/* 253 */     addMethodFromTemplate(template, "toString", toStringBody());
/*     */
/* 255 */     copyAnnotations(superclass, this.proxy);
/* 256 */     copySignature(superclass, this.proxy);
/*     */
/* 258 */     return this.proxy;
/*     */   }
/*     */
/*     */   private String instanceAdvisorSetterBody()
/*     */   {
/* 263 */     return "{   synchronized (this)   {   if (this.instanceAdvisor != null)   {      throw new RuntimeException(\"InstanceAdvisor already set\");   }   if (!($1 instanceof org.jboss.aop.proxy.container.InstanceProxyContainer))   {      throw new RuntimeException(\"Wrong type for instance advisor: \" + $1);   }   this.instanceAdvisor = $1;   currentAdvisor = (org.jboss.aop.proxy.container.InstanceProxyContainer)$1;   }}";
/*     */   }
/*     */
/*     */   private String instanceAdvisorGetterBody()
/*     */   {
/* 283 */     return "{   synchronized(this)   {      if (instanceAdvisor == null)      {         org.jboss.aop.proxy.container.InstanceProxyContainer ipc = ((org.jboss.aop.proxy.container.ClassProxyContainer)currentAdvisor).createInstanceProxyContainer();         setInstanceAdvisor(ipc);      }   }   return instanceAdvisor;}";
/*     */   }
/*     */
/*     */   private String writeObjectBody()
/*     */   {
/* 299 */     return "{   $1.writeObject(delegate);   $1.writeObject(mixins);   $1.writeObject(metadata);   $1.writeObject(classAdvisor.getClazz());}";
/*     */   }
/*     */
/*     */   private String readObjectBody(CtClass superclass)
/*     */   {
/* 311 */     return "{   delegate = (" + superclass.getName() + ")$1.readObject();" + "   mixins = (Object[])$1.readObject();" + "   metadata = (org.jboss.aop.metadata.SimpleMetaData)$1.readObject();" + "   java.lang.Class clazz = (java.lang.Class)$1.readObject();" + "   org.jboss.aop.AspectManager manager = org.jboss.aop.AspectManager.getTopLevelAspectManager();" + "   classAdvisor = manager.findAdvisor(clazz);" + "   currentAdvisor = classAdvisor;" + "}";
/*     */   }
/*     */
/*     */   private String equalsBody()
/*     */   {
/* 326 */     return "{   if (delegate != null)   {      if ($1 != null && $1 instanceof org.jboss.aop.proxy.container.Delegate)         $1 = ((org.jboss.aop.proxy.container.Delegate) $1).getDelegate();      return delegate.equals($1);   }   else      return super.equals($1);}";
/*     */   }
/*     */
/*     */   private String hashCodeBody()
/*     */   {
/* 341 */     return "{   if (delegate != null)      return delegate.hashCode();   else      return super.hashCode();}";
/*     */   }
/*     */
/*     */   private String toStringBody()
/*     */   {
/* 352 */     return "{   if (delegate != null)      return delegate.toString() + \" (proxied by \" + this.getClass().getName() + \"@\" + java.lang.Integer.toHexString(java.lang.System.identityHashCode(this)) + \")\";   else      return super.toString() + \" (empty proxy of \" + this.getClass().getSuperclass().getName() + \")\";}";
/*     */   }
/*     */
/*     */   private CtField addFieldFromTemplate(CtClass template, String name)
/*     */     throws Exception
/*     */   {
/* 363 */     return addFieldFromTemplate(template, name, null);
/*     */   }
/*     */
/*     */   private CtField addFieldFromTemplate(CtClass template, String name, CtClass type) throws Exception
/*     */   {
/* 368 */     CtField templateField = template.getField(name);
/* 369 */     CtClass fieldType = type == null ? templateField.getType() : type;
/* 370 */     CtField field = new CtField(fieldType, name, this.proxy);
/* 371 */     field.setModifiers(templateField.getModifiers());
/* 372 */     this.proxy.addField(field);
/* 373 */     return field;
/*     */   }
/*     */
/*     */   private CtMethod addMethodFromTemplate(CtClass template, String name, String body) throws Exception
/*     */   {
/* 378 */     CtMethod templateMethod = template.getDeclaredMethod(name);
/* 379 */     CtMethod method = CtNewMethod.make(templateMethod.getReturnType(), name, templateMethod.getParameterTypes(), templateMethod.getExceptionTypes(), body, this.proxy);
/* 380 */     method.setModifiers(templateMethod.getModifiers());
/* 381 */     this.proxy.addMethod(method);
/* 382 */     return method;
/*     */   }
/*     */
/*     */   private void copyConstructors(CtClass superclass, CtClass proxy) throws Exception
/*     */   {
/* 387 */     CtConstructor[] ctors = superclass.getConstructors();
/* 388 */     int minParameters = 2147483647;
/* 389 */     CtConstructor bestCtor = null;
/* 390 */     for (int i = 0; i < ctors.length; i++)
/*     */     {
/* 392 */       CtClass[] params = ctors[i].getParameterTypes();
/*     */
/* 394 */       CtConstructor ctor = CtNewConstructor.make(ctors[i].getParameterTypes(), ctors[i].getExceptionTypes(), 2, null, null, proxy);
/*     */
/* 401 */       ctor.setModifiers(ctors[i].getModifiers());
/* 402 */       proxy.addConstructor(ctor);
/*     */
/* 404 */       if (params.length < minParameters)
/*     */       {
/* 406 */         bestCtor = ctor;
/* 407 */         minParameters = params.length;
/*     */       }
/* 409 */       if (params.length != 0)
/*     */         continue;
/* 411 */       this.defaultCtor = ctor;
/*     */     }
/*     */
/* 415 */     if (minParameters > 0)
/*     */     {
/* 418 */       createDefaultConstructor(bestCtor);
/*     */     }
/*     */   }
/*     */
/*     */   private void createDefaultConstructor(CtConstructor bestCtor) throws NotFoundException, CannotCompileException
/*     */   {
/* 424 */     CtClass[] params = bestCtor.getParameterTypes();
/*     */
/* 426 */     StringBuffer superCall = new StringBuffer("super(");
/*     */
/* 428 */     for (int i = 0; i < params.length; i++)
/*     */     {
/* 430 */       if (i > 0)
/*     */       {
/* 432 */         superCall.append(", ");
/*     */       }
/*     */
/* 435 */       superCall.append(getNullType(params[i]));
/*     */     }
/*     */
/* 438 */     superCall.append(");");
/*     */
/* 440 */     this.defaultCtor = CtNewConstructor.make(EMPTY_CTCLASS_ARRAY, EMPTY_CTCLASS_ARRAY, "{" + superCall.toString() + "}", this.proxy);
/* 441 */     this.proxy.addConstructor(this.defaultCtor);
/*     */   }
/*     */
/*     */   private String getNullType(CtClass clazz)
/*     */   {
/* 446 */     if (!clazz.isPrimitive())
/*     */     {
/* 448 */       return "null";
/*     */     }
/*     */
/* 452 */     if (clazz.equals(CtClass.booleanType)) return "false";
/* 453 */     if (clazz.equals(CtClass.charType)) return "'0'";
/* 454 */     if (clazz.equals(CtClass.byteType)) return "0";
/* 455 */     if (clazz.equals(CtClass.shortType)) return "0";
/* 456 */     if (clazz.equals(CtClass.intType)) return "0";
/* 457 */     if (clazz.equals(CtClass.longType)) return "0L";
/* 458 */     if (clazz.equals(CtClass.floatType)) return "0f";
/* 459 */     if (clazz.equals(CtClass.doubleType)) return "0d";
/* 460 */     return "";
/*     */   }
/*     */
/*     */   private void addMethodsAndMixins()
/*     */     throws Exception
/*     */   {
/* 467 */     HashSet addedMethods = new HashSet();
/* 468 */     createMixinsAndIntroductions(addedMethods);
/* 469 */     createProxyMethods(addedMethods);
/*     */   }
/*     */
/*     */   private void createMixinsAndIntroductions(HashSet addedMethods) throws Exception
/*     */   {
/* 474 */     HashSet addedInterfaces = new HashSet();
/* 475 */     Set implementedInterfaces = interfacesAsSet();
/*     */
/* 477 */     if (this.mixins != null)
/*     */     {
/* 479 */       HashMap intfs = new HashMap();
/* 480 */       HashMap mixinIntfs = new HashMap();
/* 481 */       ArrayList mixes = new ArrayList();
/* 482 */       for (int i = 0; i < this.mixins.size(); i++)
/*     */       {
/* 484 */         InterfaceIntroduction introduction = (InterfaceIntroduction)this.mixins.get(i);
/* 485 */         getIntroductionInterfaces(introduction, intfs, mixinIntfs, mixes, i);
/*     */       }
/* 487 */       if (mixes.size() > 0)
/*     */       {
/* 489 */         this.defaultCtor.insertAfter("mixins = new Object[" + mixes.size() + "];");
/* 490 */         for (int i = 0; i < mixes.size(); i++)
/*     */         {
/* 494 */           InterfaceIntroduction.Mixin mixin = (InterfaceIntroduction.Mixin)mixes.get(i);
/* 495 */           String initializer = mixin.getConstruction() == null ? "new " + mixin.getClassName() + "()" : mixin.getConstruction();
/* 496 */           String code = "mixins[" + i + "] = " + initializer + ";";
/* 497 */           this.defaultCtor.insertAfter(code);
/* 498 */           setDelegateMethod.insertAfter("{if (org.jboss.aop.proxy.container.Delegate.class.isAssignableFrom(mixins[" + i + "].getClass())) " + "((org.jboss.aop.proxy.container.Delegate)mixins[" + i + "]).setDelegate($1);}");
/*     */         }
/*     */
/*     */       }
/*     */
/* 504 */       HashMap allMethods = JavassistMethodHashing.getDeclaredMethodMap(this.proxy);
/* 505 */       addedMethods.addAll(allMethods.keySet());
/*     */
/* 507 */       createMixins(addedMethods, mixes, addedInterfaces, implementedInterfaces);
/* 508 */       createIntroductions(addedMethods, intfs, addedInterfaces, implementedInterfaces);
/*     */     }
/*     */   }
/*     */
/*     */   private void getIntroductionInterfaces(InterfaceIntroduction intro, HashMap intfs, HashMap mixins, ArrayList mixes, int idx)
/*     */   {
/* 523 */     Iterator it = intro.getMixins().iterator();
/* 524 */     while (it.hasNext())
/*     */     {
/* 526 */       InterfaceIntroduction.Mixin mixin = (InterfaceIntroduction.Mixin)it.next();
/* 527 */       mixes.add(mixin);
/* 528 */       for (int i = 0; i < mixin.getInterfaces().length; i++)
/*     */       {
/* 530 */         if (intfs.containsKey(mixin.getInterfaces()[i]))
/*     */         {
/* 532 */           intfs.remove(mixin.getInterfaces()[i]);
/*     */         }
/*     */
/* 535 */         if (mixins.containsKey(mixin.getInterfaces()[i]))
/*     */         {
/* 537 */           throw new RuntimeException("cannot have an IntroductionInterface that introduces several mixins with the same interfaces " + mixin.getInterfaces()[i]);
/*     */         }
/* 539 */         mixins.put(mixin.getInterfaces()[i], new Integer(idx));
/*     */       }
/*     */     }
/* 542 */     if (intro.getInterfaces() != null)
/*     */     {
/* 544 */       for (int i = 0; i < intro.getInterfaces().length; i++)
/*     */       {
/* 546 */         if ((intfs.containsKey(intro.getInterfaces()[i])) || (mixins.containsKey(intro.getInterfaces()[i])))
/*     */         {
/*     */           continue;
/*     */         }
/*     */
/* 552 */         intfs.put(intro.getInterfaces()[i], new Integer(idx));
/*     */       }
/*     */     }
/*     */   }
/*     */
/*     */   private void createMixins(HashSet addedMethods, ArrayList mixes, HashSet addedInterfaces, Set implementedInterfaces)
/*     */     throws Exception
/*     */   {
/* 560 */     for (int mixinId = 0; mixinId < mixes.size(); mixinId++)
/*     */     {
/* 562 */       InterfaceIntroduction.Mixin mixin = (InterfaceIntroduction.Mixin)mixes.get(mixinId);
/*     */
/* 564 */       String[] intfs = mixin.getInterfaces();
/*     */
/* 566 */       for (int ifId = 0; ifId < intfs.length; ifId++)
/*     */       {
/* 568 */         String intf = intfs[ifId];
/* 569 */         if (addedInterfaces.contains(intf)) throw new Exception("2 mixins are implementing the same interfaces " + intf);
/* 570 */         if (implementedInterfaces.contains(intf)) throw new Exception("Attempting to mixin interface already used by class " + intf);
/*     */
/* 572 */         CtClass intfClass = this.pool.get(intf);
/* 573 */         CtMethod[] methods = intfClass.getMethods();
/* 574 */         HashSet mixinMethods = new HashSet();
/* 575 */         for (int m = 0; m < methods.length; m++)
/*     */         {
/* 577 */           if (!methods[m].getDeclaringClass().getName().equals("java.lang.Object")) {
/* 578 */             Long hash = new Long(JavassistMethodHashing.methodHash(methods[m]));
/* 579 */             if (!mixinMethods.contains(hash)) {
/* 580 */               if (addedMethods.contains(hash)) throw new Exception("More than one mixin has same method");
/* 581 */               mixinMethods.add(hash);
/* 582 */               addedMethods.add(hash);
/* 583 */               String aopReturnStr = methods[m].getReturnType().equals(CtClass.voidType) ? "" : "return ($r)";
/* 584 */               String returnStr = methods[m].getReturnType().equals(CtClass.voidType) ? "" : "return ";
/* 585 */               String args = "null";
/* 586 */               if (methods[m].getParameterTypes().length > 0) args = "$args";
/* 587 */               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{" + "    }" + "}";
/*     */
/* 604 */               CtMethod newMethod = CtNewMethod.make(methods[m].getReturnType(), methods[m].getName(), methods[m].getParameterTypes(), methods[m].getExceptionTypes(), code, this.proxy);
/* 605 */               newMethod.setModifiers(1);
/* 606 */               this.proxy.addMethod(newMethod);
/*     */
/* 608 */               copySignature(methods[m], newMethod);
/*     */             }
/*     */           }
/*     */         }
/* 611 */         this.proxy.addInterface(intfClass);
/* 612 */         addedInterfaces.add(intfClass.getName());
/*     */       }
/*     */     }
/*     */   }
/*     */
/*     */   private void createProxyMethods(HashSet addedMethods) throws Exception
/*     */   {
/* 619 */     HashMap allMethods = JavassistMethodHashing.getMethodMap(this.proxy.getSuperclass());
/*     */
/* 621 */     Iterator it = allMethods.entrySet().iterator();
/* 622 */     while (it.hasNext())
/*     */     {
/* 624 */       Map.Entry entry = (Map.Entry)it.next();
/* 625 */       CtMethod m = (CtMethod)entry.getValue();
/* 626 */       if ((!Modifier.isPublic(m.getModifiers())) || (Modifier.isStatic(m.getModifiers())) || (Modifier.isFinal(m.getModifiers())))
/*     */         continue;
/* 628 */       Long hash = (Long)entry.getKey();
/* 629 */       if (!addedMethods.contains(hash)) {
/* 630 */         addedMethods.add(hash);
/* 631 */         String aopReturnStr = m.getReturnType().equals(CtClass.voidType) ? "" : "return ($r)";
/* 632 */         String returnStr = m.getReturnType().equals(CtClass.voidType) ? "" : "return ";
/* 633 */         String args = "null";
/*     */
/* 635 */         String name = null;
/* 636 */         if (this.isAdvised)
/*     */         {
/* 638 */           org.jboss.aop.MethodInfo info = this.advisor.getMethodInfo(hash.longValue());
/* 639 */           Method originalMethod = info.getUnadvisedMethod();
/* 640 */           name = originalMethod.getName();
/*     */         }
/*     */         else
/*     */         {
/* 644 */           name = m.getName();
/*     */         }
/*     */
/* 647 */         if (m.getParameterTypes().length > 0) args = "$args";
/* 648 */         String code = "{       boolean handled = false;    try{       if (currentAdvisor != null) {          org.jboss.aop.MethodInfo mi = currentAdvisor.getMethodInfo(" + hash.longValue() + "L); " + "          if (mi == null) " + "             throw new java.lang.NoSuchMethodError(\"" + m.getName() + m.getSignature() + "\");" + "          org.jboss.aop.advice.Interceptor[] interceptors = mi.getInterceptors(); " + "          if (interceptors != (Object[])null && interceptors.length > 0) { " + "             handled = true;" + "             org.jboss.aop.proxy.container.ContainerProxyMethodInvocation invocation = new org.jboss.aop.proxy.container.ContainerProxyMethodInvocation(mi, interceptors, this); " + "             invocation.setArguments(" + args + "); " + "             invocation.setTargetObject(delegate); " + "             invocation.setMetaData(metadata);" + "             " + aopReturnStr + " invocation.invokeNext(); " + "          }" + "       }" + "       if (!handled && delegate != null){ " + "          " + returnStr + " delegate." + name + "($$); " + "       }" + "       return " + getNullType(m.getReturnType()) + ";" + "    }finally{" + "    }" + "}";
/*     */
/* 672 */         CtMethod newMethod = CtNewMethod.make(m.getReturnType(), m.getName(), m.getParameterTypes(), m.getExceptionTypes(), code, this.proxy);
/* 673 */         newMethod.setModifiers(1);
/* 674 */         this.proxy.addMethod(newMethod);
/*     */
/* 676 */         copyAnnotations(m, newMethod);
/* 677 */         copySignature(m, newMethod);
/*     */       }
/*     */     }
/*     */   }
/*     */
/*     */   private void createIntroductions(HashSet addedMethods, HashMap intfs, HashSet addedInterfaces, Set implementedInterfaces) throws Exception {
/* 683 */     Iterator it = intfs.keySet().iterator();
/* 684 */     while (it.hasNext())
/*     */     {
/* 686 */       String intf = (String)it.next();
/* 687 */       if (addedInterfaces.contains(intf)) throw new Exception("2 mixins are implementing the same interfaces");
/* 688 */       if (implementedInterfaces.contains(intf))
/*     */       {
/*     */         continue;
/*     */       }
/*     */
/* 693 */       CtClass intfClass = this.pool.get(intf);
/* 694 */       CtMethod[] methods = intfClass.getMethods();
/* 695 */       HashSet mixinMethods = new HashSet();
/* 696 */       for (int m = 0; m < methods.length; m++)
/*     */       {
/* 698 */         if (methods[m].getDeclaringClass().getName().equals("java.lang.Object"))
/*     */           continue;
/* 700 */         Long hash = new Long(JavassistMethodHashing.methodHash(methods[m]));
/* 701 */         if ((mixinMethods.contains(hash)) ||
/* 702 */           (addedMethods.contains(hash)))
/*     */           continue;
/* 704 */         mixinMethods.add(hash);
/* 705 */         addedMethods.add(hash);
/* 706 */         String aopReturnStr = methods[m].getReturnType().equals(CtClass.voidType) ? "" : "return ($r)";
/* 707 */         String args = "null";
/* 708 */         if (methods[m].getParameterTypes().length > 0) args = "$args";
/* 709 */         String code = "{       try{       org.jboss.aop.MethodInfo mi = currentAdvisor.getMethodInfo(" + hash.longValue() + "L); " + "       if (mi == null) " + "          throw new java.lang.NoSuchMethodError(\"" + methods[m].getName() + methods[m].getSignature() + "\");" + "       org.jboss.aop.advice.Interceptor[] interceptors = mi.getInterceptors();" + "       org.jboss.aop.proxy.container.ContainerProxyMethodInvocation invocation = new org.jboss.aop.proxy.container.ContainerProxyMethodInvocation(mi, interceptors, this); " + "       invocation.setArguments(" + args + "); " + "       invocation.setTargetObject(delegate); " + "       invocation.setMetaData(metadata);" + "       " + aopReturnStr + " invocation.invokeNext(); " + "    }finally{" + "    }" + "}";
/*     */
/* 724 */         CtMethod newMethod = CtNewMethod.make(methods[m].getReturnType(), methods[m].getName(), methods[m].getParameterTypes(), methods[m].getExceptionTypes(), code, this.proxy);
/* 725 */         newMethod.setModifiers(1);
/* 726 */         this.proxy.addMethod(newMethod);
/*     */
/* 728 */         copySignature(methods[m], newMethod);
/*     */       }
/*     */
/* 731 */       this.proxy.addInterface(intfClass);
/* 732 */       addedInterfaces.add(intfClass.getName());
/*     */     }
/*     */   }
/*     */
/*     */   private Set interfacesAsSet() throws NotFoundException
/*     */   {
/* 738 */     HashSet set = new HashSet();
/* 739 */     CtClass[] interfaces = this.proxy.getInterfaces();
/*     */
/* 741 */     for (int i = 0; i < interfaces.length; i++)
/*     */     {
/* 743 */       set.add(interfaces[i].getName());
/*     */     }
/*     */
/* 746 */     return set;
/*     */   }
/*     */
/*     */   private String getClassName()
/*     */   {
/* 751 */     String packageName = this.clazz.getPackage().getName();
/* 752 */     if ((!packageName.startsWith("java.")) && (!packageName.startsWith("sun.")))
/*     */     {
/* 754 */       packageName = packageName + ".";
/*     */     }
/*     */     else
/*     */     {
/* 758 */       packageName = "";
/*     */     }
/*     */
/* 761 */     return packageName + "AOPContainerProxy$" + counter++;
/*     */   }
/*     */
/*     */   private void overrideSpecialMethods(Class clazz, CtClass proxy) throws Exception
/*     */   {
/* 766 */     addInstanceAdvisedMethods(clazz, proxy);
/*     */   }
/*     */
/*     */   private void addInstanceAdvisedMethods(Class clazz, CtClass proxy)
/*     */     throws Exception
/*     */   {
/* 775 */     CtClass advisedInterface = null;
/* 776 */     CtClass[] interfaces = proxy.getInterfaces();
/*     */
/* 778 */     for (int i = 0; i < interfaces.length; i++)
/*     */     {
/* 780 */       if (!interfaces[i].getName().equals(ADVISED))
/*     */         continue;
/* 782 */       advisedInterface = interfaces[i];
/* 783 */       break;
/*     */     }
/*     */
/* 787 */     if (advisedInterface != null)
/*     */     {
/* 789 */       CtMethod[] methods = advisedInterface.getMethods();
/* 790 */       for (int i = 0; i < methods.length; i++)
/*     */       {
/* 792 */         if (!methods[i].getDeclaringClass().getName().equals(INSTANCE_ADVISED))
/*     */           continue;
/* 794 */         String name = methods[i].getName();
/* 795 */         String body = null;
/* 796 */         if (name.equals("_getInstanceAdvisor"))
/*     */         {
/* 798 */           body = "{ return getInstanceAdvisor(); }";
/*     */         }
/* 800 */         else if (name.equals("_setInstanceAdvisor"))
/*     */         {
/* 802 */           body = "{ setInstanceAdvisor($1); }";
/*     */         }
/*     */
/* 805 */         if (body == null)
/*     */           continue;
/* 807 */         CtMethod m = CtNewMethod.make(methods[i].getReturnType(), methods[i].getName(), methods[i].getParameterTypes(), methods[i].getExceptionTypes(), body, proxy);
/* 808 */         m.setModifiers(1);
/* 809 */         proxy.addMethod(m);
/*     */       }
/*     */     }
/*     */   }
/*     */
/*     */   private void copyAnnotations(CtMethod src, CtMethod dest)
/*     */     throws NotFoundException
/*     */   {
/* 818 */     javassist.bytecode.MethodInfo srcInfo = src.getMethodInfo2();
/* 819 */     javassist.bytecode.MethodInfo destInfo = dest.getMethodInfo2();
/* 820 */     copyAnnotations(srcInfo, destInfo, "RuntimeInvisibleAnnotations");
/* 821 */     copyAnnotations(srcInfo, destInfo, "RuntimeVisibleAnnotations");
/*     */
/* 823 */     int numParams = src.getParameterTypes().length;
/* 824 */     copyParameterAnnotations(numParams, srcInfo, destInfo, "RuntimeVisibleParameterAnnotations");
/* 825 */     copyParameterAnnotations(numParams, srcInfo, destInfo, "RuntimeInvisibleParameterAnnotations");
/*     */   }
/*     */
/*     */   private void copyAnnotations(javassist.bytecode.MethodInfo src, javassist.bytecode.MethodInfo dest, String annotationTag)
/*     */   {
/* 831 */     AnnotationsAttribute attribute = (AnnotationsAttribute)src.getAttribute(annotationTag);
/* 832 */     if (attribute != null)
/*     */     {
/* 834 */       dest.addAttribute(attribute.copy(dest.getConstPool(), new HashMap()));
/*     */     }
/*     */   }
/*     */
/*     */   private void copyParameterAnnotations(int numParams, javassist.bytecode.MethodInfo src, javassist.bytecode.MethodInfo dest, String paramsTag)
/*     */   {
/* 840 */     ParameterAnnotationsAttribute params = (ParameterAnnotationsAttribute)src.getAttribute(paramsTag);
/* 841 */     if (params != null)
/*     */     {
/* 843 */       dest.addAttribute(params.copy(dest.getConstPool(), new HashMap()));
/* 844 */       ParameterAnnotationsAttribute srcParams = new ParameterAnnotationsAttribute(src.getConstPool(), paramsTag);
/* 845 */       Annotation[][] emptyParamAnnotations = new Annotation[numParams][];
/* 846 */       for (int i = 0; i < numParams; i++)
/*     */       {
/* 848 */         emptyParamAnnotations[i] = new Annotation[0];
/*     */       }
/* 850 */       srcParams.setAnnotations(emptyParamAnnotations);
/* 851 */       src.addAttribute(srcParams);
/*     */     }
/*     */   }
/*     */
/*     */   private void copyAnnotations(CtClass src, CtClass dest) throws NotFoundException
/*     */   {
/* 857 */     ClassFile srcFile = src.getClassFile2();
/* 858 */     ClassFile destFile = dest.getClassFile2();
/* 859 */     copyAnnotations(srcFile, destFile, "RuntimeInvisibleAnnotations");
/* 860 */     copyAnnotations(srcFile, destFile, "RuntimeVisibleAnnotations");
/*     */   }
/*     */
/*     */   private void copyAnnotations(ClassFile src, ClassFile dest, String annotationTag)
/*     */   {
/* 865 */     AnnotationsAttribute attribute = (AnnotationsAttribute)src.getAttribute(annotationTag);
/* 866 */     if (attribute != null)
/*     */     {
/* 868 */       dest.addAttribute(attribute.copy(dest.getConstPool(), new HashMap()));
/*     */     }
/*     */   }
/*     */
/*     */   private void copySignature(CtMethod src, CtMethod dest)
/*     */   {
/* 875 */     javassist.bytecode.MethodInfo srcInfo = src.getMethodInfo2();
/* 876 */     javassist.bytecode.MethodInfo destInfo = dest.getMethodInfo2();
/*     */
/* 878 */     SignatureAttribute sig = (SignatureAttribute)srcInfo.getAttribute("Signature");
/* 879 */     if (sig != null)
/*     */     {
/* 881 */       destInfo.addAttribute(sig.copy(destInfo.getConstPool(), new HashMap()));
/*     */     }
/*     */   }
/*     */
/*     */   private void copySignature(CtClass src, CtClass dest)
/*     */   {
/* 887 */     ClassFile srcFile = src.getClassFile2();
/* 888 */     ClassFile destFile = dest.getClassFile2();
/*     */
/* 890 */     SignatureAttribute sig = (SignatureAttribute)srcFile.getAttribute("Signature");
/* 891 */     if (sig != null)
/*     */     {
/* 893 */       destFile.addAttribute(sig.copy(destFile.getConstPool(), new HashMap()));
/*     */     }
/*     */   }
/*     */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name:     org.jboss.aop.proxy.container.ContainerProxyFactory
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of org.jboss.aop.proxy.container.ContainerProxyFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.