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

org.eclipse.persistence.internal.jpa.weaving.ClassDetails Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.jpa.weaving;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass;

/**
 * Internal helper class that holds details of a persistent class.
 * Used by {@link PersistenceWeaver}
 */

public class ClassDetails {

    protected MetadataClass describedClass;
    /** Name of this class. */
    protected String className;
    /** Superclass' name. */
    protected String superClassName;
    /** Superclass' ClassDetails - only populated if superclass is also persistent. */
    protected ClassDetails superClassDetails;
    /** Define if lazy value holders should be weaved in this class. */
    protected boolean shouldWeaveValueHolders = false;
    /** Define if change tracking should be weaved in this class. */
    protected boolean shouldWeaveChangeTracking = false;
    /** Define if fetch groups should be weaved in this class. */
    protected boolean shouldWeaveFetchGroups = false;
    /** Define if internal optimizations should be weaved in this class. */
    protected boolean shouldWeaveInternal = false;
    /** Define if this class should be weaved for our REST support */
    protected boolean shouldWeaveRest = false;
    /** Map of this class' persistent attributes where the key is the Attribute name. */
    protected Map attributesMap;
    /** Map of this class' persistent get methods where the key is the getMethod name. */
    protected Map getterMethodToAttributeDetails;
    /** Map of this class' persistent set methods where the key is the setMethod name. */
    protected Map setterMethodToAttributeDetails;
    /** Determine if a JPA "mapped superclass". */
    protected boolean isMappedSuperClass = false;
    /** Determine if a JPA "embedable" (aggregate). */
    protected boolean isEmbedable = false;
    /** Determine if class uses attribute access, lazily initialized. */
    protected boolean usesAttributeAccess = false;
    /** Determine if this class specifically implements a clone method */
    protected boolean implementsCloneMethod = false;
    /** Determine if a new constructor can be used to bypass setting variables to default values. */
    protected boolean shouldWeaveConstructorOptimization = true;
    /** The methods that are used by virtual attributes as getter methods.
     * These will be used by our weaver to properly weave those methods
     * This list should be kept in sync with virtualSetMethodNames. Every time
     * a value is added, one should be added to virtualSetMethodNames so that at
     * a particular index, the virtualGetMethodName and the virtualSetMethodCoorespond*/
    protected List virtualAccessMethods = null;


    public ClassDetails() {
        virtualAccessMethods = new ArrayList();
    }

    public MetadataClass getDescribedClass(){
        return describedClass;
    }

    public String getClassName() {
        return className;
    }

    public void setDescribedClass(MetadataClass describedClass){
        this.describedClass = describedClass;
    }

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

    public String getSuperClassName() {
        return superClassName;
    }

    public void setSuperClassName(String superClassName) {
        this.superClassName = superClassName;
    }

    public ClassDetails getSuperClassDetails() {
        return superClassDetails;
    }

    public void setSuperClassDetails(ClassDetails superClassDetails) {
        this.superClassDetails = superClassDetails;
    }

    public boolean shouldWeaveValueHolders() {
        return shouldWeaveValueHolders;
    }

    public void setShouldWeaveValueHolders(boolean shouldWeaveValueHolders) {
        this.shouldWeaveValueHolders = shouldWeaveValueHolders;
    }

    public boolean shouldWeaveChangeTracking() {
        return shouldWeaveChangeTracking;
    }

    public void setShouldWeaveChangeTracking(boolean shouldWeaveChangeTracking) {
        this.shouldWeaveChangeTracking = shouldWeaveChangeTracking;
    }

    public void setShouldWeaveConstructorOptimization(boolean shouldWeaveConstructorOptimization) {
        this.shouldWeaveConstructorOptimization = shouldWeaveConstructorOptimization;
    }

    public boolean shouldWeaveFetchGroups() {
        return shouldWeaveFetchGroups;
    }

    public void setShouldWeaveFetchGroups(boolean shouldWeaveFetchGroups) {
        this.shouldWeaveFetchGroups = shouldWeaveFetchGroups;
    }

    public boolean shouldWeaveInternal() {
        return shouldWeaveInternal;
    }

    public void setShouldWeaveInternal(boolean shouldWeaveInternal) {
        this.shouldWeaveInternal = shouldWeaveInternal;
    }

    public boolean shouldWeaveREST(){
        return shouldWeaveRest;
    }

    public void setShouldWeaveREST(boolean shouldWeaveRest){
        this.shouldWeaveRest = shouldWeaveRest;
    }

    public Map getAttributesMap() {
        return attributesMap;
    }

    public Map getGetterMethodToAttributeDetails(){
        return getterMethodToAttributeDetails;
    }

    public Map getSetterMethodToAttributeDetails(){
        return setterMethodToAttributeDetails;
    }

    public void setAttributesMap(Map attributesMap) {
        this.attributesMap = attributesMap;
    }

    public void setGetterMethodToAttributeDetails(Map map){
        this.getterMethodToAttributeDetails = map;
    }

    public boolean getImplementsCloneMethod(){
        return implementsCloneMethod;
    }

    /**
     * INTERNAL:
     * Search the list of virtualAccessMethods for a VirtualAttributeMethodInfo with the given
     * getMethodName.  Return the VirtualAttributeMethodInfo if there is one, else return null
     * @param getMethodName
     * @return
     */
    public VirtualAttributeMethodInfo getInfoForVirtualGetMethod(String getMethodName){
        Iterator i = virtualAccessMethods.iterator();
        while (i.hasNext()){
            VirtualAttributeMethodInfo info = i.next();
            if (info.getGetMethodName() != null && info.getGetMethodName().equals(getMethodName)){
                return info;
            }
        }
        return null;
    }

    /**
     * INTERNAL:
     * Search the list of virtualAccessMethods for a VirtualAttributeMethodInfo with the given
     * setMethodName.  Return the VirtualAttributeMethodInfo if there is one, else return null
     * @param setMethodName
     * @return
     */
    public VirtualAttributeMethodInfo getInfoForVirtualSetMethod(String setMethodName){
        Iterator i = virtualAccessMethods.iterator();
        while (i.hasNext()){
            VirtualAttributeMethodInfo info = i.next();
            if (info.getGetMethodName() != null && info.getGetMethodName().equals(setMethodName)){
                return info;
            }
        }
        return null;
    }

    public void setImplementsCloneMethod(boolean implementsCloneMethod){
        this.implementsCloneMethod = implementsCloneMethod;
    }

    /**
     * Return the name of the most direct superclass that has a direct implementation of
     * a clone method.
     * If there is not one, return null
     * @return
     */
    public String getNameOfSuperclassImplementingCloneMethod(){
        if (superClassDetails == null){
            return null;
        } else if (superClassDetails.getImplementsCloneMethod()){
            return superClassDetails.getClassName();
        } else {
            return superClassDetails.getNameOfSuperclassImplementingCloneMethod();
        }
    }

    public List getVirtualAccessMethods() {
        return virtualAccessMethods;
    }

    public void setVirtualAccessMethods(List virtualAccessMethods) {
        this.virtualAccessMethods = virtualAccessMethods;
    }

    public boolean isMappedSuperClass(){
        return isMappedSuperClass;
    }

    public void setIsMappedSuperClass(boolean isMappedSuperClass){
        this.isMappedSuperClass = isMappedSuperClass;
    }

    public boolean isEmbedable(){
        return isEmbedable;
    }

    public void setIsEmbedable(boolean isEmbedable){
        this.isEmbedable = isEmbedable;
    }

    public void setSetterMethodToAttributeDetails(Map map){
        this.setterMethodToAttributeDetails = map;
    }

    /**
     * If one attribute of this class uses attribute access, by the JPA specification, all
     * attributes must use attribute access
     *
     * This method assumes it is called when this class details is completely initialized.
     */
    public boolean usesAttributeAccess() {
        return usesAttributeAccess;
    }

    public void useAttributeAccess(){
        usesAttributeAccess = true;
    }

    public AttributeDetails getAttributeDetailsFromClassOrSuperClass(String attributeName){
        AttributeDetails attribute = attributesMap.get(attributeName);
        if (attribute == null && superClassDetails != null) {
            return superClassDetails.getAttributeDetailsFromClassOrSuperClass(attributeName);
        }
       return attribute;
    }

    public boolean doesSuperclassWeaveChangeTracking(){
        if (getSuperClassDetails() == null){
            return false;
        }
        if (getSuperClassDetails().shouldWeaveChangeTracking()) {
            return true;
        }

        return getSuperClassDetails().doesSuperclassWeaveChangeTracking();
    }

    public boolean canWeaveChangeTracking(){
        if ((getSuperClassDetails() == null) || (!shouldWeaveChangeTracking())) {
            return shouldWeaveChangeTracking();
        }

        return getSuperClassDetails().canWeaveChangeTracking();
    }

    /**
     * Returns true if
     * Used with field access, and is set to false if transient variables are discovered
     */
    public boolean canWeaveConstructorOptimization(){
        if (!shouldWeaveConstructorOptimization || (getSuperClassDetails() == null)) {
            return shouldWeaveConstructorOptimization;
        }
        return getSuperClassDetails().canWeaveConstructorOptimization();
    }

    /**
     * Returns true if the given class name represents this class, or any
     * superclass that can be navigated to by recursively navigating up the
     * structure of superClassDetails stored in this class.
     *
     * Assume java.lang.Object is in the hierarchy
     *
     * @param className
     * @return
     */
    public boolean isInMetadataHierarchy(String className){
        if (className.equals(Object.class.getName().replace('.', '/'))){
            return true;
        }
        if (className.equals(this.className) || (superClassName != null && className.equals(superClassName))){
            return true;
        }
        if (superClassDetails != null){
            return superClassDetails.isInMetadataHierarchy(className);
        }
        return false;
    }

    /**
     * Returns true if the given class name represents this class, or any
     * superclass that can be navigated to by recursively navigating up the
     * structure of superClassDetails stored in this class.
     *
     * Assume java.lang.Object is in the hierarchy
     *
     * @param className
     * @return
     */
    public boolean isInSuperclassHierarchy(String className){
        if (className.equals(Object.class.getName().replace('.', '/'))){
            return true;
        }
        if (superClassName != null && className.equals(superClassName)){
            return true;
        }
        if (superClassDetails != null){
            return superClassDetails.isInMetadataHierarchy(className);
        }
        return false;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy