/**
* (C) Copyright 2013 Jabylon (http://www.jabylon.org) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
/**
*
*/
package org.jabylon.index.properties;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;
import org.eclipse.core.runtime.Plugin;
import org.jabylon.cdo.server.ServerConstants;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Johannes Utzig (jutzig.dev@googlemail.com)
*
*/
public class IndexActivator extends Plugin implements BundleActivator {
private static IndexActivator INSTANCE;
private FSDirectory directory;
public static final String PLUGIN_ID = "org.jabylon.index";
private static final Logger logger = LoggerFactory.getLogger(IndexActivator.class);
private IndexWriter indexWriter;
private ReentrantLock lock = new ReentrantLock();
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
INSTANCE = this;
}
@Override
public void stop(BundleContext context) throws Exception {
super.stop(context);
if(directory!=null)
directory.close();
INSTANCE = null;
directory = null;
logger.info("Stopping Lucene Index");
}
public Directory getOrCreateDirectory()
{
if(directory==null)
{
try {
logger.info("Opening Lucene Index");
File file = new File(ServerConstants.WORKING_DIR,"lucene");
if(!file.exists())
file.mkdirs();
directory = FSDirectory.open(new File(ServerConstants.WORKING_DIR,"lucene"));
} catch (IOException e) {
logger.error("Failed to open index directory",e);
}
}
return directory;
}
/**
* use this method to obtain an index writer. It is mandatory to call {@link #returnIndexWriter(IndexWriter)} once you are done.
* be aware that other threads might be using the same instance simultaneously
* @return
* @throws CorruptIndexException
* @throws LockObtainFailedException
* @throws IOException
*/
public IndexWriter obtainIndexWriter() throws CorruptIndexException, LockObtainFailedException, IOException {
lock.lock();
if(indexWriter==null) {
IndexWriterConfig c = new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35));
indexWriter = new IndexWriter(getOrCreateDirectory(), c);
}
return indexWriter;
}
/**
* call this method once you are done with the index writer.
* Once all consumers have returned their instance, the writer will be closed and disposed
* @param writer
* @throws CorruptIndexException
* @throws IOException
*/
public void returnIndexWriter(IndexWriter writer) throws CorruptIndexException, IOException {
if(!lock.isHeldByCurrentThread())
throw new IllegalStateException("The calling thread isn't the one that obtained the writer initially");
if(writer!=indexWriter)
throw new IllegalStateException("The given index writer is not the current index writer");
if(indexWriter!=null)
{
try {
indexWriter.close();
} finally {
indexWriter = null;
try {
if (IndexWriter.isLocked(directory)) {
IndexWriter.unlock(directory);
}
} finally {
lock.unlock();
}
}
}
}
public static IndexActivator getDefault() {
return INSTANCE;
}
}