content: /*
   * Copyright The OpenTelemetry Authors
   * SPDX-License-Identifier: Apache-2.0
   */
  
  package io.opentelemetry.javaagent.bootstrap;
  
  import java.util.function.Predicate;
  import java.util.logging.Logger;
  
  public final class InstrumentedTaskClasses {
  
    private static final Logger logger = Logger.getLogger(InstrumentedTaskClasses.class.getName());
  
    private static final String AGENT_CLASSLOADER_NAME =
        "io.opentelemetry.javaagent.bootstrap.AgentClassLoader";
  
    private static final ClassValue<Boolean> INSTRUMENTED_TASK_CLASS =
        new ClassValue<Boolean>() {
          @Override
          protected Boolean computeValue(Class<?> taskClass) {
            // do not instrument ignored task classes
            if (ignoredTaskClassesPredicate.test(taskClass.getName())) {
              return false;
            }
            // Don't trace runnables from libraries that are packaged inside the agent.
            // Although GlobalIgnoredTypesConfigurer excludes these classes from instrumentation
            // their instances can still be passed to executors which we have instrumented so we need
            // to exclude them here too.
            ClassLoader taskClassLoader = taskClass.getClassLoader();
            if (taskClassLoader != null
                && AGENT_CLASSLOADER_NAME.equals(taskClassLoader.getClass().getName())) {
              return false;
            }
            return true;
          }
        };
  
    private static volatile Predicate<String> ignoredTaskClassesPredicate;
  
    /**
     * Sets the configured ignored tasks predicate. This method is called internally from the agent
     * class loader.
     */
    public static void setIgnoredTaskClassesPredicate(Predicate<String> ignoredTasksTriePredicate) {
      if (InstrumentedTaskClasses.ignoredTaskClassesPredicate != null) {
        logger.warning("Ignored task classes were already set earlier; returning.");
        return;
      }
      InstrumentedTaskClasses.ignoredTaskClassesPredicate = ignoredTasksTriePredicate;
    }
  
    /**
     * Returns {@code true} when passes {@code taskClass} is allowed to be instrumented; i.e. the
     * instrumentation may attach context to this task.
     */
    public static boolean canInstrumentTaskClass(Class<?> taskClass) {
      return INSTRUMENTED_TASK_CLASS.get(taskClass);
    }
  
    private InstrumentedTaskClasses() {}
  }
  