Package org.hibernate.metamodel.source.hbm

Source Code of org.hibernate.metamodel.source.hbm.AbstractEntityBinder

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, 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;

import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.BagBinding;
import org.hibernate.metamodel.binding.CollectionElementType;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.InheritanceType;
import org.hibernate.metamodel.binding.ManyToOneAttributeBinding;
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
import org.hibernate.metamodel.binding.state.ManyToOneAttributeBindingState;
import org.hibernate.metamodel.binding.state.PluralAttributeBindingState;
import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState;
import org.hibernate.metamodel.domain.Attribute;
import org.hibernate.metamodel.domain.Hierarchical;
import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.Table;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.UniqueKey;
import org.hibernate.metamodel.relational.state.ManyToOneRelationalState;
import org.hibernate.metamodel.relational.state.TupleRelationalState;
import org.hibernate.metamodel.relational.state.ValueRelationalState;
import org.hibernate.metamodel.source.hbm.state.binding.HbmEntityBindingState;
import org.hibernate.metamodel.source.hbm.state.binding.HbmManyToOneAttributeBindingState;
import org.hibernate.metamodel.source.hbm.state.binding.HbmPluralAttributeBindingState;
import org.hibernate.metamodel.source.hbm.state.binding.HbmSimpleAttributeBindingState;
import org.hibernate.metamodel.source.hbm.state.relational.HbmManyToOneRelationalStateContainer;
import org.hibernate.metamodel.source.hbm.state.relational.HbmSimpleValueRelationalStateContainer;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLAnyElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLBagElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLComponentElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLDynamicComponentElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLFilterElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLHibernateMapping;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLIdbagElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLJoinedSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLListElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLManyToOneElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLMapElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLOneToOneElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLPropertiesElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLPropertyElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLQueryElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLResultsetElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSetElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSqlQueryElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLSubclassElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLTuplizerElement;
import org.hibernate.metamodel.source.hbm.xml.mapping.XMLUnionSubclassElement;
import org.hibernate.metamodel.source.spi.MetadataImplementor;

/**
* TODO : javadoc
*
* @author Steve Ebersole
*/
abstract class AbstractEntityBinder {
  private final HbmBindingContext bindingContext;
  private final Schema.Name schemaName;

  AbstractEntityBinder(HbmBindingContext bindingContext, XMLHibernateMapping.XMLClass entityClazz) {
    this.bindingContext = bindingContext;
    this.schemaName = new Schema.Name(
        entityClazz.getSchema() == null
            ? bindingContext.getMappingDefaults().getSchemaName()
            : entityClazz.getSchema(),
        entityClazz.getCatalog() == null
            ? bindingContext.getMappingDefaults().getCatalogName() :
            entityClazz.getCatalog()
    );
  }

  public boolean isRoot() {
    return false;
  }

  public abstract InheritanceType getInheritanceType();

  public HbmBindingContext getBindingContext() {
    return bindingContext;
  }

  protected MetadataImplementor getMetadata() {
    return bindingContext.getMetadataImplementor();
  }

  protected Schema.Name getSchemaName() {
    return schemaName;
  }

  protected NamingStrategy getNamingStrategy() {
    return getMetadata().getOptions().getNamingStrategy();
  }

  protected void basicEntityBinding(
      XMLHibernateMapping.XMLClass entityClazz,
      EntityBinding entityBinding,
      Hierarchical superType) {
    entityBinding.initialize(
        bindingContext,
        new HbmEntityBindingState(
            superType,
            entityClazz,
            isRoot(),
            getInheritanceType(),
            bindingContext
        )
    );

    final String entityName = entityBinding.getEntity().getName();

    if ( entityClazz.getFetchProfile() != null ) {
      bindingContext.bindFetchProfiles( entityClazz.getFetchProfile(), entityName );
    }

    getMetadata().addImport( entityName, entityName );
    if ( bindingContext.isAutoImport() ) {
      if ( entityName.indexOf( '.' ) > 0 ) {
        getMetadata().addImport( StringHelper.unqualify( entityName ), entityName );
      }
    }
  }

  protected String getDefaultAccess() {
    return bindingContext.getMappingDefaults().getPropertyAccessorName();
  }

  /**
   * Locate any explicit tuplizer definition in the metadata, for the given entity-mode.
   *
   * @param container The containing element (representing the entity/component)
   * @param entityMode The entity-mode for which to locate the tuplizer element
   *
   * @return The tuplizer element, or null.
   */
  private static XMLTuplizerElement locateTuplizerDefinition(XMLHibernateMapping.XMLClass container,
                                 EntityMode entityMode) {
    for ( XMLTuplizerElement tuplizer : container.getTuplizer() ) {
      if ( entityMode.toString().equals( tuplizer.getEntityMode() ) ) {
        return tuplizer;
      }
    }
    return null;
  }

  protected String getClassTableName(
      XMLHibernateMapping.XMLClass entityClazz,
      EntityBinding entityBinding,
      Table denormalizedSuperTable) {
    final String entityName = entityBinding.getEntity().getName();
    String logicalTableName;
    String physicalTableName;
    if ( entityClazz.getTable() == null ) {
      logicalTableName = StringHelper.unqualify( entityName );
      physicalTableName = getMetadata()
          .getOptions()
          .getNamingStrategy()
          .classToTableName( entityName );
    }
    else {
      logicalTableName = entityClazz.getTable();
      physicalTableName = getMetadata()
          .getOptions()
          .getNamingStrategy()
          .tableName( logicalTableName );
    }
// todo : find out the purpose of these logical bindings
//      mappings.addTableBinding( schema, catalog, logicalTableName, physicalTableName, denormalizedSuperTable );
    return physicalTableName;
  }

  protected void buildAttributeBindings(XMLHibernateMapping.XMLClass entityClazz,
                      EntityBinding entityBinding) {
    // null = UniqueKey (we are not binding a natural-id mapping)
    // true = mutable, by default properties are mutable
    // true = nullable, by default properties are nullable.
    buildAttributeBindings( entityClazz, entityBinding, null, true, true );
  }

  /**
   * This form is essentially used to create natural-id mappings.  But the processing is the same, aside from these
   * extra parameterized values, so we encapsulate it here.
   *
   * @param entityClazz
   * @param entityBinding
   * @param uniqueKey
   * @param mutable
   * @param nullable
   */
  protected void buildAttributeBindings(
      XMLHibernateMapping.XMLClass entityClazz,
      EntityBinding entityBinding,
      UniqueKey uniqueKey,
      boolean mutable,
      boolean nullable) {
    final boolean naturalId = uniqueKey != null;

    final String entiytName = entityBinding.getEntity().getName();
    final TableSpecification tabe = entityBinding.getBaseTable();

    AttributeBinding attributeBinding = null;
    for ( Object attribute : entityClazz.getPropertyOrManyToOneOrOneToOne() ) {
      if ( XMLBagElement.class.isInstance( attribute ) ) {
        XMLBagElement collection = XMLBagElement.class.cast( attribute );
        BagBinding collectionBinding = makeBagAttributeBinding( collection, entityBinding );
        bindingContext.getMetadataImplementor().addCollection( collectionBinding );
        attributeBinding = collectionBinding;
      }
      else if ( XMLIdbagElement.class.isInstance( attribute ) ) {
        XMLIdbagElement collection = XMLIdbagElement.class.cast( attribute );
        //BagBinding collectionBinding = entityBinding.makeBagAttributeBinding( collection.getName() );
        //bindIdbag( collection, bagBinding, entityBinding, PluralAttributeNature.BAG, collection.getName() );
        // todo: handle identifier
        //attributeBinding = collectionBinding;
        //hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding );
      }
      else if ( XMLSetElement.class.isInstance( attribute ) ) {
        XMLSetElement collection = XMLSetElement.class.cast( attribute );
        //BagBinding collectionBinding = entityBinding.makeBagAttributeBinding( collection.getName() );
        //bindSet( collection, collectionBinding, entityBinding, PluralAttributeNature.SET, collection.getName() );
        //attributeBinding = collectionBinding;
        //hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding );
      }
      else if ( XMLListElement.class.isInstance( attribute ) ) {
        XMLListElement collection = XMLListElement.class.cast( attribute );
        //ListBinding collectionBinding = entityBinding.makeBagAttributeBinding( collection.getName() );
        //bindList( collection, bagBinding, entityBinding, PluralAttributeNature.LIST, collection.getName() );
        // todo : handle list index
        //attributeBinding = collectionBinding;
        //hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding );
      }
      else if ( XMLMapElement.class.isInstance( attribute ) ) {
        XMLMapElement collection = XMLMapElement.class.cast( attribute );
        //BagBinding bagBinding = entityBinding.makeBagAttributeBinding( collection.getName() );
        //bindMap( collection, bagBinding, entityBinding, PluralAttributeNature.MAP, collection.getName() );
        // todo : handle map key
        //hibernateMappingBinder.getHibernateXmlBinder().getMetadata().addCollection( attributeBinding );
      }
      else if ( XMLManyToOneElement.class.isInstance( attribute ) ) {
        XMLManyToOneElement manyToOne = XMLManyToOneElement.class.cast( attribute );
        attributeBinding = makeManyToOneAttributeBinding( manyToOne, entityBinding );
      }
      else if ( XMLAnyElement.class.isInstance( attribute ) ) {
// todo : implement
//        value = new Any( mappings, table );
//        bindAny( subElement, (Any) value, nullable, mappings );
      }
      else if ( XMLOneToOneElement.class.isInstance( attribute ) ) {
// todo : implement
//        value = new OneToOne( mappings, table, persistentClass );
//        bindOneToOne( subElement, (OneToOne) value, propertyName, true, mappings );
      }
      else if ( XMLPropertyElement.class.isInstance( attribute ) ) {
        XMLPropertyElement property = XMLPropertyElement.class.cast( attribute );
        attributeBinding = bindProperty( property, entityBinding );
      }
      else if ( XMLComponentElement.class.isInstance( attribute )
          || XMLDynamicComponentElement.class.isInstance( attribute )
          || XMLPropertiesElement.class.isInstance( attribute ) ) {
// todo : implement
//        String subpath = StringHelper.qualify( entityName, propertyName );
//        value = new Component( mappings, persistentClass );
//
//        bindComponent(
//            subElement,
//            (Component) value,
//            persistentClass.getClassName(),
//            propertyName,
//            subpath,
//            true,
//            "properties".equals( subElementName ),
//            mappings,
//            inheritedMetas,
//            false
//          );
      }
    }

    /*
Array
PrimitiveArray
*/
    for ( XMLJoinElement join : entityClazz.getJoin() ) {
// todo : implement
//      Join join = new Join();
//      join.setPersistentClass( persistentClass );
//      bindJoin( subElement, join, mappings, inheritedMetas );
//      persistentClass.addJoin( join );
    }
    for ( XMLSubclassElement subclass : entityClazz.getSubclass() ) {
// todo : implement
//      handleSubclass( persistentClass, mappings, subElement, inheritedMetas );
    }
    for ( XMLJoinedSubclassElement subclass : entityClazz.getJoinedSubclass() ) {
// todo : implement
//      handleJoinedSubclass( persistentClass, mappings, subElement, inheritedMetas );
    }
    for ( XMLUnionSubclassElement subclass : entityClazz.getUnionSubclass() ) {
// todo : implement
//      handleUnionSubclass( persistentClass, mappings, subElement, inheritedMetas );
    }
    for ( XMLFilterElement filter : entityClazz.getFilter() ) {
// todo : implement
//        parseFilter( subElement, entityBinding );
    }
    if ( entityClazz.getNaturalId() != null ) {
// todo : implement
//        UniqueKey uk = new UniqueKey();
//        uk.setName("_UniqueKey");
//        uk.setTable(table);
//        //by default, natural-ids are "immutable" (constant)
//        boolean mutableId = "true".equals( subElement.attributeValue("mutable") );
//        createClassProperties(
//            subElement,
//            persistentClass,
//            mappings,
//            inheritedMetas,
//            uk,
//            mutableId,
//            false,
//            true
//          );
//        table.addUniqueKey(uk);
    }
    if ( entityClazz.getQueryOrSqlQuery() != null ) {
      for ( Object queryOrSqlQuery : entityClazz.getQueryOrSqlQuery() ) {
        if ( XMLQueryElement.class.isInstance( queryOrSqlQuery ) ) {
// todo : implement
//        bindNamedQuery(subElement, persistentClass.getEntityName(), mappings);
        }
        else if ( XMLSqlQueryElement.class.isInstance( queryOrSqlQuery ) ) {
// todo : implement
//      bindNamedSQLQuery(subElement, persistentClass.getEntityName(), mappings);
        }
      }
    }
    if ( entityClazz.getResultset() != null ) {
      for ( XMLResultsetElement resultSet : entityClazz.getResultset() ) {
// todo : implement
//        bindResultSetMappingDefinition( subElement, persistentClass.getEntityName(), mappings );
      }
    }
//      if ( value != null ) {
//        Property property = createProperty( value, propertyName, persistentClass
//          .getClassName(), subElement, mappings, inheritedMetas );
//        if ( !mutable ) property.setUpdateable(false);
//        if ( naturalId ) property.setNaturalIdentifier(true);
//        persistentClass.addProperty( property );
//        if ( uniqueKey!=null ) uniqueKey.addColumns( property.getColumnIterator() );
//      }

  }

