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