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*/ 019package org.apache.wiki.plugin; 020 021import org.apache.log4j.Logger; 022import org.apache.wiki.api.core.Context; 023import org.apache.wiki.api.core.ContextEnum; 024import org.apache.wiki.api.core.Engine; 025import org.apache.wiki.api.exceptions.PluginException; 026import org.apache.wiki.api.exceptions.ProviderException; 027import org.apache.wiki.api.plugin.Plugin; 028import org.apache.wiki.api.search.SearchResult; 029import org.apache.wiki.render.RenderingManager; 030import org.apache.wiki.search.SearchManager; 031import org.apache.wiki.util.XHTML; 032import org.apache.wiki.util.XhtmlUtil; 033import org.jdom2.Element; 034 035import java.io.IOException; 036import java.util.Collection; 037import java.util.Iterator; 038import java.util.Map; 039 040/** 041 * The "Search" plugin allows you to access the JSPWiki search routines and show the displays in an array on your page. 042 * 043 * <p>Parameters : </p> 044 * <ul> 045 * <li><b>query</b> - String. A standard JSPWiki search query.</li> 046 * <li><b>set</b> - String. The JSPWiki context variable that will hold the results of the query. This allows you to pass your queries to other plugins on the same page as well. </li> 047 * <li><b>max</b> - Integer. How many search results are shown at maximum.</li> 048 * </ul> 049 * 050 * @since 051 */ 052public class Search implements Plugin { 053 054 private static final Logger log = Logger.getLogger(Search.class); 055 056 /** Parameter name for setting the query string. Value is <tt>{@value}</tt>. */ 057 public static final String PARAM_QUERY = "query"; 058 059 /** Parameter name for setting the name of the set where the results are stored. Value is <tt>{@value}</tt>. */ 060 public static final String PARAM_SET = "set"; 061 062 /** The default name of the result set. */ 063 public static final String DEFAULT_SETNAME = "_defaultSet"; 064 065 /** The parameter name for setting the how many results will be fetched. Value is <tt>{@value}</tt>. */ 066 public static final String PARAM_MAX = "max"; 067 068 /** 069 * {@inheritDoc} 070 */ 071 @Override 072 public String execute( final Context context, final Map<String, String> params ) throws PluginException { 073 int maxItems = Integer.MAX_VALUE; 074 final Collection< SearchResult > results; 075 076 final String queryString = params.get( PARAM_QUERY ); 077 String set = params.get( PARAM_SET ); 078 final String max = params.get( PARAM_MAX ); 079 080 if ( set == null ) set = DEFAULT_SETNAME; 081 if ( max != null ) maxItems = Integer.parseInt( max ); 082 083 if ( queryString == null ) { 084 results = context.getVariable( set ); 085 } else { 086 try { 087 results = doBasicQuery( context, queryString ); 088 context.setVariable( set, results ); 089 } catch( final Exception e ) { 090 return "<div class='error'>" + e.getMessage() + "</div>\n"; 091 } 092 } 093 094 String res = ""; 095 096 if ( results != null ) { 097 res = renderResults(results,context,maxItems); 098 } 099 100 return res; 101 } 102 103 private Collection<SearchResult> doBasicQuery( final Context context, final String query ) throws ProviderException, IOException { 104 log.debug( "Searching for string " + query ); 105 return context.getEngine().getManager( SearchManager.class ).findPages( query, context ); 106 } 107 108 private String renderResults( final Collection<SearchResult> results, final Context context, final int maxItems ) { 109 final Engine engine = context.getEngine(); 110 111 final Element table = XhtmlUtil.element(XHTML.table); 112 //table.setAttribute(XHTML.ATTR_border,"0"); 113 //table.setAttribute(XHTML.ATTR_cellpadding,"4"); 114 table.setAttribute(XHTML.ATTR_class,"wikitable search-result"); 115 116 Element row = XhtmlUtil.element(XHTML.tr); 117 table.addContent(row); 118 119 final Element th1 = XhtmlUtil.element(XHTML.th,"Page"); 120 th1.setAttribute(XHTML.ATTR_width,"30%"); 121 th1.setAttribute(XHTML.ATTR_align,"left"); 122 row.addContent(th1); 123 124 final Element th2 = XhtmlUtil.element(XHTML.th,"Score"); 125 th2.setAttribute(XHTML.ATTR_align,"left"); 126 row.addContent(th2); 127 128 int idx = 0; 129 for ( final Iterator<SearchResult> i = results.iterator(); i.hasNext() && idx++ <= maxItems; ) { 130 final SearchResult sr = i.next(); 131 row = XhtmlUtil.element(XHTML.tr); 132 133 final Element name = XhtmlUtil.element(XHTML.td); 134 name.setAttribute(XHTML.ATTR_width,"30%"); 135 136 name.addContent( XhtmlUtil.link(context.getURL( ContextEnum.PAGE_VIEW.getRequestContext(), sr.getPage().getName() ), 137 engine.getManager( RenderingManager.class ).beautifyTitle(sr.getPage().getName() ) ) ); 138 139 row.addContent(name); 140 141 row.addContent(XhtmlUtil.element(XHTML.td,""+sr.getScore())); 142 143 table.addContent(row); 144 } 145 146 if ( results.isEmpty() ) { 147 row = XhtmlUtil.element(XHTML.tr); 148 149 final Element td = XhtmlUtil.element(XHTML.td); 150 td.setAttribute(XHTML.ATTR_colspan,"2"); 151 final Element b = XhtmlUtil.element(XHTML.b,"No results"); 152 td.addContent(b); 153 154 row.addContent(td); 155 156 table.addContent(row); 157 } 158 159 return XhtmlUtil.serialize(table); 160 } 161}