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 }