org.eclipse.mylyn.versions.tasks.mapper.internal.ChangeSetIndexer.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.mylyn.versions.tasks.mapper.internal.ChangeSetIndexer.java

Source

/*******************************************************************************
 * Copyright (c) 2012 Research Group for Industrial Software (INSO), Vienna University of Technology.
 * 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
 *
 * Contributors:
 *     Research Group for Industrial Software (INSO), Vienna University of Technology - initial API and implementation
 *******************************************************************************/
package org.eclipse.mylyn.versions.tasks.mapper.internal;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.apache.lucene.LucenePackage;
import org.apache.lucene.analysis.KeywordAnalyzer;
import org.apache.lucene.analysis.PerFieldAnalyzerWrapper;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.spans.SpanOrQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.store.NIOFSDirectory;
import org.apache.lucene.util.Version;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.versions.core.ChangeSet;
import org.eclipse.mylyn.versions.tasks.mapper.generic.IChangeSetCollector;
import org.eclipse.mylyn.versions.tasks.mapper.generic.IChangeSetIndexSearcher;
import org.eclipse.mylyn.versions.tasks.mapper.generic.IChangeSetIndexer;
import org.eclipse.mylyn.versions.tasks.mapper.generic.IChangeSetSource;

/**
 * 
 * @author Kilian Matt
 */
public class ChangeSetIndexer implements IChangeSetIndexSearcher {

    private IChangeSetSource source;

    private File indexDirectory;
    private IndexWriter indexWriter;
    private IndexReader indexReader;

    public ChangeSetIndexer(File directory, IChangeSetSource source) {
        this.indexDirectory = directory;
        this.source = source;
    }

    public void reindex(IProgressMonitor monitor) {
        try {
            PerFieldAnalyzerWrapper analyzer = new PerFieldAnalyzerWrapper(
                    new StandardAnalyzer(Version.LUCENE_CURRENT));
            analyzer.addAnalyzer(IndexedFields.REPOSITORY.getIndexKey(), new KeywordAnalyzer());
            indexWriter = new IndexWriter(new NIOFSDirectory(indexDirectory), analyzer, true,
                    MaxFieldLength.UNLIMITED);

            IChangeSetIndexer indexer = new IChangeSetIndexer() {

                public void index(ChangeSet changeset) {
                    try {
                        Document document = new Document();
                        for (IndexedFields field : IndexedFields.values()) {
                            document.add(new Field(field.getIndexKey(), field.getAccessor().getValue(changeset),
                                    Store.YES, Field.Index.ANALYZED));
                        }
                        indexWriter.addDocument(document);
                    } catch (IOException ex) {
                        throw new RuntimeException(ex);
                    }
                }
            };
            source.fetchAllChangesets(monitor, indexer);
            indexWriter.close();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    public int search(ITask task, String scmRepositoryUrl, int resultsLimit, IChangeSetCollector collector)
            throws CoreException {
        int count = 0;
        IndexReader indexReader = getIndexReader();
        if (indexReader != null) {
            IndexSearcher indexSearcher = new IndexSearcher(indexReader);
            try {
                Query query = createQuery(task, scmRepositoryUrl);
                TopDocs results = indexSearcher.search(query, resultsLimit);
                for (ScoreDoc scoreDoc : results.scoreDocs) {
                    Document document = indexReader.document(scoreDoc.doc);
                    count++;
                    if (count > resultsLimit)
                        break;

                    String revision = document.getField(IndexedFields.REVISION.getIndexKey()).stringValue();
                    String repositoryUrl = document.getField(IndexedFields.REPOSITORY.getIndexKey()).stringValue();

                    collector.collect(revision, repositoryUrl);
                }
            } catch (IOException e) {
                //            StatusHandler.log(new Status(IStatus.ERROR, org.eclipse.mylyn.versions.tasks.ui.internal.TaPLUGIN_ID,
                //"Unexpected failure within task list index", e)); //$NON-NLS-1$
            } finally {
                try {
                    indexSearcher.close();
                } catch (IOException e) {
                    // ignore
                }
            }
        }
        return count;

    }

    private Query createQuery(ITask task, String repositoryUrl) {
        BooleanQuery query = new BooleanQuery();
        query.setMinimumNumberShouldMatch(1);
        query.add(new TermQuery(new Term(IndexedFields.REPOSITORY.getIndexKey(), repositoryUrl)), Occur.MUST);
        query.add(new PrefixQuery(new Term(IndexedFields.COMMIT_MESSAGE.getIndexKey(), task.getUrl())),
                Occur.SHOULD);
        query.add(new PrefixQuery(new Term(IndexedFields.COMMIT_MESSAGE.getIndexKey(), task.getTaskId())),
                Occur.SHOULD);
        return query;
    }

    private IndexReader getIndexReader() {
        try {
            synchronized (this) {
                if (indexReader == null) {
                    indexReader = IndexReader.open(new NIOFSDirectory(indexDirectory), true);
                }
                return indexReader;
            }
        } catch (CorruptIndexException e) {
            // rebuild index
        } catch (FileNotFoundException e) {
            // rebuild index
        } catch (IOException e) {
            // ignore
        }
        return null;
    }

}