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

com.appland.appmap.transform.annotations.HookSite Maven / Gradle / Ivy

There is a newer version: 1.27.1
Show newest version
package com.appland.appmap.transform.annotations;

import com.appland.appmap.output.v1.Parameters;

import java.util.stream.Collectors;

/**
 * An example of hook, applied to a behavior. Holds metadata which can be eventually used to transform the behavior
 * bytecode to record the AppMap event.
 */
public class HookSite {
  private final Hook hook;
  private final Integer behaviorOrdinal;
  private final String hookInvocation;
  private final MethodEvent methodEvent;
  private final Boolean ignoresGlobalLock;

  /**
   * @param behaviorOrdinal Used to obtain a template for the event from the event template registry.
   * @param parameters Parameters that will be reported in the AppMap.
   * @see com.appland.appmap.record.EventTemplateRegistry
   */
  HookSite(Hook hook, Integer behaviorOrdinal, Parameters parameters) {
    this.methodEvent = hook.getMethodEvent();
    this.hook = hook;
    this.behaviorOrdinal = behaviorOrdinal;
    this.ignoresGlobalLock = (Boolean) AnnotationUtil.getValue(
      hook.getBehavior(),
      ContinueHooking.class,
      false);

    final String event;
    if ( methodEvent.getEventString().equals("call") ) {
      event = String.format("%s.get().buildCallEvent(%d)",
          "com.appland.appmap.record.EventTemplateRegistry",
          behaviorOrdinal);
    } else {
      event = String.format("%s.get().buildReturnEvent(%d)",
          "com.appland.appmap.record.EventTemplateRegistry",
          behaviorOrdinal);
    }

    final String args = parameters
        .stream()
        .map(param -> (param.classType == null || param.classType.isEmpty())
            ? param.name
            : String.format(("(%s) %s"), param.classType, param.name))
        .collect(Collectors.joining(", "))
        .replace(SourceMethodSystem.EVENT_TOKEN, event);

    String invocation = hook.getSourceSystem().toString() + "(" + args + ");";

    if (!this.getUniqueKey().isEmpty()) {
      invocation = "if (com.appland.appmap.process.ThreadLock.current().hasUniqueLock(\""
          + this.getUniqueKey()
          + "\")) {"
          + invocation
          + "}";
    }

    if (this.ignoresGlobalLock()) {
      this.hookInvocation = invocation;
    } else {
      this.hookInvocation = "if (com.appland.appmap.process.ThreadLock.current().lock()) {"
          + invocation
          + "com.appland.appmap.process.ThreadLock.current().unlock();"
          + "}";
    }
  }

  public String getHookInvocation() {
    return this.hookInvocation;
  }

  public MethodEvent getMethodEvent() {
    return this.methodEvent;
  }

  public String getUniqueKey() {
    return hook.getUniqueKey();
  }

  public Hook getHook() {
    return this.hook;
  }

  public Boolean ignoresGlobalLock() {
    return this.ignoresGlobalLock;
  }

  public Integer getBehaviorOrdinal() {
    return behaviorOrdinal;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy