Package org.hibernate.search.store

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

/* $Id: DirectoryProviderHelper.java 20243 2010-08-24 12:58:56Z epbernard $
*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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.search.store;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockFactory;
import org.apache.lucene.store.NativeFSLockFactory;
import org.apache.lucene.store.NoLockFactory;
import org.apache.lucene.store.SimpleFSLockFactory;
import org.apache.lucene.store.SingleInstanceLockFactory;
import org.slf4j.Logger;

import org.hibernate.annotations.common.util.StringHelper;
import org.hibernate.search.SearchException;
import org.hibernate.search.util.FileHelper;
import org.hibernate.search.util.LoggerFactory;
import org.hibernate.search.util.PluginLoader;

/**
* @author Emmanuel Bernard
* @author Sanne Grinovero
*/
public class DirectoryProviderHelper {
 
  private static final Logger log = LoggerFactory.make();
  private static final String ROOTINDEX_PROP_NAME = "sourceBase";
  private static final String RELATIVEINDEX_PROP_NAME = "source";
  public static final String COPYBUFFERSIZE_PROP_NAME = "buffer_size_on_copy";

  /**
   * Build a directory name out of a root and relative path, guessing the significant part
   * and checking for the file availability
   * @param directoryProviderName
   * @param properties
   * @param needWritePermissions when true the directory will be tested for read-write permissions.
   * @return The file representing the source directory
   */
  public static File getSourceDirectory( String directoryProviderName, Properties properties, boolean needWritePermissions ) {
    String root = properties.getProperty( ROOTINDEX_PROP_NAME );
    String relative = properties.getProperty( RELATIVEINDEX_PROP_NAME );
    File sourceDirectory;
    if ( log.isTraceEnabled() ) {
      log.trace(
          "Guess source directory from {} {} and {} {}", new Object[] {
            ROOTINDEX_PROP_NAME,
            ( root != null ? root : "<null>" ),
            RELATIVEINDEX_PROP_NAME,
          (relative != null ? relative : "<null>") }
      );
    }
    if ( relative == null ) relative = directoryProviderName;
    if ( StringHelper.isEmpty( root ) ) {
      log.debug( "No root directory, go with relative " + relative );
      sourceDirectory = new File( relative );
      if ( ! sourceDirectory.isDirectory() ) { // this also tests for existence
        throw new SearchException( "Unable to read source directory: " + relative );
      }
      //else keep source as it
    }
    else {
      File rootDir = new File( root );
      makeSanityCheckedDirectory( rootDir, directoryProviderName, needWritePermissions );
      sourceDirectory = new File( root, relative );
      makeSanityCheckedDirectory( sourceDirectory, directoryProviderName, needWritePermissions );
      log.debug( "Got directory from root + relative" );
    }
    return sourceDirectory;
  }
 
  /**
   * Creates an FSDirectory in provided directory and initializes
   * an index if not already existing.
   * @param indexDir The directory where to write a new index
   * @return the created FSDirectory
   * @throws IOException
   */
  public static FSDirectory createFSIndex(File indexDir, Properties dirConfiguration) throws IOException {
    LockFactory lockFactory = createLockFactory(indexDir, dirConfiguration);
    FSDirectory fsDirectory = FSDirectory.open( indexDir, null );
    // must use the setter (instead of using the constructor) to set the lockFactory, or Lucene will
    // throw an exception if it's different than a previous setting.
    fsDirectory.setLockFactory( lockFactory );
    if ( ! IndexReader.indexExists( fsDirectory ) ) {
      log.debug( "Initialize index: '{}'", indexDir.getAbsolutePath() );
      IndexWriter.MaxFieldLength fieldLength = new IndexWriter.MaxFieldLength( IndexWriter.DEFAULT_MAX_FIELD_LENGTH );
      IndexWriter iw = new IndexWriter( fsDirectory, new SimpleAnalyzer(), true, fieldLength );
      iw.close();
    }
    return fsDirectory;
  }
 
  /**
   * Creates a LockFactory as selected in the configuration for the
   * DirectoryProvider.
   * The SimpleFSLockFactory and NativeFSLockFactory need a File to know
   * where to stock the filesystem based locks; other implementations
   * ignore this parameter.
   * @param indexDir the directory to use to store locks, if needed by implementation
   * @param dirConfiguration the configuration of current DirectoryProvider
   * @return the LockFactory as configured, or a SimpleFSLockFactory
   * in case of configuration errors or as a default.
   * @throws IOException
   */
  public static LockFactory createLockFactory(File indexDir, Properties dirConfiguration) {
    //For FS-based indexes default to "simple", default to "single" otherwise.
    String defaultStrategy = indexDir==null ? "single" : "simple";
    String lockFactoryName = dirConfiguration.getProperty( "locking_strategy", defaultStrategy );
    if ( "simple".equals( lockFactoryName ) ) {
      if ( indexDir==null ) {
        throw new SearchException( "To use \"simple\" as a LockFactory strategy an indexBase path must be set");
      }
      try {
        return new SimpleFSLockFactory( indexDir );
      } catch (IOException e) {
        throw new SearchException( "Could not initialize SimpleFSLockFactory", e);
      }
    }
    else if ( "native".equals( lockFactoryName ) ) {
      if ( indexDir==null ) {
        throw new SearchException( "To use \"native\" as a LockFactory strategy an indexBase path must be set");
      }
      try {
        return new NativeFSLockFactory( indexDir );
      } catch (IOException e) {
        throw new SearchException( "Could not initialize NativeFSLockFactory", e);
      }
    }
    else if ( "single".equals( lockFactoryName ) ) {
      return new SingleInstanceLockFactory();
    }
    else if ( "none".equals( lockFactoryName ) ) {
      return new NoLockFactory();
    }
    else {
      LockFactoryFactory lockFactoryFactory = PluginLoader.instanceFromName( LockFactoryFactory.class,
            lockFactoryName, DirectoryProviderHelper.class, "locking_strategy" );
      return lockFactoryFactory.createLockFactory( indexDir, dirConfiguration );
    }
  }

  /**
   * Verify the index directory exists and is writable,
   * or creates it if not existing.
   * @param annotatedIndexName The index name declared on the @Indexed annotation
   * @param properties The properties may override the indexname.
   * @param verifyIsWritable Verify the directory is writable
   * @return the File representing the Index Directory
   * @throws SearchException
   */
  public static File getVerifiedIndexDir(String annotatedIndexName, Properties properties, boolean verifyIsWritable) {
    String indexBase = properties.getProperty( "indexBase", "." );
    String indexName = properties.getProperty( "indexName", annotatedIndexName );
    File baseIndexDir = new File( indexBase );
    makeSanityCheckedDirectory( baseIndexDir, indexName, verifyIsWritable );
    File indexDir = new File( baseIndexDir, indexName );
    makeSanityCheckedDirectory( indexDir, indexName, verifyIsWritable );
    return indexDir;
  }
 
  /**
   * @param directory The directory to create or verify
   * @param indexName To label exceptions
   * @param verifyIsWritable Verify the directory is writable
   * @throws SearchException
   */
  private static void makeSanityCheckedDirectory(File directory, String indexName, boolean verifyIsWritable) {
    if ( ! directory.exists() ) {
      log.warn( "Index directory not found, creating: '" + directory.getAbsolutePath() + "'" );
      //if not existing, create the full path
      if ( ! directory.mkdirs() ) {
        throw new SearchException( "Unable to create index directory: "
            + directory.getAbsolutePath() + " for index "
            + indexName );
      }
    }
    else {
      // else check it is not a file
      if ( ! directory.isDirectory() ) {
        throw new SearchException( "Unable to initialize index: "
            + indexName + ": "
            + directory.getAbsolutePath() + " is a file." );
      }
    }
    // and ensure it's writable
    if ( verifyIsWritable && ( ! directory.canWrite() ) ) {
      throw new SearchException( "Cannot write into index directory: "
          + directory.getAbsolutePath() + " for index "
          + indexName );
    }
  }

  static long getRefreshPeriod(Properties properties, String directoryProviderName) {
    String refreshPeriod = properties.getProperty( "refresh", "3600" );
    long period;
    try {
      period = Long.parseLong( refreshPeriod );
    } catch (NumberFormatException nfe) {
      throw new SearchException( "Unable to initialize index: " + directoryProviderName +"; refresh period is not numeric.", nfe );
    }
    log.debug( "Refresh period: {} seconds", period );
    return period * 1000; //per second
  }

  /**
   * Users may configure the number of MB to use as
   * "chunk size" for large file copy operations performed
   * by DirectoryProviders.
   * @param directoryProviderName
   * @param properties
   * @return the number of Bytes to use as "chunk size" in file copy operations.
   */
  public static long getCopyBufferSize(String directoryProviderName, Properties properties) {
    String value = properties.getProperty( COPYBUFFERSIZE_PROP_NAME );
    long size = FileHelper.DEFAULT_COPY_BUFFER_SIZE;
    if ( value != null ) {
      try {
        size = Long.parseLong( value ) * 1024 * 1024; //from MB to B.
      } catch (NumberFormatException nfe) {
        throw new SearchException( "Unable to initialize index " +
            directoryProviderName +"; "+ COPYBUFFERSIZE_PROP_NAME + " is not numeric.", nfe );
      }
      if ( size <= 0 ) {
        throw new SearchException( "Unable to initialize index " +
            directoryProviderName +"; "+ COPYBUFFERSIZE_PROP_NAME + " needs to be greater than zero.");
      }
    }
    return size;
  }
 
}
TOP

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

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.