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.Engine;
023import org.apache.wiki.api.exceptions.PluginException;
024import org.apache.wiki.plugin.PluginManager;
025
026import javax.servlet.jsp.JspException;
027import javax.servlet.jsp.tagext.BodyContent;
028import java.io.IOException;
029import java.util.Map;
030
031/**
032 *  Inserts any Wiki plugin.  The body of the tag becomes then
033 *  the body for the plugin.
034 *  <P><B>Attributes</B></P>
035 *  <UL>
036 *    <LI>plugin - name of the plugin you want to insert.
037 *    <LI>args   - An argument string for the tag.
038 *  </UL>
039 *
040 *  @since 2.0
041 */
042public class PluginTag
043    extends WikiBodyTag
044{
045    private static final long serialVersionUID = 0L;
046    private static final Logger log = Logger.getLogger( PluginTag.class );
047    
048    private String m_plugin;
049    private String m_args;
050
051    private boolean m_evaluated = false;
052
053    /**
054     *  {@inheritDoc}
055     */
056    @Override
057    public void release()
058    {
059        super.release();
060        m_plugin = m_args = null;
061        m_evaluated = false;
062    }
063    
064    /**
065     *  Set the name of the plugin to execute.
066     *  
067     *  @param p Name of the plugin.
068     */
069    public void setPlugin( final String p )
070    {
071        m_plugin = p;
072    }
073
074    /**
075     *  Set the argument string to the plugin.
076     *  
077     *  @param a Arguments string.
078     */
079    public void setArgs( final String a )
080    {
081        m_args = a;
082    }
083    
084    /**
085     *  {@inheritDoc}
086     */
087    @Override
088    public int doWikiStartTag() throws JspException, IOException
089    {
090        m_evaluated = false;
091        return EVAL_BODY_BUFFERED;
092    }
093
094    private String executePlugin( final String plugin, final String args, final String body ) throws PluginException, IOException {
095        final Engine engine = m_wikiContext.getEngine();
096        final PluginManager pm  = engine.getManager( PluginManager.class );
097
098        m_evaluated = true;
099
100        final Map<String, String> argmap = pm.parseArgs( args );
101        
102        if( body != null ) 
103        {
104            argmap.put( "_body", body );
105        }
106
107        return pm.execute( m_wikiContext, plugin, argmap );
108    }
109    
110    /**
111     *  {@inheritDoc}
112     */
113    @Override
114    public int doEndTag()
115        throws JspException
116    {
117        if( !m_evaluated )
118        {
119            try
120            {
121                pageContext.getOut().write( executePlugin( m_plugin, m_args, null ) );
122            }
123            catch( final Exception e )
124            {
125                log.error( "Failed to insert plugin", e );
126                throw new JspException( "Tag failed, check logs: "+e.getMessage() );
127            }
128        }
129        return EVAL_PAGE;
130    }
131    
132    /**
133     *  {@inheritDoc}
134     */
135    @Override
136    public int doAfterBody()
137        throws JspException
138    {
139        try
140        {
141            final BodyContent bc = getBodyContent();
142            
143            getPreviousOut().write( executePlugin( m_plugin, m_args, (bc != null) ? bc.getString() : null) );
144        }
145        catch( final Exception e )
146        {
147            log.error( "Failed to insert plugin", e );
148            throw new JspException( "Tag failed, check logs: "+e.getMessage() );
149        }
150        
151        return SKIP_BODY;
152    }
153}