

package org.compass.core.lucene.engine.store;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.store.Directory;
import org.compass.core.engine.SearchEngineException;

public class LuceneStoreTemplate {

    private static Log log = LogFactory.getLog(LuceneStoreTemplate.class);

    private LuceneSearchEngineStore searchEngineStore;

    public LuceneStoreTemplate(LuceneSearchEngineStore searchEngineStore) {
        this.searchEngineStore = searchEngineStore;
    }

    public Object executeForSubIndex(String subIndex, boolean create, LuceneSearchEngineStore.LuceneStoreCallback callback)
            throws SearchEngineException {
        Directory dir = searchEngineStore.getDirectoryBySubIndex(subIndex, create);
        return execute(subIndex, dir, callback);
    }

    public Object execute(String subIndex, Directory dir, LuceneSearchEngineStore.LuceneStoreCallback callback) throws SearchEngineException {
        Exception ex;
        try {
            return callback.doWithStore(dir);
        } catch (Exception e) {
            ex = e;
        }
        try {
            if (dir != null) {
                searchEngineStore.closeDirectory(subIndex, dir);
            }
        } catch (Exception e) {
            if (ex == null) {
                ex = e;
            } else {
                log.warn("Caught an exception trying to close the lucene directory "
                        + "with other exception pending, logging and ignoring", e);
            }
        }
        if (ex != null) {
            if (ex instanceof SearchEngineException) {
                throw (SearchEngineException) ex;
            }
            throw new SearchEngineException("Failed while executing a lucene directory based operation", ex);
        }
        return null;
    }
}
