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