    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}