Package org.jboss.test.aop.classpool.jbosscl.test

Source Code of org.jboss.test.aop.classpool.jbosscl.test.ClassPoolWithReplaceReferencesTestCase$MyTranslator

/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.aop.classpool.jbosscl.test;

import java.lang.reflect.Method;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.Collection;

import javassist.ClassPool;
import javassist.CodeConverter;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Modifier;
import junit.framework.Test;

import org.jboss.aop.AspectManager;
import org.jboss.aop.classpool.AOPClassPool;
import org.jboss.aop.classpool.AOPClassPoolRepository;
import org.jboss.classloading.spi.DomainClassLoader;
import org.jboss.test.AbstractTestDelegate;
import org.jboss.util.loading.Translator;

/**
* Test that field/constructor wrapper replacement works since there were some problems in AS5
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
* @version $Revision: 1.1 $
*/
public class ClassPoolWithReplaceReferencesTestCase extends JBossClClassPoolTest
{
   final static String STRING = String.class.getName();

   public final static URL JAR_PARENT = getURLRelativeToProjectRoot("target/jboss-aop-asintegration-mc-test-classpool-replacereferences-parent.jar");

   public final static URL JAR_CHILD = getURLRelativeToProjectRoot("target/jboss-aop-asintegration-mc-test-classpool-replacereferences-child.jar");

   public final static String PACKAGE_REPLACEMENT = PACKAGE_ROOT + ".replacereferences";

   public final static String PACKAGE_REPLACEMENT_CHILD = PACKAGE_REPLACEMENT + ".child";

   public final static String PACKAGE_REPLACEMENT_PARENT = PACKAGE_REPLACEMENT + ".parent";

   public final static String CLASS_INVOKED = PACKAGE_REPLACEMENT + ".Invoked";

   public final static String CLASS_PARENT_CALLER = PACKAGE_REPLACEMENT_PARENT + ".ParentCaller";

   public final static String CLASS_CHILD_CALLER = PACKAGE_REPLACEMENT_CHILD + ".ChildCaller";

   public final String x = "org.jboss.test.aop.classpool.jbosscl.support.excluded";

   private final static Translator TRANSLATOR = new MyTranslator();

   public ClassPoolWithReplaceReferencesTestCase(String name)
   {
      super(name);
   }

   public static Test suite()
   {
      return suite(ClassPoolWithReplaceReferencesTestCase.class);
   }

   public static AbstractTestDelegate getDelegate(Class<?> clazz) throws Exception
   {
      return new AlwaysWritablePermissionCollectionTestPolicyPluginTestDelegate(clazz);
   }
  
   public void testParentLoadedParentDelegation() throws Exception
   {
      ClassPool globalPool = null;
      ClassPool scopedPool = null;
      try
      {
         getSystem().setTranslator(TRANSLATOR);
         globalPool = createClassPool("GLOBAL", true, JAR_PARENT);
         scopedPool = createChildDomainParentFirstClassPool("SCOPED", "SCOPED", true, JAR_CHILD);

         loadClassAndRunTest(CLASS_PARENT_CALLER, globalPool.getClassLoader());
         loadClassAndRunTest(CLASS_CHILD_CALLER, scopedPool.getClassLoader());
      }
      finally
      {
         unregisterClassPool(globalPool);
         unregisterClassPool(scopedPool);
         unregisterDomain(scopedPool);
         getSystem().setTranslator(null);
      }
   }

   public void testParentLoadedNoParentDelegation() throws Exception
   {
      ClassPool globalPool = null;
      ClassPool scopedPool = null;
      try
      {
         getSystem().setTranslator(TRANSLATOR);
         globalPool = createClassPool("GLOBAL", true, JAR_PARENT);
         scopedPool = createChildDomainParentLastClassPool("SCOPED", "SCOPED", true, JAR_CHILD);

         loadClassAndRunTest(CLASS_PARENT_CALLER, globalPool.getClassLoader());
         loadClassAndRunTest(CLASS_CHILD_CALLER, scopedPool.getClassLoader());
      }
      finally
      {
         unregisterClassPool(globalPool);
         unregisterClassPool(scopedPool);
         unregisterDomain(scopedPool);
         getSystem().setTranslator(null);
      }
   }

   public void testParentNotLoadedParentDelegation() throws Exception
   {
      ClassPool globalPool = null;
      ClassPool scopedPool = null;
      try
      {
         getSystem().setTranslator(TRANSLATOR);
         globalPool = createClassPool("GLOBAL", true, JAR_PARENT);
         scopedPool = createChildDomainParentFirstClassPool("SCOPED", "SCOPED", true, JAR_CHILD);

         loadClassAndRunTest(CLASS_CHILD_CALLER, scopedPool.getClassLoader());
      }
      finally
      {
         unregisterClassPool(globalPool);
         unregisterClassPool(scopedPool);
         unregisterDomain(scopedPool);
         getSystem().setTranslator(null);
      }
   }

   public void testParentNotLoadedNoParentDelegation() throws Exception
   {
      ClassPool globalPool = null;
      ClassPool scopedPool = null;
      try
      {
         getSystem().setTranslator(TRANSLATOR);
         globalPool = createClassPool("GLOBAL", true, JAR_PARENT);
         scopedPool = createChildDomainParentLastClassPool("SCOPED", "SCOPED", true, JAR_CHILD);

         loadClassAndRunTest(CLASS_CHILD_CALLER, scopedPool.getClassLoader());
      }
      finally
      {
         unregisterClassPool(globalPool);
         unregisterClassPool(scopedPool);
         unregisterDomain(scopedPool);
         getSystem().setTranslator(null);
      }
   }

