KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > internal > webapp > data > SearchData


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Sebastian Davids <sdavids@gmx.de> - fix for Bug 182466
11  *******************************************************************************/

12 package org.eclipse.help.internal.webapp.data;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Arrays JavaDoc;
16 import java.util.Comparator JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19
20 import javax.servlet.ServletContext JavaDoc;
21 import javax.servlet.http.Cookie JavaDoc;
22 import javax.servlet.http.HttpServletRequest JavaDoc;
23 import javax.servlet.http.HttpServletResponse JavaDoc;
24
25 import org.eclipse.help.HelpSystem;
26 import org.eclipse.help.IHelpResource;
27 import org.eclipse.help.IToc;
28 import org.eclipse.help.ITopic;
29 import org.eclipse.help.internal.HelpPlugin;
30 import org.eclipse.help.internal.base.BaseHelpSystem;
31 import org.eclipse.help.internal.base.HelpBasePlugin;
32 import org.eclipse.help.internal.search.ISearchQuery;
33 import org.eclipse.help.internal.search.QueryTooComplexException;
34 import org.eclipse.help.internal.search.SearchHit;
35 import org.eclipse.help.internal.search.SearchProgressMonitor;
36 import org.eclipse.help.internal.search.SearchQuery;
37 import org.eclipse.help.internal.search.SearchResults;
38 import org.eclipse.help.internal.webapp.HelpWebappPlugin;
39 import org.eclipse.help.internal.webapp.servlet.WebappWorkingSetManager;
40 import org.eclipse.help.internal.workingset.AdaptableToc;
41 import org.eclipse.help.internal.workingset.WorkingSet;
42 import org.eclipse.help.search.ISearchEngineResult;
43 import org.eclipse.help.search.ISearchEngineResult2;
44
45 /**
46  * Helper class for searchView.jsp initialization
47  */

