1 /*** 2 * 3 */ 4 package hu.elte.tribus.services; 5 6 import hu.elte.tribus.interfaces.AnsverFinder; 7 import hu.elte.tribus.model.Conversation; 8 import hu.elte.tribus.model.QA; 9 10 import java.io.ByteArrayInputStream; 11 import java.io.IOException; 12 import java.io.ObjectInputStream; 13 import java.io.Serializable; 14 import java.sql.SQLException; 15 import java.util.Iterator; 16 17 import org.apache.log4j.Logger; 18 import org.apache.lucene.document.Field; 19 import org.apache.lucene.index.Term; 20 import org.apache.lucene.queryParser.ParseException; 21 import org.apache.lucene.queryParser.QueryParser; 22 import org.apache.lucene.search.FilteredQuery; 23 import org.apache.lucene.search.Hit; 24 import org.apache.lucene.search.Hits; 25 import org.apache.lucene.search.IndexSearcher; 26 import org.apache.lucene.search.PhraseQuery; 27 import org.apache.lucene.search.Query; 28 import org.apache.lucene.search.QueryFilter; 29 import org.hibernate.HibernateException; 30 import org.hibernate.Session; 31 import org.springframework.orm.hibernate3.HibernateCallback; 32 import org.springframework.orm.hibernate3.support.HibernateDaoSupport; 33 34 /*** 35 * This is a simplified implementation of the simplified theory. Plain lucene, 36 * indexing persisted beans. 37 * 38 * @author kocka 39 * 40 */ 41 public class IndexBasedAnsverFinder extends HibernateDaoSupport implements AnsverFinder { 42 43 private final static Logger logger = Logger.getLogger(IndexBasedAnsverFinder.class); 44 45 IndexingInterceptor indexingInterceptor = null; 46 47 public QA getQuestionAndAnsver(final String question, final Conversation conversation) throws QueryException { 48 IndexSearcher indexSearcher = null; 49 try { 50 indexSearcher = new IndexSearcher(indexingInterceptor.directory); 51 QueryParser parser = new QueryParser("question", indexingInterceptor.analyzer); 52 Query query = parser.parse(question); 53 PhraseQuery phraseQuery = new PhraseQuery(); 54 phraseQuery.add(new Term("topic",conversation.getTopic().getId().toString())); 55 FilteredQuery filteredQuery = new FilteredQuery(query, new QueryFilter(phraseQuery)); 56 final Hits hits = indexSearcher.search(filteredQuery); 57 logger.info("Resoults: "+hits.length()); 58 59 return (QA) getHibernateTemplate().execute(new HibernateCallback(){ 60 61 public Object doInHibernate(Session session) throws HibernateException, SQLException { 62 Iterator it = hits.iterator(); 63 while(it.hasNext()) { 64 Hit hit = (Hit) it.next(); 65 try { 66 Field idField = hit.getDocument().getField("id"); 67 if(idField != null) { 68 try { 69 ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream((idField.binaryValue()))); 70 Serializable id = (Serializable) objectInputStream.readObject(); 71 logger.info(id); 72 return session.load(QA.class, id); 73 } catch (ClassNotFoundException e) { 74 logger.error("This is a quite unexpected behavior from the lucene index", e); 75 } 76 } else { 77 logger.info("Id is null, skipping"); 78 } 79 } catch (IOException e) { 80 logger.warn("Index corrputed, please reindex!"); 81 } 82 83 } 84 return null; 85 }}); 86 } catch (IOException e) { 87 throw new QueryException("Lucene is down", e); 88 } catch (ParseException e) { 89 throw new QueryException("Bad/evil query", e); 90 } 91 } 92 93 public IndexingInterceptor getIndexingInterceptor() { 94 return indexingInterceptor; 95 } 96 97 public void setIndexingInterceptor(IndexingInterceptor indexingInterceptor) { 98 this.indexingInterceptor = indexingInterceptor; 99 } 100 101 102 }