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

com.avaje.ebean.enhance.agent.ClassAdapterDetectEnhancement Maven / Gradle / Ivy

There is a newer version: 8.1.1
Show newest version
package com.avaje.ebean.enhance.agent;

import com.avaje.ebean.enhance.asm.AnnotationVisitor;
import com.avaje.ebean.enhance.asm.ClassVisitor;
import com.avaje.ebean.enhance.asm.MethodVisitor;
import com.avaje.ebean.enhance.asm.Opcodes;

/**
 * ClassAdapter used to detect if this class needs enhancement for entity or
 * transactional support.
 */
class ClassAdapterDetectEnhancement extends ClassVisitor {

  private final ClassLoader classLoader;

  private final EnhanceContext enhanceContext;

  private final DetectTransactionalMethod detectTransactionalMethod = new DetectTransactionalMethod();

  private String className;

  private boolean entity;

  private boolean enhancedEntity;

  private boolean transactional;

  private boolean enhancedTransactional;

  ClassAdapterDetectEnhancement(ClassLoader classLoader, EnhanceContext context) {
    super(Opcodes.ASM5);
    this.classLoader = classLoader;
    this.enhanceContext = context;
  }

  public boolean isLog(int level) {
    return enhanceContext.isLog(level);
  }

  public void log(String msg) {
    enhanceContext.log(className, msg);
  }

  public void log(int level, String msg) {
    if (isLog(level)) {
      log(msg);
    }
  }

  boolean isEnhancedEntity() {
    return enhancedEntity;
  }

  boolean isEnhancedTransactional() {
    return enhancedTransactional;
  }

  /**
   * Return true if this is an entity bean or embeddable bean.
   */
  public boolean isEntity() {
    return entity;
  }

  /**
   * Return true if ANY method has the transactional annotation.
   */
  public boolean isTransactional() {
    return transactional;
  }

  /**
   * Visit the class with interfaces.
   */
  @Override
  public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {

    if ((access & Opcodes.ACC_INTERFACE) != 0) {
      throw new NoEnhancementRequiredException("Interface type");
    }

    this.className = name;

    for (int i = 0; i < interfaces.length; i++) {

      if (interfaces[i].equals(EnhanceConstants.C_ENTITYBEAN)) {
        enhancedEntity = true;
        entity = true;

      } else if (interfaces[i].equals(EnhanceConstants.C_ENHANCEDTRANSACTIONAL)) {
        enhancedTransactional = true;

      } else {
        ClassMeta interfaceMeta = enhanceContext.getInterfaceMeta(interfaces[i], classLoader);
        if (interfaceMeta != null && interfaceMeta.isTransactional()) {
          transactional = true;
          if (isLog(9)) {
            log("detected implements transactional interface " + interfaceMeta);
          }
        }
      }
    }

    if (isLog(4)) {
      log("interfaces:  enhancedEntity[" + enhancedEntity + "] transactional[" + enhancedTransactional + "]");
    }
  }

  /**
   * Visit class level annotations.
   */
  @Override
  public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
    if (isEntityAnnotation(desc)) {
      if (isLog(5)) {
        log("found entity annotation " + desc);
      }
      entity = true;

    } else if (desc.equals(EnhanceConstants.AVAJE_TRANSACTIONAL_ANNOTATION)) {
      if (isLog(5)) {
        log("found transactional annotation " + desc);
      }
      transactional = true;
    }
    return null;
  }

  /**
   * Return true if the annotation is for an Entity, Embeddable or MappedSuperclass.
   */
  private boolean isEntityAnnotation(String desc) {

    if (!desc.startsWith(EnhanceConstants.JAVAX_PERSISTENCE)) {
      return false;
    }
    if (desc.equals(EnhanceConstants.ENTITY_ANNOTATION)) {
      return true;
    } else if (desc.equals(EnhanceConstants.EMBEDDABLE_ANNOTATION)) {
      return true;
    } else if (desc.equals(EnhanceConstants.MAPPEDSUPERCLASS_ANNOTATION)) {
      return true;
    }
    return false;
  }

  /**
   * Visit the methods specifically looking for method level transactional
   * annotations.
   */
  @Override
  public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    return detectTransactionalMethod;
  }

  /**
   * Check methods for Transactional annotation.
   */
  private class DetectTransactionalMethod extends MethodVisitor {

    DetectTransactionalMethod() {
      super(Opcodes.ASM5);
    }

    @Override
    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
      if (desc.equals(EnhanceConstants.AVAJE_TRANSACTIONAL_ANNOTATION)) {
        transactional = true;
      }
      return null;
    }

  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy