org.summer.aop.ltw.ConstructorSplitter.java Source code

Java tutorial

Introduction

Here is the source code for org.summer.aop.ltw.ConstructorSplitter.java

Source

/***
 * Summer: An enhanced, non-invasive, and easy-to-use IoC container and
 * LTW-AOP framework enabling brand-new mocking capabilities in combination
 * with a lightweight rule engine and general meta expression language purely
 * written in Java.
 * It provides component composition at run-time as well as brand-new mocking
 * capabilities that are also applicable to binary third-party libraries, to name
 * only two of all its features.
 * There are barely limitations due to the lack of
 * Java in adding and removing fields and methods to and from a class at run-time.
 *
 * Copyright (C) 2011-2013  Sandro Sebastian Koll
 *
 * This file is part of Summer.
 *
 * Summer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Summer 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Summer. If not, see <http://www.gnu.org/licenses/>.
 */
package org.summer.aop.ltw;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.AdviceAdapter;
import org.summer.aop.AOPContext;
import org.summer.aop.Aspect;

import java.util.List;

/**
 * @author Sandro Sebastian Koll
 */
public class ConstructorSplitter extends MethodVisitor implements Opcodes {
    public ConstructorSplitter(final String className, ClassVisitor cv, int access, int constructorNumber,
            String methodDesc, String methodSignature, String[] exceptions, List<Aspect> matchingAspects) {
        super(ASM4);
        MethodVisitor constructorVisitor = cv.visitMethod(access, "<init>", methodDesc, methodSignature,
                exceptions);
        final MethodVisitor redirectedMethodVisitor = cv.visitMethod(ACC_PRIVATE,
                AOPContext.toRedirectedMethodName("<init>", constructorNumber), methodDesc, methodSignature,
                exceptions);

        // Add the original but transformed constructor
        final ConstructorReplacer constructorReplacer = new ConstructorReplacer(className, constructorVisitor,
                access, constructorNumber, methodDesc, methodSignature, exceptions, matchingAspects);
        // Redirect the super call to a new corresponding constructor and visit end.
        // Finally flip the method visitor to the redirected method visitor with the original code.
        this.mv = new AdviceAdapter(ASM4, constructorReplacer, access, "<init>", methodDesc) {
            @Override
            protected void onMethodEnter() {
                constructorReplacer.replaceConstructor();
                constructorReplacer.visitMaxs(-1, -1);
                constructorReplacer.visitEnd();
                ConstructorSplitter.this.mv = redirectedMethodVisitor;
            }
        };
    }
}