Author: sannegrinovero
Date: 2009-03-05 14:08:10 -0500 (Thu, 05 Mar 2009)
New Revision: 16087
Added:
search/trunk/src/java/org/hibernate/search/store/LockFactoryFactory.java
search/trunk/src/test/org/hibernate/search/test/directoryProvider/CustomLockFactoryFactory.java
search/trunk/src/test/org/hibernate/search/test/directoryProvider/CustomLockProviderTest.java
Modified:
search/trunk/doc/reference/en/modules/configuration.xml
search/trunk/src/java/org/hibernate/search/store/DirectoryProviderHelper.java
search/trunk/src/java/org/hibernate/search/store/RAMDirectoryProvider.java
Log:
HSEARCH-345
Modified: search/trunk/doc/reference/en/modules/configuration.xml
===================================================================
--- search/trunk/doc/reference/en/modules/configuration.xml 2009-03-05 18:55:28 UTC (rev
16086)
+++ search/trunk/doc/reference/en/modules/configuration.xml 2009-03-05 19:08:10 UTC (rev
16087)
@@ -859,7 +859,9 @@
even on RAM based indexes, but this is not recommended and of no practical
use.</para>
<para>To select a locking factory, set the
<literal>hibernate.search.<index>.locking_strategy</literal>
option to
one of <literal>simple</literal>, <literal>native</literal>,
<literal>single</literal>
- or <literal>none</literal>.
+ or <literal>none</literal>, or set it to the fully qualified name of an
implementation of
+ <literal>org.hibernate.search.store.LockFactoryFactory</literal>;
Implementing this interface you can provide
+ a custom <literal>org.apache.lucene.store.LockFactory</literal>.
<table id="search-configuration-directory-lockfactories-table">
<title>List of available LockFactory implementations</title>
@@ -915,13 +917,12 @@
</table>
</para>Configuration example:
- <programlisting>hibernate.search.default simple
-hibernate.search.Animals native</programlisting>
+ <programlisting>hibernate.search.default.locking_strategy simple
+hibernate.search.Animals.locking_strategy native
+hibernate.search.Books.locking_strategy
org.custom.components.MyLockingFactory</programlisting>
<para>
</para>
- <para>If you need more flexibility it is possible to use your own
LockFactory when implementing a custom DirectoryProvider.</para>
-
</section>
</chapter>
Modified: search/trunk/src/java/org/hibernate/search/store/DirectoryProviderHelper.java
===================================================================
---
search/trunk/src/java/org/hibernate/search/store/DirectoryProviderHelper.java 2009-03-05
18:55:28 UTC (rev 16086)
+++
search/trunk/src/java/org/hibernate/search/store/DirectoryProviderHelper.java 2009-03-05
19:08:10 UTC (rev 16087)
@@ -20,6 +20,7 @@
import org.hibernate.search.SearchException;
import org.hibernate.search.util.FileHelper;
import org.hibernate.search.util.LoggerFactory;
+import org.hibernate.util.ReflectHelper;
/**
* @author Emmanuel Bernard
@@ -95,7 +96,7 @@
* Creates a LockFactory as selected in the configuration for the
* DirectoryProvider.
* The SimpleFSLockFactory and NativeFSLockFactory need a File to know
- * were to stock the filesystem based locks; other implementations
+ * 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
@@ -103,13 +104,29 @@
* in case of configuration errors or as a default.
* @throws IOException
*/
- public static LockFactory createLockFactory(File indexDir, Properties dirConfiguration)
throws IOException {
- String lockFactoryName = dirConfiguration.getProperty( "locking_strategy",
"simple" );
+ 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 ) ) {
- return new SimpleFSLockFactory( indexDir );
+ 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 ) ) {
- return new NativeFSLockFactory( indexDir );
+ 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();
@@ -118,9 +135,27 @@
return new NoLockFactory();
}
else {
- log.warn( "Invalid configuration setting for option locking_strategy
\"{}\"; option ignored!",
- lockFactoryName );
- return new SimpleFSLockFactory( indexDir );
+ LockFactoryFactory lockFactoryFactory;
+ try {
+ Class lockFactoryClass = ReflectHelper.classForName( lockFactoryName,
dirConfiguration.getClass() );
+ lockFactoryFactory = (LockFactoryFactory) lockFactoryClass.newInstance();
+ }
+ catch (ClassNotFoundException e) {
+ throw new SearchException( "Unable to find LockFactoryFactory class " +
lockFactoryName, e );
+ }
+ catch (IllegalAccessException e) {
+ throw new SearchException( "Unable to create instance of LockFactoryFactory
class " + lockFactoryName
+ + " Be sure to have a no-arg constructor", e );
+ }
+ catch (InstantiationException e) {
+ throw new SearchException( "Unable to create instance of LockFactoryFactory
class " + lockFactoryName
+ + " Be sure to have a no-arg constructor", e );
+ }
+ catch (ClassCastException e) {
+ throw new SearchException( "Class does not implement LockFactoryFactory: "
+ + lockFactoryName, e );
+ }
+ return lockFactoryFactory.createLockFactory( indexDir, dirConfiguration );
}
}
Added: search/trunk/src/java/org/hibernate/search/store/LockFactoryFactory.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/LockFactoryFactory.java
(rev 0)
+++ search/trunk/src/java/org/hibernate/search/store/LockFactoryFactory.java 2009-03-05
19:08:10 UTC (rev 16087)
@@ -0,0 +1,30 @@
+// $Id$
+package org.hibernate.search.store;
+
+import java.io.File;
+import java.util.Properties;
+
+import org.apache.lucene.store.LockFactory;
+
+/**
+ * To use a custom implementation of org.apache.lucene.store.LockFactory
+ * you need to implement this interface and define the fully qualified
+ * classname of the factory implementation as a DirectoryProvider parameter
+ * for the locking_strategy key.
+ * The implementation must have a no-arg constructor.
+ *
+ * @author Sanne Grinovero
+ */
+public interface LockFactoryFactory {
+
+ /**
+ * Creates a LockFactory implementation.
+ * A different LockFactory is created for each DirectoryProvider.
+ * @param indexDir path to the indexBase setting, or null for
+ * DirectoryProviders which don't rely on filesystem
+ * @param dirConfiguration the properties set on the current DirectoryProvider
+ * @return the created LockFactory
+ */
+ LockFactory createLockFactory(File indexDir, Properties dirConfiguration);
+
+}
Property changes on:
search/trunk/src/java/org/hibernate/search/store/LockFactoryFactory.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: search/trunk/src/java/org/hibernate/search/store/RAMDirectoryProvider.java
===================================================================
--- search/trunk/src/java/org/hibernate/search/store/RAMDirectoryProvider.java 2009-03-05
18:55:28 UTC (rev 16086)
+++ search/trunk/src/java/org/hibernate/search/store/RAMDirectoryProvider.java 2009-03-05
19:08:10 UTC (rev 16087)
@@ -18,15 +18,15 @@
*/
public class RAMDirectoryProvider implements DirectoryProvider<RAMDirectory> {
- private RAMDirectory directory;
+ private final RAMDirectory directory = new RAMDirectory();
private String indexName;
public void initialize(String directoryProviderName, Properties properties,
SearchFactoryImplementor searchFactoryImplementor) {
indexName = directoryProviderName;
+ directory.setLockFactory( DirectoryProviderHelper.createLockFactory( null, properties )
);
}
public void start() {
- directory = new RAMDirectory();
try {
IndexWriter.MaxFieldLength fieldLength = new IndexWriter.MaxFieldLength(
IndexWriter.DEFAULT_MAX_FIELD_LENGTH );
IndexWriter iw = new IndexWriter( directory, new StandardAnalyzer(), true, fieldLength
);
@@ -42,7 +42,9 @@
return directory;
}
- public void stop() {}
+ public void stop() {
+ directory.close();
+ }
@Override
public boolean equals(Object obj) {
Added:
search/trunk/src/test/org/hibernate/search/test/directoryProvider/CustomLockFactoryFactory.java
===================================================================
---
search/trunk/src/test/org/hibernate/search/test/directoryProvider/CustomLockFactoryFactory.java
(rev 0)
+++
search/trunk/src/test/org/hibernate/search/test/directoryProvider/CustomLockFactoryFactory.java 2009-03-05
19:08:10 UTC (rev 16087)
@@ -0,0 +1,21 @@
+// $Id$
+package org.hibernate.search.test.directoryProvider;
+
+import java.io.File;
+import java.util.Properties;
+
+import org.apache.lucene.store.LockFactory;
+import org.apache.lucene.store.SingleInstanceLockFactory;
+import org.hibernate.search.store.LockFactoryFactory;
+
+public class CustomLockFactoryFactory implements LockFactoryFactory {
+
+ // A real implementation would probably not use a static field; useful to keep the test
simple.
+ static String optionValue;
+
+ public LockFactory createLockFactory(File indexDir, Properties dirConfiguration) {
+ optionValue = dirConfiguration.getProperty( "locking_option" );
+ return new SingleInstanceLockFactory();
+ }
+
+}
Added:
search/trunk/src/test/org/hibernate/search/test/directoryProvider/CustomLockProviderTest.java
===================================================================
---
search/trunk/src/test/org/hibernate/search/test/directoryProvider/CustomLockProviderTest.java
(rev 0)
+++
search/trunk/src/test/org/hibernate/search/test/directoryProvider/CustomLockProviderTest.java 2009-03-05
19:08:10 UTC (rev 16087)
@@ -0,0 +1,46 @@
+// $Id$
+package org.hibernate.search.test.directoryProvider;
+
+import junit.framework.TestCase;
+
+import org.hibernate.search.test.util.FullTextSessionBuilder;
+
+/**
+ * @author Sanne Grinovero
+ */
+public class CustomLockProviderTest extends TestCase {
+
+ public void testUseOfCustomLockingFactory() {
+ assertNull( CustomLockFactoryFactory.optionValue );
+ FullTextSessionBuilder builder = new FullTextSessionBuilder();
+ builder
+ .addAnnotatedClass( SnowStorm.class )
+ .setProperty( "hibernate.search.default.locking_option",
"somethingHere" )
+ .setProperty( "hibernate.search.default.locking_strategy",
"org.hibernate.search.test.directoryProvider.CustomLockFactoryFactory")
+ .build();
+ builder.close();
+ assertEquals( "somethingHere", CustomLockFactoryFactory.optionValue );
+ }
+
+ public void testFailOnInexistentLockingFactory() {
+ FullTextSessionBuilder builder = new FullTextSessionBuilder();
+ try {
+ builder
+ .addAnnotatedClass( SnowStorm.class )
+ .setProperty( "hibernate.search.default.locking_option",
"somethingHere" )
+ .setProperty( "hibernate.search.default.locking_strategy",
"org.hibernate.NotExistingFactory")
+ .build();
+ builder.close();
+ fail();
+ }
+ catch (org.hibernate.HibernateException e) {
+ Throwable causeSearch = e.getCause();
+ assertNotNull( causeSearch );
+ assertTrue( causeSearch instanceof org.hibernate.search.SearchException );
+ Throwable causeLockin = causeSearch.getCause();
+ assertNotNull( causeLockin );
+ assertTrue( causeLockin.getMessage().startsWith("Unable to find
LockFactory") );
+ }
+ }
+
+}