/* * Hibernate Search, full-text search for your domain model * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.search.indexes.impl; import java.util.Properties; import org.hibernate.search.backend.impl.lucene.ScheduledCommitPolicy; import org.hibernate.search.cfg.Environment; import org.hibernate.search.exception.SearchException; import org.hibernate.search.backend.spi.LuceneIndexingParameters; import org.hibernate.search.util.impl.Executors; import org.hibernate.search.engine.service.spi.ServiceManager; import org.hibernate.search.indexes.spi.DirectoryBasedIndexManager; import org.hibernate.search.indexes.spi.DirectoryBasedReaderProvider; import org.hibernate.search.indexes.spi.IndexManager; import org.hibernate.search.spi.WorkerBuildContext; import org.hibernate.search.store.optimization.OptimizerStrategy; import org.hibernate.search.store.optimization.impl.ExplicitOnlyOptimizerStrategy; import org.hibernate.search.store.optimization.impl.IncrementalOptimizerStrategy; import org.hibernate.search.util.StringHelper; import org.hibernate.search.util.configuration.impl.ConfigurationParseHelper; import org.hibernate.search.util.configuration.impl.MaskedProperty; import org.hibernate.search.util.impl.ClassLoaderHelper; import org.hibernate.search.util.logging.impl.Log; import org.hibernate.search.util.logging.impl.LoggerFactory; /** * Contains helper to parse properties which should be read by the majority * of IndexManager implementations. * * @author Sanne Grinovero (C) 2011 Red Hat Inc. */ public class PropertiesParseHelper { private static final Log log = LoggerFactory.make(); private PropertiesParseHelper() { // no need to create instances } /** * <p>isExclusiveIndexUsageEnabled. * * @param indexProps a {@link java.util.Properties} object. * @return {@code true} when a lock on the index will not be released until the * SearchIntegrator (or SessionFactory) is closed. Default to {@code false} */ public static boolean isExclusiveIndexUsageEnabled(Properties indexProps) { return ConfigurationParseHelper.getBooleanValue( indexProps, Environment.EXCLUSIVE_INDEX_USE, true ); } /** * Returns the configured value of {@link org.hibernate.search.cfg.Environment#INDEX_METADATA_COMPLETE} for this specific index. * If no value is set, the default is defined by {@link org.hibernate.search.cfg.spi.SearchConfiguration#isIndexMetadataComplete()}. * * @param indexProps The index configuration properties * @param context The WorkerBuildContext provides a view of the default setting * * @return {@code true} when the index metadata is fully defined. */ public static boolean isIndexMetadataComplete(Properties indexProps, WorkerBuildContext context) { return ConfigurationParseHelper.getBooleanValue( indexProps, Environment.INDEX_METADATA_COMPLETE, context.isIndexMetadataComplete() ); } /** * @param indexName the index name (used for logging) * @param indexProps MaskedProperties for this IndexManager * * @return the maximum queue length to be used on the backends of this index */ public static int extractMaxQueueSize(String indexName, Properties indexProps) { String maxQueueSize = indexProps.getProperty( Environment.MAX_QUEUE_LENGTH ); if ( maxQueueSize != null ) { int parsedInt = ConfigurationParseHelper .parseInt( maxQueueSize, Executors.QUEUE_MAX_LENGTH, "Illegal value for property " + Environment.MAX_QUEUE_LENGTH + " on index " + indexName ); if ( parsedInt < 1 ) { throw new SearchException( "Property " + Environment.MAX_QUEUE_LENGTH + " on index " + indexName + "must be strictly positive" ); } return parsedInt; } else { return Executors.QUEUE_MAX_LENGTH; } } public static OptimizerStrategy getOptimizerStrategy(IndexManager callback, Properties indexProperties, WorkerBuildContext buildContext) { MaskedProperty maskedProperty = new MaskedProperty( indexProperties, "optimizer" ); String optimizerImplClassName = maskedProperty.getProperty( "implementation" ); if ( optimizerImplClassName != null && ( !"default".equalsIgnoreCase( optimizerImplClassName ) ) ) { ServiceManager serviceManager = buildContext.getServiceManager(); return ClassLoaderHelper.instanceFromName( OptimizerStrategy.class, optimizerImplClassName, "Optimizer Strategy", serviceManager ); } else { boolean incremental = maskedProperty.containsKey( "operation_limit.max" ) || maskedProperty.containsKey( "transaction_limit.max" ); OptimizerStrategy optimizerStrategy; if ( incremental ) { optimizerStrategy = new IncrementalOptimizerStrategy(); optimizerStrategy.initialize( callback, maskedProperty ); } else { optimizerStrategy = new ExplicitOnlyOptimizerStrategy(); } return optimizerStrategy; } } /** * Creates a new <code>LuceneIndexingParameters</code> instance for the specified provider. * If there are no matching properties in the configuration default values will be applied. * <p> * NOTE:<br> * If a non batch value is set in the configuration apply it also to the * batch mode. This covers the case where users only specify * parameters for the non batch mode. In this case the same parameters apply for * batch indexing. Parameters are found "depth-first": if a batch parameter is set * in a global scope it will take priority on local transaction parameters. * </p> * * @param properties The properties extracted from the configuration. * @return a new {@link LuceneIndexingParameters} instance */ public static LuceneIndexingParameters extractIndexingPerformanceOptions(Properties properties) { return new LuceneIndexingParameters( properties ); } public static DirectoryBasedReaderProvider createDirectoryBasedReaderProvider(DirectoryBasedIndexManager indexManager, Properties properties, WorkerBuildContext buildContext) { Properties maskedProperties = new MaskedProperty( properties, Environment.READER_PREFIX ); String readerProviderImplName = maskedProperties.getProperty( "strategy" ); DirectoryBasedReaderProvider readerProvider; if ( StringHelper.isEmpty( readerProviderImplName ) ) { readerProvider = new SharingBufferReaderProvider(); } else if ( "not-shared".equalsIgnoreCase( readerProviderImplName ) ) { readerProvider = new NotSharedReaderProvider(); } else if ( "shared".equalsIgnoreCase( readerProviderImplName ) ) { readerProvider = new SharingBufferReaderProvider(); } else if ( "async".equalsIgnoreCase( readerProviderImplName ) ) { readerProvider = new PeriodicRefreshingReaderProvider(); } else { ServiceManager serviceManager = buildContext.getServiceManager(); readerProvider = ClassLoaderHelper.instanceFromName( DirectoryBasedReaderProvider.class, readerProviderImplName, "readerProvider", serviceManager ); } readerProvider.initialize( indexManager, maskedProperties ); return readerProvider; } public static Integer extractFlushInterval(String indexName, Properties indexProps) { String refreshInterval = indexProps.getProperty( Environment.INDEX_FLUSH_INTERVAL ); if ( refreshInterval != null ) { String errorMsgOnParseFailure = "Illegal value for property " + Environment.INDEX_FLUSH_INTERVAL + " on index " + indexName; int parsedInt = ConfigurationParseHelper.parseInt( refreshInterval, 0, errorMsgOnParseFailure ); if ( parsedInt < 0 ) { throw log.flushIntervalNeedsToBePositive( indexName ); } return parsedInt; } else { return ScheduledCommitPolicy.DEFAULT_DELAY_MS; } } }