Package com.googlecode.gwt.test.internal

Source Code of com.googlecode.gwt.test.internal.GwtPatcherUtils

package com.googlecode.gwt.test.internal;

import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;

/**
*
* Some patching utility methods. Bytecode manipulation relies on javassist API. <strong>For
* internal use only.</strong>
*
* @author Bertrand Paquet
* @author Gael Lazzari
*
*/
public class GwtPatcherUtils {

   public static void patch(CtClass c, Patcher patcher) throws Exception {
      c.setModifiers(Modifier.PUBLIC);

      if (patcher != null) {
         patcher.initClass(c);
      }

      for (CtMethod m : c.getDeclaredMethods()) {
         boolean wasAbstract = false;
         String newBody = null;
         if (Modifier.isAbstract(m.getModifiers())) {
            m.setModifiers(m.getModifiers() - Modifier.ABSTRACT);
            wasAbstract = true;
         }
         if (patcher != null) {
            newBody = patcher.getNewBody(m);
         }
         if (newBody != null) {

            if (Modifier.isNative(m.getModifiers())) {
               m.setModifiers(m.getModifiers() - Modifier.NATIVE);
            }

            replaceImplementation(m, newBody);

         } else if (wasAbstract) {
            if (patcher != null) {
               m.setBody("{ throw new " + UnsupportedOperationException.class.getName()
                        + "(\"Abstract method '" + c.getSimpleName() + "." + m.getName()
                        + "()' is not patched by " + patcher.getClass().getName() + "\"); }");
            } else {
               m.setBody("{ throw new " + UnsupportedOperationException.class.getName()
                        + "(\"Abstract method '" + c.getSimpleName() + "." + m.getName()
                        + "()' is not patched by any declared " + Patcher.class.getSimpleName()
                        + " instance\"); }");
            }
         }
      }

      if (patcher != null) {
         patcher.finalizeClass(c);
      }
   }

   private static void replaceImplementation(CtMethod m, String src) throws Exception {

      if (src == null || src.trim().length() == 0) {
         m.setBody(null);
      } else {
         src = src.trim();
         if (!src.startsWith("{")) {
            if (!m.getReturnType().equals(CtClass.voidType) && !src.startsWith("return")) {
               src = "{ return ($r)($w) " + src;
            } else {
               src = "{ " + src;
            }
         }

         if (!src.endsWith("}")) {
            if (!src.endsWith(";")) {
               src = src + "; }";
            } else {
               src = src + " }";
            }
         }
         try {
            m.setBody(src);
         } catch (CannotCompileException e) {
            throw new CannotCompileException("Unable to compile new body for method '"
                     + m.getLongName() + "' : " + src, e);
         }
      }
   }

   private GwtPatcherUtils() {

   }

}
TOP

Related Classes of com.googlecode.gwt.test.internal.GwtPatcherUtils

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.