001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2005 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (at your option) any later version.
010:
011: This program is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.ecyrd.jspwiki.search;
021:
022: import java.io.IOException;
023: import java.util.Collection;
024: import java.util.Iterator;
025: import java.util.Properties;
026: import java.util.StringTokenizer;
027: import java.util.TreeSet;
028:
029: import org.apache.log4j.Logger;
030:
031: import com.ecyrd.jspwiki.NoRequiredPropertyException;
032: import com.ecyrd.jspwiki.QueryItem;
033: import com.ecyrd.jspwiki.SearchMatcher;
034: import com.ecyrd.jspwiki.SearchResult;
035: import com.ecyrd.jspwiki.SearchResultComparator;
036: import com.ecyrd.jspwiki.WikiEngine;
037: import com.ecyrd.jspwiki.WikiPage;
038: import com.ecyrd.jspwiki.attachment.Attachment;
039: import com.ecyrd.jspwiki.providers.ProviderException;
040: import com.ecyrd.jspwiki.providers.WikiPageProvider;
041:
042: /**
043: * Interface for the search providers that handle searching the Wiki
044: *
045: * @author Arent-Jan Banck
046: * @since 2.2.21.
047: */
048: public class BasicSearchProvider implements SearchProvider {
049: private static final Logger log = Logger
050: .getLogger(BasicSearchProvider.class);
051:
052: private WikiEngine m_engine;
053:
054: public void initialize(WikiEngine engine, Properties props)
055: throws NoRequiredPropertyException, IOException {
056: m_engine = engine;
057: }
058:
059: public void pageRemoved(WikiPage page) {
060: }
061:
062: public void reindexPage(WikiPage page) {
063: }
064:
065: public QueryItem[] parseQuery(String query) {
066: StringTokenizer st = new StringTokenizer(query, " \t,");
067:
068: QueryItem[] items = new QueryItem[st.countTokens()];
069: int word = 0;
070:
071: log.debug("Expecting " + items.length + " items");
072:
073: //
074: // Parse incoming search string
075: //
076:
077: while (st.hasMoreTokens()) {
078: log.debug("Item " + word);
079: String token = st.nextToken().toLowerCase();
080:
081: items[word] = new QueryItem();
082:
083: switch (token.charAt(0)) {
084: case '+':
085: items[word].type = QueryItem.REQUIRED;
086: token = token.substring(1);
087: log.debug("Required word: " + token);
088: break;
089:
090: case '-':
091: items[word].type = QueryItem.FORBIDDEN;
092: token = token.substring(1);
093: log.debug("Forbidden word: " + token);
094: break;
095:
096: default:
097: items[word].type = QueryItem.REQUESTED;
098: log.debug("Requested word: " + token);
099: break;
100: }
101:
102: items[word++].word = token;
103: }
104:
105: return items;
106: }
107:
108: private String attachmentNames(WikiPage page, String separator) {
109: if (m_engine.getAttachmentManager().hasAttachments(page)) {
110: Collection attachments;
111: try {
112: attachments = m_engine.getAttachmentManager()
113: .listAttachments(page);
114: } catch (ProviderException e) {
115: log.error("Unable to get attachments for page", e);
116: return "";
117: }
118:
119: StringBuffer attachmentNames = new StringBuffer();
120: for (Iterator it = attachments.iterator(); it.hasNext();) {
121: Attachment att = (Attachment) it.next();
122: attachmentNames.append(att.getName());
123: if (it.hasNext())
124: attachmentNames.append(separator);
125: }
126: return attachmentNames.toString();
127: }
128:
129: return "";
130: }
131:
132: private Collection findPages(QueryItem[] query) {
133: TreeSet res = new TreeSet(new SearchResultComparator());
134: SearchMatcher matcher = new SearchMatcher(m_engine, query);
135:
136: Collection allPages = null;
137: try {
138: allPages = m_engine.getPageManager().getAllPages();
139: } catch (ProviderException pe) {
140: log.error("Unable to retrieve page list", pe);
141: return null;
142: }
143:
144: Iterator it = allPages.iterator();
145: while (it.hasNext()) {
146: try {
147: WikiPage page = (WikiPage) it.next();
148: if (page != null) {
149: String pageName = page.getName();
150: String pageContent = m_engine.getPageManager()
151: .getPageText(pageName,
152: WikiPageProvider.LATEST_VERSION)
153: + attachmentNames(page, " ");
154: SearchResult comparison = matcher.matchPageContent(
155: pageName, pageContent);
156:
157: if (comparison != null) {
158: res.add(comparison);
159: }
160: }
161: } catch (ProviderException pe) {
162: log.error("Unable to retrieve page from cache", pe);
163: } catch (IOException ioe) {
164: log.error("Failed to search page", ioe);
165: }
166: }
167:
168: return res;
169: }
170:
171: public Collection findPages(String query) {
172: return findPages(parseQuery(query));
173: }
174:
175: /**
176: * @see com.ecyrd.jspwiki.WikiProvider#getProviderInfo()
177: */
178: public String getProviderInfo() {
179: return "BasicSearchProvider";
180: }
181:
182: }
|