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

com.avaje.ebean.enhance.agent.ClassMeta 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.FieldVisitor;
import com.avaje.ebean.enhance.asm.MethodVisitor;
import com.avaje.ebean.enhance.asm.Opcodes;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Holds the meta data for an entity bean class that is being enhanced.
 */
public class ClassMeta {

	private static final Logger logger = Logger.getLogger(ClassMeta.class.getName());

	private static final String OBJECT_CLASS = Object.class.getName().replace('.', '/');
	
	private final MessageOutput logout;

	private final int logLevel;

	private String className;

	private String superClassName;

	private ClassMeta superMeta;

	/**
	 * Set to true if the class implements th GroovyObject interface.
	 */
	private boolean hasGroovyInterface;

	/**
	 * Set to true if the class implements the ScalaObject interface.
	 */
	private boolean hasScalaInterface;

	/**
	 * Set to true if the class already implements the EntityBean interface.
	 */
	private boolean hasEntityBeanInterface;
	
	private boolean alreadyEnhanced;

	private boolean hasEqualsOrHashcode;

	private boolean hasDefaultConstructor;
	
	private boolean hasStaticInit;

	private HashSet existingMethods = new HashSet();

	private LinkedHashMap fields = new LinkedHashMap();

	private HashSet classAnnotation = new HashSet();

	private AnnotationInfo annotationInfo = new AnnotationInfo(null);

	private ArrayList methodMetaList = new ArrayList();

	private final EnhanceContext enhanceContext;
	
  private List allFields;
  
	public ClassMeta(EnhanceContext enhanceContext, int logLevel, MessageOutput logout) {
		this.enhanceContext = enhanceContext;
		this.logLevel = logLevel;
		this.logout = logout;
	}
	
	/**
	 * Return the enhance context which has options for enhancement.
	 */
	public EnhanceContext getEnhanceContext() {
        return enhanceContext;
    }
	
	/**
	 * Return the AnnotationInfo collected on methods. 
	 * Used to determine Transactional method enhancement.
	 */
	public AnnotationInfo getAnnotationInfo() {
		return annotationInfo;
	}

	/**
	 * Return the transactional annotation information for a matching interface method.
	 */
	public AnnotationInfo getInterfaceTransactionalInfo(String methodName, String methodDesc) {

		AnnotationInfo annotationInfo = null;

		for (int i = 0; i < methodMetaList.size(); i++) {
			MethodMeta meta = methodMetaList.get(i);
			if (meta.isMatch(methodName, methodDesc)) {
				if (annotationInfo != null) {
					String msg = "Error in [" + className + "] searching the transactional methods[" + methodMetaList
							+ "] found more than one match for the transactional method:" + methodName + " "
							+ methodDesc;
					
					logger.log(Level.SEVERE, msg);
					log(msg);
					
				} else {
					annotationInfo = meta.getAnnotationInfo();
					if (isLog(9)){
						log("... found transactional info from interface "+className+" "+methodName+" "+methodDesc);
					}
				}
			}
		}

		return annotationInfo;
	}

	public boolean isCheckSuperClassForEntity() {
    return !superClassName.equals(OBJECT_CLASS) && isCheckEntity();
  }

	public String toString() {
		return className;
	}

	public boolean isTransactional() {
    return classAnnotation.contains(EnhanceConstants.AVAJE_TRANSACTIONAL_ANNOTATION);
  }

	public void setClassName(String className, String superClassName) {
		this.className = className;
		this.superClassName = superClassName;
	}

	public String getSuperClassName() {
		return superClassName;
	}

	public boolean isLog(int level) {
		return level <= logLevel;
	}

	public void log(String msg) {
		if (className != null) {
			msg = "cls: " + className + "  msg: " + msg;
		}
		logout.println("ebean-enhance> " + msg);
	}
	
	public void logEnhanced() {
		String m = "enhanced ";
		if (hasScalaInterface()){
			m += " (scala)";
		}
		if (hasGroovyInterface()){
			m += " (groovy)";
		}
		log(m);
	}

	public void setSuperMeta(ClassMeta superMeta) {
		this.superMeta = superMeta;
	}

	/**
	 * Set to true if the class has an existing equals() or hashcode() method.
	 */
	public void setHasEqualsOrHashcode(boolean hasEqualsOrHashcode) {
		this.hasEqualsOrHashcode = hasEqualsOrHashcode;
	}

	/**
	 * Return true if Equals/hashCode is implemented on this class or a super class.
	 */
	public boolean hasEqualsOrHashCode() {
	  if (hasEqualsOrHashcode) {
	    return true;
	    
	  } else {
      return (superMeta != null && superMeta.hasEqualsOrHashCode());
    }
	}

	/**
	 * Return true if the field is a persistent field.
	 */
	public boolean isFieldPersistent(String fieldName) {

		FieldMeta f = getFieldPersistent(fieldName);
		return (f == null) ? false: f.isPersistent();
	}

  /**
   * Return true if the field is a persistent many field.
   */
  public boolean isFieldPersistentMany(String fieldName) {
    FieldMeta f = getFieldPersistent(fieldName);
    return (f != null && f.isPersistent() && f.isMany());
  }

  /**
   * Return the field - null when not found.
   */
  public FieldMeta getFieldPersistent(String fieldName) {

    FieldMeta f = fields.get(fieldName);
    if (f != null) {
      return f;
    }
    return (superMeta == null) ? null : superMeta.getFieldPersistent(fieldName);
  }

	/**
	 * Return the list of fields local to this type (not inherited).
	 */
	public List getLocalFields() {

		ArrayList list = new ArrayList();

    for (FieldMeta fm : fields.values()) {
      if (!fm.isObjectArray()) {
        // add field local to this entity type
        list.add(fm);
      }
    }

		return list;
	}

	/**
	 * Return the list of fields inherited from super types that are entities.
	 */
	private List getInheritedFields(List list) {

		if (list == null){
			list = new ArrayList();
		}

		if (superMeta != null) {
			superMeta.addFieldsForInheritance(list);
		}
		return list;
	}

	/**
	 * Add all fields to the list.
	 */
	private void addFieldsForInheritance(List list) {
		if (isEntity()) {
			list.addAll(0, fields.values());
			if (superMeta != null) {
				superMeta.addFieldsForInheritance(list);
			}
		}
	}
	
	/**
	 * Return true if the class contains persistent fields.
	 */
  public boolean hasPersistentFields() {
    
    for (FieldMeta fieldMeta : fields.values()) {
      if (fieldMeta.isPersistent()) {
        return true;
      }
    }

    return superMeta != null && superMeta.hasPersistentFields();
  }
  
	/**
	 * Return the list of all fields including ones inherited from entity super
	 * types and mappedSuperclasses.
	 */
	public List getAllFields() {

	  if (allFields != null) {
	    return allFields;
	  }
		List list = getLocalFields();
		getInheritedFields(list);
		
		this.allFields = list;
		for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy