Package org.hibernate.metamodel.source.internal

Source Code of org.hibernate.metamodel.source.internal.MetadataImpl$MappingDefaultsImpl

/*
* 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.internal;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jboss.logging.Logger;

import org.hibernate.AssertionFailure;
import org.hibernate.DuplicateMappingException;
import org.hibernate.MappingException;
import org.hibernate.SessionFactory;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.engine.ResultSetMappingDefinition;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.engine.spi.NamedQueryDefinition;
import org.hibernate.engine.spi.NamedSQLQueryDefinition;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.id.factory.spi.MutableIdentifierGeneratorFactory;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.Value;
import org.hibernate.metamodel.MetadataSourceProcessingOrder;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.SessionFactoryBuilder;
import org.hibernate.metamodel.binding.PluralAttributeBinding;
import org.hibernate.metamodel.source.MappingDefaults;
import org.hibernate.metamodel.source.MetaAttributeContext;
import org.hibernate.metamodel.source.MetadataImplementor;
import org.hibernate.metamodel.source.MetadataSourceProcessor;
import org.hibernate.metamodel.source.annotations.AnnotationMetadataSourceProcessorImpl;
import org.hibernate.metamodel.source.hbm.HbmMetadataSourceProcessorImpl;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.FetchProfile;
import org.hibernate.metamodel.binding.IdGenerator;
import org.hibernate.metamodel.binding.TypeDef;
import org.hibernate.metamodel.domain.BasicType;
import org.hibernate.metamodel.domain.Type;
import org.hibernate.metamodel.relational.Database;
import org.hibernate.persister.spi.PersisterClassResolver;
import org.hibernate.service.BasicServiceRegistry;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.type.TypeResolver;

/**
* Container for configuration data collected during binding the metamodel.
*
* @author Steve Ebersole
* @author Hardy Ferentschik
* @author Gail Badner
*/
public class MetadataImpl implements MetadataImplementor, Serializable {

  private static final CoreMessageLogger LOG = Logger.getMessageLogger(
      CoreMessageLogger.class,
      MetadataImpl.class.getName()
  );

  private final BasicServiceRegistry serviceRegistry;
  private final Options options;

  private final Value<ClassLoaderService> classLoaderService;
  private final Value<PersisterClassResolver> persisterClassResolverService;

  private TypeResolver typeResolver = new TypeResolver();

  private SessionFactoryBuilder sessionFactoryBuilder = new SessionFactoryBuilderImpl( this );

  private final MutableIdentifierGeneratorFactory identifierGeneratorFactory;

  private final Database database;

  private final MappingDefaults mappingDefaults;

  /**
   * Maps the fully qualified class name of an entity to its entity binding
   */
  private Map<String, EntityBinding> entityBindingMap = new HashMap<String, EntityBinding>();

  private Map<String, PluralAttributeBinding> collectionBindingMap = new HashMap<String, PluralAttributeBinding>();
  private Map<String, FetchProfile> fetchProfiles = new HashMap<String, FetchProfile>();
  private Map<String, String> imports = new HashMap<String, String>();
  private Map<String, TypeDef> typeDefs = new HashMap<String, TypeDef>();
  private Map<String, IdGenerator> idGenerators = new HashMap<String, IdGenerator>();
  private Map<String, NamedQueryDefinition> namedQueryDefs = new HashMap<String, NamedQueryDefinition>();
  private Map<String, NamedSQLQueryDefinition> namedNativeQueryDefs = new HashMap<String, NamedSQLQueryDefinition>();
  private Map<String, ResultSetMappingDefinition> resultSetMappings = new HashMap<String, ResultSetMappingDefinition>();
  private Map<String, FilterDefinition> filterDefs = new HashMap<String, FilterDefinition>();

    private boolean globallyQuotedIdentifiers = false;

  public MetadataImpl(MetadataSources metadataSources, Options options) {
    this.serviceRegistry =  metadataSources.getServiceRegistry();
    this.options = options;
    this.identifierGeneratorFactory = serviceRegistry.getService( MutableIdentifierGeneratorFactory.class );
        //new DefaultIdentifierGeneratorFactory( dialect );
    this.database = new Database( options );

    this.mappingDefaults = new MappingDefaultsImpl();

    final MetadataSourceProcessor[] metadataSourceProcessors;
    if ( options.getMetadataSourceProcessingOrder() == MetadataSourceProcessingOrder.HBM_FIRST ) {
      metadataSourceProcessors = new MetadataSourceProcessor[] {
          new HbmMetadataSourceProcessorImpl( this ),
          new AnnotationMetadataSourceProcessorImpl( this )
      };
    }
    else {
      metadataSourceProcessors = new MetadataSourceProcessor[] {
          new AnnotationMetadataSourceProcessorImpl( this ),
          new HbmMetadataSourceProcessorImpl( this )
      };
    }

    this.classLoaderService = new org.hibernate.internal.util.Value<ClassLoaderService>(
        new org.hibernate.internal.util.Value.DeferredInitializer<ClassLoaderService>() {
          @Override
          public ClassLoaderService initialize() {
            return serviceRegistry.getService( ClassLoaderService.class );
          }
        }
    );
    this.persisterClassResolverService = new org.hibernate.internal.util.Value<PersisterClassResolver>(
        new org.hibernate.internal.util.Value.DeferredInitializer<PersisterClassResolver>() {
          @Override
          public PersisterClassResolver initialize() {
            return serviceRegistry.getService( PersisterClassResolver.class );
          }
        }
    );


    final ArrayList<String> processedEntityNames = new ArrayList<String>();

    prepare( metadataSourceProcessors, metadataSources );
    bindIndependentMetadata( metadataSourceProcessors, metadataSources );
    bindTypeDependentMetadata( metadataSourceProcessors, metadataSources );
    bindMappingMetadata( metadataSourceProcessors, metadataSources, processedEntityNames );
    bindMappingDependentMetadata( metadataSourceProcessors, metadataSources );

    // todo : remove this by coordinated ordering of entity processing
    new AssociationResolver( this ).resolve();
    new HibernateTypeResolver( this ).resolve();
    // IdentifierGeneratorResolver.resolve() must execute after AttributeTypeResolver.resolve()
    new IdentifierGeneratorResolver( this ).resolve();
  }

  private void prepare(MetadataSourceProcessor[] metadataSourceProcessors, MetadataSources metadataSources) {
    for ( MetadataSourceProcessor metadataSourceProcessor : metadataSourceProcessors ) {
      metadataSourceProcessor.prepare( metadataSources );
    }
  }

  private void bindIndependentMetadata(MetadataSourceProcessor[] metadataSourceProcessors, MetadataSources metadataSources) {
    for ( MetadataSourceProcessor metadataSourceProcessor : metadataSourceProcessors ) {
      metadataSourceProcessor.processIndependentMetadata( metadataSources );
    }
  }

  private void bindTypeDependentMetadata(MetadataSourceProcessor[] metadataSourceProcessors, MetadataSources metadataSources) {
    for ( MetadataSourceProcessor metadataSourceProcessor : metadataSourceProcessors ) {
      metadataSourceProcessor.processTypeDependentMetadata( metadataSources );
    }
  }

  private void bindMappingMetadata(MetadataSourceProcessor[] metadataSourceProcessors, MetadataSources metadataSources, List<String> processedEntityNames) {
    for ( MetadataSourceProcessor metadataSourceProcessor : metadataSourceProcessors ) {
      metadataSourceProcessor.processMappingMetadata( metadataSources, processedEntityNames );
    }
  }

  private void bindMappingDependentMetadata(MetadataSourceProcessor[] metadataSourceProcessors, MetadataSources metadataSources) {
    for ( MetadataSourceProcessor metadataSourceProcessor : metadataSourceProcessors ) {
      metadataSourceProcessor.processMappingDependentMetadata( metadataSources );
    }
  }

  @Override
  public void addFetchProfile(FetchProfile profile) {
    if ( profile == null || profile.getName() == null ) {
      throw new IllegalArgumentException( "Fetch profile object or name is null: " + profile );
    }
    fetchProfiles.put( profile.getName(), profile );
  }

  @Override
  public void addFilterDefinition(FilterDefinition def) {
    if ( def == null || def.getFilterName() == null ) {
      throw new IllegalArgumentException( "Filter definition object or name is null: "  + def );
    }
    filterDefs.put( def.getFilterName(), def );
  }

  public Iterable<FilterDefinition> getFilterDefinitions() {
    return filterDefs.values();
  }

  @Override
  public void addIdGenerator(IdGenerator generator) {
    if ( generator == null || generator.getName() == null ) {
      throw new IllegalArgumentException( "ID generator object or name is null." );
    }
    idGenerators.put( generator.getName(), generator );
  }

  @Override
  public IdGenerator getIdGenerator(String name) {
    if ( name == null ) {
      throw new IllegalArgumentException( "null is not a valid generator name" );
    }
    return idGenerators.get( name );
  }
  @Override
  public void registerIdentifierGenerator(String name, String generatorClassName) {
     identifierGeneratorFactory.register( name, classLoaderService().classForName( generatorClassName ) );
  }

  @Override
  public void addNamedNativeQuery(NamedSQLQueryDefinition def) {
    if ( def == null || def.getName() == null ) {
      throw new IllegalArgumentException( "Named native query definition object or name is null: " + def.getQueryString() );
    }
    namedNativeQueryDefs.put( def.getName(), def );
  }

  public NamedSQLQueryDefinition getNamedNativeQuery(String name) {
    if ( name == null ) {
      throw new IllegalArgumentException( "null is not a valid native query name" );
    }
    return namedNativeQueryDefs.get( name );
  }

  @Override
  public Iterable<NamedSQLQueryDefinition> getNamedNativeQueryDefinitions() {
    return namedNativeQueryDefs.values();
  }

  @Override
  public void addNamedQuery(NamedQueryDefinition def) {
    if ( def == null ) {
      throw new IllegalArgumentException( "Named query definition is null" );
    }
    else if ( def.getName() == null ) {
      throw new IllegalArgumentException( "Named query definition name is null: " + def.getQueryString() );
    }
    namedQueryDefs.put( def.getName(), def );
  }

  public NamedQueryDefinition getNamedQuery(String name) {
    if ( name == null ) {
      throw new IllegalArgumentException( "null is not a valid query name" );
    }
    return namedQueryDefs.get( name );
  }

  @Override
  public Iterable<NamedQueryDefinition> getNamedQueryDefinitions() {
    return namedQueryDefs.values();
  }

  @Override
  public void addResultSetMapping(ResultSetMappingDefinition resultSetMappingDefinition) {
    if ( resultSetMappingDefinition == null || resultSetMappingDefinition.getName() == null ) {
      throw new IllegalArgumentException( "Result-set mapping object or name is null: " + resultSetMappingDefinition );
    }
    resultSetMappings.put( resultSetMappingDefinition.getName(), resultSetMappingDefinition );
  }

  @Override
  public Iterable<ResultSetMappingDefinition> getResultSetMappingDefinitions() {
    return resultSetMappings.values();
  }

  @Override
  public void addTypeDefinition(TypeDef typeDef) {
    if ( typeDef == null ) {
      throw new IllegalArgumentException( "Type definition is null" );
    }
    else if ( typeDef.getName() == null ) {
      throw new IllegalArgumentException( "Type definition name is null: " + typeDef.getTypeClass() );
    }
    final TypeDef previous = typeDefs.put( typeDef.getName(), typeDef );
    if ( previous != null ) {
      LOG.debugf( "Duplicate typedef name [%s] now -> %s", typeDef.getName(), typeDef.getTypeClass() );
    }
  }

  @Override
  public Iterable<TypeDef> getTypeDefinitions() {
    return typeDefs.values();
  }

  @Override
  public TypeDef getTypeDefinition(String name) {
    return typeDefs.get( name );
  }

  private ClassLoaderService classLoaderService() {
    return classLoaderService.getValue();
  }

  private PersisterClassResolver persisterClassResolverService() {
    return persisterClassResolverService.getValue();
  }

  @Override
  public Options getOptions() {
    return options;
  }

  @Override
  public SessionFactory buildSessionFactory() {
    return sessionFactoryBuilder.buildSessionFactory();
  }

  @Override
  public BasicServiceRegistry getServiceRegistry() {
    return serviceRegistry;
  }

  @Override
  @SuppressWarnings( {"unchecked"})
  public <T> Class<T> locateClassByName(String name) {
    return classLoaderService().classForName( name );
  }

  @Override
  public Type makeJavaType(String className) {
    // todo : have this perform some analysis of the incoming type name to determine appropriate return
    return new BasicType( className, makeClassReference( className ) );
  }

  @Override
  public Value<Class<?>> makeClassReference(final String className) {
    return new Value<Class<?>>(
        new Value.DeferredInitializer<Class<?>>() {
          @Override
          public Class<?> initialize() {
            return classLoaderService.getValue().classForName( className );
          }
        }
    );
  }

  @Override
  public String qualifyClassName(String name) {
    return name;
  }

  @Override
  public Database getDatabase() {
    return database;
  }

  public EntityBinding getEntityBinding(String entityName) {
    return entityBindingMap.get( entityName );
  }

  @Override
  public EntityBinding getRootEntityBinding(String entityName) {
    EntityBinding binding = entityBindingMap.get( entityName );
    if ( binding == null ) {
      throw new IllegalStateException( "Unknown entity binding: " + entityName );
    }

    do {
      if ( binding.isRoot() ) {
        return binding;
      }
      binding = binding.getSuperEntityBinding();
    } while ( binding != null );

    throw new AssertionFailure( "Entity binding has no root: " + entityName );
  }

  public Iterable<EntityBinding> getEntityBindings() {
    return entityBindingMap.values();
  }

  public void addEntity(EntityBinding entityBinding) {
    final String entityName = entityBinding.getEntity().getName();
    if ( entityBindingMap.containsKey( entityName ) ) {
      throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, entityName );
    }
    entityBindingMap.put( entityName, entityBinding );
  }

  public PluralAttributeBinding getCollection(String collectionRole) {
    return collectionBindingMap.get( collectionRole );
  }

  @Override
  public Iterable<PluralAttributeBinding> getCollectionBindings() {
    return collectionBindingMap.values();
  }

  public void addCollection(PluralAttributeBinding pluralAttributeBinding) {
    final String owningEntityName = pluralAttributeBinding.getContainer().getPathBase();
    final String attributeName = pluralAttributeBinding.getAttribute().getName();
    final String collectionRole = owningEntityName + '.' + attributeName;
    if ( collectionBindingMap.containsKey( collectionRole ) ) {
      throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, collectionRole );
    }
    collectionBindingMap.put( collectionRole, pluralAttributeBinding );
  }

  public void addImport(String importName, String entityName) {
    if ( importName == null || entityName == null ) {
      throw new IllegalArgumentException( "Import name or entity name is null" );
    }
    LOG.trace( "Import: " + importName + " -> " + entityName );
    String old = imports.put( importName, entityName );
    if ( old != null ) {
      LOG.debug( "import name [" + importName + "] overrode previous [{" + old + "}]" );
    }
  }

  @Override
  public Iterable<Map.Entry<String, String>> getImports() {
    return imports.entrySet();
  }

  @Override
  public Iterable<FetchProfile> getFetchProfiles() {
    return fetchProfiles.values();
  }

  public TypeResolver getTypeResolver() {
    return typeResolver;
  }

  @Override
  public SessionFactoryBuilder getSessionFactoryBuilder() {
    return sessionFactoryBuilder;
  }

  @Override
  public NamingStrategy getNamingStrategy() {
    return options.getNamingStrategy();
  }

    @Override
    public boolean isGloballyQuotedIdentifiers() {
        return globallyQuotedIdentifiers || getOptions().isGloballyQuotedIdentifiers();
    }

    public void setGloballyQuotedIdentifiers(boolean globallyQuotedIdentifiers){
       this.globallyQuotedIdentifiers = globallyQuotedIdentifiers;
    }

    @Override
  public MappingDefaults getMappingDefaults() {
    return mappingDefaults;
  }

  private final MetaAttributeContext globalMetaAttributeContext = new MetaAttributeContext();

  @Override
  public MetaAttributeContext getGlobalMetaAttributeContext() {
    return globalMetaAttributeContext;
  }

  @Override
  public MetadataImplementor getMetadataImplementor() {
    return this;
  }

  private static final String DEFAULT_IDENTIFIER_COLUMN_NAME = "id";
  private static final String DEFAULT_DISCRIMINATOR_COLUMN_NAME = "class";
  private static final String DEFAULT_CASCADE = "none";
  private static final String DEFAULT_PROPERTY_ACCESS = "property";

  @Override
  public IdentifierGeneratorFactory getIdentifierGeneratorFactory() {
    return identifierGeneratorFactory;
  }

  @Override
  public org.hibernate.type.Type getIdentifierType(String entityName) throws MappingException {
    EntityBinding entityBinding = getEntityBinding( entityName );
    if ( entityBinding == null ) {
      throw new MappingException( "Entity binding not known: " + entityName );
    }
    return entityBinding
        .getHierarchyDetails()
        .getEntityIdentifier()
        .getValueBinding()
        .getHibernateTypeDescriptor()
        .getResolvedTypeMapping();
  }

  @Override
  public String getIdentifierPropertyName(String entityName) throws MappingException {
    EntityBinding entityBinding = getEntityBinding( entityName );
    if ( entityBinding == null ) {
      throw new MappingException( "Entity binding not known: " + entityName );
    }
    AttributeBinding idBinding = entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding();
    return idBinding == null ? null : idBinding.getAttribute().getName();
  }

  @Override
  public org.hibernate.type.Type getReferencedPropertyType(String entityName, String propertyName) throws MappingException {
    EntityBinding entityBinding = getEntityBinding( entityName );
    if ( entityBinding == null ) {
      throw new MappingException( "Entity binding not known: " + entityName );
    }
    // TODO: should this call EntityBinding.getReferencedAttributeBindingString), which does not exist yet?
    AttributeBinding attributeBinding = entityBinding.locateAttributeBinding( propertyName );
    if ( attributeBinding == null ) {
      throw new MappingException( "unknown property: " + entityName + '.' + propertyName );
    }
    return attributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping();
  }

  private class MappingDefaultsImpl implements MappingDefaults {

    @Override
    public String getPackageName() {
      return null;
    }

    @Override
    public String getSchemaName() {
      return options.getDefaultSchemaName();
    }

    @Override
    public String getCatalogName() {
      return options.getDefaultCatalogName();
    }

    @Override
    public String getIdColumnName() {
      return DEFAULT_IDENTIFIER_COLUMN_NAME;
    }

    @Override
    public String getDiscriminatorColumnName() {
      return DEFAULT_DISCRIMINATOR_COLUMN_NAME;
    }

    @Override
    public String getCascadeStyle() {
      return DEFAULT_CASCADE;
    }

    @Override
    public String getPropertyAccessorName() {
      return DEFAULT_PROPERTY_ACCESS;
    }

    @Override
    public boolean areAssociationsLazy() {
      return true;
    }

    private final Value<AccessType> regionFactorySpecifiedDefaultAccessType = new Value<AccessType>(
        new Value.DeferredInitializer<AccessType>() {
          @Override
          public AccessType initialize() {
            final RegionFactory regionFactory = getServiceRegistry().getService( RegionFactory.class );
            return regionFactory.getDefaultAccessType();
          }
        }
    );

    @Override
    public AccessType getCacheAccessType() {
      return options.getDefaultAccessType() != null
          ? options.getDefaultAccessType()
          : regionFactorySpecifiedDefaultAccessType.getValue();
    }
  }
}
TOP

Related Classes of org.hibernate.metamodel.source.internal.MetadataImpl$MappingDefaultsImpl

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.