Package org.hibernate.search.store

Source Code of org.hibernate.search.store.DirectoryProviderFactory

//$Id: $
package org.hibernate.search.store;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.hibernate.HibernateException;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.reflection.ReflectionManager;
import org.hibernate.reflection.XClass;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;

/**
* Create a Lucene directory provider
* <p/>
* Lucene directory providers are configured through properties
* - hibernate.search.default.* and
* - hibernate.search.<indexname>.*
* <p/>
* <indexname> properties have precedence over default
* <p/>
* The implementation is described by
* hibernate.search.[default|indexname].directory_provider
* <p/>
* If none is defined the default value is FSDirectory
*
* @author Emmanuel Bernard
* @author Sylvain Vieujot
*/
public class DirectoryProviderFactory {
  public List<DirectoryProvider<?>> providers = new ArrayList<DirectoryProvider<?>>();
  private static String LUCENE_PREFIX = "hibernate.search.";
  private static String LUCENE_DEFAULT = LUCENE_PREFIX + "default.";
  private static String DEFAULT_DIRECTORY_PROVIDER = FSDirectoryProvider.class.getName();

  //TODO for the public?
  //public DirectoryProvider<?> createDirectoryProvider(XClass entity, Configuration cfg) {

  public DirectoryProvider<?> createDirectoryProvider(XClass entity, Configuration cfg) {
    //get properties
    String directoryProviderName = getDirectoryProviderName( entity, cfg );
    Properties indexProps = getDirectoryProperties( cfg, directoryProviderName );

    //set up the directory
    String className = indexProps.getProperty( "directory_provider" );
    if ( StringHelper.isEmpty( className ) ) {
      className = DEFAULT_DIRECTORY_PROVIDER;
    }
    DirectoryProvider<?> provider = null;
    try {
      @SuppressWarnings( "unchecked" )
      Class<DirectoryProvider> directoryClass = ReflectHelper.classForName(
          className, DirectoryProviderFactory.class
      );
      provider = directoryClass.newInstance();
    }
    catch (Exception e) {
      throw new HibernateException( "Unable to instanciate directory provider: " + className, e );
    }
    provider.initialize( directoryProviderName, indexProps );
    int index = providers.indexOf( provider );
    if ( index != -1 ) {
      //share the same Directory provider for the same underlying store
      return providers.get( index );
    }
    else {
      providers.add( provider );
      return provider;
    }
  }

  private static Properties getDirectoryProperties(Configuration cfg, String directoryProviderName) {
    Properties props = cfg.getProperties();
    String indexName = LUCENE_PREFIX + directoryProviderName;
    Properties indexProps = new Properties();
    Properties indexSpecificProps = new Properties();
    for ( Map.Entry entry : props.entrySet() ) {
      String key = (String) entry.getKey();
      if ( key.startsWith( LUCENE_DEFAULT ) ) {
        indexProps.setProperty( key.substring( LUCENE_DEFAULT.length() ), (String) entry.getValue() );
      }
      else if ( key.startsWith( indexName ) ) {
        indexSpecificProps.setProperty( key.substring( indexName.length() ), (String) entry.getValue() );
      }
    }
    indexProps.putAll( indexSpecificProps );
    return indexProps;
  }

  public static String getDirectoryProviderName(XClass clazz, Configuration cfg) {
    //yuk
    ReflectionManager reflectionManager =
        ( (AnnotationConfiguration) cfg ).createExtendedMappings().getReflectionManager();
    //get the most specialized (ie subclass > superclass) non default index name
    //if none extract the name from the most generic (superclass > subclass) @Indexed class in the hierarchy
    //FIXME I'm inclined to get rid of the default value
    PersistentClass pc = cfg.getClassMapping( clazz.getName() );
    XClass rootIndex = null;
    do {
      XClass currentClazz = reflectionManager.toXClass( pc.getMappedClass() );
      Indexed indexAnn = currentClazz.getAnnotation( Indexed.class );
      if ( indexAnn != null ) {
        if ( indexAnn.index().length() != 0 ) {
          return indexAnn.index();
        }
        else {
          rootIndex = currentClazz;
        }
      }
      pc = pc.getSuperclass();
    }
    while ( pc != null );
    //there is nobody outthere with a non default @Indexed.index
    if ( rootIndex != null ) {
      return rootIndex.getName();
    }
    else {
      throw new HibernateException(
          "Trying to extract the index name from a non @Indexed class: " + clazz.getName() );
    }
  }
}
TOP

Related Classes of org.hibernate.search.store.DirectoryProviderFactory

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.