com.dubture.indexing.core.index.DocumentManager.java Source code

Java tutorial

Introduction

Here is the source code for com.dubture.indexing.core.index.DocumentManager.java

Source

/*******************************************************************************
 * This file is part of the lucene indexing eclipse plugin.
 * 
 * (c) Robert Gruendler <r.gruendler@gmail.com>
 * 
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 ******************************************************************************/
package com.dubture.indexing.core.index;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
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.IndexWriter.MaxFieldLength;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;

import com.dubture.indexing.core.IndexingCorePlugin;

/**
 * 
 * Main class for indexing and searching lucene documents.
 * 
 * @author Robert Gruendler <r.gruendler@gmail.com>
 *
 */
public class DocumentManager {
    protected static DocumentManager instance;

    protected IndexWriter writer;

    protected IndexReader reader;

    protected Map<IFile, List<ReferenceInfo>> pendingReferences;

    protected Directory index;

    protected IndexSearcher searcher;

    protected DocumentManager() throws Exception {
        init();
    }

    protected void init() throws Exception {

        StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
        MaxFieldLength length = new MaxFieldLength(255);

        index = getIndex();
        writer = new IndexWriter(index, analyzer, length);
        writer.commit();
        reader = IndexReader.open(index, true);
        searcher = new IndexSearcher(reader);
        pendingReferences = new HashMap<IFile, List<ReferenceInfo>>();

    }

    public void resetIndex() {
        // used for tests
    }

    protected Directory getIndex() throws IOException {
        if (index != null) {
            return index;
        }

        IPath location = IndexingCorePlugin.getDefault().getStateLocation();
        IPath indexPath = location.append("resources/index");
        File indexFile = indexPath.toFile();

        if (indexFile.exists() == false && indexFile.mkdirs() == false) {
            throw new IOException("Unable to create lucene index directory " + indexFile.toString());
        }

        return index = FSDirectory.open(indexFile);
    }

    public static DocumentManager getInstance() throws Exception {
        if (instance == null) {
            instance = new DocumentManager();
        }

        return instance;
    }

    public void deleteReferences(IFile file, String type) throws Exception {
        Query query = QueryBuilder.createDeleteReferencesQuery(file, type);

        IndexingCorePlugin.debug("deleting references for " + file.getFullPath().toString() + " => " + type);
        writer.deleteDocuments(query);
        writer.commit();

        updateReader();
    }

    protected void updateReader() {
        try {
            IndexReader newReader = reader.reopen();

            if (newReader != reader) {
                reader.close();
                reader = newReader;
                searcher = new IndexSearcher(reader);
                IndexingCorePlugin.debug("Updated reader");
            }
        } catch (Exception e) {
            IndexingCorePlugin.logException(e);
        }
    }

    public void addReference(IFile file, ReferenceInfo reference) throws Exception {
        IndexingCorePlugin.debug("Adding pending reference " + reference.name);

        if (!pendingReferences.containsKey(file)) {
            pendingReferences.put(file, new ArrayList<ReferenceInfo>());
        }

        List<ReferenceInfo> list = pendingReferences.get(file);
        list.add(reference);
        pendingReferences.put(file, list);
    }

    public void flush() throws Exception {
        flushReferences();
        writer.commit();
        updateReader();
    }

    @SuppressWarnings("rawtypes")
    protected void flushReferences() throws Exception {
        Iterator it = pendingReferences.keySet().iterator();

        IndexingCorePlugin.debug("flushing " + pendingReferences.size() + " references");
        while (it.hasNext()) {

            IFile file = (IFile) it.next();
            List<ReferenceInfo> refs = pendingReferences.get(file);

            for (ReferenceInfo info : refs) {
                addDocument(file, info);
            }
        }
        pendingReferences.clear();
    }

    protected void addDocument(IFile file, ReferenceInfo ref) throws Exception {
        if (ref.type == null || ref.name == null) {
            IndexingCorePlugin.debug("Reference info failure: " + ref.metadata);
            return;
        }

        Document doc = new Document();
        String path = file.getFullPath().toString();

        IndexingCorePlugin.debug("indexing document with path " + path);
        doc.add(new Field(IndexField.PATH, path, Field.Store.YES, Field.Index.NOT_ANALYZED));
        doc.add(new Field(IndexField.FILENAME, file.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED));

        doc.add(new Field(IndexField.TYPE, ref.getType(), Field.Store.YES, Field.Index.NOT_ANALYZED));
        doc.add(new Field(IndexField.REFERENCENAME, ref.name, Field.Store.YES, Field.Index.NOT_ANALYZED));
        doc.add(new Field(IndexField.METADATA, ref.getMetadata(), Field.Store.YES, Field.Index.NOT_ANALYZED));

        IndexingCorePlugin.debug("Indexing reference " + doc.toString());
        writer.addDocument(doc);
    }

    public void search(Query pathQuery, final IResultHandler handler) {
        //TODO: howto handle this?
        int hitsPerPage = 100;
        TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);

        try {
            searcher.search(pathQuery, collector);
            ScoreDoc[] hits = collector.topDocs().scoreDocs;

            for (int i = 0; i < hits.length; ++i) {
                int docId = hits[i].doc;
                handler.handle(searcher.doc(docId));
            }
        } catch (IOException e) {
            IndexingCorePlugin.logException(e);
        }
    }

    public void shutdown() {
        try {
            writer.close();
        } catch (Exception e) {
            IndexingCorePlugin.logException(e);
        }
    }

    public IndexReader getReader() {
        return reader;
    }

    public IndexWriter getWriter() {
        return writer;
    }
}