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

be.orbinson.sling.observability.weavinghooks.logmethod.LogMethodWeavingHook Maven / Gradle / Ivy

package be.orbinson.sling.observability.weavinghooks.logmethod;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.util.TraceClassVisitor;
import org.osgi.framework.hooks.weaving.WeavingHook;
import org.osgi.framework.hooks.weaving.WovenClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.PrintWriter;
import java.io.StringWriter;

public class LogMethodWeavingHook implements WeavingHook {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private final String className;
    private final String methodName;
    private final String logLevel;
    private final boolean showGeneratedBytecode;

    public LogMethodWeavingHook(LogMethodWeavingHookConfiguration config) {
        this.className = config.getClassName();
        this.methodName = config.getMethodName();
        this.logLevel = config.getLogLevel();
        this.showGeneratedBytecode = config.isShowGeneratedBytecode();
    }

    @Override
    public void weave(WovenClass wovenClass) {
        if (wovenClass.getClassName().equals(className)) {
            log.debug("Adding dynamic log methods to class  {}", wovenClass.getClassName());
            addLogMethodToClass(wovenClass);
            addDynamicImports(wovenClass);
        }
    }

    private void addLogMethodToClass(WovenClass wovenClass) {
        final ClassReader cr = new ClassReader(wovenClass.getBytes());
        final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
        ClassVisitor logMethodClassVisitor;
        if (showGeneratedBytecode) {
            StringWriter out = new StringWriter();
            final TraceClassVisitor tcv = new TraceClassVisitor(cw, new PrintWriter(out));
            logMethodClassVisitor = new LogMethodClassVisitor(tcv, className, methodName, logLevel);
            cr.accept(logMethodClassVisitor, 0);
            log.debug("Resulting class bytecode: {}", out);
        } else {
            logMethodClassVisitor = new LogMethodClassVisitor(cw, className, methodName, logLevel);
            cr.accept(logMethodClassVisitor, 0);
        }
        wovenClass.setBytes(cw.toByteArray());
    }

    /**
     * Required to add sl4fj as dynamic import if it would not be used in the bundle
     */
    private void addDynamicImports(WovenClass wovenClass) {
        wovenClass.getDynamicImports().add("org.slf4j");
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy