| /* |
| * Copyright (c) 2011, 2021 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) |
| // 07/06/2009-2.0 mobrien - 266912: Introduce IdentifiableTypeImpl between ManagedTypeImpl |
| // - EntityTypeImpl now inherits from IdentifiableTypeImpl instead of ManagedTypeImpl |
| // - MappedSuperclassTypeImpl now inherits from IdentifiableTypeImpl instead |
| // of implementing IdentifiableType indirectly |
| // 08/06/2010-2.2 mobrien 322018 - reduce protected instance variables to private to enforce encapsulation |
| package org.eclipse.persistence.internal.jpa.metamodel; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import jakarta.persistence.metamodel.MappedSuperclassType; |
| |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| |
| /** |
| * <p> |
| * <b>Purpose</b>: Provides the implementation for the MappedSuperclassType interface |
| * of the JPA 2.0 Metamodel API (part of the JSR-317 EJB 3.1 Criteria API) |
| * <p> |
| * <b>Description</b>: |
| * Instances of the type MappedSuperclassType represent mapped |
| * superclass types. |
| * |
| * @see jakarta.persistence.metamodel.MappedSuperclassType |
| * |
| * @since EclipseLink 1.2 - JPA 2.0 |
| * |
| * @param <X> The represented entity type |
| */ |
| public class MappedSuperclassTypeImpl<X> extends IdentifiableTypeImpl<X> implements MappedSuperclassType<X> { |
| |
| /** Item 54: DI 89: explicit UID will avoid performance hit runtime generation of one */ |
| private static final long serialVersionUID = 3770722221322920646L; |
| |
| /** |
| * INTERNAL: |
| * The map of Identifiable types that inherit from this MappedSuperclass. |
| * The scope of this map is outside of the JPA 2.0 specification and is limited to MappedSuperclass types. |
| * The types in this map are keyed on the Java class of the inheriting type. |
| * This map acts as the reverse of all superType fields that point to "this" MappedSuperclass. |
| **/ |
| private Map<Class, IdentifiableTypeImpl> inheritingIdentifiableTypes; |
| |
| protected MappedSuperclassTypeImpl(MetamodelImpl metamodel, ClassDescriptor relationalDescriptor) { |
| super(metamodel, relationalDescriptor); |
| inheritingIdentifiableTypes = new HashMap<Class, IdentifiableTypeImpl>(); |
| // The supertype field will remain uninstantiated until MetamodelImpl.initialize() is complete |
| } |
| |
| /** |
| * INTERNAL: |
| * Add an inheriting subclass to the map of Identifiable types that inherit from this mappedSuperclass. |
| * @param identifiableType |
| */ |
| protected void addInheritingType(IdentifiableTypeImpl identifiableType) { |
| // The Map will always be instantiated in the constructor |
| inheritingIdentifiableTypes.put(identifiableType.getJavaType(), identifiableType); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return an instance of a MappedSuperclassType based on the RelationalDescriptor. |
| * @param metamodel |
| * @param relationalDescriptor |
| * @return |
| */ |
| protected static MappedSuperclassTypeImpl<?> create(MetamodelImpl metamodel, ClassDescriptor relationalDescriptor) { |
| MappedSuperclassTypeImpl<?> mappedSuperclassTypeImpl = new MappedSuperclassTypeImpl(metamodel, relationalDescriptor); |
| return mappedSuperclassTypeImpl; |
| } |
| |
| /** |
| * INTERNAL: |
| * MappedSuperclasses need special handling to get their type from an inheriting subclass. |
| * This function determines the type for an attribute by returning the same inherited attribute from a subclass |
| * @param name |
| * @return |
| */ |
| public AttributeImpl getMemberFromInheritingType(String name) { |
| AttributeImpl inheritedAttribute = null; |
| // search the inheriting types map for an attribute matching the attribute name |
| for(IdentifiableTypeImpl inheritingType : inheritingIdentifiableTypes.values()) { |
| //Entity types are initialized before MappedSuperclass types. However, it is possible that the inheriting MappedSuperclass is not yet initialized. |
| Map inheritingTypeMembers = inheritingType.getMembers(); |
| if ((null == inheritingTypeMembers) && inheritingType.isMappedSuperclass()) { |
| //not initialized |
| inheritingType.initialize(); |
| inheritingTypeMembers = inheritingType.getMembers(); |
| } |
| |
| if(inheritingTypeMembers != null && inheritingTypeMembers.containsKey(name)) { |
| inheritedAttribute = (AttributeImpl)inheritingType.getAttribute(name); |
| break; |
| } |
| } |
| // we will return a null attribute in the case that a MappedSuperclass has no implementing entities |
| return inheritedAttribute; |
| } |
| |
| /** |
| * Return the persistence type. |
| * @return persistence type |
| */ |
| @Override |
| public jakarta.persistence.metamodel.Type.PersistenceType getPersistenceType() { |
| return PersistenceType.MAPPED_SUPERCLASS; |
| } |
| |
| @Override |
| protected void initialize(){ |
| /** |
| * Set the javaClass on the descriptor for the current classLoader (normally done in MetadataProject.addMetamodelMappedSuperclass). |
| * This will ensure the class is both set and is in the right classLoader - even if the class is already set. |
| * Perform this conversion only for our custom pseudo descriptors for MappedSuperclasses. |
| * The classLoader should be obtained from the ConversionManager so we handle EE deployments using a shared-library |
| */ |
| descriptor.convertClassNamesToClasses(metamodel.getSession().getDatasourcePlatform().getConversionManager().getLoader()); |
| super.initialize(); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return whether this type is an Entity (true) or MappedSuperclass (false) or Embeddable (false) |
| * @return |
| */ |
| @Override |
| public boolean isEntity() { |
| return false; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return whether this type is an MappedSuperclass (true) or Entity (false) or Embeddable (false) |
| * @return |
| */ |
| @Override |
| public boolean isMappedSuperclass() { |
| return !isEntity(); |
| } |
| } |