48 public class SearchData extends ActivitiesData {
49     private WebappWorkingSetManager wsmgr;
50
51     // Request parameters
52
private String JavaDoc topicHref;
53
54     private String JavaDoc selectedTopicId = ""; //$NON-NLS-1$
55

56     private String JavaDoc searchWord;
57
58     private String JavaDoc workingSetName;
59
60     // search results
61
SearchHit[] hits;
62
63     // percentage of indexing completion
64
private int indexCompletion = 100;
65
66     // QueryException if any
67
private QueryTooComplexException queryException = null;
68
69     /**
70      * Constructs the xml data for the search resuls page.
71      *
72      * @param context
73      * @param request
74      */

75     public SearchData(ServletContext JavaDoc context, HttpServletRequest JavaDoc request,
76             HttpServletResponse JavaDoc response) {
77         super(context, request, response);
78         wsmgr = new WebappWorkingSetManager(request, response, getLocale());
79         this.topicHref = request.getParameter("topic"); //$NON-NLS-1$
80
if (topicHref != null && topicHref.length() == 0)
81             topicHref = null;
82
83         searchWord = request.getParameter("searchWord"); //$NON-NLS-1$
84

85         // try loading search results or get the indexing progress info.
86
if (isSearchRequest() && !isScopeRequest()) {
87             loadSearchResults();
88             if (queryException != null) {
89                 return;
90             }
91             if (!isProgressRequest()) {
92                 for (int i = 0; i < hits.length; i++) {
93                     // the following assume topic numbering as in searchView.jsp
94
if (hits[i].getHref().equals(topicHref)) {
95                         selectedTopicId = "a" + i; //$NON-NLS-1$
96
break;
97                     }
98                 }
99             }
100         }
101     }
102
103     /**
104      * Returns true when there is a search request
105      *
106      * @return boolean
107      */

108     public boolean isSearchRequest() {
109         return (request.getParameter("searchWord") != null); //$NON-NLS-1$
110
}
111
112     /**
113      * Return indexed completion percentage
114      */

115     public boolean isProgressRequest() {
116         return (hits == null && indexCompletion != 100);
117     }
118
119     /**
120      * Returns true when there is a request to change the scope (working set)
121      */

122     public boolean isScopeRequest() {
123         return (request.getParameter("workingSet") != null); //$NON-NLS-1$
124
}
125
126     public String JavaDoc getCategoryLabel(int i) {
127         IHelpResource cat = hits[i].getCategory();
128         if (cat != null) {
129             return cat.getLabel();
130         }
131         return null;
132     }
133
134     public String JavaDoc getCategoryHref(int i) {
135         IHelpResource cat = hits[i].getCategory();
136         if (cat != null) {
137             String JavaDoc tocHref = cat.getHref();
138             IToc[] tocs = HelpSystem.getTocs();
139             for (int j=0;j<tocs.length;++j) {
140                 if (tocHref.equals(tocs[j].getHref())) {
141                     ITopic topic = tocs[j].getTopic(null);
142                     String JavaDoc topicHref = topic.getHref();
143                     if (topicHref != null) {
144                         return UrlUtil.getHelpURL(topicHref);
145                     }
146                     return "../nav/" + j; //$NON-NLS-1$
147
}
148             }
149         }
150         return null;
151     }
152
153     /**
154      * Return the number of links
155      *
156      * @return int
157      */

158     public int getResultsCount() {
159         return hits.length;
160     }
161
162     public String JavaDoc getSelectedTopicId() {
163         return selectedTopicId;
164     }
165
166     public String JavaDoc getTopicHref(int i) {
167         return UrlUtil.getHelpURL(hits[i].getHref());
168     }
169
170     public String JavaDoc getTopicLabel(int i) {
171         return UrlUtil.htmlEncode(hits[i].getLabel());
172     }
173
174     public String JavaDoc getTopicTocLabel(int i) {
175         if (hits[i].getToc() != null)
176             return UrlUtil.htmlEncode(hits[i].getToc().getLabel());
177         return ""; //$NON-NLS-1$
178
}
179     
180     public String JavaDoc getTopicDescription(int i) {
181         String JavaDoc description = hits[i].getDescription();
182         if (description != null) {
183             return UrlUtil.htmlEncode(description);
184         }
185         return ""; //$NON-NLS-1$
186
}
187
188     /**
189      * @param i
190      * @return true of result belong to an enabled TOC
191      */

192     public boolean isEnabled(int i) {
193         String JavaDoc href = hits[i].getHref();
194         return HelpBasePlugin.getActivitySupport().isEnabledTopic(href,
195                 getLocale());
196     }
197     
198     /**
199      * Returns whether or not the ith hit is a potential hit. This means
200      * it may not be an actual hit (i.e. it found something in a filtered
201      * section of the document).
202      *
203      * @param i the index of the hit to check
204      * @return whether or not the hit is a potential hit
205      */

206     public boolean isPotentialHit(int i) {
207         return ((getMode() != MODE_INFOCENTER) && hits[i].isPotentialHit());
208     }
209
210     public boolean isShowCategories() {
211         Cookie JavaDoc[] cookies = request.getCookies();
212         if (cookies != null) {
213                 for (int i=0;i<cookies.length;++i) {
214                     if ("showCategories".equals(cookies[i].getName())) { //$NON-NLS-1$
215
return String.valueOf(true).equals(cookies[i].getValue());
216                     }
217                 }
218         }
219         // default off
220
return false;
221     }
222
223     public boolean isShowDescriptions() {
224         Cookie JavaDoc[] cookies = request.getCookies();
225         if (cookies != null) {
226                 for (int i=0;i<cookies.length;++i) {
227                     if ("showDescriptions".equals(cookies[i].getName())) { //$NON-NLS-1$
228
return String.valueOf(true).equals(cookies[i].getValue());
229                     }
230                 }
231         }
232         // default on
233
return true;
234     }
235
236     /**
237      * Return indexed completion percentage
238      */

239     public String JavaDoc getIndexedPercentage() {
240         return String.valueOf(indexCompletion);
241     }
242
243     /**
244      * Returns the search query
245      */

246     public String JavaDoc getSearchWord() {
247         if (searchWord == null)
248             return ""; //$NON-NLS-1$
249
return searchWord;
250     }
251
252     /**
253      * Returns the list of selected TOC's
254      */

255     public String JavaDoc[] getSelectedTocs() {
256         String JavaDoc[] books = request.getParameterValues("scope"); //$NON-NLS-1$
257
if (books == null) {
258             // select all books
259
TocData tocData = new TocData(context, request, response);
260             books = new String JavaDoc[tocData.getTocCount()];
261             for (int i = 0; i < books.length; i++)
262                 books[i] = tocData.getTocHref(i);
263         }
264         return books;
265     }
266
267     /**
268      * Returns true if book is within a search scope
269      */

270     public boolean isTocSelected(int toc) {
271         TocData tocData = new TocData(context, request, response);
272         String JavaDoc href = tocData.getTocHref(toc);
273         String JavaDoc[] books = request.getParameterValues("scope"); //$NON-NLS-1$
274
if (books == null)
275             return false;
276         for (int i = 0; i < books.length; i++) {
277             if (books[i].equals(href)) {
278                 return true;
279             }
280         }
281         return false;
282     }
283
284     /**
285      * Returns the working set selected. This is used to display the working set
286      * name in the search banner.
287      *
288      * @return String
289      */

290     public String JavaDoc getScope() {
291         if (workingSetName != null)
292             return workingSetName;
293
294         if (isScopeRequest()) {
295             workingSetName = request.getParameter("workingSet"); //$NON-NLS-1$
296
} else if (isSearchRequest()) {
297             workingSetName = request.getParameter("scope"); //$NON-NLS-1$
298
// if we have already set the working set, then use it.
299
if (workingSetName == null)
300                 workingSetName = request.getParameter("workingSet"); //$NON-NLS-1$
301
} else if (getWorkingSets() == null || getWorkingSets().length == 0) {
302             workingSetName = ServletResources.getString("All", request); //$NON-NLS-1$
303
} else {
304             workingSetName = wsmgr.getCurrentWorkingSet();
305         }
306
307         if (workingSetName == null || workingSetName.length() == 0
308                 || getMode() == RequestData.MODE_INFOCENTER
309                 && wsmgr.getWorkingSet(workingSetName) == null)
310             workingSetName = ServletResources.getString("All", request); //$NON-NLS-1$
311
return workingSetName;
312     }
313
314     /**
315      * This method is used to persist the working set name and is called from
316      * the search view, after each search
317      */

318     public void saveScope() {
319         // if a working set is defined, set it in the preferences
320
String JavaDoc workingSet = request.getParameter("scope"); //$NON-NLS-1$
321
String JavaDoc lastWS = wsmgr.getCurrentWorkingSet();
322         if (workingSet != null && !workingSet.equals(lastWS)) {
323             wsmgr.setCurrentWorkingSet(workingSet);
324         } else if (workingSet == null && lastWS != null && lastWS.length() > 0) {
325             wsmgr.setCurrentWorkingSet(""); //$NON-NLS-1$
326
}
327     }
328
329     /**
330      * Call the search engine, and get results or the percentage of indexed
331      * documents.
332      */

333     private void loadSearchResults() {
334         try {
335             SearchProgressMonitor pm = SearchProgressMonitor
336                     .getProgressMonitor(getLocale());
337             if (pm.isDone()) {
338                 this.indexCompletion = 100;
339                 SearchResults results = createHitCollector();
340                 BaseHelpSystem.getSearchManager().search(createSearchQuery(),
341                         results, pm);
342                 hits = results.getSearchHits();
343                 if (hits == null) {
344                     HelpWebappPlugin
345                             .logWarning("No search results returned. Help index is in use."); //$NON-NLS-1$
346
}
347                 else {
348                     if (isShowCategories()) {
349                         Arrays.sort(hits, new SearchResultComparator());
350                     }
351                 }
352                 return;
353             }
354             // progress
355
indexCompletion = pm.getPercentage();
356             if (indexCompletion >= 100) {
357                 // 38573 We do not have results, so index cannot be 100
358
indexCompletion = 100 - 1;
359             }
360             return;
361         } catch (QueryTooComplexException qe) {
362             queryException = qe;
363         } catch (Exception JavaDoc e) {
364             this.indexCompletion = 0;
365         }
366
367     }
368
369     private ISearchQuery createSearchQuery() {
370         String JavaDoc fieldSearchStr = request.getParameter("fieldSearch"); //$NON-NLS-1$
371
boolean fieldSearch = fieldSearchStr != null ? new Boolean JavaDoc(
372                 fieldSearchStr).booleanValue() : false;
373         return new SearchQuery(searchWord == null ? "" : searchWord, fieldSearch, new ArrayList JavaDoc(), //$NON-NLS-1$
374
getLocale());
375     }
376
377     private SearchResults createHitCollector() {
378         WorkingSet[] workingSets;
379         if (request.getParameterValues("scopedSearch") == null) { //$NON-NLS-1$
380
// scopes are working set names
381
workingSets = getWorkingSets();
382         } else {
383             // scopes are books (advanced search)
384
workingSets = createTempWorkingSets();
385         }
386
387         int maxHits = 500;
388         String JavaDoc maxHitsStr = request.getParameter("maxHits"); //$NON-NLS-1$
389
if (maxHitsStr != null) {
390             try {
391                 int clientmaxHits = Integer.parseInt(maxHitsStr);
392                 if (0 < clientmaxHits && clientmaxHits < 500) {
393                     maxHits = clientmaxHits;
394                 }
395             } catch (NumberFormatException JavaDoc nfe) {
396             }
397         }
398         return new SearchResultFilter(workingSets, maxHits, getLocale());
399     }
400
401     /**
402      * @return WorkingSet[] or null
403      */

404     private WorkingSet[] getWorkingSets() {
405         String JavaDoc[] scopes = request.getParameterValues("scope"); //$NON-NLS-1$
406
if (scopes == null) {
407             return null;
408         }
409         // confirm working set exists and use it
410
ArrayList JavaDoc workingSetCol = new ArrayList JavaDoc(scopes.length);
411         for (int s = 0; s < scopes.length; s++) {
412             WorkingSet ws = wsmgr.getWorkingSet(scopes[s]);
413             if (ws != null) {
414                 workingSetCol.add(ws);
415             }
416         }
417         if (workingSetCol.size() == 0) {
418             return null;
419         }
420         return (WorkingSet[]) workingSetCol
421                 .toArray(new WorkingSet[workingSetCol.size()]);
422     }
423
424     /**
425      * @return WorkingSet[] or null
426      */

427     private WorkingSet[] createTempWorkingSets() {
428         String JavaDoc[] scopes = request.getParameterValues("scope"); //$NON-NLS-1$
429
if (scopes == null) {
430             // it is possible that filtering is used, but all books are
431
// deselected
432
return new WorkingSet[0];
433         }
434         if (scopes.length == HelpPlugin.getTocManager().getTocs(getLocale()).length) {
435             // do not filter if all books are selected
436
return null;
437         }
438         // create working set from books
439
ArrayList JavaDoc tocs = new ArrayList JavaDoc(scopes.length);
440         for (int s = 0; s < scopes.length; s++) {
441             AdaptableToc toc = wsmgr.getAdaptableToc(scopes[s]);
442             if (toc != null) {
443                 tocs.add(toc);
444             }
445         }
446         AdaptableToc[] adaptableTocs = (AdaptableToc[]) tocs
447                 .toArray(new AdaptableToc[tocs.size()]);
448         WorkingSet[] workingSets = new WorkingSet[1];
449         workingSets[0] = wsmgr.createWorkingSet("temp", adaptableTocs); //$NON-NLS-1$
450
return workingSets;
451     }
452
453     public String JavaDoc getQueryExceptionMessage() {
454         if (queryException == null) {
455             return null;
456         }
457         return ServletResources.getString("searchTooComplex", request); //$NON-NLS-1$
458
}
459
460     /*
461      * Filters out results that help doesn't know how to open (i.e. those hits
462      * that implement ISearchEngineResult2 and canOpen() returns true.
463      */

464     private static class SearchResultFilter extends SearchResults {
465         public SearchResultFilter(WorkingSet[] workingSets, int maxHits, String JavaDoc locale) {
466             super(workingSets, maxHits, locale);
467         }
468         public void addHits(List JavaDoc hits, String JavaDoc highlightTerms) {
469             List JavaDoc filtered = new ArrayList JavaDoc();
470             Iterator JavaDoc iter = hits.iterator();
471             while (iter.hasNext()) {
472                 Object JavaDoc obj = iter.next();
473                 if (!(obj instanceof ISearchEngineResult2 && ((ISearchEngineResult2)obj).canOpen())) {
474                     filtered.add(obj);
475                 }
476             }
477             super.addHits(filtered, highlightTerms);
478         }
479     }
480     
481     private static class SearchResultComparator implements Comparator JavaDoc {
482         public int category(Object JavaDoc element) {
483             if (element instanceof ISearchEngineResult) {
484                 ISearchEngineResult r = (ISearchEngineResult)element;
485                 IHelpResource c = r.getCategory();
486                 if (c!=null) {
487                     String JavaDoc label = c.getLabel();
488                     if (label.length()==0)
489                         return 10;
490                     return 5;
491                 }
492             }
493             return 0;
494         }
495
496         public int compare(Object JavaDoc e1, Object JavaDoc e2) {
497             int cat1 = category(e1);
498             int cat2 = category(e2);
499             if (cat1 != cat2) {
500                 return cat1 - cat2;
501             }
502             ISearchEngineResult r1 = (ISearchEngineResult)e1;
503             ISearchEngineResult r2 = (ISearchEngineResult)e2;
504             IHelpResource c1 = r1.getCategory();
505             IHelpResource c2 = r2.getCategory();
506             if (c1 != null && c2 != null) {
507                 int cat = c1.getLabel().compareToIgnoreCase(c2.getLabel());
508                 if (cat != 0) {
509                     return cat;
510                 }
511             }
512             float rank1 = ((ISearchEngineResult)e1).getScore();
513             float rank2 = ((ISearchEngineResult)e2).getScore();
514             if (rank1 - rank2 > 0) {
515                 return -1;
516             }
517             else if (rank1 == rank2) {
518                 return 0;
519             }
520             else {
521                 return 1;
522             }
523         }
524     }
525 }
526
Popular Tags