001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/search/tags/sakai_2-4-1/search-tool/tool/src/java/org/sakaiproject/search/tool/SearchBeanImpl.java $
003: * $Id: SearchBeanImpl.java 30222 2007-05-09 18:34:57Z ajpoland@iupui.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.search.tool;
021:
022: import java.io.IOException;
023: import java.io.UnsupportedEncodingException;
024: import java.net.URLEncoder;
025: import java.text.Collator;
026: import java.text.MessageFormat;
027: import java.text.SimpleDateFormat;
028: import java.util.ArrayList;
029: import java.util.Collections;
030: import java.util.Comparator;
031: import java.util.Date;
032: import java.util.HashMap;
033: import java.util.Iterator;
034: import java.util.List;
035: import java.util.Properties;
036:
037: import javax.servlet.http.HttpServletRequest;
038:
039: import org.apache.commons.logging.Log;
040: import org.apache.commons.logging.LogFactory;
041: import org.sakaiproject.authz.cover.SecurityService;
042: import org.sakaiproject.component.cover.ServerConfigurationService;
043: import org.sakaiproject.exception.IdUnusedException;
044: import org.sakaiproject.search.api.SearchList;
045: import org.sakaiproject.search.api.SearchResult;
046: import org.sakaiproject.search.api.SearchService;
047: import org.sakaiproject.search.api.TermFrequency;
048: import org.sakaiproject.search.tool.api.SearchBean;
049: import org.sakaiproject.search.tool.model.SearchOutputItem;
050: import org.sakaiproject.search.tool.model.SearchPage;
051: import org.sakaiproject.search.tool.model.SearchTerm;
052: import org.sakaiproject.site.api.Site;
053: import org.sakaiproject.site.api.SiteService;
054: import org.sakaiproject.tool.api.Placement;
055: import org.sakaiproject.tool.api.ToolManager;
056: import org.sakaiproject.util.FormattedText;
057: import org.sakaiproject.util.StringUtil;
058:
059: /**
060: * Implementation of the search bean backing bean
061: *
062: * @author ieb
063: */
064: public class SearchBeanImpl implements SearchBean {
065:
066: private static final Log log = LogFactory
067: .getLog(SearchBeanImpl.class);
068:
069: /**
070: * The searhc string parameter name
071: */
072: private static final String SEARCH_PARAM = "search";
073:
074: /**
075: * The results page
076: */
077: private static final String SEARCH_PAGE = "page";
078:
079: /**
080: * The search criteria
081: */
082: private String search;
083:
084: /**
085: * The Search Service to use
086: */
087: private SearchService searchService;
088:
089: private SiteService siteService;
090:
091: /**
092: * Time taken
093: */
094: private double timeTaken = 0;
095:
096: /**
097: * The number of results per page
098: */
099: private int pagesize = 10;
100:
101: /**
102: * The number of list links
103: */
104: private int nlistPages = 5;
105:
106: /**
107: * The default request page
108: */
109: private int requestPage = 0;
110:
111: /**
112: * The current search list
113: */
114: private SearchList searchResults;
115:
116: private String placementId;
117:
118: private String toolId;
119:
120: private ToolManager toolManager;
121:
122: private String siteId;
123:
124: private String sortName = "normal";
125:
126: private String filterName = "normal";
127:
128: private String errorMessage;
129:
130: private List<TermFrequency> termsVectors;
131:
132: private List<TermHolder> termList;
133:
134: private Site currentSite;
135:
136: private int nTerms = 100;
137:
138: private List<SearchTerm> finalTermList;
139:
140: private int topTerms = 10;
141:
142: private boolean relativeTerms = true;
143:
144: private float divisorTerms = 3;
145:
146: private String requestURL;
147:
148: // Empty constructor to aid in testing.
149:
150: public SearchBeanImpl(String siteId, SearchService ss,
151: String search, ToolManager tm) {
152: super ();
153: this .siteId = siteId;
154: this .searchService = ss;
155: this .search = search;
156: this .toolManager = tm;
157: }
158:
159: /**
160: * Creates a searchBean
161: *
162: * @param request
163: * The HTTP request
164: * @param searchService
165: * The search service to use
166: * @param siteService
167: * the site service
168: * @param portalService
169: * the portal service
170: * @throws IdUnusedException
171: * if there is no current worksite
172: */
173: public SearchBeanImpl(HttpServletRequest request,
174: SearchService searchService, SiteService siteService,
175: ToolManager toolManager) throws IdUnusedException {
176: this .search = request.getParameter(SEARCH_PARAM);
177: this .searchService = searchService;
178: this .siteService = siteService;
179: this .toolManager = toolManager;
180: this .placementId = this .toolManager.getCurrentPlacement()
181: .getId();
182: this .toolId = this .toolManager.getCurrentTool().getId();
183: this .siteId = this .toolManager.getCurrentPlacement()
184: .getContext();
185: try {
186: this .requestPage = Integer.parseInt(request
187: .getParameter(SEARCH_PAGE));
188: } catch (Exception ex) {
189:
190: }
191: currentSite = this .siteService.getSite(this .siteId);
192: String siteCheck = currentSite.getReference();
193: requestURL = request.getRequestURL().toString();
194:
195: }
196:
197: public SearchBeanImpl(HttpServletRequest request, String sortName,
198: String filterName, SearchService searchService,
199: SiteService siteService, ToolManager toolManager)
200: throws IdUnusedException {
201: this .search = request.getParameter(SEARCH_PARAM);
202: this .searchService = searchService;
203: this .siteService = siteService;
204: this .sortName = sortName;
205: this .filterName = filterName;
206: this .toolManager = toolManager;
207: this .placementId = this .toolManager.getCurrentPlacement()
208: .getId();
209: this .toolId = this .toolManager.getCurrentTool().getId();
210: this .siteId = this .toolManager.getCurrentPlacement()
211: .getContext();
212: try {
213: this .requestPage = Integer.parseInt(request
214: .getParameter(SEARCH_PAGE));
215: } catch (Exception ex) {
216:
217: }
218: currentSite = this .siteService.getSite(this .siteId);
219: String siteCheck = currentSite.getReference();
220: requestURL = request.getRequestURL().toString();
221: }
222:
223: /**
224: * {@inheritDoc}
225: * @deprecated
226: */
227: public String getSearchResults(String searchItemFormat,
228: String errorFeedbackFormat) {
229: StringBuffer sb = new StringBuffer();
230: List searchResults = search();
231: if (errorMessage != null) {
232: sb.append(MessageFormat.format(errorFeedbackFormat,
233: new Object[] { FormattedText.escapeHtml(
234: errorMessage, false) }));
235: }
236: if (searchResults != null) {
237: for (Iterator i = searchResults.iterator(); i.hasNext();) {
238:
239: SearchResult sr = (SearchResult) i.next();
240: sb.append(MessageFormat.format(searchItemFormat,
241: new Object[] {
242: FormattedText.escapeHtml(sr.getTool(),
243: false),
244: FormattedText.escapeHtml(sr.getUrl(),
245: false),
246: FormattedText.escapeHtml(sr.getTitle(),
247: false), sr.getSearchResult(),
248: new Double(sr.getScore()),
249: String.valueOf(sr.getIndex() + 1) }));
250: }
251: }
252: return sb.toString();
253:
254: }
255:
256: private void loadTermVectors() {
257: StringBuffer sb = new StringBuffer();
258: List searchResults = search();
259: if (searchResults != null) {
260: termsVectors = new ArrayList<TermFrequency>();
261: termList = null;
262: for (Iterator i = searchResults.iterator(); i.hasNext();) {
263:
264: SearchResult sr = (SearchResult) i.next();
265: try {
266: TermFrequency tf = sr.getTerms();
267: if (tf != null) {
268: termsVectors.add(sr.getTerms());
269: }
270: } catch (IOException e) {
271: log.warn("Failed to get term vector ", e);
272: }
273: }
274: }
275: }
276:
277: /**
278: * @deprecated
279: */
280: public String getTerms(String format) {
281: List<SearchTerm> l = getTerms();
282: StringBuilder sb = new StringBuilder();
283: for (Iterator li = l.iterator(); li.hasNext();) {
284: SearchTerm t = (SearchTerm) li.next();
285: sb.append(MessageFormat.format(format, new Object[] {
286: t.getName(), t.getWeight() }));
287: }
288: return sb.toString();
289: }
290:
291: protected class TermHolder {
292: public int position;
293:
294: protected String term;
295:
296: protected int frequency;
297:
298: }
299:
300: private void mergeTerms() {
301: if (termsVectors == null) {
302: loadTermVectors();
303: }
304: if (termsVectors == null) {
305: return;
306: }
307: HashMap<String, TermHolder> hm = new HashMap<String, TermHolder>();
308: for (Iterator i = termsVectors.iterator(); i.hasNext();) {
309: TermFrequency tf = (TermFrequency) i.next();
310: String[] terms = tf.getTerms();
311: int[] freq = tf.getFrequencies();
312: for (int ti = 0; ti < terms.length; ti++) {
313: TermHolder h = (TermHolder) hm.get(terms[ti]);
314: if (h == null) {
315: h = new TermHolder();
316: h.term = terms[ti];
317: h.frequency = freq[ti];
318: hm.put(terms[ti], h);
319: } else {
320: h.frequency += freq[ti];
321: }
322: }
323: }
324: termList = new ArrayList<TermHolder>();
325: termList.addAll(hm.values());
326: Collections.sort(termList, new Comparator<TermHolder>() {
327:
328: public int compare(TermHolder a, TermHolder b) {
329:
330: return b.frequency - a.frequency;
331: }
332:
333: });
334:
335: }
336:
337: /**
338: * {@inheritDoc}
339: * @deprecated
340: */
341: public String getPager(String pagerFormat, String singlePageFormat)
342: throws UnsupportedEncodingException {
343: SearchList sr = (SearchList) search();
344: if (sr == null)
345: return "";
346: int npages = (sr.getFullSize() - 1) / pagesize;
347: int cpage = requestPage - (nlistPages / 2);
348: if (cpage < 0) {
349: cpage = 0;
350: }
351: StringBuffer sb = new StringBuffer();
352:
353: int lastPage = Math.min(cpage + nlistPages, npages);
354: boolean first = true;
355: if (cpage == lastPage) {
356: sb.append(singlePageFormat);
357: } else {
358: while (cpage <= lastPage) {
359: String searchURL = "?search="
360: + URLEncoder.encode(search, "UTF-8") + "&page="
361: + String.valueOf(cpage);
362: String cssInd = "1";
363: if (first) {
364: cssInd = "0";
365: first = false;
366: } else if (cpage == (lastPage)) {
367: cssInd = "2";
368: }
369:
370: sb.append(MessageFormat.format(pagerFormat,
371: new Object[] {
372: FormattedText.escapeHtml(searchURL,
373: false),
374: String.valueOf(cpage + 1), cssInd }));
375: cpage++;
376: }
377: }
378:
379: return sb.toString();
380: }
381:
382: public boolean isEnabled() {
383: return ("true".equals(ServerConfigurationService.getString(
384: "search.enable", "false")));
385:
386: }
387:
388: /**
389: * {@inheritDoc}
390: * @deprecated
391: */
392:
393: public String getHeader(String headerFormat) {
394: SearchList sr = (SearchList) search();
395: if (sr == null)
396: return "";
397: int total = sr.getFullSize();
398: int start = 0;
399: int end = 0;
400: if (total > 0) {
401: start = sr.getStart();
402: end = Math.min(start + sr.size(), total);
403: start++;
404: }
405: return MessageFormat.format(headerFormat, new Object[] {
406: new Integer(start), new Integer(end),
407: new Integer(total), new Double(timeTaken) });
408: }
409:
410: /**
411: * Gets the current search request
412: *
413: * @return current search request
414: */
415: public String getSearch() {
416: if (search == null)
417: return "";
418: return FormattedText.escapeHtml(search, false);
419: }
420:
421: /**
422: * The time taken to perform the search only, not including rendering
423: *
424: * @return
425: */
426: public String getTimeTaken() {
427: int tt = (int) timeTaken;
428: return String.valueOf(tt);
429: }
430:
431: /* assemble the list of search sites */
432:
433: protected List getSearchSites(String[] toolPropertySiteIds) {
434: List<String> l = new ArrayList();
435:
436: l.add(this .siteId);
437:
438: if (toolPropertySiteIds == null)
439: return l;
440:
441: //String[] searchSiteIds = extractSiteIdsFromToolProperty(extractPropertiesFromTool());
442: String[] searchSiteIds = toolPropertySiteIds;
443:
444: // add searchSiteIds to l
445: for (int i = 0; i < searchSiteIds.length; i++) {
446: String ss = searchSiteIds[i];
447: if (searchSiteIds[i].length() > 0)
448: l.add(searchSiteIds[i]);
449: }
450:
451: return l;
452: }
453:
454: protected String[] getToolPropertySiteIds() {
455: Properties props = extractPropertiesFromTool();
456: String[] searchSiteIds = extractSiteIdsFromProperties(props);
457: return searchSiteIds;
458: }
459:
460: /* get any site ids that are in the tool property and normalize the string.
461: *
462: */
463: protected String[] extractSiteIdsFromProperties(Properties props) {
464: // Properties props = extractPropertiesFromTool();
465:
466: String targetSiteId = StringUtil.trimToNull(props
467: .getProperty("search_site_ids"));
468: if (targetSiteId == null)
469: return new String[] { "" };
470: String[] searchSiteIds = StringUtil.split(targetSiteId, ",");
471: for (int i = 0; i < searchSiteIds.length; i++) {
472: searchSiteIds[i] = StringUtil.trimToZero(searchSiteIds[i]);
473: }
474: return searchSiteIds;
475: }
476:
477: protected Properties extractPropertiesFromTool() {
478: Placement placement = toolManager.getCurrentPlacement();
479: Properties props = placement.getPlacementConfig();
480: if (props.isEmpty())
481: props = placement.getConfig();
482: return props;
483: }
484:
485: /**
486: * Perform the search
487: *
488: * @return a list of page names that match the search criteria
489: */
490: public SearchList search() {
491:
492: if (searchResults == null && errorMessage == null) {
493: if (search != null && search.trim().length() > 0) {
494:
495: /*
496: List l = new ArrayList();
497: l.add(this.siteId);
498: */
499: List l = getSearchSites(getToolPropertySiteIds());
500: long start = System.currentTimeMillis();
501: int searchStart = requestPage * pagesize;
502: int searchEnd = searchStart + pagesize;
503: try {
504: searchResults = searchService.search(search, l,
505: searchStart, searchEnd, filterName,
506: sortName);
507: } catch (Exception ex) {
508:
509: errorMessage = ex.getMessage();
510: log
511: .warn("Search Error encoutered, generated by a user action "
512: + ex.getClass().getName()
513: + ":"
514: + ex.getMessage());
515: log.debug("Search Error Traceback ", ex);
516:
517: }
518: long end = System.currentTimeMillis();
519: timeTaken = 0.001 * (end - start);
520: }
521: }
522: return searchResults;
523: }
524:
525: /**
526: * @return Returns the nlistPages.
527: */
528: public int getNlistPages() {
529: return nlistPages;
530: }
531:
532: /**
533: * @param nlistPages
534: * The nlistPages to set.
535: */
536: public void setNlistPages(int nlistPages) {
537: this .nlistPages = nlistPages;
538: }
539:
540: /**
541: * @return Returns the pagesize.
542: */
543: public int getPagesize() {
544: return pagesize;
545: }
546:
547: /**
548: * @param pagesize
549: * The pagesize to set.
550: */
551: public void setPagesize(int pagesize) {
552: this .pagesize = pagesize;
553: }
554:
555: /**
556: * @return Returns the requestPage.
557: */
558: public int getRequestPage() {
559: return requestPage;
560: }
561:
562: /**
563: * @param requestPage
564: * The requestPage to set.
565: */
566: public void setRequestPage(int requestPage) {
567: this .requestPage = requestPage;
568: }
569:
570: /**
571: * The Total number of results
572: *
573: * @return
574: */
575: public int getNresults() {
576: return searchResults.getFullSize();
577: }
578:
579: /**
580: * {@inheritDoc}
581: */
582: public String getSearchTitle() {
583: return Messages.getString("search_title") + " " + getSearch();
584: }
585:
586: /**
587: * {@inheritDoc}
588: */
589: public boolean hasAdmin() {
590: boolean super User = SecurityService.isSuperUser();
591: return (super User)
592: || ("true".equals(ServerConfigurationService.getString(
593: "search.allow.maintain.admin", "false")) && siteService
594: .allowUpdateSite(siteId));
595: }
596:
597: /**
598: * {@inheritDoc}
599: */
600: public String getToolUrl() {
601:
602: return ServerConfigurationService.getString("portalPath")
603: + "/tool/" + placementId;
604: }
605:
606: public boolean hasResults() {
607: SearchList sr = (SearchList) search();
608: if (sr == null) {
609: return false;
610: } else {
611: return (sr.size() > 0);
612: }
613: }
614:
615: public boolean foundNoResults() {
616: if (search == null || search.trim().length() == 0) {
617: return false;
618: }
619: return !hasResults();
620: }
621:
622: public String getOpenSearchUrl() {
623: return ServerConfigurationService.getPortalUrl() + "/tool/"
624: + placementId + "/opensearch";
625: }
626:
627: public String getSherlockIconUrl() {
628: return FormattedText.escapeHtml(getBaseUrl()
629: + SherlockSearchBeanImpl.UPDATE_IMAGE, false);
630: }
631:
632: public String getSherlockUpdateUrl() {
633: return FormattedText.escapeHtml(getBaseUrl()
634: + SherlockSearchBeanImpl.UPDATE_URL, false);
635: }
636:
637: public String getBaseUrl() {
638: return ServerConfigurationService.getPortalUrl() + "/tool/"
639: + placementId;
640: }
641:
642: public String getPortalBaseUrl() {
643: return ServerConfigurationService.getPortalUrl()
644: + "/directtool/" + placementId;
645: }
646:
647: public String getSiteTitle() {
648: return FormattedText.escapeHtml(currentSite.getTitle(), false);
649: }
650:
651: public String getSystemName() {
652: return FormattedText.escapeHtml(ServerConfigurationService
653: .getString("ui.service", "Sakai"), false);
654: }
655:
656: /*
657: * (non-Javadoc)
658: *
659: * @see org.sakaiproject.search.tool.SearchBean#getPages()
660: */
661: public List<SearchPage> getPages() {
662: List<SearchPage> pages = new ArrayList<SearchPage>();
663: try {
664: SearchList sr = (SearchList) search();
665: if (sr == null)
666: return pages;
667: int npages = (sr.getFullSize() - 1) / pagesize;
668: int cpage = requestPage - (nlistPages / 2);
669: if (cpage < 0) {
670: cpage = 0;
671: }
672: int lastPage = Math.min(cpage + nlistPages, npages);
673: boolean first = true;
674: if (cpage == lastPage) {
675: return pages;
676: } else {
677: while (cpage <= lastPage) {
678: final String searchURL = "?search="
679: + URLEncoder.encode(search, "UTF-8")
680: + "&page=" + String.valueOf(cpage);
681:
682: final String name = String.valueOf(cpage + 1);
683: String cssInd = "1";
684: if (first) {
685: cssInd = "0";
686: first = false;
687: } else if (cpage == (lastPage)) {
688: cssInd = "2";
689: }
690: final String cssI = cssInd;
691: pages.add(new SearchPage() {
692:
693: public String getName() {
694: return FormattedText
695: .escapeHtml(name, false);
696: }
697:
698: public String getUrl() {
699: return FormattedText.escapeHtml(searchURL,
700: false);
701: }
702:
703: public String getCssIndex() {
704: return cssI;
705: }
706:
707: });
708: cpage++;
709: }
710: }
711:
712: } catch (Exception ex) {
713: }
714: return pages;
715: }
716:
717: /*
718: * (non-Javadoc)
719: *
720: * @see org.sakaiproject.search.tool.SearchBean#getResults()
721: */
722: public List<SearchOutputItem> getResults() {
723: List<SearchOutputItem> l = new ArrayList<SearchOutputItem>();
724: SearchList sl = search();
725: for (Iterator i = sl.iterator(); i.hasNext();) {
726: final SearchResult sr = (SearchResult) i.next();
727: l.add(new SearchOutputItem() {
728:
729: public String getSearchResult() {
730: try {
731: return sr.getSearchResult();
732: } catch (Exception ex) {
733: return "";
734: }
735: }
736:
737: public String getTitle() {
738: try {
739: return FormattedText.escapeHtml(sr.getTitle(),
740: false);
741: } catch (Exception ex) {
742: return "";
743: }
744:
745: }
746:
747: public String getTool() {
748: try {
749: return FormattedText.escapeHtml(sr.getTool(),
750: false);
751: } catch (Exception ex) {
752: return "";
753: }
754:
755: }
756:
757: public String getUrl() {
758: try {
759: return FormattedText.escapeHtml(sr.getUrl(),
760: false);
761: } catch (Exception ex) {
762: return "";
763: }
764:
765: }
766:
767: });
768: }
769: return l;
770: }
771:
772: /*
773: * (non-Javadoc)
774: *
775: * @see org.sakaiproject.search.tool.SearchBean#getSearchFound()
776: */
777: public String getSearchFound() {
778: SearchList sr = (SearchList) search();
779: if (sr == null)
780: return "";
781: int total = sr.getFullSize();
782: int start = 0;
783: int end = 0;
784: if (total > 0) {
785: start = sr.getStart();
786: end = Math.min(start + sr.size(), total);
787: start++;
788: }
789: return MessageFormat.format(Messages
790: .getString("jsp_found_line"), new Object[] {
791: new Integer(start), new Integer(end),
792: new Integer(total), new Double(timeTaken) });
793:
794: }
795:
796: /*
797: * (non-Javadoc)
798: *
799: * @see org.sakaiproject.search.tool.SearchBean#getTerms()
800: */
801: public List<SearchTerm> getTerms() {
802: if (termList == null) {
803: mergeTerms();
804: finalTermList = null;
805: }
806: if (termList == null) {
807: return new ArrayList<SearchTerm>();
808: }
809: if (finalTermList != null) {
810: return finalTermList;
811: }
812: finalTermList = new ArrayList<SearchTerm>();
813: List<TermHolder> l = termList.subList(0, Math.min(nTerms,
814: termList.size()));
815: int j = 0;
816: for (Iterator li = l.iterator(); li.hasNext();) {
817: TermHolder t = (TermHolder) li.next();
818: t.position = j;
819: j++;
820: }
821:
822: Collections.sort(l, new Comparator<TermHolder>() {
823: Collator c = Collator.getInstance();
824:
825: public int compare(TermHolder a, TermHolder b) {
826: return c.compare(a.term, b.term);
827: }
828:
829: });
830: int factor = 1;
831: j = l.size();
832: for (Iterator li = l.iterator(); li.hasNext();) {
833: TermHolder t = (TermHolder) li.next();
834: factor = Math.max(t.frequency, factor);
835: }
836:
837: for (Iterator li = l.iterator(); li.hasNext();) {
838: final TermHolder t = (TermHolder) li.next();
839: float f = (topTerms * t.frequency) / factor;
840: if (relativeTerms) {
841: f = (topTerms * (l.size() - t.position)) / l.size();
842: }
843: f = f / divisorTerms;
844: j--;
845: final String weight = String.valueOf(f);
846: finalTermList.add(new SearchTerm() {
847:
848: public String getName() {
849: return FormattedText.escapeHtml(t.term, false);
850: }
851:
852: public String getUrl() {
853: try {
854: return FormattedText.escapeHtml(
855: "?panel=Main&search="
856: + URLEncoder.encode(t.term,
857: "UTF-8"), false);
858: } catch (UnsupportedEncodingException e) {
859: return FormattedText.escapeHtml(
860: "?panel=Main&search="
861: + URLEncoder.encode(t.term),
862: false);
863:
864: }
865: }
866:
867: public String getWeight() {
868: return weight;
869: }
870: });
871: }
872: return finalTermList;
873: }
874:
875: /*
876: * (non-Javadoc)
877: *
878: * @see org.sakaiproject.search.tool.SearchBean#hasError()
879: */
880: public boolean hasError() {
881: return (errorMessage != null);
882: }
883:
884: /*
885: * (non-Javadoc)
886: *
887: * @see org.sakaiproject.search.tool.SearchBean#getErrorMessage()
888: */
889: public String getErrorMessage() {
890: return FormattedText.escapeHtml(errorMessage, false);
891: }
892:
893: /*
894: * (non-Javadoc)
895: *
896: * @see org.sakaiproject.search.tool.api.SearchBean#getRssUrl()
897: */
898: public String getRssURL() {
899: if (hasResults()) {
900:
901: try {
902: return FormattedText.escapeHtml(getToolUrl()
903: + "/rss20?search="
904: + URLEncoder.encode(search, "UTF-8"), false);
905: } catch (UnsupportedEncodingException e) {
906: return FormattedText.escapeHtml(getToolUrl()
907: + "/rss20?search=" + URLEncoder.encode(search),
908: false);
909: }
910: } else {
911: return null;
912: }
913: }
914:
915: /* (non-Javadoc)
916: * @see org.sakaiproject.search.tool.api.SearchBean#getDateNow()
917: */
918: public String getDateNow() {
919: SimpleDateFormat format = new SimpleDateFormat(
920: "EEE, dd MMM yyyy HH:mm:ss z");
921: return format.format(new Date(System.currentTimeMillis()));
922: }
923:
924: /* (non-Javadoc)
925: * @see org.sakaiproject.search.tool.api.SearchBean#getRequestUrl()
926: */
927: public String getRequestUrl() {
928: return FormattedText.escapeHtml(requestURL, false);
929: }
930:
931: }
|