| /* |
| * 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 - Metamodel implementation expansion |
| // - 282518: Metamodel superType requires javaClass set on custom |
| // descriptor on MappedSuperclassAccessor. |
| // 07/10/2009-2.0 mobrien - Adjust BasicType processing to handle non-Entity Java types |
| // - 266912: As part of Attribute.getType() and specifically SingularAttribute.getBindableJavaType |
| // set the appropriate elementType based on the mapping type. |
| // 09/23/2009-2.0 mobrien - 266912: Implement hasSingleIdAttribute() and |
| // all other 6 remaining methods for Id and Version support. |
| // DI 70 - 77 and 56 |
| // http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_74:_20090909:_Implement_IdentifiableType.hasSingleIdAttribute.28.29 |
| // 10/14/2009-2.0 mobrien - 285512: managedType(clazz) now throws IAE again for |
| // any clazz that resolves to a BasicType - use getType(clazz) in implementations instead |
| // when you are expecting a BasicType |
| // 08/06/2010-2.2 mobrien 322018 - reduce protected instance variables to private to enforce encapsulation |
| // 08/06/2010-2.2 mobrien 303063 - handle null descriptor.javaClass passed from the metadata API |
| // 03/06/2011-2.3 mobrien 338837 - Metamodel entity processing requires specified entities in persistence.xml |
| // to avoid IllegalArgumentException when accessing an EntityType|EmbeddableType|ManagedType |
| // "The type [null] is not the expected [EntityType] for the key class" will result in certain managed persistence contexts |
| package org.eclipse.persistence.internal.jpa.metamodel; |
| |
| import java.io.Serializable; |
| import java.util.ArrayList; |
| import java.util.LinkedHashMap; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import jakarta.persistence.EntityManager; |
| import jakarta.persistence.EntityManagerFactory; |
| import jakarta.persistence.metamodel.Attribute; |
| import jakarta.persistence.metamodel.EmbeddableType; |
| import jakarta.persistence.metamodel.EntityType; |
| import jakarta.persistence.metamodel.IdentifiableType; |
| import jakarta.persistence.metamodel.ManagedType; |
| import jakarta.persistence.metamodel.Metamodel; |
| import jakarta.persistence.metamodel.Type; |
| import jakarta.persistence.metamodel.Type.PersistenceType; |
| |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.internal.helper.ClassConstants; |
| import org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl; |
| import org.eclipse.persistence.internal.localization.ExceptionLocalization; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.jpa.JpaHelper; |
| import org.eclipse.persistence.logging.AbstractSessionLog; |
| import org.eclipse.persistence.logging.SessionLog; |
| import org.eclipse.persistence.sessions.Project; |
| |
| /** |
| * <p> |
| * <b>Purpose</b>: Provides the implementation for the Metamodel interface |
| * of the JPA 2.0 Metamodel API (part of the JSR-317 EJB 3.1 Criteria API) |
| * <p> |
| * <b>Description</b>: |
| * Provides access to the metamodel of persistent |
| * Entities, MappedSuperclasses, Embeddables, ManagedTypes and Types in the persistence unit. |
| * Note: Since the types Map is lazy-loaded with key:value pairs - the designer and especially the user |
| * must realized that a particular BasicType may not be in the Map until it is referenced. |
| * |
| * @see jakarta.persistence.metamodel.Metamodel |
| * |
| * @since EclipseLink 1.2 - JPA 2.0 |
| * |
| */ |
| public class MetamodelImpl implements Metamodel, Serializable { |
| |
| /** Item 54: DI 89: explicit UID will avoid performance hit runtime generation of one */ |
| private static final long serialVersionUID = -7352420189248464690L; |
| |
| /** The EclipseLink Session associated with this Metamodel implementation that contains all our descriptors with mappings **/ |
| private AbstractSession session; |
| |
| /** The Map of entities in this metamodel keyed on Class **/ |
| private Map<String, EntityTypeImpl<?>> entities; |
| |
| /** The Map of embeddables in this metamodel keyed on Class **/ |
| private Map<String, EmbeddableTypeImpl<?>> embeddables; |
| |
| /** The Map of managed types (Entity, Embeddable and MappedSuperclass) in this metamodel keyed on Class **/ |
| private Map<String, ManagedTypeImpl<?>> managedTypes; |
| |
| /** The Map of types (Entity, Embeddable, MappedSuperclass and Basic - essentially Basic + managedTypes) in this metamodel keyed on Class **/ |
| private Map<String, TypeImpl<?>> types; |
| |
| /** The Set of MappedSuperclassTypes in this metamodel**/ |
| private Set<MappedSuperclassTypeImpl<?>> mappedSuperclasses; |
| |
| /** maintains initialization state to avoid extra work in calls to initialize **/ |
| private boolean isInitialized = false; |
| |
| /** Default elementType Class when we the type cannot be determined for unsupported mappings such as Transformation and VariableOneToOne */ |
| public static final Class<Object> DEFAULT_ELEMENT_TYPE_FOR_UNSUPPORTED_MAPPINGS = Object.class; |
| |
| public MetamodelImpl(AbstractSession session) { |
| this.session = session; |
| preInitialize(); |
| } |
| |
| public MetamodelImpl(EntityManager em) { |
| // Create a new Metamodel using the EclipseLink session on the EM |
| this(JpaHelper.getEntityManager(em).getAbstractSession()); |
| } |
| |
| public MetamodelImpl(EntityManagerFactory emf) { |
| // Create a new Metamodel using the EclipseLink session on the EMF |
| this(((AbstractSession)JpaHelper.getDatabaseSession(emf))); |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public MetamodelImpl(EntityManagerSetupImpl emSetupImpl) { |
| // Create a new Metamodel using the EclipseLink session on the EM |
| this(emSetupImpl.getSession()); |
| } |
| |
| /** |
| * Return the metamodel embeddable type representing the |
| * embeddable class. |
| * @param clazz the type of the represented embeddable class |
| * @return the metamodel embeddable type |
| * @throws IllegalArgumentException if not an embeddable class |
| */ |
| @Override |
| public <X> EmbeddableType<X> embeddable(Class<X> clazz) { |
| String key = clazz == null ? null : clazz.getName(); |
| EmbeddableTypeImpl<?> aType = this.embeddables.get(key); |
| if(aType == null) { |
| entityEmbeddableManagedTypeNotFound(embeddables, null, clazz, "Embeddable", "EmbeddableType"); |
| } |
| return (EmbeddableType<X>) aType; |
| } |
| |
| /** |
| * INTERNAL: |
| * This function will warn the user and/or throw an IllegalArgumentException if the type is not found in the metamodel. |
| * There is a chance that the entire metamodel is empty because the model was not found during entity search. This is |
| * usually due to the case where an expected managed persistence unit in a Java EE environment is actually processed as a |
| * Java SE (unmanaged) persistence unit. |
| * This may occur on certain configurations of Spring or on Java EE 6 Web Profile implementations that are not in compliance |
| * with the specification. |
| * See http://bugs.eclipse.org/338837 |
| */ |
| private void entityEmbeddableManagedTypeNotFound(Map typeMap, Object aType, Class clazz, String metamodelType, String metamodelTypeName) { |
| // 338837: verify that the collection is not empty - this would mean entities did not make it into the search path |
| if(typeMap.isEmpty()) { |
| AbstractSessionLog.getLog().log(SessionLog.WARNING, SessionLog.METAMODEL, "metamodel_type_collection_empty_during_lookup", clazz, metamodelTypeName); |
| } |
| // A null type will mean either the metamodel type does not exist because it was not found/processed, or the clazz is not part of the model |
| if(null == clazz) { |
| throw new IllegalArgumentException(ExceptionLocalization.buildMessage( |
| "metamodel_class_null_type_instance_for_null_key", |
| new Object[] { metamodelTypeName, metamodelType})); |
| } else { |
| if(null == aType) { |
| throw new IllegalArgumentException(ExceptionLocalization.buildMessage( |
| "metamodel_class_null_type_instance", |
| new Object[] { clazz.getCanonicalName(), metamodelTypeName, metamodelType})); |
| } else { |
| throw new IllegalArgumentException(ExceptionLocalization.buildMessage( |
| "metamodel_class_incorrect_type_instance", |
| new Object[] { clazz, metamodelTypeName, aType})); |
| } |
| } |
| } |
| |
| /** |
| * Return the metamodel entity type representing the entity. |
| * @param clazz the type of the represented entity |
| * @return the metamodel entity type |
| * @throws IllegalArgumentException if not an entity |
| */ |
| @Override |
| public <X> EntityType<X> entity(Class<X> clazz) { |
| String key = clazz == null ? null : clazz.getName(); |
| EntityTypeImpl<?> aType = this.entities.get(key); |
| if(aType == null) { |
| entityEmbeddableManagedTypeNotFound(entities, null, clazz, "Entity", "EntityType"); |
| } |
| return (EntityType<X>) aType; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return a List of all attributes for all ManagedTypes. |
| */ |
| public List<Attribute> getAllManagedTypeAttributes() { |
| List<Attribute> attributeList = new ArrayList<Attribute>(); |
| for(ManagedType managedType : this.managedTypes.values()) { |
| attributeList.addAll(managedType.getAttributes()); |
| } |
| return attributeList; |
| } |
| |
| /** |
| * Return the metamodel embeddable types. |
| * @return the metamodel embeddable types |
| */ |
| @Override |
| public Set<EmbeddableType<?>> getEmbeddables() { |
| return new LinkedHashSet<EmbeddableType<?>>(this.embeddables.values()); |
| } |
| |
| /** |
| * Return the metamodel entity types. |
| * @return the metamodel entity types |
| */ |
| @Override |
| public Set<EntityType<?>> getEntities() { |
| return new LinkedHashSet<EntityType<?>>(this.entities.values()); |
| } |
| |
| /** |
| * Return the metamodel managed types map. |
| */ |
| public Map<String, ManagedTypeImpl<?>> getManagedTypesMap() { |
| return this.managedTypes; |
| } |
| |
| /** |
| * Return the metamodel managed types. |
| * @return the metamodel managed types |
| */ |
| @Override |
| public Set<ManagedType<?>> getManagedTypes() { |
| return new LinkedHashSet<ManagedType<?>>(this.managedTypes.values()); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the Set of MappedSuperclassType objects |
| */ |
| public Set<MappedSuperclassTypeImpl<?>> getMappedSuperclasses() { |
| return new LinkedHashSet<MappedSuperclassTypeImpl<?>>(this.mappedSuperclasses); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the core API Project associated with the DatabaseSession |
| * that is associated with this Metamodel |
| */ |
| public Project getProject() { |
| return this.getSession().getProject(); |
| } |
| /** |
| * INTERNAL: |
| * Return the DatabaseSession associated with this Metamodel |
| */ |
| protected AbstractSession getSession() { |
| return this.session; |
| } |
| |
| /** |
| * INTERNAL: |
| * This function is a wrapper around a Map.put(K,V)<br> |
| * We return a boolean that is unused but provides a way to add a |
| * breakpoint for the false condition. |
| */ |
| private boolean putType(String javaClassKey, TypeImpl typeValue) { |
| boolean isValid = true; |
| // DI99: Check for an invalid key without reporting it (a non-Fail-Fast pattern) |
| if(null == javaClassKey) { |
| // Use Case: doing an emf.getCriteriaBuilder() before an EM has been created |
| isValid = false; |
| } |
| this.types.put(javaClassKey, typeValue); |
| return isValid; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return a Type representation of a java Class for use by the Metamodel Attributes.<p> |
| * If a type does not yet exist - one will be created and added to the Metamodel - this usually only for Basic types.<p> |
| * This function will handle all Metamodel defined and core java classes. |
| * |
| */ |
| public <X> TypeImpl<X> getType(Class<X> javaClass) { |
| // Return an existing matching type on the metamodel keyed on class name |
| String key = javaClass == null ? null : javaClass.getName(); |
| TypeImpl type = this.types.get(key); |
| // the type was not cached yet on the metamodel - lets add it - usually a non Metamodel class like Integer |
| if (null == type) { |
| // make types field modification thread-safe |
| synchronized (this.types) { |
| // check for a cached type right after we synchronize |
| type = this.types.get(key); |
| // If a type is not found (not created during metamodel.initialize() - it is usually a Basic type |
| if(null == type) { |
| type = new BasicTypeImpl<X>(javaClass); |
| // add the type to the types map keyed on Java class |
| putType(key, type); |
| } |
| } // synchronized end |
| } |
| return type; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the Map of types on this metamodel. |
| * This includes all Entity, MappedSuperclass, Embeddable and Basic types |
| */ |
| public Map<String, TypeImpl<?>> getTypes() { |
| return types; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return whether there is a descriptor that is keyed by the supplied class name.<p> |
| * Referenced by ManagedTypeImpl.create() |
| */ |
| protected boolean hasMappedSuperclass(String qualifiedClassNameKeyString) { |
| /** |
| * This function is used before the metamodel has populated its Set of mappedSuperclasses - |
| * therefore we go directly to the descriptor source. |
| * Normally this functionality would be placed on the (core) Project class, however |
| * this would create a JPA dependency in Core when we try to use MetadataClass functionality there. |
| */ |
| return this.getSession().getProject().hasMappedSuperclass(qualifiedClassNameKeyString); |
| } |
| |
| public boolean isInitialized() { |
| return isInitialized; |
| } |
| |
| /** |
| * INTERNAL: |
| * First phase of metamodel intialization. Builds a list of the classes in the metamodel and |
| * stores them in appropriate lists indexed by the classname. We index by classname to avoid having |
| * to load classes at this phase of initialization |
| */ |
| private void preInitialize(){ |
| // Design Note: Use LinkedHashMap and LinkedHashSet to preserve ordering |
| this.types = new LinkedHashMap<String, TypeImpl<?>>(); |
| this.entities = new LinkedHashMap<String, EntityTypeImpl<?>>(); |
| this.embeddables = new LinkedHashMap<String, EmbeddableTypeImpl<?>>(); |
| this.managedTypes = new LinkedHashMap<String, ManagedTypeImpl<?>>(); |
| this.mappedSuperclasses = new LinkedHashSet<MappedSuperclassTypeImpl<?>>(); |
| |
| // Process all Entity and Embeddable types (MappedSuperclasses are handled later) |
| for (ClassDescriptor descriptor : this.getSession().getProject().getOrderedDescriptors()) { |
| // The ClassDescriptor is always of type RelationalDescriptor - the cast is safe |
| ManagedTypeImpl<?> managedType = ManagedTypeImpl.create(this, descriptor); |
| String descriptorJavaType = managedType.getJavaTypeName(); |
| if(null == descriptorJavaType) { |
| AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_relationaldescriptor_javaclass_null_on_managedType", descriptor, managedType); |
| } |
| putType(descriptorJavaType, managedType); |
| this.managedTypes.put(descriptorJavaType, managedType); |
| |
| if (managedType.getPersistenceType().equals(PersistenceType.ENTITY)) { |
| this.entities.put(descriptorJavaType, (EntityTypeImpl<?>) managedType); |
| } |
| if (managedType.getPersistenceType().equals(PersistenceType.EMBEDDABLE)) { |
| this.embeddables.put(descriptorJavaType, (EmbeddableTypeImpl<?>) managedType); |
| } |
| |
| // Process all Basic Types |
| // Iterate by typeName |
| // see |
| // http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_54:_20090803:_Metamodel.type.28Clazz.29_should_differentiate_between_null_and_BasicType |
| } |
| |
| // Future: verify that all entities or'd with embeddables matches the number of types |
| |
| // Handle all MAPPED_SUPERCLASS types |
| // Get mapped superclass types (separate from descriptors on the session from the native project (not a regular descriptor) |
| for (ClassDescriptor descriptor : this.getSession().getProject().getMappedSuperclassDescriptors().values()) { |
| MappedSuperclassTypeImpl<?> mappedSuperclassType = (MappedSuperclassTypeImpl)ManagedTypeImpl.create(this, descriptor); |
| |
| // Add the MappedSuperclass to our Set of MappedSuperclasses |
| this.mappedSuperclasses.add(mappedSuperclassType); |
| |
| String descriptorJavaType = mappedSuperclassType.getJavaTypeName(); |
| if(null == descriptorJavaType) { |
| AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_relationaldescriptor_javaclass_null_on_managedType", |
| descriptor, mappedSuperclassType); |
| } |
| |
| // Add this MappedSuperclass to the Collection of Types |
| putType(descriptorJavaType, mappedSuperclassType); |
| // Add the MappedSuperclass to the Map of ManagedTypes |
| // So we can find hierarchies of the form [Entity --> MappedSuperclass(abstract) --> Entity] |
| this.managedTypes.put(descriptorJavaType, mappedSuperclassType); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * |
| * Initialize the JPA metamodel that wraps the EclipseLink JPA metadata created descriptors.<br> |
| * Note: Since the types Map is lazy-loaded with key:value pairs - the designer and especially the user |
| * must realized that a particular BasicType may not be in the Map until it is referenced. |
| * |
| * Also note that a transient superclass (non-entity, non-mappedSuperclass) |
| * exists as a BasicType (it has no attributes), and that any inheriting Entity either |
| * directly subclassing or indirectly subclassing via a MappedSuperclass inheritance chain |
| * - does not pick up non-persistence fields that normally would be inherited. |
| * (The fields exist in Java but not in ORM:Metamodel) |
| * The transient class will have no JPA annotations. |
| * |
| * This is the second phase of metamodel initialization. It causes preindexed classes to have their |
| * attributes populated. |
| */ |
| public void initialize(ClassLoader classLoader) { |
| |
| // Handle all IdentifiableTypes (after all ManagedTypes have been created) |
| // Assign all superType fields on all IdentifiableTypes (only after all managedType objects have been created) |
| for(ManagedTypeImpl<?> potentialIdentifiableType : managedTypes.values()) { |
| Class<?> aClass = potentialIdentifiableType.getJavaType(classLoader); |
| /** |
| * The superclass for top-level types is Object - however we set [null] as the supertype for root types. |
| * 1) We are constrained by the fact that the spec requires that a superType be an IdentifiableType. |
| * Since [Object] is not an Entity or MappedSuperclass - it fails this criteria - as it would be a BasicType |
| * because it has no @Entity or @MappedSuperclass annotation.<p> |
| * 2) Another object space reasoning issue behind this is to separate the Java and Metamodel object spaces. |
| * In Java all types inherit from Object, however in the JPA Metamodel all types DO NOT inherit from a common type. |
| * Therefore in the metamodel top-level root types have a superType of null. |
| * See design issue discussion: |
| * http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_42:_20090709:_IdentifiableType.supertype_-_what_do_top-level_types_set_it_to |
| */ |
| // 303063: secondary check for a null javaType (metadata processing should never allow this to happen - however we must handle it here in case |
| // http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_101:_20100218:_Descriptor.javaClass_is_null_on_a_container_EM_for_a_specific_case |
| if(null == aClass) { |
| AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_itentifiableType_javaclass_null_cannot_set_supertype", |
| potentialIdentifiableType.getDescriptor(), this); |
| } else { |
| Class superclass = aClass.getSuperclass(); |
| // explicitly set the superType to null (just in case it is initialized to a non-null value in a constructor) |
| IdentifiableType<?> identifiableTypeSuperclass = null; |
| if(potentialIdentifiableType.isIdentifiableType() && (superclass != ClassConstants.OBJECT && superclass != null)) { |
| // Get the Entity or MappedSuperclass |
| // A hierarchy of Entity --> Entity or Entity --> MappedSuperclass will be found |
| identifiableTypeSuperclass = (IdentifiableType<?>)managedTypes.get(superclass.getName()); |
| // If there is no superclass (besides Object for a top level identifiable type) then keep the supertype set to null |
| // See design issue #42 - we return Object for top-level types (with no superclass) and null if the supertype was not set |
| // http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_42:_20090709:_IdentifiableType.supertype_-_what_do_top-level_types_set_it_to |
| ((IdentifiableTypeImpl)potentialIdentifiableType).setSupertype(identifiableTypeSuperclass); |
| // set back pointer if mappedSuperclass |
| if(null != identifiableTypeSuperclass && ((IdentifiableTypeImpl)identifiableTypeSuperclass).isMappedSuperclass()) { |
| ((MappedSuperclassTypeImpl)identifiableTypeSuperclass).addInheritingType(((IdentifiableTypeImpl)potentialIdentifiableType)); |
| } |
| ((IdentifiableTypeImpl)potentialIdentifiableType).setSupertype(identifiableTypeSuperclass); |
| } |
| } |
| } |
| |
| //1 - process all non-mappedSuperclass types first so we pick up attribute types |
| //2 - process mappedSuperclass types and lookup collection attribute types on inheriting entity types when field is not set |
| |
| /** |
| * Delayed-Initialization (process all mappings) of all Managed types |
| * (This includes all IdentifiableTypes = Entity and MappedSuperclass types). |
| * To avoid a ConcurrentModificationException on the types map, iterate a list instead of the Map values directly. |
| * The following code section may add BasicTypes to the types map. |
| */ |
| for(ManagedTypeImpl<?> managedType : new ArrayList<ManagedTypeImpl<?>>(managedTypes.values())) { |
| managedType.initialize(); |
| } |
| |
| // 3 - process all the Id attributes on each IdentifiableType |
| for(ManagedTypeImpl<?> potentialIdentifiableType : managedTypes.values()) { |
| if(potentialIdentifiableType.isIdentifiableType()) { |
| ((IdentifiableTypeImpl<?>)potentialIdentifiableType).initializeIdAttributes(); |
| } |
| } |
| |
| // 338837: verify that the collections are not empty - this would mean entities did not make it into the search path |
| if((null == this.embeddables || this.embeddables.isEmpty()) && |
| (null == this.managedTypes || this.managedTypes.isEmpty()) && |
| (null == this.entities || this.entities.isEmpty())) { |
| AbstractSessionLog.getLog().log(SessionLog.WARNING, SessionLog.METAMODEL, "metamodel_type_collection_empty", null, true); |
| } |
| isInitialized = true; |
| } |
| |
| /** |
| * Return the metamodel managed type representing the |
| * entity, mapped superclass, or embeddable class. |
| * @param clazz the type of the represented managed class |
| * @return the metamodel managed type |
| * @throws IllegalArgumentException if not a managed class |
| */ |
| @Override |
| public <X> ManagedType<X> managedType(Class<X> clazz) { |
| String key = clazz == null ? null : clazz.getName(); |
| ManagedTypeImpl<?> aType = this.managedTypes.get(key); |
| // Throw an IAE exception if the returned type is not a ManagedType |
| // For any clazz that resolves to a BasicType - use getType(clazz) in implementations when you are expecting a BasicType |
| if (aType == null) { |
| entityEmbeddableManagedTypeNotFound(managedTypes, null, clazz, "Managed", "ManagedType"); |
| } |
| return (ManagedType<X>) aType; |
| } |
| |
| /** |
| * INTERNAL: |
| * Print out all the Type attributes in the Metamodel |
| */ |
| public void printAllTypes() { |
| if ((null == types) || types.isEmpty()) { |
| // 338837: verify that the collection is not empty - this would mean entities did not make it into the search path |
| AbstractSessionLog.getLog().log(SessionLog.WARNING, SessionLog.METAMODEL, "metamodel_type_collection_empty", null, true); |
| } else { |
| this.session.log(SessionLog.INFO, SessionLog.METAMODEL, "metamodel_print_type_header",this.types.size()); |
| for (Type aType : this.types.values()) { |
| this.session.log(SessionLog.INFO, SessionLog.METAMODEL, "metamodel_print_type_value",aType); |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the string representation of the receiver. |
| */ |
| @Override |
| public String toString() { |
| StringBuffer aBuffer = new StringBuffer(); |
| aBuffer.append(this.getClass().getSimpleName()); |
| aBuffer.append("@"); |
| aBuffer.append(hashCode()); |
| aBuffer.append(" ["); |
| if(null != this.types) { |
| aBuffer.append(" "); |
| aBuffer.append(this.types.size()); |
| aBuffer.append(" Types: "); |
| //aBuffer.append(this.types.keySet()); |
| } |
| if(null != this.managedTypes) { |
| aBuffer.append(", "); |
| aBuffer.append(this.managedTypes.size()); |
| aBuffer.append(" ManagedTypes: "); |
| //aBuffer.append(this.managedTypes.keySet()); |
| } |
| if(null != this.entities) { |
| aBuffer.append(", "); |
| aBuffer.append(this.entities.size()); |
| aBuffer.append(" EntityTypes: "); |
| //aBuffer.append(this.entities.keySet()); |
| } |
| if(null != this.mappedSuperclasses) { |
| aBuffer.append(", "); |
| aBuffer.append(this.mappedSuperclasses.size()); |
| aBuffer.append(" MappedSuperclassTypes: "); |
| //aBuffer.append(this.mappedSuperclasses); |
| } |
| if(null != this.embeddables) { |
| aBuffer.append(", "); |
| aBuffer.append(this.embeddables.size()); |
| aBuffer.append(" EmbeddableTypes: "); |
| //aBuffer.append(this.embeddables.keySet()); |
| } |
| aBuffer.append("]"); |
| return aBuffer.toString(); |
| } |
| } |