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