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

com.appland.appmap.config.AppMapPackage Maven / Gradle / Ivy

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

import static com.appland.appmap.util.ClassUtil.safeClassForName;

import java.util.regex.Pattern;

import org.tinylog.TaggedLogger;

import com.appland.appmap.transform.annotations.CtClassUtil;
import com.appland.appmap.util.FullyQualifiedName;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import javassist.CtBehavior;
public class AppMapPackage {
  private static final TaggedLogger logger = AppMapConfig.getLogger(null);
  private static String tracePrefix = Properties.DebugClassPrefix;

  public String path;
  public String[] exclude = new String[] {};
  public boolean shallow = false;
  public Boolean allMethods = true;

  public static class LabelConfig {

    private Pattern className = null;
    private Pattern name = null;

    private String[] labels = new String[] {};
    private Class cls;

    public LabelConfig() {}

    @JsonCreator
    public LabelConfig(@JsonProperty("class") String className, @JsonProperty("name") String name,
        @JsonProperty("labels") String[] labels) {
      this.className = Pattern.compile("\\A(" + className + ")\\z");
      this.cls = safeClassForName(Thread.currentThread().getContextClassLoader(), className);
      logger.trace("this.cls: {}", this.cls);
      this.name = Pattern.compile("\\A(" + name + ")\\z");
      this.labels = labels;
    }

    public String[] getLabels() {
      return this.labels;
    }

    public boolean matches(FullyQualifiedName name) {
      return matches(name.className, name.methodName);
    }

    public boolean matches(String className, String methodName) {
      boolean traceClass = tracePrefix == null || className.startsWith(tracePrefix);
      Class cls = safeClassForName(Thread.currentThread().getContextClassLoader(), className);

      if (traceClass) {
        logger.trace("this.cls: {} cls: {}, isChildOf?: {}", this.cls, cls, CtClassUtil.isChildOf(cls, this.cls));
      }

      return this.className.matcher(className).matches() && this.name.matcher(methodName).matches();
    }

  }

  public LabelConfig[] methods = null;

  /**
   * Check if a class/method is included in the configuration.
   * 
   * @param canonicalName the canonical name of the class/method to be checked
   * @return {@code true} if the class/method is included in the configuration. {@code false} if it
   *         is not included or otherwise explicitly excluded.
   */
  public LabelConfig find(FullyQualifiedName canonicalName) {
    String className = canonicalName != null ? canonicalName.getClassName() : null;
    boolean traceClass = tracePrefix == null || className.startsWith(tracePrefix);
    if (traceClass) {
      logger.trace(canonicalName);
    }

    if (this.path == null) {
      return null;
    }

    if (canonicalName == null) {
      return null;
    }

    // If no method configs are set, use the old matching behavior.
    if (this.methods == null) {
      if (!canonicalName.toString().startsWith(this.path)) {
        return null;
      }

      return this.excludes(canonicalName) ? null : new LabelConfig();
    }

    if (!canonicalName.packageName.equals(this.path)) {
      return null;
    }

    for (LabelConfig ls : this.methods) {
      if (ls.matches(canonicalName)) {
        return ls;
      }
    }

    return null;
  }

  /**
   * Returns whether or not the canonical name is explicitly excluded
   * 
   * @param canonicalName the canonical name of the class/method to be checked
   */
  public Boolean excludes(CtBehavior behavior) {
    FullyQualifiedName fqn = null;
    for (String exclusion : this.exclude) {
      if (behavior.getDeclaringClass().getName().startsWith(exclusion)) {
        return true;
      } else {
        if (fqn == null) {
          fqn = new FullyQualifiedName(behavior);
        }
        if (fqn.toString().startsWith(exclusion)) {
          return true;
        }
      }
    }

    return false;
  }

  public Boolean excludes(FullyQualifiedName canonicalName) {
    for (String exclusion : this.exclude) {
      if (canonicalName.toString().startsWith(exclusion)) {
        return true;
      }
    }

    return false;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy