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

org.eclipse.persistence.internal.jpa.metamodel.AttributeImpl Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 2011, 2018 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:
//     03/19/2009-2.0  dclarke  - initial API start
//     06/30/2009-2.0  mobrien - finish JPA Metadata API modifications in support
//       of the Metamodel implementation for EclipseLink 2.0 release involving
//       Map, ElementCollection and Embeddable types on MappedSuperclass descriptors
//       - 266912: JPA 2.0 Metamodel API (part of the JSR-317 EJB 3.1 Criteria API)
//     29/10/2009-2.0  mobrien - m:1 and 1:m relationships require special handling
//       in their internal m:m and 1:1 database mapping representations.
//       http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_96:_20091019:_Attribute.getPersistentAttributeType.28.29_treats_ManyToOne_the_same_as_OneToOne
//     16/06/2010-2.2  mobrien - 316991: Attribute.getJavaMember() requires reflective getMethod call
//       when only getMethodName is available on accessor for attributes of Embeddable types.
//       http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_95:_20091017:_Attribute.getJavaMember.28.29_returns_null_for_a_BasicType_on_a_MappedSuperclass_because_of_an_uninitialized_accessor
//     09/08/2010-2.2  mobrien - 322166: If attribute is defined on a lower level MappedSuperclass (and not on a superclass)
//       - do not attempt a reflective call on a superclass
//       - see design issue #25
//       http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_25:_20090616:_Inherited_parameterized_generics_for_Element_Collections_.28Basic.29
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
package org.eclipse.persistence.internal.jpa.metamodel;

import java.io.Serializable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;

import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.ManagedType;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredField;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredMethod;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ManyToManyMapping;

/**
 * 

* Purpose: Provides the implementation for the Attribute interface * of the JPA 2.0 Metamodel API (part of the JSR-317 EJB 3.1 Criteria API) *

* Description: * An attribute of a Java type * * @see javax.persistence.metamodel.Attribute * * @since EclipseLink 1.2 - JPA 2.0 * @param The represented type that contains the attribute * @param The type of the represented attribute * */ public abstract class AttributeImpl implements Attribute, Serializable { /** The ManagedType associated with this attribute **/ private ManagedTypeImpl managedType; /** The databaseMapping associated with this attribute **/ private DatabaseMapping mapping; /** * INTERNAL: * * @param managedType * @param mapping */ protected AttributeImpl(ManagedTypeImpl managedType, DatabaseMapping mapping) { this.mapping = mapping; // Cache this Attribute on the mapping - Why?? //this.mapping.setProperty(getClass().getName(), this); this.managedType = managedType; } /** * Return the managed type representing the type in which * the attribute was declared. * @return declaring type */ @Override public ManagedType getDeclaringType() { return getManagedTypeImpl(); } /** * INTERNAL: * Return the Descriptor associated with this attribute * @return */ protected ClassDescriptor getDescriptor() { return getManagedTypeImpl().getDescriptor(); } /** * Return the java.lang.reflect.Member for the represented attribute. * In the case of property access the get method will be returned * * @return corresponding java.lang.reflect.Member */ @Override public Member getJavaMember() { AttributeAccessor accessor = getMapping().getAttributeAccessor(); if (accessor.isMethodAttributeAccessor()) { // Method level access here Method aMethod = ((MethodAttributeAccessor) accessor).getGetMethod(); if(null == aMethod) { // 316991: If the getMethod is not set - use a reflective call via the getMethodName String getMethodName = null; try { getMethodName = ((MethodAttributeAccessor)mapping.getAttributeAccessor()).getGetMethodName(); if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { aMethod = AccessController.doPrivileged(new PrivilegedGetDeclaredMethod( this.getManagedTypeImpl().getJavaType(), getMethodName, null)); } else { aMethod = PrivilegedAccessHelper.getDeclaredMethod( this.getManagedTypeImpl().getJavaType(),getMethodName, null); } // Exceptions are to be ignored for reflective calls - if the methodName is also null - it will catch here } catch (PrivilegedActionException pae) { //pae.printStackTrace(); } catch (NoSuchMethodException nsfe) { //nsfe.printStackTrace(); } } return aMethod; } // Field level access here Member aMember = ((InstanceVariableAttributeAccessor) accessor).getAttributeField(); // For primitive and basic types - we should not return null - the attributeAccessor on the MappedSuperclass is not initialized - see // http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_95:_20091017:_Attribute.getJavaMember.28.29_returns_null_for_a_BasicType_on_a_MappedSuperclass_because_of_an_uninitialized_accessor // MappedSuperclasses need special handling to get their type from an inheriting subclass // Note: This code does not handle attribute overrides on any entity subclass tree - use descriptor initialization instead if(null == aMember) { if(this.getManagedTypeImpl().isMappedSuperclass()) { // get inheriting subtype member (without handling @override annotations) AttributeImpl inheritingTypeMember = ((MappedSuperclassTypeImpl)this.getManagedTypeImpl()) .getMemberFromInheritingType(mapping.getAttributeName()); // 322166: If attribute is defined on this current ManagedType (and not on a superclass) - do not attempt a reflective call on a superclass if(null != inheritingTypeMember) { // Verify we have an attributeAccessor aMember = ((InstanceVariableAttributeAccessor)inheritingTypeMember.getMapping() .getAttributeAccessor()).getAttributeField(); } } if(null == aMember) { // 316991: Handle Embeddable types // If field level access - perform a getDeclaredField call // Field level access // Check declaredFields in the case where we have no getMethod or getMethodName try { if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ aMember = AccessController.doPrivileged(new PrivilegedGetDeclaredField( this.getManagedTypeImpl().getJavaType(), mapping.getAttributeName(), false)); } else { aMember = PrivilegedAccessHelper.getDeclaredField( this.getManagedTypeImpl().getJavaType(), mapping.getAttributeName(), false); } // Exceptions are to be ignored for reflective calls - if the methodName is also null - it will catch here } catch (PrivilegedActionException pae) { //pae.printStackTrace(); } catch (NoSuchFieldException nsfe) { //nsfe.printStackTrace(); } } } // 303063: secondary check for attribute override case - this will show on code coverage if(null == aMember) { AbstractSessionLog.getLog().log(SessionLog.FINEST, AbstractSessionLog.METAMODEL, "metamodel_attribute_getmember_is_null", this, this.getManagedTypeImpl(), this.getDescriptor()); } return aMember; } /** * Return the Java type of the represented attribute. * @return Java type */ @Override public abstract Class getJavaType(); /** * INTERNAL: * Return the managed type representing the type in which the member was * declared. * @return */ public ManagedTypeImpl getManagedTypeImpl() { return this.managedType; } /** * INTERNAL: * Return the databaseMapping that represents the type * @return */ public DatabaseMapping getMapping() { return this.mapping; } /** * INTERNAL: * Return the concrete metamodel that this attribute is associated with. * @return MetamodelImpl */ protected MetamodelImpl getMetamodel() { return this.managedType.getMetamodel(); } /** * Return the name of the attribute. * @return name */ @Override public String getName() { return this.getMapping().getAttributeName(); } /** * Return the persistent attribute type for the attribute. * @return persistent attribute type */ @Override public Attribute.PersistentAttributeType getPersistentAttributeType() { /** * process the following mappings by referencing the Core API Mapping. * MANY_TO_ONE (ONE_TO_ONE internally) * ONE_TO_ONE (May originally be a MANY_TO_ONE) * BASIC * EMBEDDED * MANY_TO_MANY (May originally be a unidirectional ONE_TO_MANY on a mappedSuperclass) * ONE_TO_MANY (MANY_TO_MANY internally for unidirectional mappings on MappedSuperclasses) * ELEMENT_COLLECTION */ if (mapping.isAbstractDirectMapping()) { return PersistentAttributeType.BASIC; } if (mapping.isAggregateObjectMapping()) { return PersistentAttributeType.EMBEDDED; } if (mapping.isOneToManyMapping()) { return PersistentAttributeType.ONE_TO_MANY; } /** * EclipseLink internally processes a ONE_TO_MANY on a MappedSuperclass as a MANY_TO_MANY * because the relationship is unidirectional. */ if (mapping.isManyToManyMapping()) { // Check for a OneToMany on a MappedSuperclass being processed internally as a ManyToMany if(((ManyToManyMapping)mapping).isDefinedAsOneToManyMapping()) { return PersistentAttributeType.ONE_TO_MANY; } else { // Test coverage required return PersistentAttributeType.MANY_TO_MANY; } } if (mapping.isManyToOneMapping()) { return PersistentAttributeType.MANY_TO_ONE; } if (mapping.isOneToOneMapping()) { return PersistentAttributeType.ONE_TO_ONE; } // Test coverage required return PersistentAttributeType.ELEMENT_COLLECTION; } /** * Is the attribute an association. * @return whether boolean indicating whether attribute * corresponds to an association */ @Override public boolean isAssociation() { // If the mapping a relationship to another entity. return getMapping().isForeignReferenceMapping() && !getMapping().isDirectCollectionMapping() && !getMapping().isAggregateCollectionMapping(); } /** * Is the attribute collection-valued. * @return boolean indicating whether attribute is * collection-valued.

* This will be true for the mappings CollectionMapping, AbstractCompositeCollectionMapping, * AbstractCompositeDirectCollectionMapping and their subclasses * */ @Override public boolean isCollection() { return getMapping().isCollectionMapping(); } /** * INTERNAL: * Return whether the attribute is plural or singular * @return */ public abstract boolean isPlural(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy