KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > roller > ui > rendering > model > SearchResultsModel


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. The ASF licenses this file to You
4  * under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License. For additional information regarding
15  * copyright in this work, please see the NOTICE file in the top level
16  * directory of this distribution.
17  */

18
19 package org.apache.roller.ui.rendering.model;
20
21 import java.io.IOException JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.ResourceBundle JavaDoc;
25 import java.util.Set JavaDoc;
26 import java.util.TreeMap JavaDoc;
27 import java.util.TreeSet JavaDoc;
28 import org.apache.commons.collections.comparators.ReverseComparator;
29 import org.apache.commons.lang.StringUtils;
30 import org.apache.lucene.document.Document;
31 import org.apache.lucene.search.Hits;
32 import org.apache.roller.RollerException;
33 import org.apache.roller.business.search.FieldConstants;
34 import org.apache.roller.business.search.operations.SearchOperation;
35 import org.apache.roller.config.RollerRuntimeConfig;
36 import org.apache.roller.model.IndexManager;
37 import org.apache.roller.model.Roller;
38 import org.apache.roller.model.RollerFactory;
39 import org.apache.roller.model.WeblogManager;
40 import org.apache.roller.pojos.WeblogEntryData;
41 import org.apache.roller.pojos.WeblogEntryWrapperComparator;
42 import org.apache.roller.pojos.wrapper.WeblogEntryDataWrapper;
43 import org.apache.roller.ui.rendering.pagers.SearchResultsPager;
44 import org.apache.roller.ui.rendering.pagers.WeblogEntriesPager;
45 import org.apache.roller.ui.rendering.util.WeblogSearchRequest;
46 import org.apache.roller.util.DateUtil;
47
48
49 /**
50  * Extends normal page renderer model to represent search results.
51  *
52  * Also adds some new methods which are specific only to search results.
53  */

54 public class SearchResultsModel extends PageModel {
55     
56     private static final ResourceBundle JavaDoc bundle =
57             ResourceBundle.getBundle("ApplicationResources");
58     
59     public static final int RESULTS_PER_PAGE = 10;
60     
61     
62     // the original search request
63
WeblogSearchRequest searchRequest = null;
64     
65     // the actual search results mapped by Day -> Set of entries
66
private TreeMap JavaDoc results = new TreeMap JavaDoc(new ReverseComparator());
67     
68     // the pager used by the 3.0+ rendering system
69
private SearchResultsPager pager = null;
70     
71     private int hits = 0;
72     private int offset = 0;
73     private int limit = 0;
74     private Set JavaDoc categories = new TreeSet JavaDoc();
75     private boolean websiteSpecificSearch = true;
76     private String JavaDoc errorMessage = null;
77     
78     
79     public void init(Map JavaDoc initData) throws RollerException {
80         
81         // we expect the init data to contain a searchRequest object
82
searchRequest = (WeblogSearchRequest) initData.get("searchRequest");
83         if(searchRequest == null) {
84             throw new RollerException("expected searchRequest from init data");
85         }
86         
87         // let parent initialize
88
super.init(initData);
89         
90         // if there is no query, then we are done
91
if(searchRequest.getQuery() == null) {
92             pager = new SearchResultsPager(searchRequest, results, false);
93             return;
94         }
95         
96         // setup the search
97
IndexManager indexMgr = RollerFactory.getRoller().getIndexManager();
98         
99         SearchOperation search = new SearchOperation(indexMgr);
100         search.setTerm(searchRequest.getQuery());
101         
102         if(RollerRuntimeConfig.isSiteWideWeblog(searchRequest.getWeblogHandle())) {
103             this.websiteSpecificSearch = false;
104         } else {
105             search.setWebsiteHandle(searchRequest.getWeblogHandle());
106         }
107         
108         if(StringUtils.isNotEmpty(searchRequest.getWeblogCategoryName())) {
109             search.setCategory(searchRequest.getWeblogCategoryName());
110         }
111         
112         // execute search
113
indexMgr.executeIndexOperationNow(search);
114         
115         if (search.getResultsCount() == -1) {
116             // this means there has been a parsing (or IO) error
117
this.errorMessage = bundle.getString("error.searchProblem");
118         } else {
119             Hits hits = search.getResults();
120             this.hits = search.getResultsCount();
121             
122             // Convert the Hits into WeblogEntryData instances.
123
convertHitsToEntries(hits);
124         }
125         
126         // search completed, setup pager based on results
127
pager = new SearchResultsPager(searchRequest, results, (hits > (offset+limit)));
128     }
129     
130     /**
131      * Is this page showing search results?
132      */

133     public boolean isSearchResults() {
134         return true;
135     }
136     
137     // override page model and return search results pager
138
public WeblogEntriesPager getWeblogEntriesPager() {
139         return pager;
140     }
141     
142     // override page model and return search results pager
143
public WeblogEntriesPager getWeblogEntriesPager(String JavaDoc category) {
144         return pager;
145     }
146     
147     private void convertHitsToEntries(Hits hits) throws RollerException {
148         
149         // determine offset
150
this.offset = searchRequest.getPageNum() * RESULTS_PER_PAGE;
151         if(this.offset >= hits.length()) {
152             this.offset = 0;
153         }
154         
155         // determine limit
156
this.limit = RESULTS_PER_PAGE;
157         if(this.offset + this.limit > hits.length()) {
158             this.limit = hits.length() - this.offset;
159         }
160         
161         try {
162             TreeSet JavaDoc categories = new TreeSet JavaDoc();
163             Roller roller = RollerFactory.getRoller();
164             WeblogManager weblogMgr = roller.getWeblogManager();
165             
166             WeblogEntryData entry = null;
167             Document doc = null;
168             String JavaDoc handle = null;
169             for(int i = offset; i < offset+limit; i++) {
170                 
171                 entry = null; // reset for each iteration
172

173                 doc = hits.doc(i);
174                 handle = doc.getField(FieldConstants.WEBSITE_HANDLE).stringValue();
175                 
176                 if(websiteSpecificSearch &&
177                         handle.equals(searchRequest.getWeblogHandle())) {
178                     
179                     entry = weblogMgr.getWeblogEntry(
180                             doc.getField(FieldConstants.ID).stringValue());
181                 } else {
182                     
183                     entry = weblogMgr.getWeblogEntry(
184                             doc.getField(FieldConstants.ID).stringValue());
185                     
186                     if (doc.getField(FieldConstants.CATEGORY) != null) {
187                         categories.add(
188                                 doc.getField(FieldConstants.CATEGORY).stringValue());
189                     }
190                 }
191                 
192                 // maybe null if search result returned inactive user
193
// or entry's user is not the requested user.
194
if (entry != null) {
195                     addEntryToResults(WeblogEntryDataWrapper.wrap(entry));
196                 }
197             }
198             
199             if(categories.size() > 0) {
200                 this.categories = categories;
201             }
202         } catch(IOException JavaDoc e) {
203             throw new RollerException(e);
204         }
205     }
206     
207     
208     private void addEntryToResults(WeblogEntryDataWrapper entry) {
209         
210         // convert entry's each date to midnight (00m 00h 00s)
211
Date JavaDoc midnight = DateUtil.getStartOfDay(entry.getPubTime());
212         
213         // ensure we do not get duplicates from Lucene by
214
// using a Set Collection. Entries sorted by pubTime.
215
TreeSet JavaDoc set = (TreeSet JavaDoc) this.results.get(midnight);
216         if (set == null) {
217             // date is not mapped yet, so we need a new Set
218
set = new TreeSet JavaDoc( new WeblogEntryWrapperComparator());
219             this.results.put(midnight, set);
220         }
221         set.add(entry);
222     }
223     
224     
225     public String JavaDoc getTerm() {
226         return (searchRequest.getQuery() == null) ? "" : searchRequest.getQuery();
227     }
228
229     public int getHits() {
230         return hits;
231     }
232
233     public int getOffset() {
234         return offset;
235     }
236
237     public int getLimit() {
238         return limit;
239     }
240
241     public TreeMap JavaDoc getResults() {
242         return results;
243     }
244
245     public Set JavaDoc getCategories() {
246         return categories;
247     }
248
249     public boolean isWebsiteSpecificSearch() {
250         return websiteSpecificSearch;
251     }
252
253     public String JavaDoc getErrorMessage() {
254         return errorMessage;
255     }
256     
257 }
258
Popular Tags