/******************************************************************************* * 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.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.BooleanClause.Occur; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher; 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.store.NIOFSDirectory; 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 { indexWriter = new IndexWriter(new NIOFSDirectory(indexDirectory),ChangeSetAnalyzer.get(), 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); query.add(new PrefixQuery(new Term(IndexedFields.COMMIT_MESSAGE.getIndexKey(), task.getTaskKey())), 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; } }