1 package org.marketchangers.prayer.lucene;
2
3 import java.io.IOException;
4 import java.util.Collection;
5 import java.util.Date;
6 import java.util.Iterator;
7
8 import org.apache.lucene.analysis.Analyzer;
9 import org.apache.lucene.document.DateField;
10 import org.apache.lucene.document.Document;
11 import org.apache.lucene.document.Field;
12 import org.apache.lucene.index.IndexReader;
13 import org.apache.lucene.index.IndexWriter;
14 import org.apache.lucene.index.Term;
15 import org.apache.lucene.queryParser.MultiFieldQueryParser;
16 import org.apache.lucene.queryParser.ParseException;
17 import org.apache.lucene.search.BooleanQuery;
18 import org.apache.lucene.search.IndexSearcher;
19 import org.apache.lucene.search.Query;
20 import org.apache.lucene.search.RangeQuery;
21 import org.apache.lucene.search.Searcher;
22 import org.apache.lucene.search.TermQuery;
23 import org.apache.lucene.store.Directory;
24 import org.marketchangers.prayer.PrayerRequest;
25 import org.marketchangers.prayer.PrayerRequestQuery;
26
27 /***
28 * @author <a href="mailto:mtodd@wc-group.com">Matthew Todd</a>
29 */
30 public class DefaultIndexProvider implements IndexProvider {
31 private Directory directory;
32 private Analyzer analyzer;
33
34 public DefaultIndexProvider(Directory directory, Analyzer analyzer) {
35 this.directory = directory;
36 this.analyzer = analyzer;
37 }
38
39 public IndexReader getReader() throws IOException {
40 return IndexReader.open(directory);
41 }
42
43 public Searcher getSearcher() throws IOException {
44 return new IndexSearcher(directory);
45 }
46
47 public IndexWriter getWriter() throws IOException {
48 return new IndexWriter(directory, analyzer, shouldCreate());
49 }
50
51 private boolean shouldCreate() throws IOException {
52 return directory.list().length == 0;
53 }
54
55 /***
56 * Categories are stored by name, so searches should sumbit category name,
57 * not id. This also means that category searches may be "looser" than
58 * intended, due to stemming, though they are stored as Keywords, so maybe
59 * not.
60 */
61 public Document translateToDocument(PrayerRequest request) {
62 Document document = new Document();
63
64 keyword(document, "category", request.getCategory());
65 keyword(document, "endDate", request.getEndDate());
66 keyword(document, "id", request.getId());
67 keyword(document, "requestorUserId", request.getRequestorUserId());
68 keyword(document, "startDate", request.getStartDate());
69 keyword(document, "status", request.getStatus());
70
71 unstored(document, "background", request.getBackground());
72 unstored(document, "content", request.getContent());
73 unstored(document, "subject", request.getSubject());
74
75 keyword(document, "catchAll", "catchAll");
76
77 return document;
78 }
79
80 private void unstored(Document d, String name, Object value) {
81 if (value != null)
82 d.add(Field.UnStored(name, value.toString()));
83 }
84
85 private void keyword(Document d, String name, Date value) {
86 if (value != null)
87 d.add(Field.Keyword(name, value));
88 }
89
90 private void keyword(Document d, String name, Object value) {
91 if (value != null) {
92 d.add(Field.Keyword(name, value.toString()));
93 } else {
94 d.add(Field.Keyword(name, ""));
95 }
96 }
97
98 public Query translateToQuery(PrayerRequestQuery q) {
99 BooleanQuery query = new BooleanQuery();
100
101 if (q.hasCategoryName()) {
102 query.add(categoryName(q.getCategoryName()), true, false);
103 }
104 if (q.hasEndDate()) {
105 query.add(endDate(q.getEndDate()), true, false);
106 }
107 if (q.hasRequestorUserIds()) {
108 query.add(requestorUserIds(q.getRequestorUserIds()), true, false);
109 }
110 if (q.hasSearchTerms()) {
111 query.add(searchTerms(q.getSearchTerms()), true, false);
112 }
113 if (q.hasStartDate()) {
114 query.add(startDate(q.getStartDate()), true, false);
115 }
116 if (q.hasStatus()) {
117 query.add(status(q.getStatus()), true, false);
118 }
119
120 return query;
121 }
122
123 public Query translateToQuery(PrayerRequest r) {
124 BooleanQuery query = new BooleanQuery();
125
126 if (r.getCategory() != null) {
127 if (r.getCategory().getName() != null) {
128 query.add(categoryName(r.getCategory().getName()), true, false);
129 }
130 }
131
132 if (r.getEndDate() != null) {
133 query.add(endDate(r.getEndDate()), true, false);
134 }
135 if (r.getRequestorUserId() != null) {
136 query.add(requestorUserId(r.getRequestorUserId()), true, false);
137 }
138 if (r.getContent() != null) {
139 query.add(searchTerms(r.getContent()), true, false);
140 }
141 if (r.getStartDate() != null) {
142 query.add(startDate(r.getStartDate()), true, false);
143 }
144
145 return query;
146 }
147
148
149 private Query all() {
150 return new TermQuery(new Term("catchAll", "catchAll"));
151 }
152
153 private Query categoryName(String categoryName) {
154 return new TermQuery(new Term("category", categoryName));
155 }
156
157 private Query endDate(Date date) {
158 Term upperTerm = new Term("endDate", DateField.dateToString(date));
159 return new RangeQuery(null, upperTerm, true);
160 }
161
162 private Query requestorUserId(String requestorUserId) {
163 return new TermQuery(new Term("requestorUserId", requestorUserId));
164 }
165
166 private Query requestorUserIds(Collection requestors) {
167 BooleanQuery query = new BooleanQuery();
168
169 Iterator requestorUserIds = requestors.iterator();
170 while (requestorUserIds.hasNext()) {
171 String requestorUserId = (String) requestorUserIds.next();
172 query.add(requestorUserId(requestorUserId), false, false);
173 }
174
175 return query;
176 }
177
178 private Query searchTerms(String searchTerms) {
179 String[] fields = { "background", "content", "subject" };
180
181 try {
182 return MultiFieldQueryParser.parse(searchTerms, fields, analyzer);
183 } catch (ParseException pe) {
184 return all();
185 }
186 }
187
188 private Query startDate(Date date) {
189 Term lowerTerm = new Term("startDate", DateField.dateToString(date));
190 return new RangeQuery(lowerTerm, null, true);
191 }
192
193 private Query status(String status) {
194 return new TermQuery(new Term("status", status));
195 }
196 }