  protected SimpleAttributeBinding bindProperty(
      XMLPropertyElement property,
      EntityBinding entityBinding) {
    SimpleAttributeBindingState bindingState = new HbmSimpleAttributeBindingState(
        entityBinding.getEntity().getJavaType().getName(),
        bindingContext,
        entityBinding.getMetaAttributeContext(),
        property
    );

    // boolean (true here) indicates that by default column names should be guessed
    ValueRelationalState relationalState =
        convertToSimpleValueRelationalStateIfPossible(
            new HbmSimpleValueRelationalStateContainer(
                bindingContext,
                true,
                property
            )
        );

    Attribute attribute = entityBinding.getEntity().getOrCreateSingularAttribute( bindingState.getAttributeName() );
    return entityBinding.makeSimpleAttributeBinding( attribute )
        .initialize( bindingState )
        .initialize( relationalState );
  }

  protected static ValueRelationalState convertToSimpleValueRelationalStateIfPossible(ValueRelationalState state) {
    // TODO: should a single-valued tuple always be converted???
    if ( !TupleRelationalState.class.isInstance( state ) ) {
      return state;
    }
    TupleRelationalState tupleRelationalState = TupleRelationalState.class.cast( state );
    return tupleRelationalState.getRelationalStates().size() == 1 ?
        tupleRelationalState.getRelationalStates().get( 0 ) :
        state;
  }

  protected BagBinding makeBagAttributeBinding(
      XMLBagElement collection,
      EntityBinding entityBinding) {

    PluralAttributeBindingState bindingState =
        new HbmPluralAttributeBindingState(
            entityBinding.getEntity().getJavaType().getName(),
            bindingContext,
            entityBinding.getMetaAttributeContext(),
            collection
        );

    BagBinding collectionBinding = entityBinding.makeBagAttributeBinding(
        bindingState.getAttributeName(),
        getCollectionElementType( collection )
    )
        .initialize( bindingState );

    // todo : relational model binding
    return collectionBinding;
  }

  private CollectionElementType getCollectionElementType(XMLBagElement collection) {
    if ( collection.getElement() != null ) {
      return CollectionElementType.BASIC;
    }
    else if ( collection.getCompositeElement() != null ) {
      return CollectionElementType.COMPOSITE;
    }
    else if ( collection.getManyToMany() != null ) {
      return CollectionElementType.MANY_TO_MANY;
    }
    else if ( collection.getOneToMany() != null ) {
      return CollectionElementType.ONE_TO_MANY;
    }
    else if ( collection.getManyToAny() != null ) {
      return CollectionElementType.MANY_TO_ANY;
    }
    else {
      throw new AssertionFailure( "Unknown collection element type: " + collection );
    }
  }

  private ManyToOneAttributeBinding makeManyToOneAttributeBinding(XMLManyToOneElement manyToOne,
                                  EntityBinding entityBinding) {
    ManyToOneAttributeBindingState bindingState =
        new HbmManyToOneAttributeBindingState(
            entityBinding.getEntity().getJavaType().getName(),
            bindingContext,
            entityBinding.getMetaAttributeContext(),
            manyToOne
        );

    // boolean (true here) indicates that by default column names should be guessed
    ManyToOneRelationalState relationalState =
        new HbmManyToOneRelationalStateContainer(
            bindingContext,
            true,
            manyToOne
        );

    entityBinding.getEntity().getOrCreateSingularAttribute( bindingState.getAttributeName() );
    ManyToOneAttributeBinding manyToOneAttributeBinding =
        entityBinding.makeManyToOneAttributeBinding( bindingState.getAttributeName() )
            .initialize( bindingState )
            .initialize( relationalState );

    return manyToOneAttributeBinding;
  }

//  private static Property createProperty(
//      final Value value,
//          final String propertyName,
//      final String className,
//          final Element subnode,
//          final Mappings mappings,
//      java.util.Map inheritedMetas) throws MappingException {
//
//    if ( StringHelper.isEmpty( propertyName ) ) {
//      throw new MappingException( subnode.getName() + " mapping must defined a name attribute [" + className + "]" );
//    }
//
//    value.setTypeUsingReflection( className, propertyName );
//
//    // this is done here 'cos we might only know the type here (ugly!)
//    // TODO: improve this a lot:
//    if ( value instanceof ToOne ) {
//      ToOne toOne = (ToOne) value;
//      String propertyRef = toOne.getReferencedPropertyName();
//      if ( propertyRef != null ) {
//        mappings.addUniquePropertyReference( toOne.getReferencedEntityName(), propertyRef );
//      }
//    }
//    else if ( value instanceof Collection ) {
//      Collection coll = (Collection) value;
//      String propertyRef = coll.getReferencedPropertyName();
//      // not necessarily a *unique* property reference
//      if ( propertyRef != null ) {
//        mappings.addPropertyReference( coll.getOwnerEntityName(), propertyRef );
//      }
//    }
//
//    value.createForeignKey();
//    Property prop = new Property();
//    prop.setValue( value );
//    bindProperty( subnode, prop, mappings, inheritedMetas );
//    return prop;
//  }


//  protected HbmRelationalState processValues(Element identifierElement, TableSpecification baseTable, String propertyPath, boolean isSimplePrimaryKey) {
  // first boolean (false here) indicates that by default columns are nullable
  // second boolean (true here) indicates that by default column names should be guessed
// todo : logical 1-1 handling
//      final Attribute uniqueAttribute = node.attribute( "unique" );
//      if ( uniqueAttribute != null
//          && "true".equals( uniqueAttribute.getValue() )
//          && ManyToOne.class.isInstance( simpleValue ) ) {
//        ( (ManyToOne) simpleValue ).markAsLogicalOneToOne();
//      }
  //return processValues( identifierElement, baseTable, false, true, propertyPath, isSimplePrimaryKey );


}
TOP

Related Classes of org.hibernate.metamodel.source.hbm.AbstractEntityBinder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.