From c4c8c28a3b4eac6c9f63b120dce4bf9083196e42 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 11 Jul 2011 00:33:39 -0500 Subject: [PATCH] HHH-6371 - Develop metamodel binding creation using a push approach --- .../internal/util/beans/BeanInfoHelper.java | 10 + .../org/hibernate/metamodel/Metadata.java | 2 + .../binder/source/BindingContext.java | 4 +- .../binder/source/MetadataImplementor.java | 2 - .../AnnotationsMetadataProcessor.java | 4 +- .../AnnotationsSourceProcessor.java | 20 +- .../annotations/entity/EntityBinder.java | 14 +- .../hbm/AbstractSubEntityContainer.java | 48 ++ .../binder/source/hbm/BindingCreator.java | 657 ++++++++++++++++-- .../binder/source/hbm/EntityHierarchy.java | 64 ++ .../source/hbm/EntityHierarchySubEntity.java | 43 ++ .../source/hbm/EntitySourceInformation.java | 55 ++ .../source/hbm/HbmSourceProcessorImpl.java | 158 +---- .../metamodel/binder/source/hbm/Helper.java | 22 + .../source/hbm/HibernateMappingProcessor.java | 216 ++---- .../binder/source/hbm/HierarchyBuilder.java | 175 +++++ .../binder/source/hbm/MappingDocument.java | 154 ++++ .../binder/source/hbm/SubEntityContainer.java | 35 + .../source/hbm/xml/mapping/EntityElement.java | 3 + .../hbm/xml/mapping/JoinElementSource.java | 35 + ...tityElement.java => SubEntityElement.java} | 2 +- .../binder/source/internal/MetadataImpl.java | 18 +- .../binding/AbstractAttributeBinding.java | 19 +- .../metamodel/binding/AttributeBinding.java | 5 +- .../binding/HibernateTypeDescriptor.java | 3 - .../binding/SimpleAttributeBinding.java | 54 +- .../domain/AbstractAttributeContainer.java | 22 +- .../metamodel/domain/AttributeContainer.java | 32 +- .../AbstractTableSpecification.java | 8 +- .../relational/TableSpecification.java | 4 +- .../relational/state/ValueCreator.java | 58 +- .../src/main/xjb/hbm-mapping-bindings.xjb | 8 +- .../binding/SimpleValueBindingTests.java | 5 +- .../relational/TableManipulationTests.java | 10 +- .../TestAnnotationsBindingContextImpl.java | 4 +- 35 files changed, 1474 insertions(+), 499 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/AbstractSubEntityContainer.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntityHierarchy.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntityHierarchySubEntity.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntitySourceInformation.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HierarchyBuilder.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/MappingDocument.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/SubEntityContainer.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/JoinElementSource.java rename hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/{SubclassEntityElement.java => SubEntityElement.java} (94%) diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/beans/BeanInfoHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/util/beans/BeanInfoHelper.java index 4687e8c511..335a088ab1 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/beans/BeanInfoHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/beans/BeanInfoHelper.java @@ -54,6 +54,14 @@ public class BeanInfoHelper { throw new BeanIntrospectionException( "Bean [" + bean + "] was not of declared bean type [" + beanClass.getName() + "]" ); } + visitBeanInfo( beanClass, stopClass, delegate ); + } + + public static void visitBeanInfo(Class beanClass, BeanInfoDelegate delegate) { + visitBeanInfo( beanClass, Object.class, delegate ); + } + + public static void visitBeanInfo(Class beanClass, Class stopClass, BeanInfoDelegate delegate) { try { BeanInfo info = Introspector.getBeanInfo( beanClass, stopClass ); try { @@ -76,4 +84,6 @@ public class BeanInfoHelper { throw new BeanIntrospectionException( "Unable to determine bean info from class [" + beanClass.getName() + "]", e ); } } + + } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java index cd3f5acc2d..4584e228e3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/Metadata.java @@ -76,6 +76,8 @@ public interface Metadata { public Iterable getCollectionBindings(); + public TypeDef getTypeDefinition(String name); + public Iterable getTypeDefinitions(); public Iterable getFilterDefinitions(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/BindingContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/BindingContext.java index 7c23c5b254..fac913abe5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/BindingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/BindingContext.java @@ -25,7 +25,7 @@ package org.hibernate.metamodel.binder.source; import org.hibernate.cfg.NamingStrategy; import org.hibernate.internal.util.Value; -import org.hibernate.metamodel.domain.JavaType; +import org.hibernate.metamodel.domain.Type; import org.hibernate.service.ServiceRegistry; /** @@ -42,7 +42,7 @@ public interface BindingContext { public Class locateClassByName(String name); - public JavaType makeJavaType(String className); + public Type makeJavaType(String className); public boolean isGloballyQuotedIdentifiers(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/MetadataImplementor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/MetadataImplementor.java index 666c098548..6e35d0b826 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/MetadataImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/MetadataImplementor.java @@ -71,8 +71,6 @@ public interface MetadataImplementor extends Metadata, BindingContext, Mapping { public void addResultSetMapping(ResultSetMappingDefinition resultSetMappingDefinition); - public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject); - // todo : this needs to move to AnnotationBindingContext public void setGloballyQuotedIdentifiers(boolean b); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/AnnotationsMetadataProcessor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/AnnotationsMetadataProcessor.java index e3569df968..f5039cf2e2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/AnnotationsMetadataProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/AnnotationsMetadataProcessor.java @@ -36,7 +36,7 @@ import org.hibernate.metamodel.binder.source.MetadataImplementor; import org.hibernate.metamodel.binder.source.annotations.entity.ConfiguredClass; import org.hibernate.metamodel.binder.source.annotations.entity.EntityBinder; import org.hibernate.metamodel.binder.source.internal.OverriddenMappingDefaults; -import org.hibernate.metamodel.domain.JavaType; +import org.hibernate.metamodel.domain.Type; import org.hibernate.service.ServiceRegistry; /** @@ -120,7 +120,7 @@ public class AnnotationsMetadataProcessor implements AnnotationsBindingContext { } @Override - public JavaType makeJavaType(String className) { + public Type makeJavaType(String className) { return parentBindingContext.makeJavaType( className ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/AnnotationsSourceProcessor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/AnnotationsSourceProcessor.java index 849870a737..4c2e5e926e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/AnnotationsSourceProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/AnnotationsSourceProcessor.java @@ -63,7 +63,7 @@ import org.hibernate.metamodel.binder.source.internal.JaxbRoot; import org.hibernate.metamodel.binder.source.internal.MetadataImpl; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.domain.Hierarchical; -import org.hibernate.metamodel.domain.JavaType; +import org.hibernate.metamodel.domain.Type; import org.hibernate.metamodel.domain.NonEntity; import org.hibernate.metamodel.domain.Superclass; import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings; @@ -270,18 +270,13 @@ public class AnnotationsSourceProcessor implements SourceProcessor, AnnotationsB return classLoaderService.getValue().classForName( name ); } - @Override - public boolean isGloballyQuotedIdentifiers() { - return metadata.isGloballyQuotedIdentifiers(); - } - - private Map nameToJavaTypeMap = new HashMap(); + private Map nameToJavaTypeMap = new HashMap(); @Override - public JavaType makeJavaType(String className) { - JavaType javaType = nameToJavaTypeMap.get( className ); + public Type makeJavaType(String className) { + Type javaType = nameToJavaTypeMap.get( className ); if ( javaType == null ) { - javaType = new JavaType( locateClassByName( className ) ); + javaType = metadata.makeJavaType( className ); nameToJavaTypeMap.put( className, javaType ); } return javaType; @@ -291,6 +286,11 @@ public class AnnotationsSourceProcessor implements SourceProcessor, AnnotationsB public Value> makeClassReference(String className) { return new Value>( locateClassByName( className ) ); } + + @Override + public boolean isGloballyQuotedIdentifiers() { + return metadata.isGloballyQuotedIdentifiers(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/entity/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/entity/EntityBinder.java index 1e59bec1d0..93d1762859 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/entity/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/annotations/entity/EntityBinder.java @@ -585,7 +585,7 @@ public class EntityBinder { //todo throw exception? } for ( String columnName : columnNames ) { - uniqueKey.addColumn( table.getOrCreateColumn( columnName ) ); + uniqueKey.addColumn( table.locateOrCreateColumn( columnName ) ); } } } @@ -620,8 +620,7 @@ public class EntityBinder { throw new AssertionFailure( "Unexpected attribute type for id attribute" ); } - SingularAttribute attribute = entityBinding.getEntity().getOrCreateComponentAttribute( idName ); - + SingularAttribute attribute = entityBinding.getEntity().locateOrCreateComponentAttribute( idName ); SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleIdAttributeBinding( attribute ); @@ -669,7 +668,7 @@ public class EntityBinder { // now that we have the id attribute we can create the attribute and binding MappedAttribute idAttribute = iter.next(); - Attribute attribute = container.getOrCreateSingularAttribute( idAttribute.getName() ); + Attribute attribute = container.locateOrCreateSingularAttribute( idAttribute.getName() ); SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleIdAttributeBinding( attribute ); attributeBinding.initialize( new AttributeBindingStateImpl( (SimpleAttribute) idAttribute ) ); @@ -821,7 +820,7 @@ public class EntityBinder { for ( Map.Entry entry : configuredClass.getEmbeddedClasses().entrySet() ) { String attributeName = entry.getKey(); EmbeddableClass embeddedClass = entry.getValue(); - SingularAttribute component = attributeContainer.getOrCreateComponentAttribute( attributeName ); + SingularAttribute component = attributeContainer.locateOrCreateComponentAttribute( attributeName ); for ( SimpleAttribute simpleAttribute : embeddedClass.getSimpleAttributes() ) { bindSingleMappedAttribute( entityBinding, @@ -845,7 +844,7 @@ public class EntityBinder { AssociationAttribute associationAttribute) { switch ( associationAttribute.getAssociationType() ) { case MANY_TO_ONE: { - container.getOrCreateSingularAttribute( associationAttribute.getName() ); + entityBinding.getEntity().locateOrCreateSingularAttribute( associationAttribute.getName() ); ManyToOneAttributeBinding manyToOneAttributeBinding = entityBinding.makeManyToOneAttributeBinding( associationAttribute.getName() ); @@ -877,7 +876,8 @@ public class EntityBinder { return; } - Attribute attribute = container.getOrCreateSingularAttribute( simpleAttribute.getName() ); + String attributeName = simpleAttribute.getName(); + SingularAttribute attribute = entityBinding.getEntity().locateOrCreateSingularAttribute( attributeName ); SimpleAttributeBinding attributeBinding; if ( simpleAttribute.isDiscriminator() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/AbstractSubEntityContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/AbstractSubEntityContainer.java new file mode 100644 index 0000000000..e299e72e4a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/AbstractSubEntityContainer.java @@ -0,0 +1,48 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binder.source.hbm; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Steve Ebersole + */ +public class AbstractSubEntityContainer implements SubEntityContainer { + private List subEntityDescriptors; + + public void addSubEntityDescriptor(EntityHierarchySubEntity subEntityDescriptor) { + if ( subEntityDescriptors == null ) { + subEntityDescriptors = new ArrayList(); + } + subEntityDescriptors.add( subEntityDescriptor ); + } + + public Iterable subEntityDescriptors() { + return subEntityDescriptors == null + ? Collections.emptyList() + : subEntityDescriptors; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/BindingCreator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/BindingCreator.java index 2148e1172c..b3bfb13913 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/BindingCreator.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/BindingCreator.java @@ -23,23 +23,59 @@ */ package org.hibernate.metamodel.binder.source.hbm; +import java.beans.BeanInfo; +import java.beans.PropertyDescriptor; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Stack; import org.hibernate.EntityMode; import org.hibernate.cache.spi.access.AccessType; +import org.hibernate.cfg.NamingStrategy; import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.internal.util.Value; +import org.hibernate.internal.util.beans.BeanInfoHelper; +import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.binder.MappingException; +import org.hibernate.metamodel.binder.source.MetadataImplementor; import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement; -import org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement; +import org.hibernate.metamodel.binder.source.hbm.xml.mapping.JoinElementSource; +import org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement; +import org.hibernate.metamodel.binding.BagBinding; import org.hibernate.metamodel.binding.Caching; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.InheritanceType; +import org.hibernate.metamodel.binding.SimpleAttributeBinding; +import org.hibernate.metamodel.binding.TypeDef; +import org.hibernate.metamodel.domain.AbstractAttributeContainer; +import org.hibernate.metamodel.domain.Attribute; import org.hibernate.metamodel.domain.Entity; +import org.hibernate.metamodel.relational.Column; +import org.hibernate.metamodel.relational.Identifier; +import org.hibernate.metamodel.relational.Schema; +import org.hibernate.metamodel.relational.SimpleValue; +import org.hibernate.metamodel.relational.Size; +import org.hibernate.metamodel.relational.TableSpecification; +import org.hibernate.metamodel.relational.Tuple; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLAnyElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLBagElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLCacheElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLColumnElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLComponentElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLDynamicComponentElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLIdbagElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinedSubclassElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLListElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLManyToOneElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLMapElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLOneToOneElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLParamElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLPropertiesElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLPropertyElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSetElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlDeleteElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlInsertElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlUpdateElement; @@ -54,72 +90,96 @@ import org.hibernate.tuple.entity.EntityTuplizer; * @author Steve Ebersole */ public class BindingCreator { - private final HbmBindingContext bindingContext; + private final MetadataImplementor metadata; private final List processedEntityNames; - public BindingCreator(HbmBindingContext bindingContext, List processedEntityNames) { - this.bindingContext = bindingContext; + private InheritanceType currentInheritanceType; + private HbmBindingContext currentBindingContext; + + public BindingCreator(MetadataImplementor metadata, List processedEntityNames) { + this.metadata = metadata; this.processedEntityNames = processedEntityNames; } - public EntityBinding createEntityBinding(EntityElement entityElement, String containingSuperEntityName) { - final String entityName = bindingContext.determineEntityName( entityElement ); - if ( processedEntityNames.contains( entityName ) ) { - return bindingContext.getMetadataImplementor().getEntityBinding( entityName ); + // todo : currently this does not allow inheritance across hbm/annotations. Do we need to? + + public void processEntityHierarchy(EntityHierarchy entityHierarchy) { + currentInheritanceType = entityHierarchy.getHierarchyInheritanceType(); + EntityBinding rootEntityBinding = createEntityBinding( entityHierarchy.getEntitySourceInformation(), null ); + if ( currentInheritanceType != InheritanceType.NO_INHERITANCE ) { + processHierarchySubEntities( entityHierarchy, rootEntityBinding ); + } + } + + private void processHierarchySubEntities(SubEntityContainer subEntityContainer, EntityBinding superEntityBinding) { + for ( EntityHierarchySubEntity subEntity : subEntityContainer.subEntityDescriptors() ) { + EntityBinding entityBinding = createEntityBinding( subEntity.getEntitySourceInformation(), superEntityBinding ); + processHierarchySubEntities( subEntity, entityBinding ); + } + } + + private EntityBinding createEntityBinding(EntitySourceInformation entitySourceInfo, EntityBinding superEntityBinding) { + if ( processedEntityNames.contains( entitySourceInfo.getMappedEntityName() ) ) { + return metadata.getEntityBinding( entitySourceInfo.getMappedEntityName() ); } - final EntityBinding entityBinding = doEntityBindingCreation( entityElement, containingSuperEntityName ); + currentBindingContext = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext(); + try { + final EntityBinding entityBinding = doCreateEntityBinding( entitySourceInfo, superEntityBinding ); + + metadata.addEntity( entityBinding ); + processedEntityNames.add( entityBinding.getEntity().getName() ); + return entityBinding; + } + finally { + currentBindingContext = null; + } + } + + private EntityBinding doCreateEntityBinding(EntitySourceInformation entitySourceInfo, EntityBinding superEntityBinding) { + final EntityBinding entityBinding = createBasicEntityBinding( entitySourceInfo, superEntityBinding ); + + bindPrimaryTable( entitySourceInfo, entityBinding ); + bindAttributes( entitySourceInfo, entityBinding ); + bindSecondaryTables( entitySourceInfo, entityBinding ); + bindTableUniqueConstraints( entityBinding ); - bindingContext.getMetadataImplementor().addEntity( entityBinding ); - processedEntityNames.add( entityBinding.getEntity().getName() ); return entityBinding; } - private EntityBinding doEntityBindingCreation(EntityElement entityElement, String containingSuperEntityName) { - if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) { - return makeEntityBinding( (XMLHibernateMapping.XMLClass) entityElement ); + private EntityBinding createBasicEntityBinding( + EntitySourceInformation entitySourceInfo, + EntityBinding superEntityBinding) { + if ( superEntityBinding == null ) { + return makeRootEntityBinding( entitySourceInfo ); } else { - String superEntityName = containingSuperEntityName; - if ( superEntityName == null ) { - final SubclassEntityElement subclass = (SubclassEntityElement) entityElement; - superEntityName = bindingContext.qualifyClassName( subclass.getExtends() ); + if ( currentInheritanceType == InheritanceType.SINGLE_TABLE ) { + return makeDiscriminatedSubclassBinding( entitySourceInfo, superEntityBinding ); } - - if ( superEntityName == null) { - throw new MappingException( - "Encountered inheritance strategy, but no super type found", - bindingContext.getOrigin() - ); + else if ( currentInheritanceType == InheritanceType.JOINED ) { + return makeJoinedSubclassBinding( entitySourceInfo, superEntityBinding ); } - - if ( XMLSubclassElement.class.isInstance( entityElement ) ) { - return makeEntityBinding( (XMLSubclassElement) entityElement, superEntityName ); - } - else if ( XMLJoinedSubclassElement.class.isInstance( entityElement ) ) { - return makeEntityBinding( (XMLJoinedSubclassElement) entityElement, superEntityName ); - } - else if ( XMLUnionSubclassElement.class.isInstance( entityElement ) ) { - return makeEntityBinding( (XMLUnionSubclassElement) entityElement, superEntityName ); + else if ( currentInheritanceType == InheritanceType.TABLE_PER_CLASS ) { + return makeUnionedSubclassBinding( entitySourceInfo, superEntityBinding ); } else { - throw new MappingException( - "unknown type of class or subclass: " + entityElement.getClass().getName(), - bindingContext.getOrigin() - ); + // extreme internal error! + throw new RuntimeException( "Internal condition failure" ); } } } - protected EntityBinding makeEntityBinding(XMLHibernateMapping.XMLClass xmlClass) { + private EntityBinding makeRootEntityBinding(EntitySourceInformation entitySourceInfo) { final EntityBinding entityBinding = new EntityBinding(); // todo : this is actually not correct // the problem is that we need to know whether we have mapped subclasses which happens later // one option would be to simply reset the InheritanceType at that time. - entityBinding.setInheritanceType( InheritanceType.NO_INHERITANCE ); + entityBinding.setInheritanceType( currentInheritanceType ); entityBinding.setRoot( true ); - final String entityName = bindingContext.determineEntityName( xmlClass ); + final XMLHibernateMapping.XMLClass xmlClass = (XMLHibernateMapping.XMLClass) entitySourceInfo.getEntityElement(); + final String entityName = entitySourceInfo.getMappedEntityName(); final String verbatimClassName = xmlClass.getName(); final EntityMode entityMode = verbatimClassName == null ? EntityMode.MAP : EntityMode.POJO; @@ -127,41 +187,37 @@ public class BindingCreator { final String className; if ( entityMode == EntityMode.POJO ) { - className = bindingContext.qualifyClassName( verbatimClassName ); + className = entitySourceInfo.getSourceMappingDocument() + .getMappingLocalBindingContext() + .qualifyClassName( verbatimClassName ); } else { className = null; } - Entity entity = new Entity( entityName, className, bindingContext.makeClassReference( className ), null ); + Entity entity = new Entity( + entityName, + className, + entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext().makeClassReference( className ), + null + ); entityBinding.setEntity( entity ); - performBasicEntityBind( entityBinding, xmlClass ); + performBasicEntityBind( entityBinding, entitySourceInfo ); entityBinding.setMutable( xmlClass.isMutable() ); entityBinding.setExplicitPolymorphism( "explicit".equals( xmlClass.getPolymorphism() ) ); entityBinding.setWhereFilter( xmlClass.getWhere() ); entityBinding.setRowId( xmlClass.getRowid() ); - entityBinding.setOptimisticLockStyle( interpretOptimisticLockStyle( xmlClass ) ); - entityBinding.setCaching( interpretCaching( xmlClass, entityName ) ); + entityBinding.setOptimisticLockStyle( interpretOptimisticLockStyle( entitySourceInfo ) ); + entityBinding.setCaching( interpretCaching( entitySourceInfo ) ); return entityBinding; } - private static Caching interpretCaching(XMLHibernateMapping.XMLClass xmlClass, String entityName) { - final XMLCacheElement cache = xmlClass.getCache(); - if ( cache == null ) { - return null; - } - final String region = cache.getRegion() != null ? cache.getRegion() : entityName; - final AccessType accessType = Enum.valueOf( AccessType.class, cache.getUsage() ); - final boolean cacheLazyProps = !"non-lazy".equals( cache.getInclude() ); - return new Caching( region, accessType, cacheLazyProps ); - } - - private OptimisticLockStyle interpretOptimisticLockStyle(XMLHibernateMapping.XMLClass entityClazz) { + private OptimisticLockStyle interpretOptimisticLockStyle(EntitySourceInformation entitySourceInfo) { final String optimisticLockModeString = Helper.getStringValue( - entityClazz.getOptimisticLock(), + ( (XMLHibernateMapping.XMLClass) entitySourceInfo.getEntityElement() ).getOptimisticLock(), "version" ); try { @@ -170,45 +226,69 @@ public class BindingCreator { catch (Exception e) { throw new MappingException( "Unknown optimistic-lock value : " + optimisticLockModeString, - bindingContext.getOrigin() + entitySourceInfo.getSourceMappingDocument().getOrigin() ); } } - protected EntityBinding makeEntityBinding(XMLSubclassElement subclassElement, String superEntityName) { + private static Caching interpretCaching(EntitySourceInformation entitySourceInfo) { + final XMLCacheElement cache = ( (XMLHibernateMapping.XMLClass) entitySourceInfo.getEntityElement() ).getCache(); + if ( cache == null ) { + return null; + } + final String region = cache.getRegion() != null ? cache.getRegion() : entitySourceInfo.getMappedEntityName(); + final AccessType accessType = Enum.valueOf( AccessType.class, cache.getUsage() ); + final boolean cacheLazyProps = !"non-lazy".equals( cache.getInclude() ); + return new Caching( region, accessType, cacheLazyProps ); + } + + private EntityBinding makeDiscriminatedSubclassBinding( + EntitySourceInformation entitySourceInfo, + EntityBinding superEntityBinding) { // temporary!!! final EntityBinding entityBinding = new EntityBinding(); entityBinding.setInheritanceType( InheritanceType.SINGLE_TABLE ); + bindSuperType( entityBinding, superEntityBinding ); - final String entityName = bindingContext.determineEntityName( subclassElement ); - final String verbatimClassName = subclassElement.getName(); + final String verbatimClassName = entitySourceInfo.getEntityElement().getName(); final EntityMode entityMode = verbatimClassName == null ? EntityMode.MAP : EntityMode.POJO; entityBinding.setEntityMode( entityMode ); final String className; if ( entityMode == EntityMode.POJO ) { - className = bindingContext.qualifyClassName( verbatimClassName ); + className = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext().qualifyClassName( verbatimClassName ); } else { className = null; } - final Entity entity = new Entity( entityName, className, bindingContext.makeClassReference( className ), null ); + final Entity entity = new Entity( + entitySourceInfo.getMappedEntityName(), + className, + entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext().makeClassReference( className ), + null + ); entityBinding.setEntity( entity ); - performBasicEntityBind( entityBinding, subclassElement ); + performBasicEntityBind( entityBinding, entitySourceInfo ); return entityBinding; } - protected EntityBinding makeEntityBinding(XMLJoinedSubclassElement joinedEntityElement, String superEntityName) { + private EntityBinding makeJoinedSubclassBinding( + EntitySourceInformation entitySourceInfo, + EntityBinding superEntityBinding) { // temporary!!! final EntityBinding entityBinding = new EntityBinding(); entityBinding.setInheritanceType( InheritanceType.JOINED ); + bindSuperType( entityBinding, superEntityBinding ); + + final XMLJoinedSubclassElement joinedEntityElement = (XMLJoinedSubclassElement) entitySourceInfo.getEntityElement(); + final HbmBindingContext bindingContext = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext(); final String entityName = bindingContext.determineEntityName( joinedEntityElement ); final String verbatimClassName = joinedEntityElement.getName(); @@ -227,16 +307,22 @@ public class BindingCreator { final Entity entity = new Entity( entityName, className, bindingContext.makeClassReference( className ), null ); entityBinding.setEntity( entity ); - performBasicEntityBind( entityBinding, joinedEntityElement ); + performBasicEntityBind( entityBinding, entitySourceInfo ); return entityBinding; } - protected EntityBinding makeEntityBinding(XMLUnionSubclassElement unionEntityElement, String superEntityName) { + private EntityBinding makeUnionedSubclassBinding( + EntitySourceInformation entitySourceInfo, + EntityBinding superEntityBinding) { // temporary!!! final EntityBinding entityBinding = new EntityBinding(); entityBinding.setInheritanceType( InheritanceType.TABLE_PER_CLASS ); + bindSuperType( entityBinding, superEntityBinding ); + + final XMLUnionSubclassElement unionEntityElement = (XMLUnionSubclassElement) entitySourceInfo.getEntityElement(); + final HbmBindingContext bindingContext = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext(); final String entityName = bindingContext.determineEntityName( unionEntityElement ); final String verbatimClassName = unionEntityElement.getName(); @@ -255,15 +341,23 @@ public class BindingCreator { final Entity entity = new Entity( entityName, className, bindingContext.makeClassReference( className ), null ); entityBinding.setEntity( entity ); - performBasicEntityBind( entityBinding, unionEntityElement ); + performBasicEntityBind( entityBinding, entitySourceInfo ); return entityBinding; } + private void bindSuperType(EntityBinding entityBinding, EntityBinding superEntityBinding) { +// entityBinding.setSuperEntityBinding( superEntityBinding ); +// // not sure what to do with the domain model super type... + } + @SuppressWarnings( {"unchecked"}) - protected void performBasicEntityBind(EntityBinding entityBinding, EntityElement entityElement) { + private void performBasicEntityBind(EntityBinding entityBinding, EntitySourceInformation entitySourceInfo) { entityBinding.setJpaEntityName( null ); + final EntityElement entityElement = entitySourceInfo.getEntityElement(); + final HbmBindingContext bindingContext = entitySourceInfo.getSourceMappingDocument().getMappingLocalBindingContext(); + final String proxy = entityElement.getProxy(); final boolean isLazy = entityElement.isLazy() == null ? true @@ -287,7 +381,10 @@ public class BindingCreator { entityBinding.setLazy( isLazy ); } - final String customTuplizerClassName = extractCustomTuplizerClassName( entityElement, entityBinding.getEntityMode() ); + final String customTuplizerClassName = extractCustomTuplizerClassName( + entityElement, + entityBinding.getEntityMode() + ); if ( customTuplizerClassName != null ) { entityBinding.setCustomEntityTuplizerClass( bindingContext.locateClassByName( customTuplizerClassName ) ); } @@ -345,4 +442,422 @@ public class BindingCreator { } return null; } + + private void bindPrimaryTable(EntitySourceInformation entitySourceInformation, EntityBinding entityBinding) { + final EntityElement entityElement = entitySourceInformation.getEntityElement(); + final HbmBindingContext bindingContext = entitySourceInformation.getSourceMappingDocument().getMappingLocalBindingContext(); + + if ( XMLSubclassElement.class.isInstance( entityElement ) ) { + // todo : need to look it up from root entity, or have persister manage it + } + else { + // todo : add mixin interface + final String explicitTableName; + final String explicitSchemaName; + final String explicitCatalogName; + if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) { + explicitTableName = ( (XMLHibernateMapping.XMLClass) entityElement ).getTable(); + explicitSchemaName = ( (XMLHibernateMapping.XMLClass) entityElement ).getSchema(); + explicitCatalogName = ( (XMLHibernateMapping.XMLClass) entityElement ).getCatalog(); + } + else if ( XMLJoinedSubclassElement.class.isInstance( entityElement ) ) { + explicitTableName = ( (XMLJoinedSubclassElement) entityElement ).getTable(); + explicitSchemaName = ( (XMLJoinedSubclassElement) entityElement ).getSchema(); + explicitCatalogName = ( (XMLJoinedSubclassElement) entityElement ).getCatalog(); + } + else if ( XMLUnionSubclassElement.class.isInstance( entityElement ) ) { + explicitTableName = ( (XMLUnionSubclassElement) entityElement ).getTable(); + explicitSchemaName = ( (XMLUnionSubclassElement) entityElement ).getSchema(); + explicitCatalogName = ( (XMLUnionSubclassElement) entityElement ).getCatalog(); + } + else { + // throw up + explicitTableName = null; + explicitSchemaName = null; + explicitCatalogName = null; + } + final NamingStrategy namingStrategy = bindingContext.getMetadataImplementor() + .getOptions() + .getNamingStrategy(); + final String tableName = explicitTableName != null + ? namingStrategy.tableName( explicitTableName ) + : namingStrategy.tableName( namingStrategy.classToTableName( entityBinding.getEntity().getName() ) ); + + final String schemaName = explicitSchemaName == null + ? bindingContext.getMappingDefaults().getSchemaName() + : explicitSchemaName; + final String catalogName = explicitCatalogName == null + ? bindingContext.getMappingDefaults().getCatalogName() + : explicitCatalogName; + + final Schema schema = metadata.getDatabase().getSchema( new Schema.Name( schemaName, catalogName ) ); + entityBinding.setBaseTable( schema.locateOrCreateTable( Identifier.toIdentifier( tableName ) ) ); + } + } + + + private Stack attributeColumnTableStack = new Stack(); + + private void bindAttributes(final EntitySourceInformation entitySourceInformation, EntityBinding entityBinding) { + // todo : we really need the notion of a Stack here for the table from which the columns come for binding these attributes. + // todo : adding the concept (interface) of a source of attribute metadata would allow reuse of this method for entity, component, unique-key, etc + // for now, simply assume all columns come from the base table.... + + attributeColumnTableStack.push( entityBinding.getBaseTable() ); + try { + bindAttributes( + new AttributeMetadataContainer() { + @Override + public List getAttributeElements() { + return entitySourceInformation.getEntityElement().getPropertyOrManyToOneOrOneToOne(); + } + }, + entityBinding + ); + } + finally { + attributeColumnTableStack.pop(); + } + + } + + private void bindAttributes(AttributeMetadataContainer attributeMetadataContainer, EntityBinding entityBinding) { + for ( Object attribute : attributeMetadataContainer.getAttributeElements() ) { + + if ( XMLPropertyElement.class.isInstance( attribute ) ) { + XMLPropertyElement property = XMLPropertyElement.class.cast( attribute ); + bindProperty( property, entityBinding ); + } + else if ( XMLManyToOneElement.class.isInstance( attribute ) ) { + XMLManyToOneElement manyToOne = XMLManyToOneElement.class.cast( attribute ); + makeManyToOneAttributeBinding( manyToOne, entityBinding ); + } + else if ( XMLOneToOneElement.class.isInstance( attribute ) ) { +// todo : implement +// value = new OneToOne( mappings, table, persistentClass ); +// bindOneToOne( subElement, (OneToOne) value, propertyName, true, mappings ); + } + else if ( XMLBagElement.class.isInstance( attribute ) ) { + XMLBagElement collection = XMLBagElement.class.cast( attribute ); + BagBinding collectionBinding = makeBagAttributeBinding( collection, entityBinding ); + metadata.addCollection( collectionBinding ); + } + else if ( XMLIdbagElement.class.isInstance( attribute ) ) { + XMLIdbagElement collection = XMLIdbagElement.class.cast( attribute ); +//BagBinding collectionBinding = entityBinding.makeBagAttributeBinding( collection.getName() ); +//bindIdbag( collection, bagBinding, entityBinding, PluralAttributeNature.BAG, collection.getName() ); +// todo: handle identifier +//attributeBinding = collectionBinding; +//hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding ); + } + else if ( XMLSetElement.class.isInstance( attribute ) ) { + XMLSetElement collection = XMLSetElement.class.cast( attribute ); +//BagBinding collectionBinding = entityBinding.makeBagAttributeBinding( collection.getName() ); +//bindSet( collection, collectionBinding, entityBinding, PluralAttributeNature.SET, collection.getName() ); +//attributeBinding = collectionBinding; +//hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding ); + } + else if ( XMLListElement.class.isInstance( attribute ) ) { + XMLListElement collection = XMLListElement.class.cast( attribute ); +//ListBinding collectionBinding = entityBinding.makeBagAttributeBinding( collection.getName() ); +//bindList( collection, bagBinding, entityBinding, PluralAttributeNature.LIST, collection.getName() ); +// todo : handle list index +//attributeBinding = collectionBinding; +//hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding ); + } + else if ( XMLMapElement.class.isInstance( attribute ) ) { + XMLMapElement collection = XMLMapElement.class.cast( attribute ); +//BagBinding bagBinding = entityBinding.makeBagAttributeBinding( collection.getName() ); +//bindMap( collection, bagBinding, entityBinding, PluralAttributeNature.MAP, collection.getName() ); +// todo : handle map key +//hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding ); + } + else if ( XMLAnyElement.class.isInstance( attribute ) ) { +// todo : implement +// value = new Any( mappings, table ); +// bindAny( subElement, (Any) value, nullable, mappings ); + } + else if ( XMLComponentElement.class.isInstance( attribute ) + || XMLDynamicComponentElement.class.isInstance( attribute ) + || XMLPropertiesElement.class.isInstance( attribute ) ) { +// todo : implement +// String subpath = StringHelper.qualify( entityName, propertyName ); +// value = new Component( mappings, persistentClass ); +// +// bindComponent( +// subElement, +// (Component) value, +// persistentClass.getClassName(), +// propertyName, +// subpath, +// true, +// "properties".equals( subElementName ), +// mappings, +// inheritedMetas, +// false +// ); + } + } + } + + private void bindProperty(XMLPropertyElement property, EntityBinding entityBinding) { + SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( property.getName() ); + resolveTypeInformation( property, attributeBinding ); + + attributeBinding.setInsertable( Helper.getBooleanValue( property.isInsert(), true ) ); + attributeBinding.setInsertable( Helper.getBooleanValue( property.isUpdate(), true ) ); + attributeBinding.setGeneration( PropertyGeneration.parse( property.getGenerated() ) ); + attributeBinding.setLazy( property.isLazy() ); + attributeBinding.setIncludedInOptimisticLocking( property.isOptimisticLock() ); + + attributeBinding.setPropertyAccessorName( + Helper.getPropertyAccessorName( + property.getAccess(), + false, + currentBindingContext.getMappingDefaults().getPropertyAccessorName() + ) + ); + + attributeBinding.setMetaAttributeContext( + Helper.extractMetaAttributeContext( property.getMeta(), entityBinding.getMetaAttributeContext() ) + ); + +// todo : implement. Is this meant to indicate the natural-id? +// attributeBinding.setAlternateUniqueKey( ... ); + + attributeBinding.setValue( makeValue( property, attributeBinding ) ); + + } + + private void resolveTypeInformation(XMLPropertyElement property, final SimpleAttributeBinding attributeBinding) { + final Class attributeJavaType = determineJavaType( attributeBinding.getAttribute() ); + if ( attributeJavaType != null ) { + ( (AbstractAttributeContainer.SingularAttributeImpl) attributeBinding.getAttribute() ).resolveType( + currentBindingContext.makeJavaType( attributeJavaType.getName() ) + ); + } + + // prefer type attribute over nested element + if ( property.getTypeAttribute() != null ) { + final String explicitTypeName = property.getTypeAttribute(); + final TypeDef typeDef = currentBindingContext.getMetadataImplementor().getTypeDefinition( explicitTypeName ); + if ( typeDef != null ) { + attributeBinding.getHibernateTypeDescriptor().setTypeName( typeDef.getTypeClass() ); + attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( typeDef.getParameters() ); + } + else { + attributeBinding.getHibernateTypeDescriptor().setTypeName( explicitTypeName ); + } + } + else if ( property.getType() != null ) { + // todo : consider changing in-line type definitions to implicitly generate uniquely-named type-defs + attributeBinding.getHibernateTypeDescriptor().setTypeName( property.getType().getName() ); + for ( XMLParamElement xmlParamElement : property.getType().getParam() ) { + attributeBinding.getHibernateTypeDescriptor().getTypeParameters().put( + xmlParamElement.getName(), + xmlParamElement.getValue() + ); + } + } + else { + // see if we can reflect to determine the appropriate type + try { + final String attributeName = attributeBinding.getAttribute().getName(); + final Class ownerClass = attributeBinding.getAttribute().getAttributeContainer().getClassReference(); + BeanInfoHelper.visitBeanInfo( + ownerClass, + new BeanInfoHelper.BeanInfoDelegate() { + @Override + public void processBeanInfo(BeanInfo beanInfo) throws Exception { + for ( PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors() ) { + if ( propertyDescriptor.getName().equals( attributeName ) ) { + attributeBinding.getHibernateTypeDescriptor().setTypeName( + propertyDescriptor.getPropertyType().getName() + ); + break; + } + } + } + } + ); + } + catch ( Exception e ) { + // todo : log it? + } + } + } + + private Class determineJavaType(final Attribute attribute) { + try { + final Class ownerClass = attribute.getAttributeContainer().getClassReference(); + AttributeJavaTypeDeterminerDelegate delegate = new AttributeJavaTypeDeterminerDelegate( attribute.getName() ); + BeanInfoHelper.visitBeanInfo( ownerClass, delegate ); + return delegate.javaType; + } + catch ( Exception e ) { + // todo : log it? + } + return null; + } + + private static class AttributeJavaTypeDeterminerDelegate implements BeanInfoHelper.BeanInfoDelegate { + private final String attributeName; + private Class javaType = null; + + private AttributeJavaTypeDeterminerDelegate(String attributeName) { + this.attributeName = attributeName; + } + + @Override + public void processBeanInfo(BeanInfo beanInfo) throws Exception { + for ( PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors() ) { + if ( propertyDescriptor.getName().equals( attributeName ) ) { + javaType = propertyDescriptor.getPropertyType(); + break; + } + } + } + } + + private org.hibernate.metamodel.relational.Value makeValue( + XMLPropertyElement property, + SimpleAttributeBinding attributeBinding) { + + // todo : to be completely correct, we need to know which table the value belongs to. + // There is a note about this somewhere else with ideas on the subject. + // For now, just use the entity's base table. + final TableSpecification valueSource = attributeBinding.getEntityBinding().getBaseTable(); + + if ( property.getColumn() != null && ! property.getColumn().isEmpty() ) { + if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) { + throw new MappingException( + "column/formula attribute may not be used together with / subelement", + currentBindingContext.getOrigin() + ); + } + if ( property.getFormula() != null ) { + throw new MappingException( + "column and formula attributes may not be used together", + currentBindingContext.getOrigin() + ); + } + return valueSource.locateOrCreateColumn( property.getColumn() ); + } + else if ( property.getFormula() != null && ! property.getFormula().isEmpty() ) { + if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) { + throw new MappingException( + "column/formula attribute may not be used together with / subelement", + currentBindingContext.getOrigin() + ); + } + return valueSource.locateOrCreateDerivedValue( property.getFormula() ); + } + else if ( property.getColumnOrFormula() != null && ! property.getColumnOrFormula().isEmpty() ) { + List values = new ArrayList(); + for ( Object columnOrFormula : property.getColumnOrFormula() ) { + final SimpleValue value; + if ( XMLColumnElement.class.isInstance( columnOrFormula ) ) { + final XMLColumnElement columnElement = (XMLColumnElement) columnOrFormula; + final Column column = valueSource.locateOrCreateColumn( columnElement.getName() ); + column.setNullable( ! columnElement.isNotNull() ); + column.setDefaultValue( columnElement.getDefault() ); + column.setSqlType( columnElement.getSqlType() ); + column.setSize( + new Size( + Helper.getIntValue( columnElement.getPrecision(), -1 ), + Helper.getIntValue( columnElement.getScale(), -1 ), + Helper.getLongValue( columnElement.getLength(), -1 ), + Size.LobMultiplier.NONE + ) + ); + column.setDatatype( null ); // todo : ??? + column.setReadFragment( columnElement.getRead() ); + column.setWriteFragment( columnElement.getWrite() ); + column.setUnique( columnElement.isUnique() ); + column.setCheckCondition( columnElement.getCheck() ); + column.setComment( columnElement.getComment() ); + value = column; + } + else { + // todo : ??? Seems jaxb is not generating this class ?!?!?! +// final XMLFormulaElement formulaElement = (XMLFormulaElement) columnOrFormula; + value = null; + } + if ( value != null ) { + values.add( value ); + } + } + + if ( values.size() == 1 ) { + return values.get( 0 ); + } + + final Tuple tuple = valueSource.createTuple( + attributeBinding.getEntityBinding().getEntity().getName() + '.' + + attributeBinding.getAttribute().getName() + ); + for ( SimpleValue value : values ) { + tuple.addValue( value ); + } + return tuple; + } + else { + // assume a column named based on the NamingStrategy + final String name = metadata.getOptions() + .getNamingStrategy() + .propertyToColumnName( attributeBinding.getAttribute().getName() ); + return valueSource.locateOrCreateColumn( name ); + } + +// // TODO: not sure I like this here... +// if ( isPrimaryKey() ) { +// if ( SimpleValue.class.isInstance( value ) ) { +// if ( !Column.class.isInstance( value ) ) { +// // this should never ever happen.. +// throw new org.hibernate.MappingException( "Simple ID is not a column." ); +// } +// entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( value ) ); +// } +// else { +// for ( SimpleValueRelationalState val : TupleRelationalState.class.cast( state ) +// .getRelationalStates() ) { +// if ( Column.class.isInstance( val ) ) { +// entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( val ) ); +// } +// } +// } +// } + } + + private void makeManyToOneAttributeBinding(XMLManyToOneElement manyToOne, EntityBinding entityBinding) { + //To change body of created methods use File | Settings | File Templates. + } + + private BagBinding makeBagAttributeBinding(XMLBagElement collection, EntityBinding entityBinding) { + return null; //To change body of created methods use File | Settings | File Templates. + } + + private void bindSecondaryTables(EntitySourceInformation entitySourceInfo, EntityBinding entityBinding) { + final EntityElement entityElement = entitySourceInfo.getEntityElement(); + + if ( ! ( entityElement instanceof JoinElementSource ) ) { + return; + } + + for ( XMLJoinElement join : ( (JoinElementSource) entityElement ).getJoin() ) { + // todo : implement + // Join join = new Join(); + // join.setPersistentClass( persistentClass ); + // bindJoin( subElement, join, mappings, inheritedMetas ); + // persistentClass.addJoin( join ); + } + } + + private void bindTableUniqueConstraints(EntityBinding entityBinding) { + //To change body of created methods use File | Settings | File Templates. + } + + private static interface AttributeMetadataContainer { + public List getAttributeElements(); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntityHierarchy.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntityHierarchy.java new file mode 100644 index 0000000000..f624660b47 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntityHierarchy.java @@ -0,0 +1,64 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binder.source.hbm; + +import org.hibernate.metamodel.binding.InheritanceType; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping; + +/** + * Models the source view of an entity hierarchy. + * + * @author Steve Ebersole + */ +public class EntityHierarchy extends AbstractSubEntityContainer { + private final EntitySourceInformation entitySourceInformation; + private InheritanceType hierarchyInheritanceType = InheritanceType.NO_INHERITANCE; + + public EntityHierarchy(XMLHibernateMapping.XMLClass rootEntity, MappingDocument sourceMappingDocument) { + this.entitySourceInformation = new EntitySourceInformation( rootEntity, sourceMappingDocument ); + } + + public EntitySourceInformation getEntitySourceInformation() { + return entitySourceInformation; + } + + public InheritanceType getHierarchyInheritanceType() { + return hierarchyInheritanceType; + } + + @Override + public void addSubEntityDescriptor(EntityHierarchySubEntity subEntityDescriptor) { + super.addSubEntityDescriptor( subEntityDescriptor ); + + // check inheritance type consistency + final InheritanceType inheritanceType = Helper.interpretInheritanceType( + subEntityDescriptor.getEntitySourceInformation().getEntityElement() + ); + if ( this.hierarchyInheritanceType != InheritanceType.NO_INHERITANCE + && this.hierarchyInheritanceType != inheritanceType ) { + // throw exception + } + this.hierarchyInheritanceType = inheritanceType; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntityHierarchySubEntity.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntityHierarchySubEntity.java new file mode 100644 index 0000000000..16ab8c846c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntityHierarchySubEntity.java @@ -0,0 +1,43 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binder.source.hbm; + +import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement; + +/** + * A sub entity within an entity hierarchy. + * + * @author Steve Ebersole + */ +public class EntityHierarchySubEntity extends AbstractSubEntityContainer { + private final EntitySourceInformation entitySourceInformation; + + public EntityHierarchySubEntity(EntityElement entityElement, MappingDocument sourceMappingDocument) { + this.entitySourceInformation = new EntitySourceInformation( entityElement, sourceMappingDocument ); + } + + public EntitySourceInformation getEntitySourceInformation() { + return entitySourceInformation; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntitySourceInformation.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntitySourceInformation.java new file mode 100644 index 0000000000..b2d2b6aee7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/EntitySourceInformation.java @@ -0,0 +1,55 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binder.source.hbm; + +import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement; + +/** + * An aggregation of information about the source of an entity mapping. + * + * @author Steve Ebersole + */ +public class EntitySourceInformation { + private final EntityElement entityElement; + private final MappingDocument sourceMappingDocument; + private final String mappedEntityName; + + public EntitySourceInformation(EntityElement entityElement, MappingDocument sourceMappingDocument) { + this.entityElement = entityElement; + this.sourceMappingDocument = sourceMappingDocument; + this.mappedEntityName = sourceMappingDocument.getMappingLocalBindingContext().determineEntityName( entityElement ); + } + + public EntityElement getEntityElement() { + return entityElement; + } + + public MappingDocument getSourceMappingDocument() { + return sourceMappingDocument; + } + + public String getMappedEntityName() { + return mappedEntityName; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HbmSourceProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HbmSourceProcessorImpl.java index 4baedb0a25..493f4aeaf3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HbmSourceProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HbmSourceProcessorImpl.java @@ -24,35 +24,24 @@ package org.hibernate.metamodel.binder.source.hbm; import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; -import org.hibernate.MappingException; -import org.hibernate.cfg.NamingStrategy; -import org.hibernate.internal.util.Value; import org.hibernate.metamodel.MetadataSources; -import org.hibernate.metamodel.binder.source.BindingContext; -import org.hibernate.metamodel.binder.source.MappingDefaults; import org.hibernate.metamodel.binder.source.MetadataImplementor; import org.hibernate.metamodel.binder.source.SourceProcessor; -import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement; -import org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement; import org.hibernate.metamodel.binder.source.internal.JaxbRoot; -import org.hibernate.metamodel.domain.JavaType; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping; -import org.hibernate.service.ServiceRegistry; /** * The {@link SourceProcessor} implementation responsible for processing {@code hbm.xml} sources. * * @author Steve Ebersole */ -public class HbmSourceProcessorImpl implements SourceProcessor, BindingContext { +public class HbmSourceProcessorImpl implements SourceProcessor { private final MetadataImplementor metadata; - private List processors; + + private List processors = new ArrayList(); + private List entityHierarchies; public HbmSourceProcessorImpl(MetadataImplementor metadata) { this.metadata = metadata; @@ -61,12 +50,20 @@ public class HbmSourceProcessorImpl implements SourceProcessor, BindingContext { @Override @SuppressWarnings( {"unchecked"}) public void prepare(MetadataSources sources) { - this.processors = new ArrayList(); + final HierarchyBuilder hierarchyBuilder = new HierarchyBuilder( metadata ); + for ( JaxbRoot jaxbRoot : sources.getJaxbRootList() ) { - if ( jaxbRoot.getRoot() instanceof XMLHibernateMapping ) { - processors.add( new HibernateMappingProcessor( this, (JaxbRoot) jaxbRoot ) ); + if ( ! XMLHibernateMapping.class.isInstance( jaxbRoot.getRoot() ) ) { + continue; } + + final MappingDocument mappingDocument = new MappingDocument( jaxbRoot, metadata ); + processors.add( new HibernateMappingProcessor( metadata, mappingDocument ) ); + + hierarchyBuilder.processMappingDocument( mappingDocument ); } + + this.entityHierarchies = hierarchyBuilder.groupEntityHierarchies(); } @Override @@ -85,93 +82,9 @@ public class HbmSourceProcessorImpl implements SourceProcessor, BindingContext { @Override public void processMappingMetadata(MetadataSources sources, List processedEntityNames) { - // Lets get the entities (the mapping processors really) into a better order for processing based on - // inheritance hierarchy to avoid the need for an "extends queue". Really, correctly speaking, we are - // localizing the "extends queue" to just this method stack. - - // 'orderedProcessors' represents the processors we know are not waiting on any super-types in the entity - // hierarchy to be found. 'extendsQueue', conversely, holds processors (and other information) relating - // we know have to wait on at least one of the super-types in their entity hierarchy to be found. - final LinkedHashSet orderedProcessors = new LinkedHashSet(); - final Set extendsQueue = new HashSet(); - - // 'availableEntityNames' holds all of the available entity names. This means the incoming set of - // 'processedEntityNames' as well as any entity-names found here as they are added to 'orderedProcessors' - final Set availableEntityNames = new HashSet(); - availableEntityNames.addAll( processedEntityNames ); - - // this loop is essentially splitting processors into those that can be processed immediately and those that - // have to wait on entities not yet seen. Those that have to wait go in the extendsQueue. Those that can be - // processed immediately go into 'orderedProcessors'. - for ( HibernateMappingProcessor processor : processors ) { - final HibernateMappingInformation hibernateMappingInformation = new HibernateMappingInformation( processor ); - ExtendsQueueEntry extendsQueueEntry = null; - for ( Object entityElementO : processor.getHibernateMapping().getClazzOrSubclassOrJoinedSubclass() ) { - final EntityElement entityElement = (EntityElement) entityElementO; - final String entityName = processor.determineEntityName( entityElement ); - hibernateMappingInformation.includedEntityNames.add( entityName ); - if ( SubclassEntityElement.class.isInstance( entityElement ) ) { - final String entityItExtends = ( (SubclassEntityElement) entityElement ).getExtends(); - if ( ! availableEntityNames.contains( entityItExtends ) ) { - if ( extendsQueueEntry == null ) { - extendsQueueEntry = new ExtendsQueueEntry( hibernateMappingInformation ); - extendsQueue.add( extendsQueueEntry ); - } - extendsQueueEntry.waitingOnEntityNames.add( entityItExtends ); - } - } - } - if ( extendsQueueEntry == null ) { - // we found no extends names that we have to wait on - orderedProcessors.add( processor ); - availableEntityNames.addAll( hibernateMappingInformation.includedEntityNames ); - } - } - - // This loop tries to move entries from 'extendsQueue' into 'orderedProcessors', stopping when we cannot - // process any more or they have all been processed. - while ( ! extendsQueue.isEmpty() ) { - // set up a pass over the queue - int numberOfMappingsProcessed = 0; - Iterator iterator = extendsQueue.iterator(); - while ( iterator.hasNext() ) { - final ExtendsQueueEntry entry = iterator.next(); - if ( availableEntityNames.containsAll( entry.waitingOnEntityNames ) ) { - // all the entity names this entry was waiting on have been made available - iterator.remove(); - orderedProcessors.add( entry.hibernateMappingInformation.processor ); - availableEntityNames.addAll( entry.hibernateMappingInformation.includedEntityNames ); - numberOfMappingsProcessed++; - } - } - - if ( numberOfMappingsProcessed == 0 ) { - // todo : we could log the waiting dependencies... - throw new MappingException( "Unable to process extends dependencies in hbm files" ); - } - } - - // This loop executes the processors. - for ( HibernateMappingProcessor processor : orderedProcessors ) { - processor.processMappingMetadata( processedEntityNames ); - } - } - - private static class HibernateMappingInformation { - private final HibernateMappingProcessor processor; - private final Set includedEntityNames = new HashSet(); - - private HibernateMappingInformation(HibernateMappingProcessor processor) { - this.processor = processor; - } - } - - private static class ExtendsQueueEntry { - private HibernateMappingInformation hibernateMappingInformation; - private final Set waitingOnEntityNames = new HashSet(); - - private ExtendsQueueEntry(HibernateMappingInformation hibernateMappingInformation) { - this.hibernateMappingInformation = hibernateMappingInformation; + BindingCreator bindingCreator = new BindingCreator( metadata, processedEntityNames ); + for ( EntityHierarchy entityHierarchy : entityHierarchies ) { + bindingCreator.processEntityHierarchy( entityHierarchy ); } } @@ -181,39 +94,4 @@ public class HbmSourceProcessorImpl implements SourceProcessor, BindingContext { processor.processMappingDependentMetadata(); } } - - @Override - public ServiceRegistry getServiceRegistry() { - return metadata.getServiceRegistry(); - } - - @Override - public NamingStrategy getNamingStrategy() { - return metadata.getNamingStrategy(); - } - - @Override - public MappingDefaults getMappingDefaults() { - return metadata.getMappingDefaults(); - } - - @Override - public MetadataImplementor getMetadataImplementor() { - return metadata; - } - - @Override - public Class locateClassByName(String name) { - return metadata.locateClassByName( name ); - } - - @Override - public JavaType makeJavaType(String className) { - return metadata.makeJavaType( className ); - } - - @Override - public Value> makeClassReference(String className) { - return metadata.makeClassReference( className ); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/Helper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/Helper.java index 795ff4a813..24315d6ccb 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/Helper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/Helper.java @@ -35,8 +35,12 @@ import org.hibernate.metamodel.binder.source.MetaAttributeContext; import org.hibernate.metamodel.binder.source.hbm.xml.mapping.CustomSqlElement; import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement; import org.hibernate.metamodel.binding.CustomSQL; +import org.hibernate.metamodel.binding.InheritanceType; import org.hibernate.metamodel.binding.MetaAttribute; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinedSubclassElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLMetaElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLUnionSubclassElement; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.classloading.spi.ClassLoaderService; import org.hibernate.service.classloading.spi.ClassLoadingException; @@ -46,6 +50,20 @@ import org.hibernate.service.classloading.spi.ClassLoadingException; * @author Gail Badner */ public class Helper { + public static InheritanceType interpretInheritanceType(EntityElement entityElement) { + if ( XMLSubclassElement.class.isInstance( entityElement ) ) { + return InheritanceType.SINGLE_TABLE; + } + else if ( XMLJoinedSubclassElement.class.isInstance( entityElement ) ) { + return InheritanceType.JOINED; + } + else if ( XMLUnionSubclassElement.class.isInstance( entityElement ) ) { + return InheritanceType.TABLE_PER_CLASS; + } + else { + return InheritanceType.NO_INHERITANCE; + } + } /** * Given a user-specified description of how to perform custom SQL, build the {@link CustomSQL} representation. @@ -140,6 +158,10 @@ public class Helper { return value == null ? defaultValue : Integer.parseInt( value ); } + public static long getLongValue(String value, long defaultValue) { + return value == null ? defaultValue : Long.parseLong( value ); + } + public static boolean getBooleanValue(String value, boolean defaultValue) { return value == null ? defaultValue : Boolean.valueOf( value ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HibernateMappingProcessor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HibernateMappingProcessor.java index 616d054b3a..effc489369 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HibernateMappingProcessor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HibernateMappingProcessor.java @@ -29,22 +29,14 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.hibernate.cfg.NamingStrategy; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.Value; import org.hibernate.metamodel.binder.MappingException; import org.hibernate.metamodel.binder.Origin; -import org.hibernate.metamodel.binder.source.MappingDefaults; -import org.hibernate.metamodel.binder.source.MetaAttributeContext; import org.hibernate.metamodel.binder.source.MetadataImplementor; -import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement; -import org.hibernate.metamodel.binder.source.internal.JaxbRoot; -import org.hibernate.metamodel.binder.source.internal.OverriddenMappingDefaults; -import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.FetchProfile; import org.hibernate.metamodel.binding.TypeDef; -import org.hibernate.metamodel.domain.JavaType; import org.hibernate.metamodel.relational.AuxiliaryDatabaseObject; import org.hibernate.metamodel.relational.BasicAuxiliaryDatabaseObjectImpl; import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLFetchProfileElement; @@ -67,106 +59,38 @@ import org.hibernate.type.Type; * * @author Steve Ebersole */ -public class HibernateMappingProcessor implements HbmBindingContext { - private final HbmSourceProcessorImpl hbmHandler; - private final JaxbRoot jaxbRoot; +public class HibernateMappingProcessor { + private final MetadataImplementor metadata; + private final MappingDocument mappingDocument; - private final XMLHibernateMapping hibernateMapping; + private Value classLoaderService = new Value( + new Value.DeferredInitializer() { + @Override + public ClassLoaderService initialize() { + return metadata.getServiceRegistry().getService( ClassLoaderService.class ); + } + } + ); - private final MappingDefaults mappingDefaults; - private final MetaAttributeContext metaAttributeContext; - - private final boolean autoImport; - - public HibernateMappingProcessor(HbmSourceProcessorImpl hbmHandler, JaxbRoot jaxbRoot) { - this.hbmHandler = hbmHandler; - this.jaxbRoot = jaxbRoot; - - this.hibernateMapping = jaxbRoot.getRoot(); - this.mappingDefaults = new OverriddenMappingDefaults( - hbmHandler.getMappingDefaults(), - hibernateMapping.getPackage(), - hibernateMapping.getSchema(), - hibernateMapping.getCatalog(), - null, // idColumnName - null, // discriminatorColumnName - hibernateMapping.getDefaultCascade(), - hibernateMapping.getDefaultAccess(), - hibernateMapping.isDefaultLazy() - ); - - this.autoImport = hibernateMapping.isAutoImport(); - this.metaAttributeContext = extractMetaAttributes(); + public HibernateMappingProcessor(MetadataImplementor metadata, MappingDocument mappingDocument) { + this.metadata = metadata; + this.mappingDocument = mappingDocument; } - private MetaAttributeContext extractMetaAttributes() { - return hibernateMapping.getMeta() == null - ? new MetaAttributeContext( hbmHandler.getMetadataImplementor().getGlobalMetaAttributeContext() ) - : Helper.extractMetaAttributeContext( - hibernateMapping.getMeta(), - true, - hbmHandler.getMetadataImplementor() - .getGlobalMetaAttributeContext() - ); + private XMLHibernateMapping mappingRoot() { + return mappingDocument.getMappingRoot(); } - XMLHibernateMapping getHibernateMapping() { - return hibernateMapping; + private Origin origin() { + return mappingDocument.getOrigin(); } - @Override - public boolean isAutoImport() { - return autoImport; + private HbmBindingContext bindingContext() { + return mappingDocument.getMappingLocalBindingContext(); } - @Override - public Origin getOrigin() { - return jaxbRoot.getOrigin(); - } - - @Override - public ServiceRegistry getServiceRegistry() { - return getMetadataImplementor().getServiceRegistry(); - } - - @Override - public NamingStrategy getNamingStrategy() { - return getMetadataImplementor().getOptions().getNamingStrategy(); - } - - @Override - public boolean isGloballyQuotedIdentifiers() { - return getMetadataImplementor().isGloballyQuotedIdentifiers(); - } - - @Override - public MappingDefaults getMappingDefaults() { - return mappingDefaults; - } - - @Override - public MetaAttributeContext getMetaAttributeContext() { - return metaAttributeContext; - } - - @Override - public MetadataImplementor getMetadataImplementor() { - return hbmHandler.getMetadataImplementor(); - } - - @Override - public Class locateClassByName(String name) { - return getMetadataImplementor().locateClassByName( name ); - } - - @Override - public JavaType makeJavaType(String className) { - return getMetadataImplementor().makeJavaType( className ); - } - - @Override - public Value> makeClassReference(String className) { - return getMetadataImplementor().makeClassReference( className ); + private Class classForName(String name) { + return classLoaderService.getValue().classForName( bindingContext().qualifyClassName( name ) ); } public void processIndependentMetadata() { @@ -175,15 +99,16 @@ public class HibernateMappingProcessor implements HbmBindingContext { } private void processDatabaseObjectDefinitions() { - if ( hibernateMapping.getDatabaseObject() == null ) { + if ( mappingRoot().getDatabaseObject() == null ) { return; } - for ( XMLHibernateMapping.XMLDatabaseObject databaseObjectElement : hibernateMapping.getDatabaseObject() ) { + + for ( XMLHibernateMapping.XMLDatabaseObject databaseObjectElement : mappingRoot().getDatabaseObject() ) { final AuxiliaryDatabaseObject auxiliaryDatabaseObject; if ( databaseObjectElement.getDefinition() != null ) { final String className = databaseObjectElement.getDefinition().getClazz(); try { - auxiliaryDatabaseObject = (AuxiliaryDatabaseObject) classLoaderService.getValue().classForName( className ).newInstance(); + auxiliaryDatabaseObject = (AuxiliaryDatabaseObject) classForName( className ).newInstance(); } catch (ClassLoadingException e) { throw e; @@ -191,7 +116,7 @@ public class HibernateMappingProcessor implements HbmBindingContext { catch (Exception e) { throw new MappingException( "could not instantiate custom database object class [" + className + "]", - jaxbRoot.getOrigin() + origin() ); } } @@ -208,20 +133,21 @@ public class HibernateMappingProcessor implements HbmBindingContext { dialectScopes ); } - getMetadataImplementor().addAuxiliaryDatabaseObject( auxiliaryDatabaseObject ); + metadata.addAuxiliaryDatabaseObject( auxiliaryDatabaseObject ); } } private void processTypeDefinitions() { - if ( hibernateMapping.getTypedef() == null ) { + if ( mappingRoot().getTypedef() == null ) { return; } - for ( XMLHibernateMapping.XMLTypedef typedef : hibernateMapping.getTypedef() ) { + + for ( XMLHibernateMapping.XMLTypedef typedef : mappingRoot().getTypedef() ) { final Map parameters = new HashMap(); for ( XMLParamElement paramElement : typedef.getParam() ) { parameters.put( paramElement.getName(), paramElement.getValue() ); } - getMetadataImplementor().addTypeDefinition( + metadata.addTypeDefinition( new TypeDef( typedef.getName(), typedef.getClazz(), @@ -237,10 +163,11 @@ public class HibernateMappingProcessor implements HbmBindingContext { } private void processFilterDefinitions() { - if(hibernateMapping.getFilterDef() == null){ + if ( mappingRoot().getFilterDef() == null ) { return; } - for ( XMLHibernateMapping.XMLFilterDef filterDefinition : hibernateMapping.getFilterDef() ) { + + for ( XMLHibernateMapping.XMLFilterDef filterDefinition : mappingRoot().getFilterDef() ) { final String name = filterDefinition.getName(); final Map parameters = new HashMap(); String condition = null; @@ -257,45 +184,33 @@ public class HibernateMappingProcessor implements HbmBindingContext { // todo : should really delay this resolution until later to allow typedef names parameters.put( paramElement.getName(), - getMetadataImplementor().getTypeResolver().heuristicType( paramElement.getType() ) + metadata.getTypeResolver().heuristicType( paramElement.getType() ) ); } else { - throw new MappingException( "Unrecognized nested filter content", jaxbRoot.getOrigin() ); + throw new MappingException( "Unrecognized nested filter content", origin() ); } } if ( condition == null ) { condition = filterDefinition.getCondition(); } - getMetadataImplementor().addFilterDefinition( new FilterDefinition( name, condition, parameters ) ); + metadata.addFilterDefinition( new FilterDefinition( name, condition, parameters ) ); } } private void processIdentifierGenerators() { - if ( hibernateMapping.getIdentifierGenerator() == null ) { + if ( mappingRoot().getIdentifierGenerator() == null ) { return; } - for ( XMLHibernateMapping.XMLIdentifierGenerator identifierGeneratorElement : hibernateMapping.getIdentifierGenerator() ) { - getMetadataImplementor().registerIdentifierGenerator( + + for ( XMLHibernateMapping.XMLIdentifierGenerator identifierGeneratorElement : mappingRoot().getIdentifierGenerator() ) { + metadata.registerIdentifierGenerator( identifierGeneratorElement.getName(), identifierGeneratorElement.getClazz() ); } } - public void processMappingMetadata(List processedEntityNames) { - if ( hibernateMapping.getClazzOrSubclassOrJoinedSubclass() == null ) { - return; - } - - final BindingCreator bindingCreator = new BindingCreator( this, processedEntityNames ); - - for ( Object entityElementO : hibernateMapping.getClazzOrSubclassOrJoinedSubclass() ) { - final EntityElement entityElement = (EntityElement) entityElementO; - bindingCreator.createEntityBinding( entityElement, null ); - } - } - public void processMappingDependentMetadata() { processFetchProfiles(); processImports(); @@ -304,10 +219,11 @@ public class HibernateMappingProcessor implements HbmBindingContext { } private void processFetchProfiles(){ - if ( hibernateMapping.getFetchProfile() == null ) { + if ( mappingRoot().getFetchProfile() == null ) { return; } - processFetchProfiles( hibernateMapping.getFetchProfile(), null ); + + processFetchProfiles( mappingRoot().getFetchProfile(), null ); } public void processFetchProfiles(List fetchProfiles, String containingEntityName) { @@ -320,39 +236,42 @@ public class HibernateMappingProcessor implements HbmBindingContext { throw new MappingException( "could not determine entity for fetch-profile fetch [" + profileName + "]:[" + fetch.getAssociation() + "]", - jaxbRoot.getOrigin() + origin() ); } fetches.add( new FetchProfile.Fetch( entityName, fetch.getAssociation(), fetch.getStyle() ) ); } - getMetadataImplementor().addFetchProfile( new FetchProfile( profileName, fetches ) ); + metadata.addFetchProfile( new FetchProfile( profileName, fetches ) ); } } private void processImports() { - if ( hibernateMapping.getImport() == null ) { + if ( mappingRoot().getImport() == null ) { return; } - for ( XMLHibernateMapping.XMLImport importValue : hibernateMapping.getImport() ) { - String className = qualifyClassName( importValue.getClazz() ); + + for ( XMLHibernateMapping.XMLImport importValue : mappingRoot().getImport() ) { + String className = mappingDocument.getMappingLocalBindingContext().qualifyClassName( importValue.getClazz() ); String rename = importValue.getRename(); rename = ( rename == null ) ? StringHelper.unqualify( className ) : rename; - getMetadataImplementor().addImport( className, rename ); + metadata.addImport( className, rename ); } } private void processResultSetMappings() { - if ( hibernateMapping.getResultset() == null ) { + if ( mappingRoot().getResultset() == null ) { return; } + // bindResultSetMappingDefinitions( element, null, mappings ); } private void processNamedQueries() { - if ( hibernateMapping.getQueryOrSqlQuery() == null ) { + if ( mappingRoot().getQueryOrSqlQuery() == null ) { return; } - for ( Object queryOrSqlQuery : hibernateMapping.getQueryOrSqlQuery() ) { + + for ( Object queryOrSqlQuery : mappingRoot().getQueryOrSqlQuery() ) { if ( XMLQueryElement.class.isInstance( queryOrSqlQuery ) ) { // bindNamedQuery( element, null, mappings ); } @@ -362,28 +281,9 @@ public class HibernateMappingProcessor implements HbmBindingContext { else { throw new MappingException( "unknown type of query: " + - queryOrSqlQuery.getClass().getName(), jaxbRoot.getOrigin() + queryOrSqlQuery.getClass().getName(), origin() ); } } } - - private Value classLoaderService = new Value( - new Value.DeferredInitializer() { - @Override - public ClassLoaderService initialize() { - return getMetadataImplementor().getServiceRegistry().getService( ClassLoaderService.class ); - } - } - ); - - @Override - public String qualifyClassName(String unqualifiedName) { - return Helper.qualifyIfNeeded( unqualifiedName, mappingDefaults.getPackageName() ); - } - - @Override - public String determineEntityName(EntityElement entityElement) { - return Helper.determineEntityName( entityElement, mappingDefaults.getPackageName() ); - } } \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HierarchyBuilder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HierarchyBuilder.java new file mode 100644 index 0000000000..662b0859ff --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/HierarchyBuilder.java @@ -0,0 +1,175 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binder.source.hbm; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.hibernate.MappingException; +import org.hibernate.metamodel.binder.source.MetadataImplementor; +import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement; +import org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinedSubclassElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLUnionSubclassElement; + +/** + * @author Steve Ebersole + */ +public class HierarchyBuilder { + private final MetadataImplementor metadata; + + private final List entityHierarchies = new ArrayList(); + + // process state + private final Map subEntityContainerMap = new HashMap(); + private final List extendsQueue = new ArrayList(); + + // mapping file specific state + private MappingDocument currentMappingDocument; + + public HierarchyBuilder(MetadataImplementor metadata) { + this.metadata = metadata; + } + + public void processMappingDocument(MappingDocument mappingDocument) { + this.currentMappingDocument = mappingDocument; + try { + processCurrentMappingDocument(); + } + finally { + this.currentMappingDocument = null; + } + } + + private void processCurrentMappingDocument() { + for ( Object entityElementO : currentMappingDocument.getMappingRoot().getClazzOrSubclassOrJoinedSubclass() ) { + final EntityElement entityElement = (EntityElement) entityElementO; + if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) { + // we can immediately handle elements in terms of creating the hierarchy entry + final XMLHibernateMapping.XMLClass xmlClass = (XMLHibernateMapping.XMLClass) entityElement; + final EntityHierarchy hierarchy = new EntityHierarchy( xmlClass, currentMappingDocument ); + entityHierarchies.add( hierarchy ); + subEntityContainerMap.put( hierarchy.getEntitySourceInformation().getMappedEntityName(), hierarchy ); + processSubElements( entityElement, hierarchy ); + } + else { + // we have to see if this things super-type has been found yet, and if not add it to the + // extends queue + final EntityHierarchySubEntity subEntityDescriptor = new EntityHierarchySubEntity( + entityElement, + currentMappingDocument + ); + final String entityName = subEntityDescriptor.getEntitySourceInformation().getMappedEntityName(); + subEntityContainerMap.put( entityName, subEntityDescriptor ); + final String entityItExtends = currentMappingDocument.getMappingLocalBindingContext().qualifyClassName( + ((SubEntityElement) entityElement).getExtends() + ); + processSubElements( entityElement, subEntityDescriptor ); + final SubEntityContainer container = subEntityContainerMap.get( entityItExtends ); + if ( container != null ) { + // we already have this entity's super, attach it and continue + container.addSubEntityDescriptor( subEntityDescriptor ); + } + else { + // we do not yet have the super and have to wait, so add it fto the extends queue + extendsQueue.add( new ExtendsQueueEntry( subEntityDescriptor, entityItExtends ) ); + } + } + } + } + + public List groupEntityHierarchies() { + while ( ! extendsQueue.isEmpty() ) { + // set up a pass over the queue + int numberOfMappingsProcessed = 0; + Iterator iterator = extendsQueue.iterator(); + while ( iterator.hasNext() ) { + final ExtendsQueueEntry entry = iterator.next(); + final SubEntityContainer container = subEntityContainerMap.get( entry.entityItExtends ); + if ( container != null ) { + // we now have this entity's super, attach it and remove entry from extends queue + container.addSubEntityDescriptor( entry.subEntityDescriptor ); + iterator.remove(); + numberOfMappingsProcessed++; + } + } + + if ( numberOfMappingsProcessed == 0 ) { + // todo : we could log the waiting dependencies... + throw new MappingException( "Unable to process extends dependencies in hbm files" ); + } + } + + return entityHierarchies; + } + + private void processSubElements(EntityElement entityElement, SubEntityContainer container) { + if ( XMLHibernateMapping.XMLClass.class.isInstance( entityElement ) ) { + final XMLHibernateMapping.XMLClass xmlClass = (XMLHibernateMapping.XMLClass) entityElement; + processElements( xmlClass.getJoinedSubclass(), container ); + processElements( xmlClass.getSubclass(), container ); + processElements( xmlClass.getUnionSubclass(), container ); + } + else if ( XMLSubclassElement.class.isInstance( entityElement ) ) { + final XMLSubclassElement xmlSubclass = (XMLSubclassElement) entityElement; + processElements( xmlSubclass.getSubclass(), container ); + } + else if ( XMLJoinedSubclassElement.class.isInstance( entityElement ) ) { + final XMLJoinedSubclassElement xmlJoinedSubclass = (XMLJoinedSubclassElement) entityElement; + processElements( xmlJoinedSubclass.getJoinedSubclass(), container ); + } + else if ( XMLUnionSubclassElement.class.isInstance( entityElement ) ) { + final XMLUnionSubclassElement xmlUnionSubclass = (XMLUnionSubclassElement) entityElement; + processElements( xmlUnionSubclass.getUnionSubclass(), container ); + } + } + + private void processElements(List subElements, SubEntityContainer container) { + for ( Object subElementO : subElements ) { + final SubEntityElement subElement = (SubEntityElement) subElementO; + final EntityHierarchySubEntity subEntityDescriptor = new EntityHierarchySubEntity( + subElement, + currentMappingDocument + ); + container.addSubEntityDescriptor( subEntityDescriptor ); + final String subEntityName = subEntityDescriptor.getEntitySourceInformation().getMappedEntityName(); + subEntityContainerMap.put( subEntityName, subEntityDescriptor ); + } + } + + private static class ExtendsQueueEntry { + private final EntityHierarchySubEntity subEntityDescriptor; + private final String entityItExtends; + + private ExtendsQueueEntry(EntityHierarchySubEntity subEntityDescriptor, String entityItExtends) { + this.subEntityDescriptor = subEntityDescriptor; + this.entityItExtends = entityItExtends; + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/MappingDocument.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/MappingDocument.java new file mode 100644 index 0000000000..feb941cfc6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/MappingDocument.java @@ -0,0 +1,154 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binder.source.hbm; + +import java.util.List; + +import org.hibernate.cfg.NamingStrategy; +import org.hibernate.internal.util.Value; +import org.hibernate.metamodel.binder.Origin; +import org.hibernate.metamodel.binder.source.MappingDefaults; +import org.hibernate.metamodel.binder.source.MetaAttributeContext; +import org.hibernate.metamodel.binder.source.MetadataImplementor; +import org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement; +import org.hibernate.metamodel.binder.source.internal.JaxbRoot; +import org.hibernate.metamodel.domain.Type; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping; +import org.hibernate.service.ServiceRegistry; + +/** + * Aggregates together information about a mapping document. + * + * @author Steve Ebersole + */ +public class MappingDocument { + private final JaxbRoot hbmJaxbRoot; + private final LocalBindingContextImpl mappingLocalBindingContext; + + public MappingDocument(JaxbRoot hbmJaxbRoot, MetadataImplementor metadata) { + this.hbmJaxbRoot = hbmJaxbRoot; + this.mappingLocalBindingContext = new LocalBindingContextImpl( metadata ); + } + + public XMLHibernateMapping getMappingRoot() { + return hbmJaxbRoot.getRoot(); + } + + public Origin getOrigin() { + return hbmJaxbRoot.getOrigin(); + } + + public JaxbRoot getJaxbRoot() { + return hbmJaxbRoot; + } + + public HbmBindingContext getMappingLocalBindingContext() { + return mappingLocalBindingContext; + } + + private class LocalBindingContextImpl implements HbmBindingContext { + private final MetadataImplementor metadata; + private final MetaAttributeContext metaAttributeContext; + + private LocalBindingContextImpl(MetadataImplementor metadata) { + this.metadata = metadata; + if ( hbmJaxbRoot.getRoot().getMeta() == null || hbmJaxbRoot.getRoot().getMeta().isEmpty() ) { + this.metaAttributeContext = new MetaAttributeContext( metadata.getGlobalMetaAttributeContext() ); + } + else { + this.metaAttributeContext = Helper.extractMetaAttributeContext( + hbmJaxbRoot.getRoot().getMeta(), + true, + metadata.getGlobalMetaAttributeContext() + ); + } + } + + @Override + public ServiceRegistry getServiceRegistry() { + return metadata.getServiceRegistry(); + } + + @Override + public NamingStrategy getNamingStrategy() { + return metadata.getNamingStrategy(); + } + + @Override + public MappingDefaults getMappingDefaults() { + return metadata.getMappingDefaults(); + } + + @Override + public MetadataImplementor getMetadataImplementor() { + return metadata; + } + + @Override + public Class locateClassByName(String name) { + return metadata.locateClassByName( name ); + } + + @Override + public Type makeJavaType(String className) { + return metadata.makeJavaType( className ); + } + + @Override + public Value> makeClassReference(String className) { + return metadata.makeClassReference( className ); + } + + @Override + public boolean isAutoImport() { + return hbmJaxbRoot.getRoot().isAutoImport(); + } + + @Override + public MetaAttributeContext getMetaAttributeContext() { + return metaAttributeContext; + } + + @Override + public Origin getOrigin() { + return hbmJaxbRoot.getOrigin(); + } + + @Override + public String qualifyClassName(String unqualifiedName) { + return Helper.qualifyIfNeeded( unqualifiedName, getMappingDefaults().getPackageName() ); + } + + @Override + public String determineEntityName(EntityElement entityElement) { + return Helper.determineEntityName( entityElement, getMappingDefaults().getPackageName() ); + } + + @Override + public void processFetchProfiles(List fetchProfiles, String containingEntityName) { + // todo : this really needs to not be part of the context + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/SubEntityContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/SubEntityContainer.java new file mode 100644 index 0000000000..09bb98b4d3 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/SubEntityContainer.java @@ -0,0 +1,35 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binder.source.hbm; + +/** + * Contract for elements within a {@link EntityHierarchy} which can contain sub elements. Essentially this + * abstracts that common aspect away from both root and sub entities. + * + * @author Steve Ebersole + */ +public interface SubEntityContainer { + public void addSubEntityDescriptor(EntityHierarchySubEntity subEntityDescriptor); + public Iterable subEntityDescriptors(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/EntityElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/EntityElement.java index e81dec0678..5b94d87e70 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/EntityElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/EntityElement.java @@ -26,6 +26,7 @@ package org.hibernate.metamodel.binder.source.hbm.xml.mapping; import java.util.List; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFetchProfileElement; +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLLoaderElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLResultsetElement; import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlDeleteElement; @@ -64,4 +65,6 @@ public interface EntityElement extends MetaAttributeContainer { public List getResultset(); public List getQueryOrSqlQuery(); + + public List getPropertyOrManyToOneOrOneToOne(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/JoinElementSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/JoinElementSource.java new file mode 100644 index 0000000000..a3cf6122be --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/JoinElementSource.java @@ -0,0 +1,35 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.binder.source.hbm.xml.mapping; + +import java.util.List; + +import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinElement; + +/** + * @author Steve Ebersole + */ +public interface JoinElementSource { + public List getJoin(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/SubclassEntityElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/SubEntityElement.java similarity index 94% rename from hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/SubclassEntityElement.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/SubEntityElement.java index 71ba1d74ab..eaea4c68c8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/SubclassEntityElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/hbm/xml/mapping/SubEntityElement.java @@ -26,6 +26,6 @@ package org.hibernate.metamodel.binder.source.hbm.xml.mapping; /** * @author Steve Ebersole */ -public interface SubclassEntityElement extends EntityElement { +public interface SubEntityElement extends EntityElement { public String getExtends(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/internal/MetadataImpl.java index bf4fcdafd8..eb0ee4a5c7 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/internal/MetadataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binder/source/internal/MetadataImpl.java @@ -52,6 +52,7 @@ import org.hibernate.metamodel.binder.source.MappingDefaults; import org.hibernate.metamodel.binder.source.MetaAttributeContext; import org.hibernate.metamodel.binder.source.MetadataImplementor; import org.hibernate.metamodel.binder.source.SourceProcessor; +import org.hibernate.metamodel.binder.source.annotations.AnnotationsSourceProcessor; import org.hibernate.metamodel.binder.source.hbm.HbmSourceProcessorImpl; import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.EntityBinding; @@ -59,13 +60,12 @@ import org.hibernate.metamodel.binding.FetchProfile; import org.hibernate.metamodel.binding.IdGenerator; import org.hibernate.metamodel.binding.PluralAttributeBinding; import org.hibernate.metamodel.binding.TypeDef; -import org.hibernate.metamodel.domain.JavaType; +import org.hibernate.metamodel.domain.BasicType; +import org.hibernate.metamodel.domain.Type; import org.hibernate.metamodel.relational.Database; -import org.hibernate.metamodel.binder.source.annotations.AnnotationsSourceProcessor; import org.hibernate.persister.spi.PersisterClassResolver; import org.hibernate.service.BasicServiceRegistry; import org.hibernate.service.classloading.spi.ClassLoaderService; -import org.hibernate.type.Type; import org.hibernate.type.TypeResolver; /** @@ -311,7 +311,8 @@ public class MetadataImpl implements MetadataImplementor, Serializable { return typeDefs.values(); } - public TypeDef getTypeDef(String name) { + @Override + public TypeDef getTypeDefinition(String name) { return typeDefs.get( name ); } @@ -345,8 +346,9 @@ public class MetadataImpl implements MetadataImplementor, Serializable { } @Override - public JavaType makeJavaType(String className) { - return new JavaType( className, classLoaderService() ); + public Type makeJavaType(String className) { + // todo : have this perform some analysis of the incoming type name to determine appropriate return + return new BasicType( className, makeClassReference( className ) ); } @Override @@ -493,7 +495,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { } @Override - public Type getIdentifierType(String entityName) throws MappingException { + public org.hibernate.type.Type getIdentifierType(String entityName) throws MappingException { EntityBinding entityBinding = getEntityBinding( entityName ); if ( entityBinding == null ) { throw new MappingException( "Entity binding not known: " + entityName ); @@ -516,7 +518,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable { } @Override - public Type getReferencedPropertyType(String entityName, String propertyName) throws MappingException { + public org.hibernate.type.Type getReferencedPropertyType(String entityName, String propertyName) throws MappingException { EntityBinding entityBinding = getEntityBinding( entityName ); if ( entityBinding == null ) { throw new MappingException( "Entity binding not known: " + entityName ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java index 960548a079..38d5d89d1a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java @@ -44,13 +44,14 @@ import org.hibernate.metamodel.relational.state.ValueCreator; import org.hibernate.metamodel.relational.state.ValueRelationalState; /** - * TODO : javadoc + * Basic support for {@link AttributeBinding} implementors * * @author Steve Ebersole */ public abstract class AbstractAttributeBinding implements AttributeBinding { - private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); private final EntityBinding entityBinding; + + private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); private final Set entityReferencingAttributeBindings = new HashSet(); private Attribute attribute; @@ -62,9 +63,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { private Set cascadeTypes; private boolean optimisticLockable; - // DOM4J specific... - private String nodeName; - private MetaAttributeContext metaAttributeContext; protected AbstractAttributeBinding(EntityBinding entityBinding) { @@ -79,7 +77,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { isAlternateUniqueKey = state.isAlternateUniqueKey(); cascadeTypes = state.getCascadeTypes(); optimisticLockable = state.isOptimisticLockable(); - nodeName = state.getNodeName(); metaAttributeContext = state.getMetaAttributeContext(); } @@ -97,6 +94,10 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { this.attribute = attribute; } + public void setValue(Value value) { + this.value = value; + } + protected boolean forceNonNullable() { return false; } @@ -156,10 +157,6 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { return optimisticLockable; } - public String getNodeName() { - return nodeName; - } - @Override public MetaAttributeContext getMetaAttributeContext() { return metaAttributeContext; @@ -256,7 +253,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { return isLazy; } - protected void setLazy(boolean isLazy) { + public void setLazy(boolean isLazy) { this.isLazy = isLazy; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBinding.java index a7ae3df2f3..0427c1503a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AttributeBinding.java @@ -58,7 +58,10 @@ public interface AttributeBinding { public Value getValue(); /** - * Obtain the descriptor for the Hibernate Type for this binding. + * Obtain the descriptor for the Hibernate {@link org.hibernate.type.Type} for this binding. + *

+ * For information about the Java type, query the {@link Attribute} obtained from {@link #getAttribute()} + * instead. * * @return The type descriptor */ diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java index d65925f1b6..c4c1d5c13c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java @@ -41,7 +41,6 @@ public class HibernateTypeDescriptor { return typeName; } - /* package-protected */ public void setTypeName(String typeName) { this.typeName = typeName; } @@ -50,7 +49,6 @@ public class HibernateTypeDescriptor { return explicitType; } - /* package-protected */ public void setExplicitType(Type explicitType) { this.explicitType = explicitType; } @@ -59,7 +57,6 @@ public class HibernateTypeDescriptor { return typeParameters; } - /* package-protected */ void setTypeParameters(Map typeParameters) { this.typeParameters = typeParameters; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleAttributeBinding.java index f458f986ec..fd5571a50e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleAttributeBinding.java @@ -24,7 +24,10 @@ package org.hibernate.metamodel.binding; import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.binder.source.MetaAttributeContext; import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState; +import org.hibernate.metamodel.domain.SingularAttribute; +import org.hibernate.metamodel.relational.Value; import org.hibernate.metamodel.relational.state.ColumnRelationalState; import org.hibernate.metamodel.relational.state.ValueRelationalState; @@ -34,14 +37,20 @@ import org.hibernate.metamodel.relational.state.ValueRelationalState; * @author Steve Ebersole */ public class SimpleAttributeBinding extends AbstractAttributeBinding implements KeyValueBinding { - private final boolean forceNonNullable; - private final boolean forceUnique; private boolean insertable; private boolean updatable; - private boolean keyCascadeDeleteEnabled; - private String unsavedValue; private PropertyGeneration generation; + private String propertyAccessorName; + private String unsavedValue; + + private boolean forceNonNullable; + private boolean forceUnique; + private boolean keyCascadeDeleteEnabled; + + private boolean includedInOptimisticLocking; + private MetaAttributeContext metaAttributeContext; + SimpleAttributeBinding(EntityBinding entityBinding, boolean forceNonNullable, boolean forceUnique) { super( entityBinding ); this.forceNonNullable = forceNonNullable; @@ -67,6 +76,11 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements return isPrimaryKey() || state.isUnique(); } + @Override + public SingularAttribute getAttribute() { + return (SingularAttribute) super.getAttribute(); + } + @Override public boolean isSimpleValue() { return true; @@ -76,7 +90,7 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements return insertable; } - protected void setInsertable(boolean insertable) { + public void setInsertable(boolean insertable) { this.insertable = insertable; } @@ -84,7 +98,7 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements return updatable; } - protected void setUpdatable(boolean updatable) { + public void setUpdatable(boolean updatable) { this.updatable = updatable; } @@ -117,4 +131,32 @@ public class SimpleAttributeBinding extends AbstractAttributeBinding implements public PropertyGeneration getGeneration() { return generation; } + + public void setGeneration(PropertyGeneration generation) { + this.generation = generation; + } + + public String getPropertyAccessorName() { + return propertyAccessorName; + } + + public void setPropertyAccessorName(String propertyAccessorName) { + this.propertyAccessorName = propertyAccessorName; + } + + public boolean isIncludedInOptimisticLocking() { + return includedInOptimisticLocking; + } + + public void setIncludedInOptimisticLocking(boolean includedInOptimisticLocking) { + this.includedInOptimisticLocking = includedInOptimisticLocking; + } + + public MetaAttributeContext getMetaAttributeContext() { + return metaAttributeContext; + } + + public void setMetaAttributeContext(MetaAttributeContext metaAttributeContext) { + this.metaAttributeContext = metaAttributeContext; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java index b9bbfece34..fc894ecfc1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java @@ -88,7 +88,7 @@ public abstract class AbstractAttributeContainer implements AttributeContainer, } @Override - public SingularAttribute getOrCreateSingularAttribute(String name) { + public SingularAttribute locateOrCreateSingularAttribute(String name) { SingularAttribute attribute = (SingularAttribute) getAttribute( name ); if ( attribute == null ) { @@ -99,7 +99,7 @@ public abstract class AbstractAttributeContainer implements AttributeContainer, } @Override - public SingularAttribute getOrCreateComponentAttribute(String name) { + public SingularAttribute locateOrCreateComponentAttribute(String name) { SingularAttribute attribute = (SingularAttribute) getAttribute( name ); if ( attribute == null ) { Component component = new Component( name, null ); @@ -110,27 +110,27 @@ public abstract class AbstractAttributeContainer implements AttributeContainer, } @Override - public PluralAttribute getOrCreateBag(String name) { - return getOrCreatePluralAttribute( name, PluralAttributeNature.BAG ); + public PluralAttribute locateOrCreateBag(String name) { + return locateOrCreatePluralAttribute( name, PluralAttributeNature.BAG ); } @Override - public PluralAttribute getOrCreateSet(String name) { - return getOrCreatePluralAttribute( name, PluralAttributeNature.SET ); + public PluralAttribute locateOrCreateSet(String name) { + return locateOrCreatePluralAttribute( name, PluralAttributeNature.SET ); } @Override - public IndexedPluralAttribute getOrCreateList(String name) { - return (IndexedPluralAttribute) getOrCreatePluralAttribute( name, PluralAttributeNature.LIST ); + public IndexedPluralAttribute locateOrCreateList(String name) { + return (IndexedPluralAttribute) locateOrCreatePluralAttribute( name, PluralAttributeNature.LIST ); } @Override - public IndexedPluralAttribute getOrCreateMap(String name) { - return (IndexedPluralAttribute) getOrCreatePluralAttribute( name, PluralAttributeNature.MAP ); + public IndexedPluralAttribute locateOrCreateMap(String name) { + return (IndexedPluralAttribute) locateOrCreatePluralAttribute( name, PluralAttributeNature.MAP ); } @Override - public PluralAttribute getOrCreatePluralAttribute(String name, PluralAttributeNature nature) { + public PluralAttribute locateOrCreatePluralAttribute(String name, PluralAttributeNature nature) { PluralAttribute attribute = (PluralAttribute) getAttribute( name ); if ( attribute == null ) { attribute = nature.isIndexed() diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java index b48a75deb3..0dabf559d4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AttributeContainer.java @@ -32,13 +32,6 @@ import java.util.Set; * @author Steve Ebersole */ public interface AttributeContainer extends Type { - /** - * Retrieve the attributes contained in this container. - * - * @return The contained attributes - */ - public Set getAttributes(); - /** * Retrieve an attribute by name. * @@ -48,17 +41,18 @@ public interface AttributeContainer extends Type { */ public Attribute getAttribute(String name); - public SingularAttribute getOrCreateSingularAttribute(String name); + /** + * Retrieve the attributes contained in this container. + * + * @return The contained attributes + */ + public Set getAttributes(); - public SingularAttribute getOrCreateComponentAttribute(String name); - - public PluralAttribute getOrCreatePluralAttribute(String name, PluralAttributeNature nature); - - public PluralAttribute getOrCreateBag(String name); - - public PluralAttribute getOrCreateSet(String name); - - public IndexedPluralAttribute getOrCreateList(String name); - - public IndexedPluralAttribute getOrCreateMap(String name); + public SingularAttribute locateOrCreateSingularAttribute(String name); + public SingularAttribute locateOrCreateComponentAttribute(String name); + public PluralAttribute locateOrCreatePluralAttribute(String name, PluralAttributeNature nature); + public PluralAttribute locateOrCreateBag(String name); + public PluralAttribute locateOrCreateSet(String name); + public IndexedPluralAttribute locateOrCreateList(String name); + public IndexedPluralAttribute locateOrCreateMap(String name); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/AbstractTableSpecification.java b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/AbstractTableSpecification.java index b5a3461c14..d768d9df1e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/AbstractTableSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/AbstractTableSpecification.java @@ -56,8 +56,8 @@ public abstract class AbstractTableSpecification implements TableSpecification { } @Override - public Column getOrCreateColumn(String name) { - if ( values.containsKey( name ) ) { + public Column locateOrCreateColumn(String name) { + if(values.containsKey( name )){ return (Column) values.get( name ); } final Column column = new Column( this, values.size(), name ); @@ -66,8 +66,8 @@ public abstract class AbstractTableSpecification implements TableSpecification { } @Override - public DerivedValue getOrCreateDerivedValue(String fragment) { - if ( values.containsKey( fragment ) ) { + public DerivedValue locateOrCreateDerivedValue(String fragment) { + if(values.containsKey( fragment )){ return (DerivedValue) values.get( fragment ); } final DerivedValue value = new DerivedValue( this, values.size(), fragment ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/TableSpecification.java b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/TableSpecification.java index 86752c3552..69fbd02d55 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/TableSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/TableSpecification.java @@ -59,7 +59,7 @@ public interface TableSpecification extends ValueContainer, Loggable { * * @return The generated column */ - public Column getOrCreateColumn(String name); + public Column locateOrCreateColumn(String name); /** * Factory method for creating a {@link Column} associated with this container. @@ -77,7 +77,7 @@ public interface TableSpecification extends ValueContainer, Loggable { * * @return The generated value. */ - public DerivedValue getOrCreateDerivedValue(String fragment); + public DerivedValue locateOrCreateDerivedValue(String fragment); public Iterable getForeignKeys(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/state/ValueCreator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/state/ValueCreator.java index 3e97cce8cd..8081d6a89a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/relational/state/ValueCreator.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/relational/state/ValueCreator.java @@ -37,12 +37,12 @@ import org.hibernate.metamodel.relational.Value; */ public class ValueCreator { - public static Column createColumn(TableSpecification table, - String attributeName, - ColumnRelationalState state, - boolean forceNonNullable, - boolean forceUnique - ) { + public static Column createColumn( + TableSpecification table, + String attributeName, + ColumnRelationalState state, + boolean forceNonNullable, + boolean forceUnique) { final String explicitName = state.getExplicitColumnName(); final String logicalColumnName = state.getNamingStrategy().logicalColumnName( explicitName, attributeName ); String columnName = @@ -55,25 +55,26 @@ public class ValueCreator { if ( columnName == null ) { throw new IllegalArgumentException( "columnName must be non-null." ); } - if( state.isGloballyQuotedIdentifiers()){ + if ( state.isGloballyQuotedIdentifiers() ) { columnName = StringHelper.quote( columnName ); } - Column value = table.getOrCreateColumn( columnName ); + Column value = table.locateOrCreateColumn( columnName ); value.initialize( state, forceNonNullable, forceUnique ); return value; } - public static DerivedValue createDerivedValue(TableSpecification table, - DerivedValueRelationalState state) { - return table.getOrCreateDerivedValue( state.getFormula() ); + public static DerivedValue createDerivedValue( + TableSpecification table, + DerivedValueRelationalState state) { + return table.locateOrCreateDerivedValue( state.getFormula() ); } - public static SimpleValue createSimpleValue(TableSpecification table, - String attributeName, - SimpleValueRelationalState state, - boolean forceNonNullable, - boolean forceUnique - ) { + public static SimpleValue createSimpleValue( + TableSpecification table, + String attributeName, + SimpleValueRelationalState state, + boolean forceNonNullable, + boolean forceUnique) { if ( state instanceof ColumnRelationalState ) { ColumnRelationalState columnRelationalState = ColumnRelationalState.class.cast( state ); return createColumn( table, attributeName, columnRelationalState, forceNonNullable, forceUnique ); @@ -86,12 +87,12 @@ public class ValueCreator { } } - public static Tuple createTuple(TableSpecification table, - String attributeName, - TupleRelationalState state, - boolean forceNonNullable, - boolean forceUnique - ) { + public static Tuple createTuple( + TableSpecification table, + String attributeName, + TupleRelationalState state, + boolean forceNonNullable, + boolean forceUnique) { Tuple tuple = table.createTuple( "[" + attributeName + "]" ); for ( SimpleValueRelationalState valueState : state.getRelationalStates() ) { tuple.addValue( createSimpleValue( table, attributeName, valueState, forceNonNullable, forceUnique ) ); @@ -99,11 +100,12 @@ public class ValueCreator { return tuple; } - public static Value createValue(TableSpecification table, - String attributeName, - ValueRelationalState state, - boolean forceNonNullable, - boolean forceUnique) { + public static Value createValue( + TableSpecification table, + String attributeName, + ValueRelationalState state, + boolean forceNonNullable, + boolean forceUnique) { Value value = null; if ( SimpleValueRelationalState.class.isInstance( state ) ) { value = createSimpleValue( diff --git a/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb b/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb index e10ce58606..34668f34c7 100644 --- a/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb +++ b/hibernate-core/src/main/xjb/hbm-mapping-bindings.xjb @@ -20,15 +20,17 @@ org.hibernate.metamodel.binder.source.hbm.xml.mapping.EntityElement + org.hibernate.metamodel.binder.source.hbm.xml.mapping.JoinElementSource - org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement + org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement + org.hibernate.metamodel.binder.source.hbm.xml.mapping.JoinElementSource - org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement + org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement - org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubclassEntityElement + org.hibernate.metamodel.binder.source.hbm.xml.mapping.SubEntityElement org.hibernate.metamodel.binder.source.hbm.xml.mapping.CustomSqlElement diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java index 4f648a287a..633a990aea 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/SimpleValueBindingTests.java @@ -29,7 +29,6 @@ import org.junit.Test; import org.hibernate.internal.util.Value; import org.hibernate.metamodel.domain.Entity; -import org.hibernate.metamodel.domain.JavaType; import org.hibernate.metamodel.domain.SingularAttribute; import org.hibernate.metamodel.relational.Column; import org.hibernate.metamodel.relational.Datatype; @@ -61,14 +60,14 @@ public class SimpleValueBindingTests extends BaseUnitTestCase { entityBinding.setEntity( entity ); entityBinding.setBaseTable( table ); - SingularAttribute idAttribute = entity.getOrCreateSingularAttribute( "id" ); + SingularAttribute idAttribute = entity.locateOrCreateSingularAttribute( "id" ); SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleAttributeBinding( idAttribute ); attributeBinding.getHibernateTypeDescriptor().setTypeName( "long" ); assertSame( idAttribute, attributeBinding.getAttribute() ); entityBinding.getEntityIdentifier().setValueBinding( attributeBinding ); - Column idColumn = table.getOrCreateColumn( "id" ); + Column idColumn = table.locateOrCreateColumn( "id" ); idColumn.setDatatype( BIGINT ); idColumn.setSize( Size.precision( 18, 0 ) ); table.getPrimaryKey().addColumn( idColumn ); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/relational/TableManipulationTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/relational/TableManipulationTests.java index 4e0ac45c93..6974fff0e2 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/relational/TableManipulationTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/relational/TableManipulationTests.java @@ -54,7 +54,7 @@ public class TableManipulationTests extends BaseUnitTestCase { assertNull( table.getPrimaryKey().getName() ); assertFalse( table.values().iterator().hasNext() ); - Column idColumn = table.getOrCreateColumn( "id" ); + Column idColumn = table.locateOrCreateColumn( "id" ); idColumn.setDatatype( INTEGER ); idColumn.setSize( Size.precision( 18, 0 ) ); table.getPrimaryKey().addColumn( idColumn ); @@ -62,7 +62,7 @@ public class TableManipulationTests extends BaseUnitTestCase { assertEquals( "my_table_pk", table.getPrimaryKey().getName() ); assertEquals( "my_table.PK", table.getPrimaryKey().getExportIdentifier() ); - Column col_1 = table.getOrCreateColumn( "col_1" ); + Column col_1 = table.locateOrCreateColumn( "col_1" ); col_1.setDatatype( VARCHAR ); col_1.setSize( Size.length( 512 ) ); @@ -107,7 +107,7 @@ public class TableManipulationTests extends BaseUnitTestCase { Schema schema = new Schema( null, null ); Table book = schema.createTable( Identifier.toIdentifier( "BOOK" ) ); - Column bookId = book.getOrCreateColumn( "id" ); + Column bookId = book.locateOrCreateColumn( "id" ); bookId.setDatatype( INTEGER ); bookId.setSize( Size.precision( 18, 0 ) ); book.getPrimaryKey().addColumn( bookId ); @@ -115,13 +115,13 @@ public class TableManipulationTests extends BaseUnitTestCase { Table page = schema.createTable( Identifier.toIdentifier( "PAGE" ) ); - Column pageId = page.getOrCreateColumn( "id" ); + Column pageId = page.locateOrCreateColumn( "id" ); pageId.setDatatype( INTEGER ); pageId.setSize( Size.precision( 18, 0 ) ); page.getPrimaryKey().addColumn( pageId ); page.getPrimaryKey().setName( "PAGE_PK" ); - Column pageBookId = page.getOrCreateColumn( "BOOK_ID" ); + Column pageBookId = page.locateOrCreateColumn( "BOOK_ID" ); pageId.setDatatype( INTEGER ); pageId.setSize( Size.precision( 18, 0 ) ); ForeignKey pageBookFk = page.createForeignKey( book, "PAGE_BOOK_FK" ); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/TestAnnotationsBindingContextImpl.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/TestAnnotationsBindingContextImpl.java index 99fa5039b5..5864344a7c 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/TestAnnotationsBindingContextImpl.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/TestAnnotationsBindingContextImpl.java @@ -41,7 +41,7 @@ import org.hibernate.internal.util.Value; import org.hibernate.metamodel.binder.source.MappingDefaults; import org.hibernate.metamodel.binder.source.MetadataImplementor; import org.hibernate.metamodel.binder.source.annotations.AnnotationsBindingContext; -import org.hibernate.metamodel.domain.JavaType; +import org.hibernate.metamodel.domain.Type; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.classloading.spi.ClassLoaderService; @@ -93,7 +93,7 @@ public class TestAnnotationsBindingContextImpl implements AnnotationsBindingCont } @Override - public JavaType makeJavaType(String className) { + public Type makeJavaType(String className) { throw new NotYetImplementedException(); }