Wednesday, September 07, 2005

Using a CustomEditorConfigurer to Specify a Lucene FSDirectory Using Spring

When I started to use Spring with my Lucene application, I searched for an easy way to specify the directory name where the Lucene repository is stored. Since the FSDirectory class is not instantiated directly (you need to call FSDirectory.getDirectory), I couldn't see how to configure Spring to create the object for me.

Then I discovered that the JavaBeans api has the ability to automatically convert from a String to any other class using a configurator object. With this ability, specifying a bean that uses an FSDirectory can be done in the following way:

<bean id="serverDatabase" class="com.server.DB" method="setup">
  <property name='directory'><value>data/LuceneRepsitory</value></property>
</bean>

The idea is that when Spring wired beans together some configurer object would convert that String into a Lucune FSDirectory object. This conversion is done by the following Java class:

public class FileSystemLuceneDirectoryEditor extends PropertyEditorSupport {
    public void setAsText(final String textValue) {
        try {
            final boolean fileExists = new File(textValue).exists();
            final boolean createDirectory = fileExists == true ? false : true;
            setValue(FSDirectory.getDirectory(textValue, createDirectory));
        } catch (IOException e) {
            throw new CriteriaWatchException(e);
        }
    }
}

The configurer class needs to be introduced to Spring through its XML configuration file:

  <bean id='customEditorConfigurer' class='org.springframework.beans.factory.config.CustomEditorConfigurer'>
    <property name='customEditors'>
      <map>
        <entry key='org.apache.lucene.store.Directory'>
          <bean id='luceneDirectoryEditor' class='FileSystemLuceneDirectoryEditor'/>
        </entry>
      </map>
    </property>
  </bean>

After the above work is done, Spring automatically converts any String values that are destined to be Directory parameters.