HHH-7798 Initial structure for array attributes

This commit is contained in:
brmeyer 2012-11-13 15:51:34 -05:00
parent a1ba4dbdb7
commit 59d8fdbd28
15 changed files with 305 additions and 14 deletions

View File

@ -23,6 +23,8 @@
*/
package org.hibernate.metamodel.internal;
import static org.hibernate.engine.spi.SyntheticAttributeHelper.SYNTHETIC_COMPOSITE_ID_ATTRIBUTE_NAME;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
@ -32,8 +34,6 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.jboss.logging.Logger;
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.MultiTenancyStrategy;
@ -55,14 +55,15 @@ import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.ValueHolder;
import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes;
import org.hibernate.metamodel.internal.source.hbm.ArrayAttributeSource;
import org.hibernate.metamodel.spi.MetadataImplementor;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding;
import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.AttributeBindingContainer;
import org.hibernate.metamodel.spi.binding.BasicAttributeBinding;
import org.hibernate.metamodel.spi.binding.BasicPluralAttributeElementBinding;
import org.hibernate.metamodel.spi.binding.BasicPluralAttributeIndexBinding;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer;
import org.hibernate.metamodel.spi.binding.CompositePluralAttributeElementBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding;
@ -84,6 +85,7 @@ import org.hibernate.metamodel.spi.binding.RelationalValueBinding;
import org.hibernate.metamodel.spi.binding.SecondaryTable;
import org.hibernate.metamodel.spi.binding.SingularAssociationAttributeBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding.NaturalIdMutability;
import org.hibernate.metamodel.spi.binding.TypeDefinition;
import org.hibernate.metamodel.spi.domain.Aggregate;
import org.hibernate.metamodel.spi.domain.Attribute;
@ -115,6 +117,8 @@ import org.hibernate.metamodel.spi.source.EntityHierarchy;
import org.hibernate.metamodel.spi.source.EntitySource;
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource;
import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource.JoinColumnResolutionContext;
import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource.JoinColumnResolutionDelegate;
import org.hibernate.metamodel.spi.source.IdentifierSource;
import org.hibernate.metamodel.spi.source.InLineViewSource;
import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource;
@ -150,11 +154,7 @@ import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.ComponentType;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
import static org.hibernate.engine.spi.SyntheticAttributeHelper.SYNTHETIC_COMPOSITE_ID_ATTRIBUTE_NAME;
import static org.hibernate.metamodel.spi.binding.SingularAttributeBinding.NaturalIdMutability;
import static org.hibernate.metamodel.spi.source.ForeignKeyContributingSource.JoinColumnResolutionContext;
import static org.hibernate.metamodel.spi.source.ForeignKeyContributingSource.JoinColumnResolutionDelegate;
import org.jboss.logging.Logger;
/**
* The common binder shared between annotations and {@code hbm.xml} processing.
@ -651,7 +651,10 @@ public class Binder {
if ( attributeBinding.getPluralAttributeElementBinding().getNature() == PluralAttributeElementBinding.Nature.BASIC ) {
if ( pluralAttributeNature == PluralAttributeSource.Nature.SET ) {
bindBasicSetElementTablePrimaryKey( attributeBinding );
} else if ( pluralAttributeNature == PluralAttributeSource.Nature.LIST || pluralAttributeNature == PluralAttributeSource.Nature.MAP ) {
} else if (
pluralAttributeNature == PluralAttributeSource.Nature.LIST
|| pluralAttributeNature == PluralAttributeSource.Nature.MAP
|| pluralAttributeNature == PluralAttributeSource.Nature.ARRAY ) {
bindIndexedTablePrimaryKey( ( IndexedPluralAttributeBinding ) attributeBinding );
} else {
throw new NotYetImplementedException( "Only Sets with basic elements are supported so far." );
@ -1084,6 +1087,25 @@ public class Binder {
base
);
}
private AbstractPluralAttributeBinding bindArrayAttribute(
final AttributeBindingContainer attributeBindingContainer,
final PluralAttributeSource attributeSource,
PluralAttribute attribute ) {
if ( attribute == null ) {
attribute = attributeBindingContainer.getAttributeContainer().createArray( attributeSource.getName() );
}
final int base = IndexedPluralAttributeSource.class.isInstance( attributeSource ) ? IndexedPluralAttributeSource.class.cast( attributeSource ).getIndexSource().base() : 0;
return attributeBindingContainer.makeArrayAttributeBinding(
attribute,
pluralAttributeElementNature( attributeSource ),
determinePluralAttributeKeyReferencedBinding( attributeBindingContainer, attributeSource ),
propertyAccessorName( attributeSource ),
attributeSource.isIncludedInOptimisticLocking(),
createMetaAttributeContext( attributeBindingContainer, attributeSource ),
base
);
}
private ManyToOneAttributeBinding bindManyToOneAttribute(
final AttributeBindingContainer attributeBindingContainer,
@ -1449,6 +1471,13 @@ public class Binder {
attribute
);
break;
case ARRAY:
attributeBinding = bindArrayAttribute(
attributeBindingContainer,
attributeSource,
attribute
);
break;
default:
throw new NotYetImplementedException( nature.toString() );
}
@ -1457,7 +1486,7 @@ public class Binder {
// (ex: Set vs. SortedSet).
bindSortingAndOrdering( attributeBinding, attributeSource );
final Type resolvedType = resolvePluralType( attributeBinding, nature );
final Type resolvedType = resolvePluralType( attributeBinding, attributeSource, nature );
final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor();
ReflectedCollectionJavaTypes reflectedCollectionJavaTypes = typeHelper.getReflectedCollectionJavaTypes( attributeBinding );
bindHibernateTypeDescriptor(
@ -2473,7 +2502,10 @@ public class Binder {
);
}
private Type resolvePluralType( PluralAttributeBinding pluralAttributeBinding, PluralAttributeSource.Nature nature){
private Type resolvePluralType(
PluralAttributeBinding pluralAttributeBinding,
PluralAttributeSource attributeSource,
PluralAttributeSource.Nature nature){
if ( pluralAttributeBinding.getHibernateTypeDescriptor().getExplicitTypeName() != null ) {
return resolveCustomCollectionType( pluralAttributeBinding );
} else {
@ -2486,6 +2518,10 @@ public class Binder {
return typeFactory.bag( role, propertyRef, embedded );
case LIST:
return typeFactory.list( role, propertyRef, embedded );
case ARRAY:
// ArrayAttributeSource arraySource
// = (ArrayAttributeSource) attributeSource;
// return typeFactory.array( role, propertyRef, embedded, arraySource.getPluralAttributeElement().getCollectionType() );
case MAP:
if ( pluralAttributeBinding.isSorted() ) {
return typeFactory.sortedMap( role, propertyRef, embedded, pluralAttributeBinding.getComparator() );

View File

@ -251,6 +251,8 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
}
else if ( Set.class.isAssignableFrom( associationAttribute.getAttributeType() ) ) {
return PluralAttributeSource.Nature.SET;
} else if ( associationAttribute.getAttributeType().isArray() ) {
return PluralAttributeSource.Nature.ARRAY;
}
else {
return PluralAttributeSource.Nature.BAG;

View File

@ -161,8 +161,11 @@ public abstract class AbstractComponentAttributeSourceImpl extends AbstractHbmSo
);
}
protected AttributeSource buildAttributeSource(JaxbArrayElement attributeElement) {
// todo : implement
throw new NotYetImplementedException();
return new ArrayAttributeSource(
sourceMappingDocument(),
attributeElement,
parentContainer
);
}
protected AttributeSource buildAttributeSource(JaxbPrimitiveArrayElement attributeElement) {
// todo : implement

View File

@ -34,6 +34,7 @@ import org.hibernate.internal.util.StringHelper;
import org.hibernate.jaxb.spi.Origin;
import org.hibernate.jaxb.spi.hbm.EntityElement;
import org.hibernate.jaxb.spi.hbm.JaxbAnyElement;
import org.hibernate.jaxb.spi.hbm.JaxbArrayElement;
import org.hibernate.jaxb.spi.hbm.JaxbBagElement;
import org.hibernate.jaxb.spi.hbm.JaxbComponentElement;
import org.hibernate.jaxb.spi.hbm.JaxbDynamicComponentElement;
@ -62,6 +63,7 @@ import org.hibernate.metamodel.spi.source.SubclassEntitySource;
/**
* @author Steve Ebersole
* @author Hardy Ferentschik
* @author Brett Meyer
*/
public abstract class AbstractEntitySourceImpl
extends AbstractHbmSourceNode
@ -145,6 +147,7 @@ public abstract class AbstractEntitySourceImpl
);
processMapAttributes( attributeSources, element.getMap() );
processListAttributes( attributeSources, element.getList() );
processArrayAttributes( attributeSources, element.getArray() );
processSetAttributes( attributeSources, element.getSet() );
processIdBagAttributes( attributeSources, element.getIdbag() );
processBagAttributes( attributeSources, element.getBag() );
@ -231,6 +234,17 @@ public abstract class AbstractEntitySourceImpl
);
}
}
protected void processArrayAttributes(List<AttributeSource> results,
List<JaxbArrayElement> propertyElements){
for ( JaxbArrayElement element : propertyElements ) {
results.add(
new ArrayAttributeSource(
sourceMappingDocument(),
element, this
)
);
}
}
protected void processListAttributes(List<AttributeSource> results,
List<JaxbListElement> propertyElements){
for ( JaxbListElement element : propertyElements ) {

View File

@ -0,0 +1,71 @@
/*
* 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.internal.source.hbm;
import org.hibernate.jaxb.spi.hbm.JaxbArrayElement;
import org.hibernate.jaxb.spi.hbm.JaxbListIndexElement;
import org.hibernate.metamodel.spi.source.AttributeSourceContainer;
import org.hibernate.metamodel.spi.source.IndexedPluralAttributeSource;
import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource;
/**
* @author Brett Meyer
*/
public class ArrayAttributeSource extends AbstractPluralAttributeSourceImpl implements IndexedPluralAttributeSource {
private final ListAttributeIndexSource indexSource;
public ArrayAttributeSource(
MappingDocument sourceMappingDocument,
JaxbArrayElement arrayElement,
AttributeSourceContainer container ) {
super( sourceMappingDocument, arrayElement, container );
JaxbListIndexElement listIndexElement = arrayElement.getListIndex();
if ( listIndexElement == null ) {
this.indexSource = new ListAttributeIndexSource( sourceMappingDocument(), arrayElement.getIndex() );
} else {
this.indexSource = new ListAttributeIndexSource( sourceMappingDocument(), listIndexElement );
}
}
@Override
public PluralAttributeIndexSource getIndexSource() {
return indexSource;
}
@Override
public JaxbArrayElement getPluralAttributeElement() {
return ( JaxbArrayElement ) super.getPluralAttributeElement();
}
/**
* {@inheritDoc}
*
* @see org.hibernate.metamodel.spi.source.PluralAttributeSource#getNature()
*/
@Override
public Nature getNature() {
return Nature.ARRAY;
}
}

View File

@ -216,6 +216,29 @@ public abstract class AbstractAttributeBindingContainer implements AttributeBind
return binding;
}
@Override
public ArrayBinding makeArrayAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementBinding.Nature nature,
SingularAttributeBinding referencedAttributeBinding,
String propertyAccessorName,
boolean includedInOptimisticLocking,
MetaAttributeContext metaAttributeContext,
int base) {
Helper.checkPluralAttributeNature( attribute, PluralAttribute.Nature.ARRAY );
final ArrayBinding binding = new ArrayBinding(
this,
attribute,
nature,
referencedAttributeBinding,
propertyAccessorName,
includedInOptimisticLocking,
metaAttributeContext,
base );
registerAttributeBinding( binding );
return binding;
}
@Override
public MapBinding makeMapAttributeBinding(
PluralAttribute attribute,

View File

@ -212,6 +212,29 @@ public abstract class AbstractCompositeAttributeBindingContainer
);
}
@Override
public ArrayBinding makeArrayAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementBinding.Nature nature,
SingularAttributeBinding referencedAttributeBinding,
String propertyAccessorName,
boolean includedInOptimisticLocking,
MetaAttributeContext metaAttributeContext,
int base) {
if ( !isModifiable() ) {
throw new UnsupportedOperationException( "Attribute bindings are read-only and cannot be modified." );
}
return super.makeArrayAttributeBinding(
attribute,
nature,
referencedAttributeBinding,
propertyAccessorName,
includedInOptimisticLocking,
metaAttributeContext,
base
);
}
@Override
public MapBinding makeMapAttributeBinding(
PluralAttribute attribute,

View File

@ -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.spi.binding;
import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.source.MetaAttributeContext;
/**
* @author Brett Meyer
*/
public class ArrayBinding extends AbstractPluralAttributeBinding implements IndexedPluralAttributeBinding {
private final PluralAttributeIndexBinding pluralAttributeIndexBinding;
private final int base;
public ArrayBinding(AttributeBindingContainer container,
PluralAttribute attribute,
PluralAttributeElementBinding.Nature pluralAttributeElementNature,
SingularAttributeBinding referencedAttributeBinding,
String propertyAccessorName, boolean includedInOptimisticLocking,
MetaAttributeContext metaAttributeContext, int base) {
super( container, attribute, pluralAttributeElementNature,
referencedAttributeBinding, propertyAccessorName,
includedInOptimisticLocking, metaAttributeContext );
pluralAttributeIndexBinding = new BasicPluralAttributeIndexBinding(
this, PluralAttributeIndexBinding.Nature.BASIC );
this.base = base;
}
public int base() {
return base;
}
/**
* {@inheritDoc}
*
* @see org.hibernate.metamodel.spi.binding.IndexedPluralAttributeBinding#getPluralAttributeIndexBinding()
*/
@Override
public PluralAttributeIndexBinding getPluralAttributeIndexBinding() {
return pluralAttributeIndexBinding;
}
}

View File

@ -233,6 +233,29 @@ public interface AttributeBindingContainer {
MetaAttributeContext metaAttributeContext,
int base);
/**
* Factory method for array attribute bindings.
*
*
* @param attribute The attribute for which to make a binding.
* @param nature The nature of the collection elements.
* @param referencedAttributeBinding
* @param propertyAccessorName
* @param includedInOptimisticLocking
* @param metaAttributeContext
* @param base
*
* @return The attribute binding instance.
*/
public ArrayBinding makeArrayAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementBinding.Nature nature,
SingularAttributeBinding referencedAttributeBinding,
String propertyAccessorName,
boolean includedInOptimisticLocking,
MetaAttributeContext metaAttributeContext,
int base);
/**
* Factory method for map attribute bindings.
*

View File

@ -426,6 +426,26 @@ public class CompositeAttributeBinding
);
}
@Override
public ArrayBinding makeArrayAttributeBinding(
PluralAttribute attribute,
PluralAttributeElementBinding.Nature nature,
SingularAttributeBinding referencedAttributeBinding,
String propertyAccessorName,
boolean includedInOptimisticLocking,
MetaAttributeContext metaAttributeContext,
int base) {
return compositeAttributeBindingContainer.makeArrayAttributeBinding(
attribute,
nature,
referencedAttributeBinding,
propertyAccessorName,
includedInOptimisticLocking,
metaAttributeContext,
base
);
}
@Override
public MapBinding makeMapAttributeBinding(
PluralAttribute attribute,

View File

@ -193,6 +193,11 @@ public abstract class AbstractAttributeContainer implements AttributeContainer,
return (IndexedPluralAttribute) createPluralAttribute( name, PluralAttribute.Nature.LIST );
}
@Override
public IndexedPluralAttribute createArray(String name) {
return (IndexedPluralAttribute) createPluralAttribute( name, PluralAttribute.Nature.ARRAY );
}
@Override
public IndexedPluralAttribute createMap(String name) {
return (IndexedPluralAttribute) createPluralAttribute( name, PluralAttribute.Nature.MAP );

View File

@ -71,6 +71,7 @@ public interface AttributeContainer extends Type {
public PluralAttribute createSet(String name);
public IndexedPluralAttribute createList(String name);
public IndexedPluralAttribute createMap(String name);
public IndexedPluralAttribute createArray(String name);
public SingularAttribute createSyntheticSingularAttribute(String name);
public SingularAttribute createSyntheticCompositeAttribute(String name, Hierarchical container);

View File

@ -78,7 +78,8 @@ public interface PluralAttributeSource
ID_BAG( Collection.class ),
SET( Set.class ),
LIST( List.class ),
MAP( Map.class );
MAP( Map.class ),
ARRAY( null ); // TODO: ?
private final Class<?> reportedJavaType;

View File

@ -449,6 +449,7 @@ arbitrary number of queries, and import declarations of arbitrary classes.
<xs:group ref="collection-elements-group"/>
<xs:element name="loader" minOccurs="0" type="loader-element"/>
<xs:group ref="sql-dml-all-element-group"/>
<xs:element name="filter" minOccurs="0" maxOccurs="unbounded" type="filter-element"/>
</xs:sequence>
<xs:attributeGroup ref="table-information-group"/>
<xs:attribute name="access" type="xs:string"/>
@ -460,6 +461,7 @@ arbitrary number of queries, and import declarations of arbitrary classes.
<xs:attribute name="element-class" type="xs:string"/>
<xs:attribute name="embed-xml" default="true" type="xs:boolean"/>
<xs:attribute name="fetch" type="fetch-attribute-with-subselect"/>
<xs:attribute name="lazy" type="lazy-attribute-with-extra"/>
<xs:attribute name="inverse" default="false" type="xs:boolean"/>
<xs:attribute name="mutable" default="true" type="xs:boolean"/>
<xs:attribute name="name" use="required" type="xs:string"/>

View File

@ -89,6 +89,9 @@
<jaxb:bindings node="//xsd:complexType[@name='filter-param-element']">
<inheritance:implements>org.hibernate.metamodel.spi.source.FilterParameterSource</inheritance:implements>
</jaxb:bindings>
<jaxb:bindings node="//xsd:complexType[@name='array-element']">
<inheritance:implements>org.hibernate.jaxb.spi.hbm.PluralAttributeElement</inheritance:implements>
</jaxb:bindings>
<jaxb:bindings node="//xsd:complexType[@name='filter-param-element']//xsd:attribute[@name='name']">