HHH-6447 - Develop shared binding creation approach

This commit is contained in:
Steve Ebersole 2011-07-15 09:46:01 -05:00
parent dfd4e61a98
commit 0c7498e31d
28 changed files with 1720 additions and 154 deletions

View File

@ -23,21 +23,30 @@
*/
package org.hibernate.metamodel.binding;
import org.hibernate.engine.spi.CascadeStyle;
/**
* TODO : javadoc
*
* @author Gail Badner
* @author Steve Ebersole
*/
public interface EntityReferencingAttributeBinding extends AttributeBinding {
boolean isReferenceResolved();
public boolean isPropertyReference();
boolean isPropertyReference();
public String getReferencedEntityName();
public void setReferencedEntityName(String referencedEntityName);
String getReferencedEntityName();
public String getReferencedAttributeName();
public void setReferencedAttributeName(String referencedAttributeName);
String getReferencedAttributeName();
public Iterable<CascadeStyle> getCascadeStyles();
public void setCascadeStyles(Iterable<CascadeStyle> cascadeStyles);
EntityBinding getReferencedEntityBinding();
void resolveReference(AttributeBinding attributeBinding);
// "resolvable"
public void resolveReference(AttributeBinding attributeBinding);
public boolean isReferenceResolved();
public EntityBinding getReferencedEntityBinding();
public AttributeBinding getReferencedAttributeBinding();
}

View File

