View Javadoc

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 	// ------------------------------------------------- Query-Building Methods
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 }