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

com.appland.appmap.transform.instrumentation.BBAdvice Maven / Gradle / Ivy

package com.appland.appmap.transform.instrumentation;

import java.lang.reflect.Method;

import com.appland.appmap.process.ThreadLock;
import com.appland.appmap.process.hooks.MethodCall;
import com.appland.appmap.process.hooks.MethodException;
import com.appland.appmap.process.hooks.MethodReturn;
import com.appland.appmap.record.EventTemplateRegistry;
import com.appland.appmap.transform.annotations.AppMapAppMethod;
import com.appland.appmap.transform.annotations.MethodEvent;

import net.bytebuddy.asm.Advice.AllArguments;
import net.bytebuddy.asm.Advice.OnMethodEnter;
import net.bytebuddy.asm.Advice.OnMethodExit;
import net.bytebuddy.asm.Advice.Origin;
import net.bytebuddy.asm.Advice.Return;
import net.bytebuddy.asm.Advice.This;
import net.bytebuddy.asm.Advice.Thrown;
import net.bytebuddy.implementation.bytecode.assign.Assigner.Typing;


public class BBAdvice {
  @OnMethodEnter
  public static void onEnter(@This(optional = true) Object self, @Origin Method method,
      @AllArguments Object[] args) throws Throwable {
    AppMapAppMethod annot = method.getAnnotation(AppMapAppMethod.class);
    int[] values = annot.value();
    EventTemplateRegistry etr = EventTemplateRegistry.get();
    int callTemplateOrdinal = values[MethodEvent.METHOD_INVOCATION.getIndex()];

    ThreadLock.current().enter();

    if (ThreadLock.current().lock()) {
      MethodCall.handle(etr.buildCallEvent(callTemplateOrdinal), self, args);
      ThreadLock.current().unlock();
    } ;
  }

  @OnMethodExit(onThrowable = Throwable.class)
  public static void onExit(@This(optional = true) Object self, @Origin Method method,
      @AllArguments Object[] args, @Return(typing = Typing.DYNAMIC) Object ret,
      @Thrown Throwable exc) throws Throwable {
    try {
      if (exc == null) {
        handleReturn(self, method, args, ret);
      } else {
        handleExc(self, method, args, exc);
      }
    } finally {
      ThreadLock.current().exit();
    }
  }

  public static void handleReturn(Object self, Method method, Object[] args, Object ret)
      throws Throwable {
    EventTemplateRegistry etr = EventTemplateRegistry.get();
    AppMapAppMethod annot = method.getAnnotation(AppMapAppMethod.class);
    int[] values = annot.value();
    int returnTemplateOrdinal = values[MethodEvent.METHOD_RETURN.getIndex()];

    if (ThreadLock.current().lock()) {
      MethodReturn.handle(etr.buildReturnEvent(returnTemplateOrdinal), self, ret, args);
      ThreadLock.current().unlock();
    }
  }

  public static void handleExc(Object self, Method method,
      Object[] args, Throwable exc) throws Throwable {
    AppMapAppMethod annot = method.getAnnotation(AppMapAppMethod.class);
    int[] values = annot.value();
    EventTemplateRegistry etr = EventTemplateRegistry.get();
    int excTemplateOrdinal = values[MethodEvent.METHOD_EXCEPTION.getIndex()];

    if (ThreadLock.current().lock()) {
      MethodException.handle(etr.buildReturnEvent(excTemplateOrdinal), self, exc, args);
      ThreadLock.current().unlock();
    }
    throw exc;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy