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.tags; 020 021import org.apache.logging.log4j.LogManager; 022import org.apache.logging.log4j.Logger; 023import org.apache.wiki.api.core.Command; 024import org.apache.wiki.api.core.Context; 025import org.apache.wiki.api.core.Engine; 026import org.apache.wiki.api.search.SearchResult; 027import org.apache.wiki.api.spi.Wiki; 028import org.apache.wiki.ui.PageCommand; 029 030import javax.servlet.http.HttpServletRequest; 031import javax.servlet.jsp.JspWriter; 032import javax.servlet.jsp.PageContext; 033import java.io.IOException; 034import java.util.Collection; 035 036/** 037 * Iterates through Search result results. 038 * 039 * <P><B>Attributes</B></P> 040 * <UL> 041 * <LI>max = how many search results should be shown. 042 * </UL> 043 * 044 * @since 2.0 045 */ 046// FIXME: Shares MUCH too much in common with IteratorTag. Must refactor. 047public class SearchResultIteratorTag extends IteratorTag { 048 049 private static final long serialVersionUID = 0L; 050 051 private int m_maxItems; 052 private int m_count; 053 private int m_start; 054 055 private static final Logger log = LogManager.getLogger(SearchResultIteratorTag.class); 056 057 /** {@inheritDoc} */ 058 @Override 059 public void release() { 060 super.release(); 061 m_maxItems = m_count = 0; 062 } 063 064 public void setMaxItems( final int arg ) 065 { 066 m_maxItems = arg; 067 } 068 069 public void setStart( final int arg ) 070 { 071 m_start = arg; 072 } 073 074 /** {@inheritDoc} */ 075 @Override 076 public final int doStartTag() { 077 // Do lazy eval if the search results have not been set. 078 if( m_iterator == null ) { 079 final Collection< ? > searchresults = (Collection< ? >)pageContext.getAttribute( "searchresults", PageContext.REQUEST_SCOPE ); 080 setList( searchresults ); 081 082 int skip = 0; 083 084 // Skip the first few ones... 085 m_iterator = searchresults.iterator(); 086 while( m_iterator.hasNext() && (skip++ < m_start) ) { 087 m_iterator.next(); 088 } 089 } 090 091 m_count = 0; 092 m_wikiContext = ( Context )pageContext.getAttribute( Context.ATTR_CONTEXT, PageContext.REQUEST_SCOPE ); 093 094 return nextResult(); 095 } 096 097 private int nextResult() { 098 if( m_iterator != null && m_iterator.hasNext() && m_count++ < m_maxItems ) { 099 final SearchResult r = ( SearchResult )m_iterator.next(); 100 101 // Create a wiki context for the result 102 final Engine engine = m_wikiContext.getEngine(); 103 final HttpServletRequest request = m_wikiContext.getHttpRequest(); 104 final Command command = PageCommand.VIEW.targetedCommand( r.getPage() ); 105 final Context context = Wiki.context().create( engine, request, command ); 106 107 // Stash it in the page context 108 pageContext.setAttribute( Context.ATTR_CONTEXT, context, PageContext.REQUEST_SCOPE ); 109 pageContext.setAttribute( getId(), r ); 110 111 return EVAL_BODY_BUFFERED; 112 } 113 114 return SKIP_BODY; 115 } 116 117 /** {@inheritDoc} */ 118 @Override 119 public int doAfterBody() { 120 if( bodyContent != null ) { 121 try { 122 final JspWriter out = getPreviousOut(); 123 out.print(bodyContent.getString()); 124 bodyContent.clearBody(); 125 } catch( final IOException e ) { 126 log.error("Unable to get inner tag text", e); 127 // FIXME: throw something? 128 } 129 } 130 131 return nextResult(); 132 } 133 134 /** {@inheritDoc} */ 135 @Override 136 public int doEndTag() { 137 m_iterator = null; 138 return super.doEndTag(); 139 } 140 141}