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 518ee2035d..3d46066fec 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 @@ -47,6 +47,18 @@ import org.hibernate.metamodel.source.util.DomHelper; * @author Steve Ebersole */ public abstract class AbstractAttributeBinding implements AttributeBinding { + public static interface DomainState { + HibernateTypeDescriptor getHibernateTypeDescriptor(); + Attribute getAttribute(); + boolean isLazy(); + String getPropertyAccessorName(); + boolean isAlternateUniqueKey(); + String getCascade(); + boolean isOptimisticLockable(); + String getNodeName(); + Map getMetaAttributes(EntityBinding entityBinding); + } + private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); private final EntityBinding entityBinding; @@ -55,7 +67,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { private boolean isLazy; private String propertyAccessorName; - private boolean alternateUniqueKey; + private boolean isAlternateUniqueKey; private String cascade; private boolean optimisticLockable; @@ -68,22 +80,16 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { this.entityBinding = entityBinding; } - public void fromHbmXml(MappingDefaults defaults, Element element, Attribute attribute) { - this.attribute = attribute; - hibernateTypeDescriptor.setTypeName( DomHelper.extractAttributeValue( element, "type", null ) ); - - metaAttributes = HbmHelper.extractMetas( element, entityBinding.getMetaAttributes() ); - nodeName = DomHelper.extractAttributeValue( element, "node", attribute.getName() ); - isLazy = DomHelper.extractBooleanAttributeValue( element, "lazy", isLazyDefault( defaults ) ); - propertyAccessorName = ( - DomHelper.extractAttributeValue( - element, - "access", - isEmbedded() ? "embedded" : defaults.getDefaultAccess() - ) - ); - cascade = DomHelper.extractAttributeValue( element, "cascade", defaults.getDefaultCascade() ); - optimisticLockable = DomHelper.extractBooleanAttributeValue( element, "optimistic-lock", true ); + public void initialize(DomainState state) { + hibernateTypeDescriptor.intialize( state.getHibernateTypeDescriptor() ); + attribute = state.getAttribute(); + isLazy = state.isLazy(); + propertyAccessorName = state.getPropertyAccessorName(); + isAlternateUniqueKey = state.isAlternateUniqueKey(); + cascade = state.getCascade(); + optimisticLockable = state.isOptimisticLockable(); + nodeName = state.getNodeName(); + metaAttributes = state.getMetaAttributes( entityBinding ); } @Override @@ -164,11 +170,11 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { @Override public boolean isAlternateUniqueKey() { - return alternateUniqueKey; + return isAlternateUniqueKey; } public void setAlternateUniqueKey(boolean alternateUniqueKey) { - this.alternateUniqueKey = alternateUniqueKey; + this.isAlternateUniqueKey = alternateUniqueKey; } @Override 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 954a74b615..cc9bdc2f7f 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 @@ -116,6 +116,5 @@ public interface AttributeBinding { public boolean[] getColumnUpdateability(); public boolean[] getColumnInsertability(); public boolean isSimpleValue(); - public boolean isEmbedded(); public boolean isLazy(); } 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 25ac5c4023..15e4a992a2 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 @@ -25,6 +25,7 @@ package org.hibernate.metamodel.binding; import org.dom4j.Element; +import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.Value; import org.hibernate.metamodel.source.hbm.HbmHelper; import org.hibernate.metamodel.source.util.DomHelper; @@ -35,6 +36,11 @@ import org.hibernate.metamodel.source.util.DomHelper; * @author Steve Ebersole */ public class CollectionElement { + public static interface DomainState { + HibernateTypeDescriptor getHibernateTypeDescriptor(); + String getNodeName(); + } + private final HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); private final PluralAttributeBinding collectionBinding; @@ -46,7 +52,8 @@ public class CollectionElement { this.collectionBinding = collectionBinding; } - public void fromHbmXml(Element node) { - nodeName = DomHelper.extractAttributeValue( node, "node", null ); + public void initialize(DomainState state) { + hibernateTypeDescriptor.intialize( state.getHibernateTypeDescriptor() ); + nodeName = state.getNodeName(); } } 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 2a8b94499d..461ce60eff 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 @@ -32,8 +32,4 @@ public class ElementCollectionElement extends CollectionElement { public ElementCollectionElement(PluralAttributeBinding binding) { super( binding ); } - - public void fromHbmXml() { - //TODO: - } } 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 4ce3433066..22fae42ee2 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 @@ -84,6 +84,7 @@ public class EntityBinding { private List synchronizedTableNames; + // TODO: change to initialize from DomainState public void fromHbmXml(MappingDefaults defaults, Element node, Entity entity) { this.entity = entity; metaAttributes = HbmHelper.extractMetas( node, true, defaults.getMappingMetas() ); 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 738b982d3d..b4bdc4120f 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 @@ -52,4 +52,10 @@ public class HibernateTypeDescriptor { public void setExplicitType(Type explicitType) { this.explicitType = explicitType; } + + public void intialize(HibernateTypeDescriptor hibernateTypeDescriptor) { + typeName = hibernateTypeDescriptor.typeName; + explicitType = hibernateTypeDescriptor.explicitType; + typeParameters = hibernateTypeDescriptor.typeParameters; + } } 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 914d3dcaf3..e2c2087855 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 @@ -27,6 +27,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.Map; import org.dom4j.Attribute; import org.dom4j.Element; @@ -35,7 +36,9 @@ import org.jboss.logging.Logger; import org.hibernate.FetchMode; import org.hibernate.HibernateLogger; import org.hibernate.MappingException; +import org.hibernate.mapping.MetaAttribute; import org.hibernate.metamodel.relational.Table; +import org.hibernate.metamodel.relational.Value; import org.hibernate.metamodel.source.hbm.HbmHelper; import org.hibernate.metamodel.source.util.DomHelper; @@ -46,6 +49,36 @@ import org.hibernate.metamodel.source.util.DomHelper; */ public abstract class PluralAttributeBinding extends AbstractAttributeBinding { + public static interface DomainState extends AbstractAttributeBinding.DomainState { + FetchMode getFetchMode(); + boolean isExtraLazy(); + CollectionElement getCollectionElement(PluralAttributeBinding binding); + boolean isInverse(); + boolean isMutable(); + boolean isSubselectLoadable(); + String getCacheConcurrencyStrategy(); + String getCacheRegionName(); + String getOrderBy(); + String getWhere(); + String getReferencedPropertyName(); + boolean isSorted(); + Comparator getComparator(); + String getComparatorClassName(); + boolean isOrphanDelete(); + int getBatchSize(); + boolean isEmbedded(); + boolean isOptimisticLocked(); + Class getCollectionPersisterClass(); + String getTypeName(); + java.util.Map getFilters(); + java.util.Set getSynchronizedTables(); + CustomSQL getCustomSQLInsert(); + CustomSQL getCustomSQLUpdate(); + CustomSQL getCustomSQLDelete(); + CustomSQL getCustomSQLDeleteAll(); + String getLoaderName(); + } + private static final HibernateLogger LOG = Logger.getMessageLogger( HibernateLogger.class, PluralAttributeBinding.class.getName() ); @@ -76,7 +109,7 @@ public abstract class PluralAttributeBinding extends AbstractAttributeBinding { private Class collectionPersisterClass; private String typeName; private final java.util.Map filters = new HashMap(); - private final java.util.Set synchronizedTables = new HashSet(); + private final java.util.Set synchronizedTables = new HashSet(); private CustomSQL customSQLInsert; private CustomSQL customSQLUpdate; @@ -90,8 +123,42 @@ public abstract class PluralAttributeBinding extends AbstractAttributeBinding { collectionElement = new CollectionElement( this ); } + public void initialize(DomainState state) { + super.initialize( state ); + fetchMode = state.getFetchMode(); + extraLazy = state.isExtraLazy(); + collectionElement = state.getCollectionElement( this ); + inverse = state.isInverse(); + mutable = state.isMutable(); + subselectLoadable = state.isSubselectLoadable(); + if ( isSubselectLoadable() ) { + getEntityBinding().setSubselectLoadableCollections( true ); + } + cacheConcurrencyStrategy = state.getCacheConcurrencyStrategy(); + cacheRegionName = state.getCacheRegionName(); + orderBy = state.getOrderBy(); + where = state.getWhere(); + referencedPropertyName = state.getReferencedPropertyName(); + sorted = state.isSorted(); + comparator = state.getComparator(); + comparatorClassName = state.getComparatorClassName(); + orphanDelete = state.isOrphanDelete(); + batchSize = state.getBatchSize(); + embedded = state.isEmbedded(); + optimisticLocked = state.isOptimisticLocked(); + collectionPersisterClass = state.getCollectionPersisterClass(); + typeName = state.getTypeName(); + filters.putAll( state.getFilters() ); + synchronizedTables.addAll( state.getSynchronizedTables() ); + customSQLInsert = state.getCustomSQLInsert(); + customSQLUpdate = state.getCustomSQLUpdate(); + customSQLDelete = state.getCustomSQLDelete(); + customSQLDeleteAll = state.getCustomSQLDeleteAll(); + loaderName = state.getLoaderName(); + } + + public void fromHbmXml(MappingDefaults defaults, Element element, org.hibernate.metamodel.domain.Attribute attribute) { - super.fromHbmXml( defaults, element, attribute ); inverse = DomHelper.extractBooleanAttributeValue( element, "inverse", false ); mutable = DomHelper.extractBooleanAttributeValue( element, "mutable", true ); if ( "subselect".equals( element.attributeValue("fetch") ) ) { @@ -283,11 +350,6 @@ public abstract class PluralAttributeBinding extends AbstractAttributeBinding { return batchSize; } - @Override - public boolean isEmbedded() { - return embedded; - } - public boolean isOptimisticLocked() { return optimisticLocked; } 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 b93d533e00..a4f6bd0a86 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 @@ -28,7 +28,6 @@ import org.dom4j.Element; import org.hibernate.MappingException; import org.hibernate.mapping.PropertyGeneration; -import org.hibernate.metamodel.source.hbm.HbmHelper; import org.hibernate.metamodel.source.util.DomHelper; /** @@ -37,54 +36,18 @@ import org.hibernate.metamodel.source.util.DomHelper; * @author Steve Ebersole */ public class SimpleAttributeBinding extends SingularAttributeBinding { + public static interface DomainState extends SingularAttributeBinding.DomainState { + public abstract PropertyGeneration getPropertyGeneration(); + } private PropertyGeneration generation; - private boolean isLazy; SimpleAttributeBinding(EntityBinding entityBinding) { super( entityBinding ); } - public void fromHbmXml(MappingDefaults defaults, Element element, org.hibernate.metamodel.domain.Attribute attribute) { - super.fromHbmXml( defaults, element, attribute ); - this.isLazy = DomHelper.extractBooleanAttributeValue( element, "lazy", false ); - this.generation = PropertyGeneration.parse( DomHelper.extractAttributeValue( element, "generated", null ) ); - if ( generation == PropertyGeneration.ALWAYS || generation == PropertyGeneration.INSERT ) { - // generated properties can *never* be insertable... - if ( isInsertable() ) { - final Attribute insertAttribute = element.attribute( "insert" ); - if ( insertAttribute == null ) { - // insertable simply because the user did not specify anything; just override it - setInsertable( false ); - } - else { - // the user specifically supplied insert="true", which constitutes an illegal combo - throw new MappingException( - "cannot specify both insert=\"true\" and generated=\"" + generation.getName() + - "\" for property: " + - getAttribute().getName() - ); - } - } - - // properties generated on update can never be updateable... - if ( isUpdateable() && generation == PropertyGeneration.ALWAYS ) { - final Attribute updateAttribute = element.attribute( "update" ); - if ( updateAttribute == null ) { - // updateable only because the user did not specify - // anything; just override it - setUpdateable( false ); - } - else { - // the user specifically supplied update="true", - // which constitutes an illegal combo - throw new MappingException( - "cannot specify both update=\"true\" and generated=\"" + generation.getName() + - "\" for property: " + - getAttribute().getName() - ); - } - } - } + public final void initialize(DomainState state) { + super.initialize( state ); + generation = state.getPropertyGeneration(); } protected boolean isLazyDefault(MappingDefaults defaults) { @@ -99,14 +62,4 @@ public class SimpleAttributeBinding extends SingularAttributeBinding { public PropertyGeneration getGeneration() { return generation; } - - @Override - public boolean isLazy() { - return isLazy; - } - - @Override - public boolean isEmbedded() { - return false; - } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SingularAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SingularAttributeBinding.java index 82f2e7aa0d..6139d87a8b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SingularAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SingularAttributeBinding.java @@ -26,7 +26,6 @@ package org.hibernate.metamodel.binding; import org.dom4j.Element; import org.hibernate.metamodel.domain.Attribute; -import org.hibernate.metamodel.source.hbm.HbmHelper; import org.hibernate.metamodel.source.util.DomHelper; /** @@ -35,6 +34,13 @@ import org.hibernate.metamodel.source.util.DomHelper; * @author Gail Badner */ public abstract class SingularAttributeBinding extends AbstractAttributeBinding implements KeyValueBinding { + public static interface DomainState extends AbstractAttributeBinding.DomainState { + boolean isInsertable(); + boolean isUpdateable(); + boolean isKeyCasadeDeleteEnabled(); + String getUnsavedValue(); + } + private boolean insertable; private boolean updateable; private boolean keyCasadeDeleteEnabled; @@ -44,10 +50,12 @@ public abstract class SingularAttributeBinding extends AbstractAttributeBinding super( entityBinding ); } - public void fromHbmXml(MappingDefaults defaults, Element element, Attribute attribute) { - super.fromHbmXml( defaults, element, attribute ); - insertable = DomHelper.extractBooleanAttributeValue( element, "insert", true ); - updateable = DomHelper.extractBooleanAttributeValue( element, "update", true ); + public final void initialize(DomainState state) { + super.initialize( state ); + insertable = state.isInsertable(); + updateable = state.isUpdateable(); + keyCasadeDeleteEnabled = state.isKeyCasadeDeleteEnabled(); + unsavedValue = state.getUnsavedValue(); } public boolean isInsertable() { 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 a50d76d602..c3561ac267 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 @@ -27,7 +27,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.StringTokenizer; import org.dom4j.Attribute; @@ -38,13 +37,9 @@ import org.hibernate.HibernateLogger; import org.hibernate.MappingException; import org.hibernate.cfg.NamingStrategy; import org.hibernate.engine.Versioning; -import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.StringHelper; -import org.hibernate.mapping.MetaAttribute; import org.hibernate.metamodel.binding.AttributeBinding; import org.hibernate.metamodel.binding.BagBinding; -import org.hibernate.metamodel.binding.CollectionElement; -import org.hibernate.metamodel.binding.ElementCollectionElement; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.metamodel.binding.PluralAttributeBinding; import org.hibernate.metamodel.binding.SimpleAttributeBinding; @@ -61,7 +56,8 @@ import org.hibernate.metamodel.relational.Tuple; import org.hibernate.metamodel.relational.UniqueKey; import org.hibernate.metamodel.relational.Value; import org.hibernate.metamodel.source.Metadata; -import org.hibernate.metamodel.source.util.DomHelper; +import org.hibernate.metamodel.source.hbm.state.domain.HbmPluralAttributeDomainState; +import org.hibernate.metamodel.source.hbm.state.domain.HbmSimpleAttributeDomainState; /** * TODO : javadoc @@ -142,10 +138,6 @@ abstract class AbstractEntityBinder { return hibernateMappingBinder.getDefaultAccess(); } - protected boolean isDefaultLazy() { - return hibernateMappingBinder.isDefaultLazy(); - } - private void bindPojoRepresentation(Element node, EntityBinding entityBinding) { String className = hibernateMappingBinder.getClassName( node.attribute( "name" ) ); String proxyName = hibernateMappingBinder.getClassName( node.attribute( "proxy" ) ); @@ -426,11 +418,12 @@ abstract class AbstractEntityBinder { protected void bindSimpleAttribute(Element propertyElement, SimpleAttributeBinding attributeBinding, EntityBinding entityBinding, String attributeName) { if ( attributeBinding.getAttribute() == null ) { - // attribute has not been bound yet - attributeBinding.fromHbmXml( - hibernateMappingBinder, - propertyElement, - entityBinding.getEntity().getOrCreateSingularAttribute( attributeName ) + attributeBinding.initialize( + new HbmSimpleAttributeDomainState( + hibernateMappingBinder, + propertyElement, + entityBinding.getEntity().getOrCreateSingularAttribute( attributeName ) + ) ); } @@ -449,12 +442,13 @@ abstract class AbstractEntityBinder { String attributeName) { if ( collectionBinding.getAttribute() == null ) { // domain model has not been bound yet - collectionBinding.fromHbmXml( - hibernateMappingBinder, - collectionNode, - entityBinding.getEntity().getOrCreatePluralAttribute( attributeName, attributeNature ) + collectionBinding.initialize( + new HbmPluralAttributeDomainState( + hibernateMappingBinder, + collectionNode, + entityBinding.getEntity().getOrCreatePluralAttribute( attributeName, attributeNature ) + ) ); - bindCollectionElement( collectionNode, collectionBinding ); } if ( collectionBinding.getValue() == null ) { @@ -462,22 +456,6 @@ abstract class AbstractEntityBinder { } } - private void bindCollectionElement( - Element collectionNode, - PluralAttributeBinding collectionBinding) { - CollectionElement collectionElement = createCollectionElement( collectionNode, collectionBinding); - collectionElement.fromHbmXml( collectionNode ); - collectionBinding.setCollectionElement( collectionElement ); - } - - private CollectionElement createCollectionElement(Element collectionNode, PluralAttributeBinding collectionBinding) { - Element element = collectionNode.element( "element" ); - if ( element != null ) { - return new ElementCollectionElement( collectionBinding ); - } - // TODO: implement other types of collection elements - return null; - } // private static Property createProperty( // final Value value, // final String propertyName, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HbmHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HbmHelper.java index b6190c6449..dc47df5756 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HbmHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HbmHelper.java @@ -134,4 +134,12 @@ public class HbmHelper { boolean callable = DomHelper.extractBooleanAttributeValue( element, "callable", false ); return new CustomSQL( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) ); } + + public static String getPropertyAccessorName(Element element, boolean isEmbedded, String defaultAccess) { + return DomHelper.extractAttributeValue( + element, + "access", + isEmbedded ? "embedded" : defaultAccess + ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/AbstractHbmAttributeDomainState.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/AbstractHbmAttributeDomainState.java new file mode 100644 index 0000000000..94a0e6dce1 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/AbstractHbmAttributeDomainState.java @@ -0,0 +1,93 @@ +/* + * 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.source.hbm.state.domain; + +import java.util.Map; + +import org.dom4j.Element; + +import org.hibernate.mapping.MetaAttribute; +import org.hibernate.metamodel.binding.AbstractAttributeBinding; +import org.hibernate.metamodel.binding.EntityBinding; +import org.hibernate.metamodel.binding.HibernateTypeDescriptor; +import org.hibernate.metamodel.binding.MappingDefaults; +import org.hibernate.metamodel.domain.Attribute; +import org.hibernate.metamodel.source.hbm.HbmHelper; +import org.hibernate.metamodel.source.util.DomHelper; + +/** + * @author Gail Badner + */ +public abstract class AbstractHbmAttributeDomainState implements AbstractAttributeBinding.DomainState { + private final MappingDefaults defaults; + private final Element element; + private final Attribute attribute; + public AbstractHbmAttributeDomainState(MappingDefaults defaults, + Element element, + Attribute attribute) { + this.defaults = defaults; + this.element = element; + this.attribute = attribute; + } + + protected final MappingDefaults getDefaults() { + return defaults; + } + protected final Element getElement() { + return element; + } + + public final HibernateTypeDescriptor getHibernateTypeDescriptor() { + HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); + hibernateTypeDescriptor.setTypeName( DomHelper.extractAttributeValue( element, "type", null ) ); + return hibernateTypeDescriptor; + } + public final Attribute getAttribute() { + return attribute; + } + public final String getPropertyAccessorName() { + return HbmHelper.getPropertyAccessorName( element, isEmbedded(), defaults.getDefaultAccess() ); + } + + protected abstract boolean isEmbedded(); + + public final boolean isAlternateUniqueKey() { + //TODO: implement + return false; + } + public final String getCascade() { + return DomHelper.extractAttributeValue( element, "cascade", defaults.getDefaultCascade() ); + } + public final boolean isOptimisticLockable() { + return DomHelper.extractBooleanAttributeValue( element, "optimistic-lock", true ); + } + public final String getNodeName() { + return DomHelper.extractAttributeValue( element, "node", attribute.getName() ); + } + + public final Map getMetaAttributes(EntityBinding entityBinding) { + //TODO: implement + return HbmHelper.extractMetas( element, entityBinding.getMetaAttributes() ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/HbmCollectionElementDomainState.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/HbmCollectionElementDomainState.java new file mode 100644 index 0000000000..0bde69672e --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/HbmCollectionElementDomainState.java @@ -0,0 +1,32 @@ +package org.hibernate.metamodel.source.hbm.state.domain; + +import org.dom4j.Element; + +import org.hibernate.metamodel.binding.CollectionElement; +import org.hibernate.metamodel.binding.HibernateTypeDescriptor; +import org.hibernate.metamodel.source.util.DomHelper; + +/** + * Created by IntelliJ IDEA. + * User: gbadner + * Date: 3/29/11 + * Time: 9:19 PM + * To change this template use File | Settings | File Templates. + */ +public class HbmCollectionElementDomainState implements CollectionElement.DomainState { + private final Element element; + + HbmCollectionElementDomainState(Element element) { + this.element = element; + } + + public final HibernateTypeDescriptor getHibernateTypeDescriptor() { + HibernateTypeDescriptor hibernateTypeDescriptor = new HibernateTypeDescriptor(); + hibernateTypeDescriptor.setTypeName( DomHelper.extractAttributeValue( element, "type", null ) ); + return hibernateTypeDescriptor; + } + + public final String getNodeName() { + return DomHelper.extractAttributeValue( element, "node", null ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/HbmPluralAttributeDomainState.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/HbmPluralAttributeDomainState.java new file mode 100644 index 0000000000..dbbf5163bb --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/HbmPluralAttributeDomainState.java @@ -0,0 +1,228 @@ +/* + * 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.source.hbm.state.domain; + +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.HashMap; + +import org.dom4j.Element; + +import org.hibernate.FetchMode; +import org.hibernate.MappingException; +import org.hibernate.metamodel.binding.CollectionElement; +import org.hibernate.metamodel.binding.CustomSQL; +import org.hibernate.metamodel.binding.ElementCollectionElement; +import org.hibernate.metamodel.binding.MappingDefaults; +import org.hibernate.metamodel.binding.PluralAttributeBinding; +import org.hibernate.metamodel.domain.Attribute; +import org.hibernate.metamodel.source.hbm.HbmHelper; +import org.hibernate.metamodel.source.util.DomHelper; + +/** + * @author Gail Badner + */ +public class HbmPluralAttributeDomainState extends AbstractHbmAttributeDomainState implements PluralAttributeBinding.DomainState { + public HbmPluralAttributeDomainState(MappingDefaults defaults, + Element element, + Attribute attribute) { + super( defaults, element, attribute ); + } + + public FetchMode getFetchMode() { + FetchMode fetchMode; + org.dom4j.Attribute fetchModeAttribute = getElement().attribute( "fetch" ); + if ( fetchModeAttribute != null ) { + fetchMode = "join".equals( fetchModeAttribute.getValue() ) ? FetchMode.JOIN : FetchMode.SELECT; + } + else { + org.dom4j.Attribute jfNode = getElement().attribute( "outer-join" ); + String jfNodeValue = ( jfNode == null ? "auto" : jfNode.getValue() ); + if ( "auto".equals( jfNodeValue ) ) { + fetchMode = FetchMode.DEFAULT; + } + else if ( "true".equals( jfNodeValue ) ) { + fetchMode = FetchMode.JOIN; + } + else { + fetchMode = FetchMode.SELECT; + } + } + return fetchMode; + } + + public boolean isLazy() { + return isExtraLazy() || + DomHelper.extractBooleanAttributeValue( getElement(), "lazy", getDefaults().isDefaultLazy() ); + } + + public boolean isExtraLazy() { + String lazyString = DomHelper.extractAttributeValue( getElement(), "lazy" ); + return ( "extra".equals( lazyString ) ); + } + public CollectionElement getCollectionElement(PluralAttributeBinding binding) { + Element element = getElement().element( "element" ); + if ( element != null ) { + ElementCollectionElement collectionElement = new ElementCollectionElement( binding ); + collectionElement.initialize( new HbmCollectionElementDomainState( element ) ); + } + // TODO: implement other types of collection elements + return null; + } + + public boolean isInverse() { + return DomHelper.extractBooleanAttributeValue( getElement(), "inverse", false ); + } + public boolean isMutable() { + return DomHelper.extractBooleanAttributeValue( getElement(), "mutable", true ); + } + public boolean isSubselectLoadable() { + return "subselect".equals( getElement().attributeValue( "fetch" ) ); + } + public String getCacheConcurrencyStrategy() { + Element cacheElement = getElement().element( "cache" ); + return cacheElement == null ? null : cacheElement.attributeValue( "usage" ); + } + public String getCacheRegionName() { + Element cacheElement = getElement().element( "cache" ); + return cacheElement == null ? null : cacheElement.attributeValue( "region" ); + } + public String getOrderBy() { + return DomHelper.extractAttributeValue( getElement(), "order-by", null ); + } + public String getWhere() { + return DomHelper.extractAttributeValue( getElement(), "where", null ); + } + public String getReferencedPropertyName() { + return getElement().element( "key" ).attributeValue( "property-ref" ); + } + public boolean isSorted() { + // SORT + // unsorted, natural, comparator.class.name + return ( ! "unsorted".equals( getSortString() ) ); + } + public Comparator getComparator() { + return null; + } + + public String getComparatorClassName() { + String sortString = getSortString(); + return ( + isSorted() && ! "natural".equals( sortString ) ? + sortString : + null + ); + } + + private String getSortString() { + return DomHelper.extractAttributeValue( getElement(), "sort", "unsorted" ); + } + public boolean isOrphanDelete() { + // ORPHAN DELETE (used for programmer error detection) + return ( getCascade().indexOf( "delete-orphan" ) >= 0 ); + } + public int getBatchSize() { + return DomHelper.extractIntAttributeValue( getElement(), "batch-size", 0 ); + } + public boolean isEmbedded() { + return DomHelper.extractBooleanAttributeValue( getElement(), "embed-xml", true ); + } + public boolean isOptimisticLocked() { + return true; + } + + public Class getCollectionPersisterClass() { + try { + return DomHelper.extractClassAttributeValue( getElement(), "persister" ); + } + catch (ClassNotFoundException cnfe) { + throw new MappingException( "Could not find collection persister class: " + + getElement().attributeValue( "persister" ) ); + } + } + public String getTypeName() { + // TODO: does this go here??? + //Attribute typeNode = collectionElement.attribute( "collection-type" ); + //if ( typeNode != null ) { + // TODO: implement when typedef binding is implemented + /* + String typeName = typeNode.getValue(); + TypeDef typeDef = mappings.getTypeDef( typeName ); + if ( typeDef != null ) { + collectionBinding.setTypeName( typeDef.getTypeClass() ); + collectionBinding.setTypeParameters( typeDef.getParameters() ); + } + else { + collectionBinding.setTypeName( typeName ); + } + */ + //} + return null; + } + + public java.util.Map getFilters() { + // TODO: IMPLEMENT + //Iterator iter = collectionElement.elementIterator( "filter" ); + //while ( iter.hasNext() ) { + // final Element filter = (Element) iter.next(); + // parseFilter( filter, collectionElement, collectionBinding ); + //} + return new HashMap(); + } + public java.util.Set getSynchronizedTables() { + java.util.Set synchronizedTables = new HashSet(); + Iterator tables = getElement().elementIterator( "synchronize" ); + while ( tables.hasNext() ) { + synchronizedTables.add( ( ( Element ) tables.next() ).attributeValue( "table" ) ); + } + return synchronizedTables; + } + + public CustomSQL getCustomSQLInsert() { + return HbmHelper.getCustomSql( getElement().element( "sql-insert" ) ); + } + public CustomSQL getCustomSQLUpdate() { + return HbmHelper.getCustomSql( getElement().element( "sql-update" ) ); + } + public CustomSQL getCustomSQLDelete() { + return HbmHelper.getCustomSql( getElement().element( "sql-delete" ) ); + + } + public CustomSQL getCustomSQLDeleteAll() { + return HbmHelper.getCustomSql( getElement().element( "sql-delete-all" ) ); + } + public String getLoaderName() { + return DomHelper.extractAttributeValue( getElement().element( "loader" ), "query-ref" ); + } + + public boolean isKeyCasadeDeleteEnabled() { + //TODO: implement + return false; + } + public String getUnsavedValue() { + //TODO: implement + return null; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/HbmSimpleAttributeDomainState.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/HbmSimpleAttributeDomainState.java new file mode 100644 index 0000000000..35d2cd38cf --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/state/domain/HbmSimpleAttributeDomainState.java @@ -0,0 +1,109 @@ +/* + * 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.source.hbm.state.domain; + +import org.dom4j.Element; + +import org.hibernate.MappingException; +import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.binding.MappingDefaults; +import org.hibernate.metamodel.binding.SimpleAttributeBinding; +import org.hibernate.metamodel.source.util.DomHelper; + +/** + * @author Gail Badner + */ +public class HbmSimpleAttributeDomainState extends AbstractHbmAttributeDomainState implements SimpleAttributeBinding.DomainState { + public HbmSimpleAttributeDomainState(MappingDefaults defaults, + final Element element, + org.hibernate.metamodel.domain.Attribute attribute) { + super( defaults, element, attribute ); + } + + protected boolean isEmbedded() { + return false; + } + + public boolean isLazy() { + return DomHelper.extractBooleanAttributeValue( getElement(), "lazy", false ); + } + + public PropertyGeneration getPropertyGeneration() { + return PropertyGeneration.parse( DomHelper.extractAttributeValue( getElement(), "generated", null ) ); + } + public boolean isInsertable() { + //TODO: implement + PropertyGeneration generation = getPropertyGeneration(); + boolean isInsertable = DomHelper.extractBooleanAttributeValue( getElement(), "insert", true ); + if ( generation == PropertyGeneration.ALWAYS || generation == PropertyGeneration.INSERT ) { + // generated properties can *never* be insertable... + if ( isInsertable ) { + final org.dom4j.Attribute insertAttribute = getElement().attribute( "insert" ); + if ( insertAttribute == null ) { + // insertable simply because the user did not specify anything; just override it + isInsertable = false; + } + else { + // the user specifically supplied insert="true", which constitutes an illegal combo + throw new MappingException( + "cannot specify both insert=\"true\" and generated=\"" + generation.getName() + + "\" for property: " + + getAttribute().getName() + ); + } + } + } + return isInsertable; + } + public boolean isUpdateable() { + PropertyGeneration generation = getPropertyGeneration(); + boolean isUpdateable = DomHelper.extractBooleanAttributeValue( getElement(), "update", true ); + if ( isUpdateable && generation == PropertyGeneration.ALWAYS ) { + final org.dom4j.Attribute updateAttribute = getElement().attribute( "update" ); + if ( updateAttribute == null ) { + // updateable only because the user did not specify + // anything; just override it + isUpdateable = false; + } + else { + // the user specifically supplied update="true", + // which constitutes an illegal combo + throw new MappingException( + "cannot specify both update=\"true\" and generated=\"" + generation.getName() + + "\" for property: " + + getAttribute().getName() + ); + } + } + return isUpdateable; + } + public boolean isKeyCasadeDeleteEnabled() { + //TODO: implement + return false; + } + public String getUnsavedValue() { + //TODO: implement + return null; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java index 455ba9a7d3..539224f434 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/AbstractBasicBindingTests.java @@ -83,7 +83,31 @@ public abstract class AbstractBasicBindingTests extends BaseUnitTestCase { assertNotNull( nameBinding.getValue() ); } + @Test + public void testEntityWithElementCollection() { + EntityBinding entityBinding = buildEntityWithElementCollectionBinding(); + + assertNotNull( entityBinding ); + assertNotNull( entityBinding.getEntityIdentifier() ); + assertNotNull( entityBinding.getEntityIdentifier().getValueBinding() ); + assertNull( entityBinding.getVersioningValueBinding() ); + + AttributeBinding idAttributeBinding = entityBinding.getAttributeBinding( "id" ); + assertNotNull( idAttributeBinding ); + assertSame( idAttributeBinding, entityBinding.getEntityIdentifier().getValueBinding() ); + assertNotNull( idAttributeBinding.getAttribute() ); + assertNotNull( idAttributeBinding.getValue() ); + assertTrue( idAttributeBinding.getValue() instanceof Column ); + + AttributeBinding nameBinding = entityBinding.getAttributeBinding( "name" ); + assertNotNull( nameBinding ); + assertNotNull( nameBinding.getAttribute() ); + assertNotNull( nameBinding.getValue() ); + } + public abstract EntityBinding buildSimpleVersionedEntityBinding(); public abstract EntityBinding buildSimpleEntityBinding(); + + public abstract EntityBinding buildEntityWithElementCollectionBinding(); } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java index 5a1c8f95de..5c1a655fcb 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java @@ -83,6 +83,9 @@ public class BasicAnnotationBindingTests extends AbstractBasicBindingTests { fail( "Unable to index" ); } } - return indexer.complete(); + + List indexList = new ArrayList(); + indexList.add( indexer.complete() ); + return new AnnotationIndex( indexList ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java index 5fce773913..c2a5be1a41 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java @@ -23,10 +23,6 @@ */ package org.hibernate.metamodel.binding; -import javax.xml.bind.JAXBException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.xml.sax.InputSource; import org.hibernate.internal.util.ConfigHelper;