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", 082 PageContext.REQUEST_SCOPE ); 083 setList( searchresults ); 084 085 int skip = 0; 086 087 // Skip the first few ones... 088 m_iterator = searchresults.iterator(); 089 while( m_iterator.hasNext() && (skip++ < m_start) ) m_iterator.next(); 090 } 091 092 m_count = 0; 093 m_wikiContext = (WikiContext) pageContext.getAttribute( WikiTagBase.ATTR_CONTEXT, 094 PageContext.REQUEST_SCOPE ); 095 096 return nextResult(); 097 } 098 099 private int nextResult() 100 { 101 if( m_iterator != null && m_iterator.hasNext() && m_count++ < m_maxItems ) 102 { 103 SearchResult r = (SearchResult) m_iterator.next(); 104 105 // Create a wiki context for the result 106 WikiEngine engine = m_wikiContext.getEngine(); 107 HttpServletRequest request = m_wikiContext.getHttpRequest(); 108 Command command = PageCommand.VIEW.targetedCommand( r.getPage() ); 109 WikiContext context = new WikiContext( engine, request, command ); 110 111 // Stash it in the page context 112 pageContext.setAttribute( WikiTagBase.ATTR_CONTEXT, 113 context, 114 PageContext.REQUEST_SCOPE ); 115 pageContext.setAttribute( getId(), r ); 116 117 return EVAL_BODY_BUFFERED; 118 } 119 120 return SKIP_BODY; 121 } 122 123 public int doAfterBody() 124 { 125 if( bodyContent != null ) 126 { 127 try 128 { 129 JspWriter out = getPreviousOut(); 130 out.print(bodyContent.getString()); 131 bodyContent.clearBody(); 132 } 133 catch( IOException e ) 134 { 135 log.error("Unable to get inner tag text", e); 136 // FIXME: throw something? 137 } 138 } 139 140 return nextResult(); 141 } 142 143 public int doEndTag() 144 { 145 m_iterator = null; 146 147 return super.doEndTag(); 148 } 149}