/*
* $Id$
*
* Copyright 2007 Glencoe Software, Inc. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package ome.services.search;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import ome.conditions.ApiUsageException;
import ome.conditions.InternalException;
import ome.model.annotations.CommentAnnotation;
import ome.model.annotations.TextAnnotation;
import ome.system.ServiceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.FuzzyTermEnum;
import org.hibernate.Session;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.SearchFactory;
import org.hibernate.search.reader.ReaderProvider;
import org.hibernate.search.store.DirectoryProvider;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
/**
* Search to find similar terms to some given terms.
*
* @author Josh Moore, josh at glencoesoftware.com
* @since Beta4
*/
public class SimilarTerms extends SearchAction {
private static final Logger log = LoggerFactory.getLogger(SimilarTerms.class);
private static final long serialVersionUID = 1L;
private final String[] terms;
public SimilarTerms(SearchValues values, String...terms) {
super(values);
this.terms = terms;
}
@Transactional(readOnly = true)
public Object doWork(Session s, ServiceFactory sf) {
if (values.onlyTypes == null || values.onlyTypes.size() != 1) {
throw new ApiUsageException(
"Searches by similar terms are currently limited to a single type.\n"
+ "Plese use Search.onlyType()");
}
final Class<?> cls = values.onlyTypes.get(0);
final FullTextSession session = Search.getFullTextSession(s);
final SearchFactory factory = session.getSearchFactory();
final DirectoryProvider[] directory = factory.getDirectoryProviders(cls);
final ReaderProvider provider = factory.getReaderProvider();
Assert.notEmpty(directory, "Must have a directory provider");
Assert.isTrue(directory.length == 1, "Can only handle one directory");
final IndexReader reader = provider.openReader(directory[0]);
FuzzyTermEnum fuzzy = null;
List<TextAnnotation> rv = new ArrayList<TextAnnotation>();
try {
fuzzy = new FuzzyTermEnum(reader, new Term("combined_fields", terms[0]));
while (fuzzy.next()) {
CommentAnnotation text = new CommentAnnotation();
text.setNs(terms[0]);
text.setTextValue(fuzzy.term().text());
rv.add(text);
}
return rv;
} catch (IOException e) {
throw new InternalException("Error reading from index: "+e.getMessage());
} finally {
if (fuzzy != null) {
fuzzy.endEnum();
}
}
}
}