@ -64,23 +64,28 @@ public class ManyToOneAttributeBinding extends SimpleAttributeBinding implements
return this;
}
@Override
public final boolean isPropertyReference() {
return referencedAttributeName != null;
}
@Override
public final String getReferencedEntityName() {
return referencedEntityName;
}
public void setReferencedEntity(String referencedEntityName) {
@Override
public void setReferencedEntityName(String referencedEntityName) {
this.referencedEntityName = referencedEntityName;
}
@Override
public final String getReferencedAttributeName() {
return referencedAttributeName;
}
public void setReferencedEntityAttributeName(String referencedEntityAttributeName) {
@Override
public void setReferencedAttributeName(String referencedEntityAttributeName) {
this.referencedAttributeName = referencedEntityAttributeName;
}

View File

@ -29,6 +29,7 @@ import java.util.LinkedHashSet;
import java.util.Set;
import org.hibernate.HibernateException;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.internal.util.Value;
/**
@ -99,6 +100,11 @@ public abstract class AbstractAttributeContainer implements AttributeContainer,
return attribute;
}
@Override
public SingularAttribute locateOrCreateVirtualAttribute(String name) {
throw new NotYetImplementedException();
}
@Override
public SingularAttribute locateOrCreateComponentAttribute(String name) {
SingularAttributeImpl attribute = (SingularAttributeImpl) getAttribute( name );
@ -142,6 +148,11 @@ public abstract class AbstractAttributeContainer implements AttributeContainer,
return realComponent().locateOrCreateSingularAttribute( name );
}
@Override
public SingularAttribute locateOrCreateVirtualAttribute(String name) {
return realComponent().locateOrCreateVirtualAttribute( name );
}
@Override
public PluralAttribute locateOrCreatePluralAttribute(String name, PluralAttributeNature nature) {
return realComponent().locateOrCreatePluralAttribute( name, nature );

View File

@ -49,6 +49,7 @@ public interface AttributeContainer extends Type {
public Set<Attribute> getAttributes();
public SingularAttribute locateOrCreateSingularAttribute(String name);
public SingularAttribute locateOrCreateVirtualAttribute(String name);
public PluralAttribute locateOrCreatePluralAttribute(String name, PluralAttributeNature nature);
public PluralAttribute locateOrCreateBag(String name);

View File

@ -47,4 +47,6 @@ public interface BindingContext {
public boolean isGloballyQuotedIdentifiers();
public Value<Class<?>> makeClassReference(String className);
public String qualifyClassName(String name);
}

View File

@ -0,0 +1,32 @@
/*
* 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;
/**
* @author Steve Ebersole
*/
public interface LocalBindingContext extends BindingContext {
public Origin getOrigin();
public String qualifyClassName(String unqualifiedName);
}

View File

@ -0,0 +1,40 @@
/*
* 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.binder;
/**
* @author Steve Ebersole
*/
public interface AttributeSource {
/**
* Obtain the attribute name.
*
* @return The attribute name. {@code nulls} are NOT allowed!
*/
public String getName();
public boolean isSingular();
public Iterable<MetaAttributeSource> metaAttributes();
}

View File

@ -0,0 +1,31 @@
/*
* 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.binder;
/**
* @author Steve Ebersole
*/
public interface AttributeSourceContainer {
public Iterable<AttributeSource> attributeSources();
}

View File

@ -0,0 +1,508 @@
/*
* 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.binder;
import java.beans.BeanInfo;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.internal.util.beans.BeanInfoHelper;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.binding.ManyToOneAttributeBinding;
import org.hibernate.metamodel.binding.MetaAttribute;
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.SimpleValue;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.Tuple;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.source.hbm.Helper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.tuple.entity.EntityTuplizer;
/**
* @author Steve Ebersole
*/
public class Binder {
private final MetadataImplementor metadata;
private final List<String> processedEntityNames;
private InheritanceType currentInheritanceType;
private LocalBindingContext currentBindingContext;
public Binder(MetadataImplementor metadata, List<String> processedEntityNames) {
this.metadata = metadata;
this.processedEntityNames = processedEntityNames;
}
public void processEntityHierarchy(EntityHierarchy entityHierarchy) {
currentInheritanceType = entityHierarchy.getHierarchyInheritanceType();
EntityBinding rootEntityBinding = createEntityBinding( entityHierarchy.getRootEntitySource(), null );
if ( currentInheritanceType != InheritanceType.NO_INHERITANCE ) {
processHierarchySubEntities( entityHierarchy.getRootEntitySource(), rootEntityBinding );
}
}
private void processHierarchySubEntities(SubclassEntityContainer subclassEntitySource, EntityBinding superEntityBinding) {
for ( SubclassEntitySource subEntity : subclassEntitySource.subclassEntitySources() ) {
EntityBinding entityBinding = createEntityBinding( subEntity, superEntityBinding );
processHierarchySubEntities( subEntity, entityBinding );
}
}
// Entities ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private EntityBinding createEntityBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
if ( processedEntityNames.contains( entitySource.getEntityName() ) ) {
return metadata.getEntityBinding( entitySource.getEntityName() );
}
currentBindingContext = entitySource.getBindingContext();
try {
final EntityBinding entityBinding = doCreateEntityBinding( entitySource, superEntityBinding );
metadata.addEntity( entityBinding );
processedEntityNames.add( entityBinding.getEntity().getName() );
return entityBinding;
}
finally {
currentBindingContext = null;
}
}
private EntityBinding doCreateEntityBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
final EntityBinding entityBinding = createBasicEntityBinding( entitySource, superEntityBinding );
bindSecondaryTables( entitySource, entityBinding );
bindAttributes( entitySource, entityBinding );
bindTableUniqueConstraints( entityBinding );
return entityBinding;
}
private EntityBinding createBasicEntityBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
if ( superEntityBinding == null ) {
return makeRootEntityBinding( (RootEntitySource) entitySource );
}
else {
if ( currentInheritanceType == InheritanceType.SINGLE_TABLE ) {
return makeDiscriminatedSubclassBinding( entitySource, superEntityBinding );
}
else if ( currentInheritanceType == InheritanceType.JOINED ) {
return makeJoinedSubclassBinding( entitySource, superEntityBinding );
}
else if ( currentInheritanceType == InheritanceType.TABLE_PER_CLASS ) {
return makeUnionedSubclassBinding( entitySource, superEntityBinding );
}
else {
// extreme internal error!
throw new AssertionFailure( "Internal condition failure" );
}
}
}
private EntityBinding makeRootEntityBinding(RootEntitySource entitySource) {
final EntityBinding entityBinding = new EntityBinding();
entityBinding.setInheritanceType( currentInheritanceType );
entityBinding.setRoot( true );
final EntityMode entityMode = entitySource.getEntityMode();
entityBinding.setEntityMode( entityMode );
final String entityName = entitySource.getEntityName();
final String className = entityMode == EntityMode.POJO ? entitySource.getClassName() : null;
final Entity entity = new Entity(
entityName,
className,
currentBindingContext.makeClassReference( className ),
null
);
entityBinding.setEntity( entity );
performBasicEntityBind( entitySource, entityBinding );
bindPrimaryTable( entityBinding, entitySource );
bindIdentifier( entitySource, entityBinding );
bindVersion( entityBinding, entitySource );
bindDiscriminator( entitySource, entityBinding );
entityBinding.setMutable( entitySource.isMutable() );
entityBinding.setExplicitPolymorphism( entitySource.isExplicitPolymorphism() );
entityBinding.setWhereFilter( entitySource.getWhere() );
entityBinding.setRowId( entitySource.getRowId() );
entityBinding.setOptimisticLockStyle( entitySource.getOptimisticLockStyle() );
entityBinding.setCaching( entitySource.getCaching() );
return entityBinding;
}
private EntityBinding makeDiscriminatedSubclassBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
return null; //To change body of created methods use File | Settings | File Templates.
}
private EntityBinding makeJoinedSubclassBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
return null; //To change body of created methods use File | Settings | File Templates.
}
private EntityBinding makeUnionedSubclassBinding(EntitySource entitySource, EntityBinding superEntityBinding) {
return null; //To change body of created methods use File | Settings | File Templates.
}
private void performBasicEntityBind(EntitySource entitySource, EntityBinding entityBinding) {
entityBinding.setJpaEntityName( entitySource.getJpaEntityName() );
if ( entityBinding.getEntityMode() == EntityMode.POJO ) {
final String proxy = entitySource.getProxy();
if ( proxy != null ) {
entityBinding.setProxyInterfaceType(
currentBindingContext.makeClassReference(
currentBindingContext.qualifyClassName( proxy )
)
);
entityBinding.setLazy( true );
}
else if ( entitySource.isLazy() ) {
entityBinding.setProxyInterfaceType( entityBinding.getEntity().getClassReferenceUnresolved() );
entityBinding.setLazy( true );
}
}
else {
entityBinding.setProxyInterfaceType( null );
entityBinding.setLazy( entitySource.isLazy() );
}
final String customTuplizerClassName = entitySource.getCustomTuplizerClassName();
if ( customTuplizerClassName != null ) {
entityBinding.setCustomEntityTuplizerClass( currentBindingContext.<EntityTuplizer>locateClassByName( customTuplizerClassName ) );
}
final String customPersisterClassName = entitySource.getCustomPersisterClassName();
if ( customPersisterClassName != null ) {
entityBinding.setCustomEntityPersisterClass( currentBindingContext.<EntityPersister>locateClassByName( customPersisterClassName ) );
}
entityBinding.setMetaAttributeContext( buildMetaAttributeContext( entitySource ) );
entityBinding.setDynamicUpdate( entitySource.isDynamicUpdate() );
entityBinding.setDynamicInsert( entitySource.isDynamicInsert() );
entityBinding.setBatchSize( entitySource.getBatchSize() );
entityBinding.setSelectBeforeUpdate( entitySource.isSelectBeforeUpdate() );
entityBinding.setAbstract( entitySource.isAbstract() );
entityBinding.setCustomLoaderName( entitySource.getCustomLoaderName() );
entityBinding.setCustomInsert( entitySource.getCustomSqlInsert() );
entityBinding.setCustomUpdate( entitySource.getCustomSqlUpdate() );
entityBinding.setCustomDelete( entitySource.getCustomSqlDelete() );
if ( entitySource.getSynchronizedTableNames() != null ) {
entityBinding.addSynchronizedTableNames( entitySource.getSynchronizedTableNames() );
}
}
private void bindIdentifier(RootEntitySource entitySource, EntityBinding entityBinding) {
if ( entitySource.getIdentifierSource() == null ) {
throw new AssertionFailure( "Expecting identifier information on root entity descriptor" );
}
switch ( entitySource.getIdentifierSource().getNature() ) {
case SIMPLE: {
bindSimpleIdentifier( (SimpleIdentifierSource) entitySource.getIdentifierSource(), entityBinding );
}
case AGGREGATED_COMPOSITE: {
}
case COMPOSITE: {
}
}
}
private void bindSimpleIdentifier(SimpleIdentifierSource identifierSource, EntityBinding entityBinding) {
final SimpleAttributeBinding idAttributeBinding = doBasicSingularAttributeBindingCreation(
identifierSource.getIdentifierAttributeSource(), entityBinding
);
entityBinding.getEntityIdentifier().setValueBinding( idAttributeBinding );
entityBinding.getEntityIdentifier().setIdGenerator( identifierSource.getIdentifierGeneratorDescriptor() );
final org.hibernate.metamodel.relational.Value relationalValue = idAttributeBinding.getValue();
if ( SimpleValue.class.isInstance( relationalValue ) ) {
if ( !Column.class.isInstance( relationalValue ) ) {
// this should never ever happen..
throw new AssertionFailure( "Simple-id was not a column." );
}
entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( relationalValue ) );
}
else {
for ( SimpleValue subValue : ( (Tuple) relationalValue ).values() ) {
if ( Column.class.isInstance( subValue ) ) {
entityBinding.getBaseTable().getPrimaryKey().addColumn( Column.class.cast( subValue ) );
}
}
}
}
private void bindVersion(EntityBinding entityBinding, RootEntitySource entitySource) {
final SingularAttributeSource versioningAttributeSource = entitySource.getVersioningAttributeSource();
if ( versioningAttributeSource == null ) {
return;
}
SimpleAttributeBinding attributeBinding = doBasicSingularAttributeBindingCreation(
versioningAttributeSource, entityBinding
);
entityBinding.setVersionBinding( attributeBinding );
}
private void bindDiscriminator(RootEntitySource entitySource, EntityBinding entityBinding) {
//To change body of created methods use File | Settings | File Templates.
}
private void bindAttributes(EntitySource entitySource, EntityBinding entityBinding) {
for ( AttributeSource attributeSource : entitySource.attributeSources() ) {
if ( attributeSource.isSingular() ) {
doBasicSingularAttributeBindingCreation( (SingularAttributeSource) attributeSource, entityBinding );
}
// todo : components and collections
}
}
private SimpleAttributeBinding doBasicSingularAttributeBindingCreation(
SingularAttributeSource attributeSource,
EntityBinding entityBinding) {
final SingularAttribute attribute = attributeSource.isVirtualAttribute()
? entityBinding.getEntity().locateOrCreateVirtualAttribute( attributeSource.getName() )
: entityBinding.getEntity().locateOrCreateSingularAttribute( attributeSource.getName() );
final SimpleAttributeBinding attributeBinding;
if ( attributeSource.getNature() == SingularAttributeNature.BASIC ) {
attributeBinding = entityBinding.makeSimpleAttributeBinding( attribute );
resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding );
}
else if ( attributeSource.getNature() == SingularAttributeNature.MANY_TO_ONE ) {
attributeBinding = entityBinding.makeManyToOneAttributeBinding( attribute );
resolveTypeInformation( attributeSource.getTypeInformation(), attributeBinding );
resolveToOneReferenceInformation( (ToOneAttributeSource) attributeSource, (ManyToOneAttributeBinding) attributeBinding );
}
else {
throw new NotYetImplementedException();
}
attributeBinding.setInsertable( attributeSource.isInsertable() );
attributeBinding.setUpdatable( attributeSource.isUpdatable() );
attributeBinding.setGeneration( attributeSource.getGeneration() );
attributeBinding.setLazy( attributeSource.isLazy() );
attributeBinding.setIncludedInOptimisticLocking( attributeSource.isIncludedInOptimisticLocking() );
attributeBinding.setPropertyAccessorName(
Helper.getPropertyAccessorName(
attributeSource.getPropertyAccessorName(),
false,
currentBindingContext.getMappingDefaults().getPropertyAccessorName()
)
);
final org.hibernate.metamodel.relational.Value relationalValue = makeValue( attributeSource, attributeBinding );
attributeBinding.setValue( relationalValue );
attributeBinding.setMetaAttributeContext(
buildMetaAttributeContext( attributeSource.metaAttributes(), entityBinding.getMetaAttributeContext() )
);
return attributeBinding;
}
private void resolveTypeInformation(ExplicitHibernateTypeSource typeSource, SimpleAttributeBinding attributeBinding) {
final Class<?> attributeJavaType = determineJavaType( attributeBinding.getAttribute() );
if ( attributeJavaType != null ) {
attributeBinding.getHibernateTypeDescriptor().setJavaTypeName( attributeJavaType.getName() );
attributeBinding.getAttribute().resolveType( currentBindingContext.makeJavaType( attributeJavaType.getName() ) );
}
final String explicitTypeName = typeSource.getName();
if ( explicitTypeName != null ) {
final TypeDef typeDef = currentBindingContext.getMetadataImplementor().getTypeDefinition( explicitTypeName );
if ( typeDef != null ) {
attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( typeDef.getTypeClass() );
attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( typeDef.getParameters() );
}
else {
attributeBinding.getHibernateTypeDescriptor().setExplicitTypeName( explicitTypeName );
}
final Map<String,String> parameters = typeSource.getParameters();
if ( parameters != null ) {
attributeBinding.getHibernateTypeDescriptor().getTypeParameters().putAll( parameters );
}
}
else {
if ( attributeJavaType == null ) {
// we will have problems later determining the Hibernate Type to use. Should we throw an
// exception now? Might be better to get better contextual info
}
}
}
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 ignore ) {
// 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 void resolveToOneReferenceInformation(ToOneAttributeSource attributeSource, ManyToOneAttributeBinding attributeBinding) {
final String referencedEntityName = attributeSource.getReferencedEntityName() != null
? attributeSource.getReferencedEntityName()
: attributeBinding.getAttribute().getSingularAttributeType().getClassName();
attributeBinding.setReferencedEntityName( referencedEntityName );
attributeBinding.setReferencedAttributeName( attributeSource.getReferencedEntityAttributeName() );
}
private MetaAttributeContext buildMetaAttributeContext(EntitySource entitySource) {
return buildMetaAttributeContext(
entitySource.metaAttributes(),
true,
currentBindingContext.getMetadataImplementor().getGlobalMetaAttributeContext()
);
}
private static MetaAttributeContext buildMetaAttributeContext(
Iterable<MetaAttributeSource> metaAttributeSources,
MetaAttributeContext parentContext) {
return buildMetaAttributeContext( metaAttributeSources, false, parentContext );
}
private static MetaAttributeContext buildMetaAttributeContext(
Iterable<MetaAttributeSource> metaAttributeSources,
boolean onlyInheritable,
MetaAttributeContext parentContext) {
final MetaAttributeContext subContext = new MetaAttributeContext( parentContext );
for ( MetaAttributeSource metaAttributeSource : metaAttributeSources ) {
if ( onlyInheritable & !metaAttributeSource.isInheritable() ) {
continue;
}
final String name = metaAttributeSource.getName();
final MetaAttribute inheritedMetaAttribute = parentContext.getMetaAttribute( name );
MetaAttribute metaAttribute = subContext.getLocalMetaAttribute( name );
if ( metaAttribute == null || metaAttribute == inheritedMetaAttribute ) {
metaAttribute = new MetaAttribute( name );
subContext.add( metaAttribute );
}
metaAttribute.addValue( metaAttributeSource.getValue() );
}
return subContext;
}
private org.hibernate.metamodel.relational.Value makeValue(
RelationValueMetadataSource relationValueMetadataSource,
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 table = attributeBinding.getEntityBinding().getBaseTable();
if ( relationValueMetadataSource.relationalValueSources().size() > 0 ) {
List<SimpleValue> values = new ArrayList<SimpleValue>();
for ( RelationalValueSource valueSource : relationValueMetadataSource.relationalValueSources() ) {
if ( ColumnSource.class.isInstance( valueSource ) ) {
final ColumnSource columnSource = ColumnSource.class.cast( valueSource );
final Column column = table.locateOrCreateColumn( columnSource.getName() );
column.setNullable( columnSource.isNullable() );
column.setDefaultValue( columnSource.getDefaultValue() );
column.setSqlType( columnSource.getSqlType() );
column.setSize( columnSource.getSize() );
column.setDatatype( columnSource.getDatatype() );
column.setReadFragment( columnSource.getReadFragment() );
column.setWriteFragment( columnSource.getWriteFragment() );
column.setUnique( columnSource.isUnique() );
column.setCheckCondition( columnSource.getCheckCondition() );
column.setComment( columnSource.getComment() );
values.add( column );
}
else {
values.add( table.locateOrCreateDerivedValue( ( (DerivedValueSource) valueSource ).getExpression() ) );
}
}
if ( values.size() == 1 ) {
return values.get( 0 );
}
Tuple tuple = new Tuple( table, null );
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 table.locateOrCreateColumn( name );
}
}
}

