All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.gwt.test.internal.GwtPatcherUtils Maven / Gradle / Ivy

There is a newer version: 0.63
Show newest version
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. For
 * internal use only.
 *
 * @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() {

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy