/* * Copyright (C) 2013 lichtflut Forschungs- und Entwicklungsgesellschaft mbH * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.arastreju.sge.index; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.MergePolicy; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; import org.arastreju.sge.context.Context; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; /** * <p> * Holds together everything needed to operate a lucene index. * also takes care of mapping contexts to indexes and providing them * to ArastrejuIndex. * </p> * * <p> * Created Feb 01, 2013 * </p> * * @author Timo Buhrmester */ public class ContextIndex { private static final Logger LOGGER = LoggerFactory.getLogger(ContextIndex.class); // ---------------------------------------------------- private final Directory dir; private final IndexWriter writer; private IndexReader reader; private org.apache.lucene.search.IndexSearcher searcher; // ---------------------------------------------------- /** * Constructor. * @param baseDirectory The base directory of the indices. * @param ctx The context to be used. * @throws IOException When index cannot be obtained. */ ContextIndex(String baseDirectory, Context ctx) throws IOException { String path = baseDirectory + File.separatorChar + new sun.misc.BASE64Encoder().encode(ctx.toURI().getBytes()); LOGGER.debug("creating ContextIndex, root='" + baseDirectory + "'; ctx='" + ctx.toString() + "'; (path='" + path + "')"); this.dir = FSDirectory.open(new File(path)); IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_35, new LowercaseWhitespaceAnalyzer(Version.LUCENE_35)); this.writer = new IndexWriter(dir, cfg); // writer.setInfoStream(System.err); if (!IndexReader.indexExists(dir)) { /* cause the index to be created, this saves us a couple indexExists() checks */ Document dummyDoc = new Document(); dummyDoc.add(new Field("dummy_key", "dummy_value", Field.Store.NO, Field.Index.NOT_ANALYZED)); writer.addDocument(dummyDoc); writer.commit(); writer.deleteAll(); writer.commit(); } this.reader = IndexReader.open(writer, true); this.searcher = new org.apache.lucene.search.IndexSearcher(reader); } public Directory getDir() { return dir; } public org.apache.lucene.search.IndexSearcher getSearcher() { refreshReader(); return searcher; } public IndexReader getReader() { refreshReader(); return reader; } public IndexWriter getWriter() { return writer; } public void close() throws IOException { writer.close(); reader.close(); searcher.close(); dir.close(); } // ---------------------------------------------------- private void refreshReader() { try { if (reader.isCurrent()) { return; } IndexReader nr = IndexReader.openIfChanged(reader, writer, true); if (nr != null) { searcher.close(); reader.close(); reader = nr; searcher = new org.apache.lucene.search.IndexSearcher(reader); } } catch (IOException e) { String msg = "caught IOException while refreshing IndexReader"; LOGGER.error(msg, e); throw new RuntimeException(msg, e); } } }