   private void loadClassAndRunTest(String classname, ClassLoader loader) throws Exception
   {
      Class<?> caller = loader.loadClass(classname);
      Method m = caller.getMethod("test");
      m.invoke(null, new Object[]
      {});
   }

   final static class MyTranslator implements Translator
   {
      public void unregisterClassLoader(DomainClassLoader loader)
      {
      }

      public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws Exception
      {
         if (!className.startsWith(PACKAGE_REPLACEMENT))
         {
            return null;
         }
         if (className.endsWith("Invoked"))
         {
            return null;
         }

         ClassPool pool = AspectManager.instance().registerClassLoader(loader);
         CtClass clazz = pool.get(className);
         if (className.endsWith("Caller"))
         {
            instrumentReplaceReferences(clazz);
         }
         else
         {
            instrumentCreateWrappers(clazz);
         }

         if (clazz.isModified())
         {
            return clazz.toBytecode();
         }
         return null;
      }

      private CtClass instrumentCreateWrappers(CtClass clazz)
      {
         try
         {
            if (!clazz.getName().startsWith(PACKAGE_REPLACEMENT))
            {
               return clazz;
            }
            addWrappersToClass(clazz);
         }
         catch (Exception e)
         {
            System.err.println("Exception creating wrappers for " + clazz);
            e.printStackTrace();
         }
         return clazz;
      }

      private CtClass instrumentReplaceReferences(CtClass clazz) throws Exception
      {
         if (!clazz.getName().startsWith(PACKAGE_REPLACEMENT))
         {
            return clazz;
         }
         replaceReferences(clazz);
         return clazz;
      }

      public void unregisterClassLoader(ClassLoader loader)
      {
      }

      private void addWrappersToClass(CtClass clazz) throws Exception
      {
         addFieldWrappers(clazz);
         addConstructorWrappers(clazz);
      }

      private void addFieldWrappers(CtClass clazz) throws Exception
      {
         CtClass objectCt = clazz.getClassPool().getCtClass(Object.class.getName());

         for (CtField field : clazz.getFields())
         {
            if (field.getDeclaringClass() == objectCt)
            {
               continue;
            }
            CtMethod rmethod =
               CtNewMethod.make(
                     Modifier.PUBLIC | Modifier.STATIC,
                     CtClass.intType,
                     getFieldReadWrapperName(field.getName()),
                     new CtClass[]{objectCt},
                     null,
                     "{" + CLASS_INVOKED + ".invoked = true; return ((" + clazz.getName() + ")$1)." + field.getName() + ";}",
                     clazz);
            clazz.addMethod(rmethod);


            CtMethod wmethod =
               CtNewMethod.make(
                     Modifier.PUBLIC | Modifier.STATIC,
                     CtClass.voidType,
                     getFieldWriteWrapperName(field.getName()),
                     new CtClass[]{objectCt, field.getType()},
                     null,
                     "{" + CLASS_INVOKED + ".invoked = true; ((" + clazz.getName() + ")$1)." + field.getName() + "=(int)$2;}",
                     clazz);
            clazz.addMethod(wmethod);
         }
      }

      private void addConstructorWrappers(CtClass clazz) throws Exception
      {
         for (CtConstructor ctor : clazz.getConstructors())
         {
            CtMethod wrapper = CtNewMethod.make(clazz, getConstructorName(clazz), ctor.getParameterTypes(), null,
                  "{" + CLASS_INVOKED + ".invoked = true; return new " + clazz.getName() + "($$);}", clazz);
            wrapper.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
            clazz.addMethod(wrapper);
         }
      }

      private void replaceReferences(final CtClass clazz) throws Exception
      {
         CodeConverter conv = new CodeConverter();
         AOPClassPool pool = AOPClassPool
               .createAOPClassPool(clazz.getClassPool(), AOPClassPoolRepository.getInstance());
         Collection<String> refs = AccessController.doPrivileged(new PrivilegedAction<Collection<String>>() {

            public Collection<String> run()
            {
               return clazz.getRefClasses();
            }});
        
         for (String ref : refs)
         {
            if (ref.startsWith(PACKAGE_REPLACEMENT_CHILD) || ref.startsWith(PACKAGE_REPLACEMENT_PARENT))
            {
               if (ref.endsWith("Caller"))
               {
                  continue;
               }
               CtClass ctRef = pool.get(ref);
               CtField[] fields = ctRef.getDeclaredFields();
               for (CtField fld : fields)
               {
                  conv.replaceFieldRead(fld, ctRef, getFieldReadWrapperName(fld.getName()));
                  conv.replaceFieldWrite(fld, ctRef, getFieldWriteWrapperName(fld.getName()));
               }
               conv.replaceNew(ctRef, ctRef, getConstructorName(ctRef));
            }
         }
         clazz.instrument(conv);
      }

      private String getFieldReadWrapperName(String fieldName)
      {
         return fieldName + "_read";
      }

      private String getFieldWriteWrapperName(String fieldName)
      {
         return fieldName + "_write";
      }

      private String getConstructorName(CtClass clazz)
      {
         return clazz.getSimpleName() + "_new";
      }
   }
}
TOP

Related Classes of org.jboss.test.aop.classpool.jbosscl.test.ClassPoolWithReplaceReferencesTestCase$MyTranslator

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.