001 /* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019 package org.apache.wiki.search; 020 021 import java.io.IOException; 022 import java.util.Collection; 023 import java.util.Iterator; 024 import java.util.Properties; 025 import java.util.StringTokenizer; 026 import java.util.TreeSet; 027 028 import org.apache.log4j.Logger; 029 import org.apache.wiki.WikiEngine; 030 import org.apache.wiki.WikiPage; 031 import org.apache.wiki.api.exceptions.NoRequiredPropertyException; 032 import org.apache.wiki.api.exceptions.ProviderException; 033 import org.apache.wiki.attachment.Attachment; 034 import org.apache.wiki.providers.WikiPageProvider; 035 036 /** 037 * Interface for the search providers that handle searching the Wiki 038 * 039 * @since 2.2.21. 040 */ 041 public class BasicSearchProvider implements SearchProvider 042 { 043 private static final Logger log = Logger.getLogger(BasicSearchProvider.class); 044 045 private WikiEngine m_engine; 046 047 /** 048 * {@inheritDoc} 049 */ 050 public void initialize(WikiEngine engine, Properties props) 051 throws NoRequiredPropertyException, IOException 052 { 053 m_engine = engine; 054 } 055 056 /** 057 * {@inheritDoc} 058 */ 059 public void pageRemoved(WikiPage page) {} 060 061 /** 062 * {@inheritDoc} 063 */ 064 public void reindexPage(WikiPage page) {} 065 066 /** 067 * Parses a query into something that we can use. 068 * 069 * @param query A query string. 070 * @return A parsed array. 071 */ 072 public QueryItem[] parseQuery(String query) 073 { 074 StringTokenizer st = new StringTokenizer( query, " \t," ); 075 076 QueryItem[] items = new QueryItem[st.countTokens()]; 077 int word = 0; 078 079 log.debug("Expecting "+items.length+" items"); 080 081 // 082 // Parse incoming search string 083 // 084 085 while( st.hasMoreTokens() ) 086 { 087 log.debug("Item "+word); 088 String token = st.nextToken().toLowerCase(); 089 090 items[word] = new QueryItem(); 091 092 switch( token.charAt(0) ) 093 { 094 case '+': 095 items[word].type = QueryItem.REQUIRED; 096 token = token.substring(1); 097 log.debug("Required word: "+token); 098 break; 099 100 case '-': 101 items[word].type = QueryItem.FORBIDDEN; 102 token = token.substring(1); 103 log.debug("Forbidden word: "+token); 104 break; 105 106 default: 107 items[word].type = QueryItem.REQUESTED; 108 log.debug("Requested word: "+token); 109 break; 110 } 111 112 items[word++].word = token; 113 } 114 115 return items; 116 } 117 118 private String attachmentNames(WikiPage page, String separator) 119 { 120 if(m_engine.getAttachmentManager().hasAttachments(page)) 121 { 122 Collection attachments; 123 try 124 { 125 attachments = m_engine.getAttachmentManager().listAttachments(page); 126 } 127 catch (ProviderException e) 128 { 129 log.error("Unable to get attachments for page", e); 130 return ""; 131 } 132 133 StringBuffer attachmentNames = new StringBuffer(); 134 for( Iterator it = attachments.iterator(); it.hasNext(); ) 135 { 136 Attachment att = (Attachment) it.next(); 137 attachmentNames.append(att.getName()); 138 if(it.hasNext()) 139 attachmentNames.append(separator); 140 } 141 return attachmentNames.toString(); 142 } 143 144 return ""; 145 } 146 147 private Collection findPages( QueryItem[] query ) 148 { 149 TreeSet<SearchResult> res = new TreeSet<SearchResult>( new SearchResultComparator() ); 150 SearchMatcher matcher = new SearchMatcher( m_engine, query ); 151 152 Collection allPages = null; 153 try 154 { 155 allPages = m_engine.getPageManager().getAllPages(); 156 } 157 catch( ProviderException pe ) 158 { 159 log.error( "Unable to retrieve page list", pe ); 160 return null; 161 } 162 163 Iterator it = allPages.iterator(); 164 while( it.hasNext() ) 165 { 166 try 167 { 168 WikiPage page = (WikiPage) it.next(); 169 if (page != null) 170 { 171 String pageName = page.getName(); 172 String pageContent = m_engine.getPageManager().getPageText(pageName, WikiPageProvider.LATEST_VERSION) + 173 attachmentNames(page, " "); 174 SearchResult comparison = matcher.matchPageContent( pageName, pageContent ); 175 176 if( comparison != null ) 177 { 178 res.add( comparison ); 179 } 180 } 181 } 182 catch( ProviderException pe ) 183 { 184 log.error( "Unable to retrieve page from cache", pe ); 185 } 186 catch( IOException ioe ) 187 { 188 log.error( "Failed to search page", ioe ); 189 } 190 } 191 192 return res; 193 } 194 195 /** 196 * {@inheritDoc} 197 */ 198 public Collection findPages(String query) 199 { 200 return findPages(parseQuery(query)); 201 } 202 203 /** 204 * {@inheritDoc} 205 */ 206 public String getProviderInfo() 207 { 208 return "BasicSearchProvider"; 209 } 210 211 }