View File

@ -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.source.binder;
import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.Size;
/**
* @author Steve Ebersole
*/
public interface ColumnSource extends RelationalValueSource {
public String getName();
public boolean isNullable();
public String getDefaultValue();
public String getSqlType();
public Datatype getDatatype();
public Size getSize();
public String getReadFragment();
public String getWriteFragment();
public boolean isUnique();
public String getCheckCondition();
public String getComment();
}

View File

@ -0,0 +1,31 @@
/*
* 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.binder;
/**
* @author Steve Ebersole
*/
public interface DerivedValueSource extends RelationalValueSource {
public String getExpression();
}

View File

@ -0,0 +1,36 @@
/*
* 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.binder;
import org.hibernate.metamodel.binding.InheritanceType;
/**
* Models the source-agnostic view of an entity hierarchy.
*
* @author Steve Ebersole
*/
public interface EntityHierarchy {
public InheritanceType getHierarchyInheritanceType();
public RootEntitySource getRootEntitySource();
}

View File

@ -0,0 +1,65 @@
/*
* 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.binder;
import java.util.List;
import org.hibernate.metamodel.binding.CustomSQL;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.Origin;
/**
* @author Steve Ebersole
*/
public interface EntitySource extends SubclassEntityContainer, AttributeSourceContainer {
public Origin getOrigin();
public LocalBindingContext getBindingContext();
public String getEntityName();
public String getClassName();
public String getJpaEntityName();
public boolean isAbstract();
public boolean isLazy();
public String getProxy();
public int getBatchSize();
public boolean isDynamicInsert();
public boolean isDynamicUpdate();
public boolean isSelectBeforeUpdate();
public String getCustomTuplizerClassName();
public String getCustomPersisterClassName();
public String getCustomLoaderName();
public CustomSQL getCustomSqlInsert();
public CustomSQL getCustomSqlUpdate();
public CustomSQL getCustomSqlDelete();
public List<String> getSynchronizedTableNames();
public Iterable<MetaAttributeSource> metaAttributes();
// public List<XMLFetchProfileElement> getFetchProfile();
}

