diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BagBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BagBinding.java index c00bfc332c..604957677a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BagBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/BagBinding.java @@ -31,8 +31,8 @@ import org.hibernate.metamodel.binding.state.PluralAttributeBindingState; * @author Steve Ebersole */ public class BagBinding extends PluralAttributeBinding { - protected BagBinding(EntityBinding entityBinding) { - super( entityBinding ); + protected BagBinding(EntityBinding entityBinding, CollectionElementType collectionElementType) { + super( entityBinding, collectionElementType ); } public BagBinding initialize(PluralAttributeBindingState bindingState) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java index 22edb0f25a..c1fa1c6150 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java @@ -30,17 +30,22 @@ import org.hibernate.metamodel.relational.Value; * * @author Steve Ebersole */ -public class CollectionElement { +public abstract class CollectionElement { private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); private final PluralAttributeBinding collectionBinding; - + private final CollectionElementType collectionElementType; private String nodeName; private Value elementValue; - CollectionElement(PluralAttributeBinding collectionBinding) { + CollectionElement(PluralAttributeBinding collectionBinding, CollectionElementType collectionElementType) { this.collectionBinding = collectionBinding; + this.collectionElementType = collectionElementType; + } + + public final CollectionElementType getCollectionElementType() { + return collectionElementType; } /* package-protected */ @@ -52,4 +57,13 @@ public class CollectionElement { void setNodeName(String nodeName) { this.nodeName = nodeName; } + + public boolean isOneToMany() { + return collectionElementType.isOneToMany(); + } + + public boolean isManyToMany() { + return collectionElementType.isManyToMany(); + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElementType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElementType.java new file mode 100644 index 0000000000..254305a184 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElementType.java @@ -0,0 +1,104 @@ +/* + * 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.binding; + +/** + * @author Gail Badner + */ +public enum CollectionElementType { + ELEMENT( "element" ) { + public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) { + return new ElementCollectionElement( attributeBinding ); + } + }, + COMPOSITE_ELEMENT( "composite-element" ) { + public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) { + return new ElementCollectionElement( attributeBinding ); + } + }, + ONE_TO_MANY( "one-to-many" ) { + public boolean isOneToMany() { + return true; + } + public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) { + return new OneToManyCollectionElement( attributeBinding ); + } + }, + MANY_TO_MANY( "many-to-many" ) { + public boolean isManyToMany() { + return true; + } + public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) { + return new ManyToManyCollectionElement( attributeBinding ); + } + }, + MANY_TO_ANY( "many-to-any" ) { + //TODO: should isManyToMany() return true? + public boolean isManyToAny() { + return true; + } + public CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding) { + return new ManyToAnyCollectionElement( attributeBinding ); + } + }; + + private final String name; + + private CollectionElementType(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public String toString() { + return super.toString() + "[" + getName() + "]"; + } + + public boolean isOneToMany() { + return false; + } + + public boolean isManyToMany() { + return false; + } + + public boolean isManyToAny() { + return false; + } + + protected abstract CollectionElement createCollectionElementInternal(PluralAttributeBinding attributeBinding); + + /* package-protected */ + CollectionElement createCollectionElement(PluralAttributeBinding attributeBinding) { + CollectionElement collectionElement = createCollectionElementInternal( attributeBinding ); + if ( collectionElement.getCollectionElementType() != this ) { + throw new IllegalStateException( "Collection element has unexpected type nature: actual=[" + + collectionElement.getCollectionElementType() + "; expected=[" + this + "]" ); + } + return collectionElement; + } +} + diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ElementCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ElementCollectionElement.java index 461ce60eff..c5946d3737 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ElementCollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ElementCollectionElement.java @@ -30,6 +30,6 @@ import org.dom4j.Element; */ public class ElementCollectionElement extends CollectionElement { public ElementCollectionElement(PluralAttributeBinding binding) { - super( binding ); + super( binding, CollectionElementType.ELEMENT ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java index 83effb1d8b..f1e86e1159 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityBinding.java @@ -270,8 +270,8 @@ public class EntityBinding { return binding; } - public BagBinding makeBagAttributeBinding(String attributeName) { - final BagBinding binding = new BagBinding( this ); + public BagBinding makeBagAttributeBinding(String attributeName, CollectionElementType collectionElementType) { + final BagBinding binding = new BagBinding( this, collectionElementType ); registerAttributeBinding( attributeName, binding ); binding.setAttribute( entity.getAttribute( attributeName ) ); return binding; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToAnyCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToAnyCollectionElement.java new file mode 100644 index 0000000000..895caa0fee --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToAnyCollectionElement.java @@ -0,0 +1,37 @@ +/* + * 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.binding; + +import java.util.HashMap; + +import org.dom4j.Element; + +/** + * @author Gail Badner + */ +public class ManyToAnyCollectionElement extends CollectionElement { + ManyToAnyCollectionElement(PluralAttributeBinding binding) { + super( binding, CollectionElementType.MANY_TO_ANY ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToManyCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToManyCollectionElement.java index 6bc7b20fbc..c300517473 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToManyCollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/ManyToManyCollectionElement.java @@ -36,8 +36,8 @@ public class ManyToManyCollectionElement extends CollectionElement { private String manyToManyOrderBy; - ManyToManyCollectionElement(Element collectionNode, PluralAttributeBinding binding) { - super( binding ); + ManyToManyCollectionElement(PluralAttributeBinding binding) { + super( binding, CollectionElementType.MANY_TO_MANY ); } public void fromHbmXml(Element node){ diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/OneToManyCollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/OneToManyCollectionElement.java new file mode 100644 index 0000000000..aae79124f5 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/OneToManyCollectionElement.java @@ -0,0 +1,34 @@ +/* + * 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.binding; + +/** + * @author Gail Badner + */ +public class OneToManyCollectionElement extends CollectionElement { + + OneToManyCollectionElement(PluralAttributeBinding binding) { + super( binding, CollectionElementType.ONE_TO_MANY ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/PluralAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/PluralAttributeBinding.java index c34b1e8b50..c5ae11d26c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/PluralAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/PluralAttributeBinding.java @@ -79,9 +79,9 @@ public abstract class PluralAttributeBinding extends AbstractAttributeBinding { private String loaderName; - protected PluralAttributeBinding(EntityBinding entityBinding) { + protected PluralAttributeBinding(EntityBinding entityBinding, CollectionElementType collectionElementType) { super( entityBinding ); - collectionElement = new CollectionElement( this ); + collectionElement = collectionElementType.createCollectionElement( this ); } protected void initializeBinding(PluralAttributeBindingState state) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java index d2ab3058ca..e0b3dd2644 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java @@ -25,6 +25,7 @@ package org.hibernate.metamodel.source.hbm; import org.dom4j.Attribute; +import org.hibernate.AssertionFailure; import org.hibernate.EntityMode; import org.hibernate.MappingException; import org.hibernate.cfg.NamingStrategy; @@ -32,6 +33,7 @@ import org.hibernate.engine.internal.Versioning; import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.BagBinding; +import org.hibernate.metamodel.binding.CollectionElementType; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.ManyToOneAttributeBinding; import org.hibernate.metamodel.binding.SimpleAttributeBinding; @@ -489,13 +491,36 @@ PrimitiveArray entityBinding.getMetaAttributes() ); - BagBinding collectionBinding = entityBinding.makeBagAttributeBinding( bindingState.getAttributeName() ) + BagBinding collectionBinding = entityBinding.makeBagAttributeBinding( + bindingState.getAttributeName(), + getCollectionElementType( collection ) ) .initialize( bindingState ); // todo : relational model binding return collectionBinding; } + private CollectionElementType getCollectionElementType(XMLBagElement collection) { + if ( collection.getElement() != null ) { + return CollectionElementType.ELEMENT; + } + else if ( collection.getCompositeElement() != null ) { + return CollectionElementType.COMPOSITE_ELEMENT; + } + else if ( collection.getManyToMany() != null ) { + return CollectionElementType.MANY_TO_MANY; + } + else if ( collection.getOneToMany() != null ) { + return CollectionElementType.ONE_TO_MANY; + } + else if ( collection.getManyToAny() != null ) { + return CollectionElementType.MANY_TO_ANY; + } + else { + throw new AssertionFailure( "Unknown collection element type: " + collection ); + } + } + private ManyToOneAttributeBinding makeManyToOneAttributeBinding(XMLManyToOneElement manyToOne, EntityBinding entityBinding) { ManyToOneAttributeBindingState bindingState =