Package org.hibernate.search.engine

Source Code of org.hibernate.search.engine.MultiClassesQueryLoader$RootEntityMetadata

// $Id: MultiClassesQueryLoader.java 15374 2008-10-22 21:36:38Z epbernard $
package org.hibernate.search.engine;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.HashMap;
import java.util.Arrays;

import org.hibernate.Session;
import org.hibernate.Criteria;
import org.hibernate.annotations.common.AssertionFailure;

/**
* @author Emmanuel Bernard
*/
public class MultiClassesQueryLoader implements Loader {
  private Session session;
  private SearchFactoryImplementor searchFactoryImplementor;
  private List<RootEntityMetadata> entityMatadata;
  //useful if loading with a query is unsafe
  private ObjectLoader objectLoader;

  public void init(Session session, SearchFactoryImplementor searchFactoryImplementor) {
    this.session = session;
    this.searchFactoryImplementor = searchFactoryImplementor;
    this.objectLoader = new ObjectLoader();
    this.objectLoader.init( session, searchFactoryImplementor );
  }

  public void setEntityTypes(Class[] entityTypes) {
    List<Class> safeEntityTypes;
    //TODO should we go find the root entity for a given class rather than just checking for it's root status?
    //     root entity could lead to quite inefficient queries in Hibernate when using table per class
    if ( entityTypes.length == 0 ) {
      //support all classes
      safeEntityTypes = new ArrayList<Class>();
      for( Map.Entry<Class<?>, DocumentBuilder<?>> entry : searchFactoryImplementor.getDocumentBuilders().entrySet() ) {
        //get only root entities to limit queries
        if ( entry.getValue().isRoot() ) {
          safeEntityTypes.add( entry.getKey() );
        }
      }
    }
    else {
      safeEntityTypes = Arrays.asList(entityTypes);
    }
    entityMatadata = new ArrayList<RootEntityMetadata>( safeEntityTypes.size() );
    for (Class clazz :  safeEntityTypes) {
      entityMatadata.add( new RootEntityMetadata( clazz, searchFactoryImplementor, session ) );
    }
  }

  public Object load(EntityInfo entityInfo) {
    return ObjectLoaderHelper.load( entityInfo, session );
  }

  public List load(EntityInfo... entityInfos) {
    if ( entityInfos.length == 0 ) return Collections.EMPTY_LIST;
    if ( entityInfos.length == 1 ) {
      final Object entity = load( entityInfos[0] );
      if ( entity == null ) {
        return Collections.EMPTY_LIST;
      }
      else {
        final List<Object> list = new ArrayList<Object>( 1 );
        list.add( entity );
        return list;
      }
    }

    //split EntityInfo per root entity
    Map<RootEntityMetadata, List<EntityInfo>> entityinfoBuckets =
        new HashMap<RootEntityMetadata, List<EntityInfo>>( entityMatadata.size());
    for (EntityInfo entityInfo : entityInfos) {
      boolean found = false;
      for (RootEntityMetadata rootEntityInfo : entityMatadata) {
        if ( rootEntityInfo.mappedSubclasses.contains( entityInfo.clazz ) ) {
          List<EntityInfo> bucket = entityinfoBuckets.get( rootEntityInfo );
          if ( bucket == null ) {
            bucket = new ArrayList<EntityInfo>();
            entityinfoBuckets.put( rootEntityInfo, bucket );
          }
          bucket.add( entityInfo );
          found = true;
          break; //we stop looping for the right bucket
        }
      }
      if (!found) throw new AssertionFailure( "Could not find root entity for " + entityInfo.clazz );
    }

    //initialize objects by bucket
    for ( Map.Entry<RootEntityMetadata, List<EntityInfo>> entry : entityinfoBuckets.entrySet() ) {
      final RootEntityMetadata key = entry.getKey();
      final List<EntityInfo> value = entry.getValue();
      final EntityInfo[] bucketEntityInfos = value.toArray( new EntityInfo[value.size()] );
      if ( key.useObjectLoader ) {
        objectLoader.load( bucketEntityInfos );
      }
      else {
        ObjectLoaderHelper.initializeObjects( bucketEntityInfos,
            key.criteria, key.rootEntity, searchFactoryImplementor);
      }
    }
    return ObjectLoaderHelper.returnAlreadyLoadedObjectsInCorrectOrder( entityInfos, session );
  }

  private static class RootEntityMetadata {
    public final Class<?> rootEntity;
    public final Set<Class<?>> mappedSubclasses;
    private final Criteria criteria;
    public final boolean useObjectLoader;

    RootEntityMetadata(Class<?> rootEntity, SearchFactoryImplementor searchFactoryImplementor, Session session) {
      this.rootEntity = rootEntity;
      DocumentBuilder<?> provider = searchFactoryImplementor.getDocumentBuilder( rootEntity );
      if ( provider == null) throw new AssertionFailure("Provider not found for class: " + rootEntity);
      this.mappedSubclasses = provider.getMappedSubclasses();
      this.criteria = session.createCriteria( rootEntity );
      this.useObjectLoader = !provider.isSafeFromTupleId();
    }
  }
}
TOP

Related Classes of org.hibernate.search.engine.MultiClassesQueryLoader$RootEntityMetadata

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.