View File

@ -0,0 +1,47 @@
/*
* 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.binder;
import java.util.Map;
/**
* Source-agnostic descriptor for explicit user-supplied Hibernate type information
*
* @author Steve Ebersole
*/
public interface ExplicitHibernateTypeSource {
/**
* Obtain the supplied Hibernate type name.
*
* @return The Hibernate type name
*/
public String getName();
/**
* Obtain any supplied Hibernate type parameters.
*
* @return The Hibernate type parameters.
*/
public Map<String,String> getParameters();
}

View File

@ -0,0 +1,31 @@
/*
* 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.binder;
/**
* @author Steve Ebersole
*/
public interface IdentifierAttributeSource {
}

View File

@ -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.source.binder;
/**
* @author Steve Ebersole
*/
public interface IdentifierSource {
public static enum Nature {
SIMPLE,
COMPOSITE,
AGGREGATED_COMPOSITE
}
public Nature getNature();
}

View File

@ -0,0 +1,53 @@
/*
* 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.binder;
/**
* Describes incoming {@link org.hibernate.mapping.MetaAttribute} values. This is only from {@code hbm} via the
* {@code <meta/>} element(s).
*
* @author Steve Ebersole
*/
public interface MetaAttributeSource {
/**
* Obtain the supplied meta-attribute name
*
* @return The meta-attribute name
*/
public String getName();
/**
* Obtain the supplied meta-attribute value.
*
* @return The meta-attribute value
*/
public String getValue();
/**
* Is the meta-attribute value inheritable?
*
* @return Is the value inheritable?
*/
public boolean isInheritable();
}

View File

@ -0,0 +1,33 @@
/*
* 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.binder;
import java.util.List;
/**
* @author Steve Ebersole
*/
public interface RelationValueMetadataSource {
public List<RelationalValueSource> relationalValueSources();
}

View File

@ -0,0 +1,30 @@
/*
* 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.binder;
/**
* @author Steve Ebersole
*/
public interface RelationalValueSource {
}

View File

@ -0,0 +1,47 @@
/*
* 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.binder;
import java.util.List;
import org.hibernate.EntityMode;
import org.hibernate.engine.OptimisticLockStyle;
import org.hibernate.metamodel.binding.Caching;
/**
* @author Steve Ebersole
*/
public interface RootEntitySource extends EntitySource {
public IdentifierSource getIdentifierSource();
public SingularAttributeSource getVersioningAttributeSource();
public SingularAttributeSource getDiscriminatorAttributeSource();
public EntityMode getEntityMode();
public boolean isMutable();
public boolean isExplicitPolymorphism();
public String getWhere();
public String getRowId();
public OptimisticLockStyle getOptimisticLockStyle();
public Caching getCaching();
}

View File

@ -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.source.binder;
import org.hibernate.metamodel.binding.IdGenerator;
/**
* @author Steve Ebersole
*/
public interface SimpleIdentifierSource extends IdentifierSource {
public SingularAttributeSource getIdentifierAttributeSource();
public IdGenerator getIdentifierGeneratorDescriptor();
}

View File

@ -0,0 +1,36 @@
/*
* 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.binder;
/**
* Describes the understood natures of a singular attribute.
*
* @author Steve Ebersole
*/
public enum SingularAttributeNature {
BASIC,
MANY_TO_ONE,
ONE_TO_ONE,
ANY
}

View File

@ -0,0 +1,107 @@
/*
* 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.binder;
import java.util.List;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.mapping.PropertyGeneration;
/**
* Source-agnostic description of information needed to bind a singular attribute.
*
* @author Steve Ebersole
*/
public interface SingularAttributeSource extends AttributeSource, RelationValueMetadataSource {
/**
* Determine whether this is a virtual attribute or whether it physically exists on the users domain model.
*
* @return {@code true} indicates the attribute is virtual, meaning it does NOT exist on the domain model;
* {@code false} indicates the attribute physically exists.
*/
public boolean isVirtualAttribute();
/**
* Obtain the nature of this attribute type.
*
* @return The attribute type nature
*/
public SingularAttributeNature getNature();
/**
* Obtain information about the Hibernate type ({@link org.hibernate.type.Type}) for this attribute.
*
* @return The Hibernate type information
*/
public ExplicitHibernateTypeSource getTypeInformation();
/**
* Obtain the name of the property accessor style used to access this attribute.
*
* @return The property accessor style for this attribute.
* @see org.hibernate.property.PropertyAccessor
*/
public String getPropertyAccessorName();
/**
* Determine whether this attribute is insertable.
*
* @return {@code true} indicates the attribute value should be used in the {@code SQL INSERT}; {@code false}
* indicates it should not.
*/
public boolean isInsertable();
/**
* Determine whether this attribute is updateable.
*
* @return {@code true} indicates the attribute value should be used in the {@code SQL UPDATE}; {@code false}
* indicates it should not.
*/
public boolean isUpdatable();
/**
* Obtain a description of if/when the attribute value is generated by the database.
*
* @return The attribute value generation information
*/
public PropertyGeneration getGeneration();
/**
* Should the attribute be (bytecode enhancement) lazily loaded?
*
* @return {@code true} to indicate the attribute should be lazily loaded.
*/
public boolean isLazy();
/**
* If the containing entity is using {@link org.hibernate.engine.OptimisticLockStyle#ALL} or
* {@link org.hibernate.engine.OptimisticLockStyle#DIRTY} style optimistic locking, should this attribute
* be used?
*
* @return {@code true} indicates it should be included; {@code false}, it should not.
*/
public boolean isIncludedInOptimisticLocking();
public Iterable<CascadeStyle> getCascadeStyle();
}

View File

@ -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.source.binder;
/**
* 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 SubclassEntityContainer {
public Iterable<SubclassEntitySource> subclassEntitySources();
}

View File

@ -0,0 +1,30 @@
/*
* 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.binder;
/**
* @author Steve Ebersole
*/
public interface SubclassEntitySource extends EntitySource {
}

View File

@ -0,0 +1,32 @@
/*
* 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.binder;
/**
* @author Steve Ebersole
*/
public interface ToOneAttributeSource extends SingularAttributeSource {
public String getReferencedEntityName();
public String getReferencedEntityAttributeName();
}

View File

@ -57,6 +57,7 @@ import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.Entity;
import org.hibernate.metamodel.domain.SingularAttribute;
import org.hibernate.metamodel.relational.Column;
import org.hibernate.metamodel.relational.Datatype;
import org.hibernate.metamodel.relational.Identifier;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.SimpleValue;
@ -66,6 +67,15 @@ import org.hibernate.metamodel.relational.Tuple;
import org.hibernate.metamodel.source.MappingException;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.source.binder.ColumnSource;
import org.hibernate.metamodel.source.binder.DerivedValueSource;
import org.hibernate.metamodel.source.binder.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.source.binder.MetaAttributeSource;
import org.hibernate.metamodel.source.binder.RelationValueMetadataSource;
import org.hibernate.metamodel.source.binder.RelationalValueSource;
import org.hibernate.metamodel.source.binder.SingularAttributeNature;
import org.hibernate.metamodel.source.binder.SingularAttributeSource;
import org.hibernate.metamodel.source.binder.ToOneAttributeSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.EntityElement;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.JoinElementSource;
import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLAnyElement;
@ -797,54 +807,6 @@ public class BindingCreator {
}
// Initial prototype/sandbox for notion of "orchestrated information collection from sources" ~~~~~~~~~~~~~~~~~~~~~~
private static enum SingularAttributeNature { BASIC, MANY_TO_ONE, ONE_TO_ONE, ANY };
private interface SingularAttributeSource {
public String getName();
public ExplicitHibernateTypeSource getTypeInformation();
public String getPropertyAccessorName();
public boolean isInsertable();
public boolean isUpdatable();
public PropertyGeneration getGeneration();
public boolean isLazy();
public boolean isIncludedInOptimisticLocking();
public Iterable<CascadeStyle> getCascadeStyle();
public SingularAttributeNature getNature();
public boolean isVirtualAttribute();
public RelationValueMetadataSource getValueInformation();
public Iterable<MetaAttributeSource> metaAttributes();
}
private interface ToOneAttributeSource extends SingularAttributeSource {
public String getReferencedEntityName();
public String getReferencedEntityAttributeName();
}
private interface ExplicitHibernateTypeSource {
public String getName();
public Map<String,String> getParameters();
}
private interface MetaAttributeSource {
public String getName();
public String getValue();
public boolean isInheritable();
}
private static interface RelationValueMetadataSource {
public String getColumnAttribute();
public String getFormulaAttribute();
public List getColumnOrFormulaElements();
}
// HBM specific implementations of "attribute sources" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
@ -853,7 +815,7 @@ public class BindingCreator {
private class PropertyAttributeSource implements SingularAttributeSource {
private final XMLPropertyElement propertyElement;
private final ExplicitHibernateTypeSource typeSource;
private final RelationValueMetadataSource valueSource;
private final List<RelationalValueSource> valueSources;
private PropertyAttributeSource(final XMLPropertyElement propertyElement) {
this.propertyElement = propertyElement;
@ -877,7 +839,8 @@ public class BindingCreator {
return parameters;
}
};
this.valueSource = new RelationValueMetadataSource() {
this.valueSources = buildValueSources(
new ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return propertyElement.getColumn();
@ -892,7 +855,8 @@ public class BindingCreator {
public List getColumnOrFormulaElements() {
return propertyElement.getColumnOrFormula();
}
};
}
);
}
@Override
@ -951,8 +915,13 @@ public class BindingCreator {
}
@Override
public RelationValueMetadataSource getValueInformation() {
return valueSource;
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
@ -967,7 +936,7 @@ public class BindingCreator {
private class SingularIdentifierAttributeSource implements SingularAttributeSource {
private final XMLHibernateMapping.XMLClass.XMLId idElement;
private final ExplicitHibernateTypeSource typeSource;
private final RelationValueMetadataSource valueSource;
private final List<RelationalValueSource> valueSources;
public SingularIdentifierAttributeSource(final XMLHibernateMapping.XMLClass.XMLId idElement) {
this.idElement = idElement;
@ -991,7 +960,8 @@ public class BindingCreator {
return parameters;
}
};
this.valueSource = new RelationValueMetadataSource() {
this.valueSources = buildValueSources(
new ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return idElement.getColumnAttribute();
@ -1006,7 +976,8 @@ public class BindingCreator {
public List getColumnOrFormulaElements() {
return idElement.getColumn();
}
};
}
);
}
@Override
@ -1067,8 +1038,13 @@ public class BindingCreator {
}
@Override
public RelationValueMetadataSource getValueInformation() {
return valueSource;
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
@ -1082,24 +1058,12 @@ public class BindingCreator {
*/
private class VersionAttributeSource implements SingularAttributeSource {
private final XMLHibernateMapping.XMLClass.XMLVersion versionElement;
private final List<RelationalValueSource> valueSources;
private VersionAttributeSource(XMLHibernateMapping.XMLClass.XMLVersion versionElement) {
private VersionAttributeSource(final XMLHibernateMapping.XMLClass.XMLVersion versionElement) {
this.versionElement = versionElement;
}
private final ExplicitHibernateTypeSource typeSource = new ExplicitHibernateTypeSource() {
@Override
public String getName() {
return versionElement.getType() == null ? "integer" : versionElement.getType();
}
@Override
public Map<String, String> getParameters() {
return null;
}
};
private final RelationValueMetadataSource valueSource = new RelationValueMetadataSource() {
this.valueSources = buildValueSources(
new ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return versionElement.getColumnAttribute();
@ -1114,6 +1078,20 @@ public class BindingCreator {
public List getColumnOrFormulaElements() {
return versionElement.getColumn();
}
}
);
}
private final ExplicitHibernateTypeSource typeSource = new ExplicitHibernateTypeSource() {
@Override
public String getName() {
return versionElement.getType() == null ? "integer" : versionElement.getType();
}
@Override
public Map<String, String> getParameters() {
return null;
}
};
@Override
@ -1190,8 +1168,13 @@ public class BindingCreator {
}
@Override
public RelationValueMetadataSource getValueInformation() {
return valueSource;
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
@ -1205,24 +1188,12 @@ public class BindingCreator {
*/
private class TimestampAttributeSource implements SingularAttributeSource {
private final XMLHibernateMapping.XMLClass.XMLTimestamp timestampElement;
private final List<RelationalValueSource> valueSources;
private TimestampAttributeSource(XMLHibernateMapping.XMLClass.XMLTimestamp timestampElement) {
private TimestampAttributeSource(final XMLHibernateMapping.XMLClass.XMLTimestamp timestampElement) {
this.timestampElement = timestampElement;
}
private final ExplicitHibernateTypeSource typeSource = new ExplicitHibernateTypeSource() {
@Override
public String getName() {
return "db".equals( timestampElement.getSource() ) ? "dbtimestamp" : "timestamp";
}
@Override
public Map<String, String> getParameters() {
return null;
}
};
private final RelationValueMetadataSource valueSource = new RelationValueMetadataSource() {
this.valueSources = buildValueSources(
new ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return timestampElement.getColumn();
@ -1237,6 +1208,20 @@ public class BindingCreator {
public List getColumnOrFormulaElements() {
return null;
}
}
);
}
private final ExplicitHibernateTypeSource typeSource = new ExplicitHibernateTypeSource() {
@Override
public String getName() {
return "db".equals( timestampElement.getSource() ) ? "dbtimestamp" : "timestamp";
}
@Override
public Map<String, String> getParameters() {
return null;
}
};
@Override
@ -1313,8 +1298,13 @@ public class BindingCreator {
}
@Override
public RelationValueMetadataSource getValueInformation() {
return valueSource;
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
@ -1328,11 +1318,12 @@ public class BindingCreator {
*/
private class ManyToOneAttributeSource implements ToOneAttributeSource {
private final XMLManyToOneElement manyToOneElement;
private final RelationValueMetadataSource valueSource;
private final List<RelationalValueSource> valueSources;
private ManyToOneAttributeSource(final XMLManyToOneElement manyToOneElement) {
this.manyToOneElement = manyToOneElement;
this.valueSource = new RelationValueMetadataSource() {
this.valueSources = buildValueSources(
new ValueSourcesAdapter() {
@Override
public String getColumnAttribute() {
return manyToOneElement.getColumn();
@ -1347,7 +1338,8 @@ public class BindingCreator {
public List getColumnOrFormulaElements() {
return manyToOneElement.getColumnOrFormula();
}
};
}
);
}
@Override
@ -1406,8 +1398,13 @@ public class BindingCreator {
}
@Override
public RelationValueMetadataSource getValueInformation() {
return valueSource;
public List<RelationalValueSource> relationalValueSources() {
return valueSources;
}
@Override
public boolean isSingular() {
return true;
}
@Override
@ -1522,8 +1519,8 @@ public class BindingCreator {
final String referencedEntityName = attributeSource.getReferencedEntityName() != null
? attributeSource.getReferencedEntityName()
: attributeBinding.getAttribute().getSingularAttributeType().getClassName();
attributeBinding.setReferencedEntity( referencedEntityName );
attributeBinding.setReferencedEntityAttributeName( attributeSource.getReferencedEntityAttributeName() );
attributeBinding.setReferencedEntityName( referencedEntityName );
attributeBinding.setReferencedAttributeName( attributeSource.getReferencedEntityAttributeName() );
}
private org.hibernate.metamodel.relational.Value makeValue(
@ -1687,4 +1684,199 @@ public class BindingCreator {
return cascadeStyles;
}
private static interface ValueSourcesAdapter {
public String getColumnAttribute();
public String getFormulaAttribute();
public List getColumnOrFormulaElements();
}
private List<RelationalValueSource> buildValueSources(final ValueSourcesAdapter valueSourcesAdapter) {
List<RelationalValueSource> result = new ArrayList<RelationalValueSource>();
if ( StringHelper.isNotEmpty( valueSourcesAdapter.getColumnAttribute() ) ) {
if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
&& ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) {
throw new MappingException(
"column/formula attribute may not be used together with <column>/<formula> subelement",
currentBindingContext.getOrigin()
);
}
if ( StringHelper.isNotEmpty( valueSourcesAdapter.getFormulaAttribute() ) ) {
throw new MappingException(
"column and formula attributes may not be used together",
currentBindingContext.getOrigin()
);
}
result.add( new ColumnAttributeSource( valueSourcesAdapter.getColumnAttribute() ) );
}
else if ( StringHelper.isNotEmpty( valueSourcesAdapter.getFormulaAttribute() ) ) {
if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
&& ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) {
throw new MappingException(
"column/formula attribute may not be used together with <column>/<formula> subelement",
currentBindingContext.getOrigin()
);
}
// column/formula attribute combo checked already
result.add( new Formula( valueSourcesAdapter.getFormulaAttribute() ) );
}
else if ( valueSourcesAdapter.getColumnOrFormulaElements() != null
&& ! valueSourcesAdapter.getColumnOrFormulaElements().isEmpty() ) {
List<SimpleValue> values = new ArrayList<SimpleValue>();
for ( Object columnOrFormulaElement : valueSourcesAdapter.getColumnOrFormulaElements() ) {
if ( XMLColumnElement.class.isInstance( columnOrFormulaElement ) ) {
result.add( new ColumnSource( (XMLColumnElement) columnOrFormulaElement ) );
}
else {
result.add( new Formula( (String) columnOrFormulaElement ) );
}
}
}
return result;
}
private static class ColumnAttributeSource implements org.hibernate.metamodel.source.binder.ColumnSource {
private final String columnName;
private ColumnAttributeSource(String columnName) {
this.columnName = columnName;
}
@Override
public String getName() {
return columnName;
}
@Override
public boolean isNullable() {
return true;
}
@Override
public String getDefaultValue() {
return null;
}
@Override
public String getSqlType() {
return null;
}
@Override
public Datatype getDatatype() {
return null;
}
@Override
public Size getSize() {
return null;
}
@Override
public String getReadFragment() {
return null;
}
@Override
public String getWriteFragment() {
return null;
}
@Override
public boolean isUnique() {
return false;
}
@Override
public String getCheckCondition() {
return null;
}
@Override
public String getComment() {
return null;
}
}
private static class Formula implements DerivedValueSource {
private final String expression;
private Formula(String expression) {
this.expression = expression;
}
@Override
public String getExpression() {
return expression;
}
}
private class ColumnSource implements org.hibernate.metamodel.source.binder.ColumnSource {
private final XMLColumnElement columnElement;
private ColumnSource(XMLColumnElement columnElement) {
this.columnElement = columnElement;
}
@Override
public String getName() {
return columnElement.getName();
}
@Override
public boolean isNullable() {
return ! columnElement.isNotNull();
}
@Override
public String getDefaultValue() {
return columnElement.getDefault();
}
@Override
public String getSqlType() {
return columnElement.getSqlType();
}
@Override
public Datatype getDatatype() {
return null;
}
@Override
public Size getSize() {
return new Size(
Helper.getIntValue( columnElement.getPrecision(), -1 ),
Helper.getIntValue( columnElement.getScale(), -1 ),
Helper.getLongValue( columnElement.getLength(), -1 ),
Size.LobMultiplier.NONE
);
}
@Override
public String getReadFragment() {
return columnElement.getRead();
}
@Override
public String getWriteFragment() {
return columnElement.getWrite();
}
@Override
public boolean isUnique() {
return columnElement.isUnique();
}
@Override
public String getCheckCondition() {
return columnElement.getCheck();
}
@Override
public String getComment() {
return columnElement.getComment();
}
}
}

View File

@ -25,6 +25,7 @@ package org.hibernate.metamodel.source.hbm;
import java.util.List;
import org.hibernate.metamodel.source.LocalBindingContext;
import org.hibernate.metamodel.source.Origin;
import org.hibernate.metamodel.source.BindingContext;
import org.hibernate.metamodel.source.MetaAttributeContext;
@ -36,16 +37,12 @@ import org.hibernate.metamodel.source.hbm.jaxb.mapping.XMLFetchProfileElement;
*
* @author Steve Ebersole
*/
public interface HbmBindingContext extends BindingContext {
public interface HbmBindingContext extends LocalBindingContext {
public boolean isAutoImport();
public MetaAttributeContext getMetaAttributeContext();
public Origin getOrigin();
public String determineEntityName(EntityElement entityElement);
public String qualifyClassName(String unqualifiedName);
public void processFetchProfiles(List<XMLFetchProfileElement> fetchProfiles, String containingEntityName);
}