/*  Copyright (c) 2000, 2003, Oracle Corporation. All Rights Reserved. */

package oracle.portal.provider.v2.render;

import java.io.Writer;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Enumeration;

import oracle.portal.provider.v2.PortletException;
import oracle.portal.utils.v2.ParameterMap;
import oracle.portal.utils.v2.SimpleParameterMap;

import oracle.portal.log.LogManager;
import oracle.portal.provider.v2.monitor.PerfMonitor;

/**
 *  A PortletContainerRenderer is a utility class that renders the container
 *  for a portlet.
 * 
 *  The container that is renderered may vary depending on the SHOW mode that
 *  is being requested. For example, Edit, Edit Defaults. Help, About, and 
 *  Show Details are all rendered in "full screen" mode whereas the regular
 *  Show and Preview modes have variable size containers depending on the 
 *  size of the portlet. 
 */
public abstract class PortletContainerRenderer 
{
    /**
     * This is the key used in the parameter map of the render methods in this
     * class to override the portlet title to be rendered. It should be mapped to a
     * value of type <code>java.lang.String</code>. If not specified in the
     * map, this defaults to the customized portlet title or portlet title in
     * provider.xml in SHOW mode and a mode specific title describing the mode
     * in other modes.
     */
    public static final String PORTLET_TITLE = "_portletTitle";

    /**
     * This is the key used in the parameter map of the render methods in this
     * class to override the mode to be rendered. It should be mapped to one of
     * the integer mode values in {@link PortletRenderer}, wrapped as a
     * <code>java.lang.Integer</code>.  If not specified in the map, the render
     * mode will be determined from the PortletRenderRequest.  This parameter
     * is included for backwards compatibility with {@link
     * PortletRendererUtil#renderPortletHeader(PortletRenderRequest,
     * java.io.Writer, String, int)}.
     */
    public static final String RENDER_MODE = "_renderMode";

    /**
     * This is the key used in the parameter map of the render methods in this
     * class to specify whether a header should be rendered when the mode to be
     * rendered is EDIT or EDIT_DEFAULTS. It should be mapped to a value of type
     * <code>java.lang.Boolean</code>. When <code>true</code> (the default), a
     * header and footer are rendered in EDIT mode.
     */
    public static final String RENDER_CUSTOMIZE = "_renderCustomize";

    /**
     * This is the key used in the parameter map of the render methods in this
     * class to override the name of the edit form object (as referenced by
     * javascript code) when the mode to be rendered is EDIT or
     * EDIT_DEFAULTS. It should be mapped to a value of type
     * <code>java.lang.String</code>. If not specified in the map, this
     * defaults to the value {@link #CUSTOMIZE_FORM_NAME}.
     */
    public static final String EDIT_FORM_NAME = "_editFormName";

    /**
     * This is the key used in the parameter map of the render methods in this
     * class to override the name of the hidden field that indicates the button
     * clicked in EDIT or EDIT_DEFAULTS mode (<code>"OK"</code> or
     * <code>"APPLY"</code>). It should be mapped to a value of type
     * <code>java.lang.String</code>. If not specified in the map, this
     * defaults to the value {@link #DEFAULT_ACTION_PARAM}.
     */
    public static final String ACTION_PARAM_NAME = "_actionParamName";

    /**
     * This is the key used in the parameter map of the render methods in this
     * class to pass a URL that displays context sensitive help for the current
     * screen (does not apply in SHOW mode). Note that this is <b>not</b> the
     * URL that is used to access the portlet's HELP mode.  It should be mapped
     * to a value of type <code>java.lang.String</code>. If not specified in
     * the map, no context sensitive help link is generated.
     */
    public static final String HELP_URL = "_helpURL";

    /**
     * This is the key used in the parameter map of the render methods in this
     * class to specify the <code>Writer</code> to output to. It should be
     * mapped to a value of type <code>java.io.Writer</code>. If not specified
     * in the map, the <code>PrintWriter</code> returned by {@link
     * PortletRenderRequest#getWriter()} will be used.  If you are calling
     * RenderPortletHeader or RenderPortletFooter from a JSP, it is important
     * that you use the same Writer to render all the JSP content - either the
     * JSPWriter or PortletRenderRequest.getWriter().  Mixing writers can cause
     * output to be displayed out of sequence due to buffering in the
     * JSPWriter.
     */
    public static final String PRINT_WRITER = "_printWriter";

    /**
     * Default form name.
     * This value is used for the customize form name if a value is not supplid
     * in the parameter map
     */
    public static final String CUSTOMIZE_FORM_NAME = "custform";

    /**
     * Default action parameter name.
     * This value is used for the name of the hidden field that will capture the
     * form action (button pressed) if a value is not supplied by the caller
     * in the parameter map
     */
    public static final String DEFAULT_ACTION_PARAM = "action";

    /**
     * Renders a portlet header.<p>
     * 
     * The container that is rendered should be dependent on the mode that is
     * being renderered
     *
     * @param pr PortletRenderRequest for this rendering.
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be <code>null</code> if the default
     * rendering behaviour is acceptable. Keys should be one of the string key
     * constants defined in this class. See the description of each key
     * constant for acceptable mapped values.
     */
    public void renderPortletHeader(PortletRenderRequest request,
                                    Map params)
        throws PortletException
    {
        LogManager.debug("Entering PortletContainerRenderer." +
                         "renderPortletHeader");
        
        PerfMonitor monitor = request.getRenderContext().getPerfMonitor();
        monitor.startTimer(PerfMonitor.RENDER_HEADER_TIMER);
        
        // Don't render headers / footers for mobile devices
        if(!request.getContentType().equals(PortletRenderer.TYPE_HTML))
        {
            LogManager.debug("Leaving PortletContainerRenderer." +
                             "renderPortletHeader");
            return;
        }
        
        PrintWriter writer = null;
        int renderMode = request.getMode();
        try
        {
            if (params == null)
            {
                // params was sent in as null - create a parameter map so we
                // don't have to keep checking for null in all subroutines.
                params = new HashMap(1);
                writer = request.getWriter();
            }
            else
            {
                // Make sure we use the appropriate writer object.
                writer = getPrintWriter(request, params);

                Integer renderModeObj = (Integer)params.get(RENDER_MODE);
                if (renderModeObj != null)
                {
                    renderMode = renderModeObj.intValue();
                }
            }

            switch (renderMode)
            {
            case PortletRenderer.MODE_SHOW:
                renderShowHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_PREVIEW:
                renderPreviewHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_ABOUT:
                renderAboutHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_HELP:
                renderHelpHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_EDIT:
                renderEditHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_EDIT_DEFAULTS:
                renderEditDefaultsHeader(request, writer, params);
                break;
            case PortletRenderer.MODE_SHOW_DETAILS:
                renderDetailsHeader(request, writer, params);
                break;
            }
        }
        catch (Exception e)
        {
            throw new PortletException(e);
        }

        monitor.finishTimer(PerfMonitor.RENDER_HEADER_TIMER);

        LogManager.debug("Leaving PortletContainerRenderer." +
                         "renderPortletHeader");
    }

    /** Renders a portlet footer.
     *
     * The container that is rendered should be dependent on the mode that is
     * being renderered
     *
     * @param request PortletRenderRequest for this rendering
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be <code>null</code> if the default
     * rendering behaviour is acceptable. Keys should be one of the string key
     * constants defined in this class. See the description of each key
     * constant for acceptable mapped values.
     */
    public void renderPortletFooter(PortletRenderRequest request,
                                    Map params)
        throws PortletException
    {
        LogManager.debug("Entering PortletContainerRenderer." +
                         "renderPortletFooter");
        
        PerfMonitor monitor = request.getRenderContext().getPerfMonitor();
        monitor.startTimer(PerfMonitor.RENDER_FOOTER_TIMER);

        // Don't render headers / footers for mobile devices
        if(!request.getContentType().equals(PortletRenderer.TYPE_HTML))
        {
            LogManager.debug("Leaving PortletContainerRenderer." +
                             "renderPortletFooter");
            return;
        }

        PrintWriter writer = null;
        int renderMode = request.getMode();
        try
        {
            if (params == null)
            {
                // params was sent in as null - create a parameter map so we
                // don't have to keep checking for null in all subroutines.
                params = new HashMap(1);
                writer = request.getWriter();
            }
            else
            {
                // Make sure we use the appropriate writer object.
                writer = getPrintWriter(request, params);

                Integer renderModeObj = (Integer)params.get(RENDER_MODE);
                if (renderModeObj != null)
                {
                    renderMode = renderModeObj.intValue();
                }
            }

            switch (renderMode)
            {
            case PortletRenderer.MODE_SHOW:
                renderShowFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_PREVIEW:
                renderPreviewFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_ABOUT:
                renderAboutFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_HELP:
                renderHelpFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_EDIT:
                renderEditFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_EDIT_DEFAULTS:
                renderEditDefaultsFooter(request, writer, params);
                break;
            case PortletRenderer.MODE_SHOW_DETAILS:
                renderDetailsFooter(request, writer, params);
                break;
            }
        }
        catch(Exception e)
        {
            throw new PortletException(e);
        }

        monitor.finishTimer(PerfMonitor.RENDER_FOOTER_TIMER);
        LogManager.debug("Leaving PortletContainerRenderer." +
                         "renderPortletFooter");
    }



    /**
     * Renders the header for the portlet SHOW mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderShowHeader(PortletRenderRequest request,
                                 PrintWriter out,
                                 Map params)
        throws PortletException, IOException
    {
        // override this method to create your show header
    }


    /**
     * Renders the footer for the portlet SHOW mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderShowFooter(PortletRenderRequest request,
                                 PrintWriter out,
                                 Map params)
        throws PortletException, IOException
    {
        // override this method to create your SHOW footer here
    }

    /**
     * Renders the header for the portlet PREVIEW mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderPreviewHeader(PortletRenderRequest request,
                                    PrintWriter out,
                                    Map params)
        throws PortletException, IOException
    {
        // override this method to create your preview header here.
        // Preview is usually the same as SHOW but links are not active
    }


    /**
     * Renders the footer for the portlet PREVIEW mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderPreviewFooter(PortletRenderRequest request,
                                    PrintWriter out,
                                    Map params)
        throws PortletException, IOException
    {
        // override this method to create your preview footer
        // Preview is usually the same as SHOW but links are not active
    }

    /**
     * Renders the header for the portlet SHOW_DETAILS mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderDetailsHeader(PortletRenderRequest request,
                                    PrintWriter out,
                                    Map params)
        throws PortletException, IOException
    {
        // override this method to create your header for show details
    }


    /**
     * Renders the footer for the portlet SHOW_DETAILS mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderDetailsFooter(PortletRenderRequest request,
                                    PrintWriter out,
                                    Map params)
        throws PortletException, IOException
    {
        // override this method to create your footer for show details
    }


    /**
     * Renders the header for the portlet EDIT mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderEditHeader(PortletRenderRequest request,
                                 PrintWriter out,
                                 Map params)
        throws PortletException, IOException
    {
        // override this method to create your edit header
        // EDIT and EDIT_DEFAULTS usually use the same container
    }


    /**
     * Renders the footer for the portlet EDIT mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderEditFooter(PortletRenderRequest request,
                                 PrintWriter out,
                                 Map params)
        throws PortletException, IOException
    {
        // override this method to create your edit footer
        // EDIT and EDIT_DEFAULTS usually use the same container
    }


    /**
     * Renders the header for the portlet EDIT_DEFAULTS mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderEditDefaultsHeader(PortletRenderRequest request,
                                         PrintWriter out,
                                         Map params)
        throws PortletException, IOException
    {
        // override this method to create your edit defaults header
        // EDIT and EDIT_DEFAULTS usually use the same container
    }


    /**
     * Renders the footer for the portlet EDIT_DEFAULTS mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderEditDefaultsFooter(PortletRenderRequest request,
                                         PrintWriter out,
                                         Map params)
        throws PortletException, IOException
    {
        // override this method to create your edit defaults footer
        // EDIT and EDIT_DEFAULTS usually use the same container
    }


    /**
     * Renders the header for the portlet HELP mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderHelpHeader(PortletRenderRequest request,
                                 PrintWriter out,
                                 Map params)
        throws PortletException, IOException
    {
        // override this method to create your help header
        // HELP and ABOUT usually use the same container
    }


    /**
     * Renders the footer for the portlet HELP mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderHelpFooter(PortletRenderRequest request,
                                 PrintWriter out,
                                 Map params)
        throws PortletException, IOException
    {
        // override this method to create your help footer
        // HELP and ABOUT usually use the same container
    }


    /**
     * Renders the header for the portlet ABOUT mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderAboutHeader(PortletRenderRequest request,
                                  PrintWriter out,
                                  Map params)
        throws PortletException, IOException
    {
        // override this method to create your about header
        // HELP and ABOUT usually use the same container
    }


    /**
     * Renders the footer for the portlet ABOUT mode
     *
     * @param request the portlet render request
     * @param out PrintWriter that should be used to write the portlet header
     * @param params <code>Map</code> specifying parameters which override the
     * default rendering behaviour. May be empty if the default rendering
     * behaviour is acceptable. Keys should be one of the string key constants
     * defined in this class. See the description of each key constant for
     * acceptable mapped values.
     */
    public void renderAboutFooter(PortletRenderRequest request,
                                  PrintWriter out,
                                  Map params)
        throws PortletException, IOException
    {
        // override this method to create your about footer
        // HELP and ABOUT usually use the same container
    }
    

    /**
     *  Utility method to convert a ParameterMap into a Map.
     *
     *  This is used by deprecated methods to call the new version of the same
     *  method.
     *
     *  @param params ParameterMap to be converted
     *  @return Map containing parameters from the ParameterMap
     */
    protected Map convertParameterMap(ParameterMap params)
    {
        if (params == null)
        {
            return null;
        }
        
        if (params instanceof SimpleParameterMap)
        {
            SimpleParameterMap simple = (SimpleParameterMap)params;
            return simple.getMap();
        }
        
        // Implementation of ParameterMap is not a SimpleParameterMap so
        // contents must be moved item, by item to a new map
        HashMap newMap = new HashMap(10);
        String name = null;
        Enumeration enum = params.getParameterNames();
        while(enum.hasMoreElements())
        {
            name = (String)enum.nextElement(); 
            newMap.put(name, params.getParameterValue(name));
        }
        return newMap;
    }




    
//////////////////////////////////////////////////////////////////////////////
// 
//                           DEPRECATED METHODS
//    
//////////////////////////////////////////////////////////////////////////////


    /** 
     * Renders a portlet header
     * 
     * The container that is rendered should be dependent on the mode that is
     * being renderered
     *
     * @param pr PortletRenderRequest for this rendering.
     * @param params Parameters for rendering the container
     * 
     *  @deprecated use {@link #renderPortletHeader(PortletRenderRequest, 
     *                                              Map)}
     */
    public void renderPortletHeader(PortletRenderRequest request,
                                    ParameterMap params)
        throws PortletException
    {
        renderPortletHeader(request, convertParameterMap(params));
    }

    /** 
     * Renders a portlet footer
     * 
     * The container that is rendered should be dependent on the mode that is
     * being renderered
     *
     * @param pr PortletRenderRequest for this rendering.
     * @param params Parameters for rendering the container
     * 
     *  @deprecated use {@link #renderPortletFooter(PortletRenderRequest, 
     *                                              Map)}
     */
    public void renderPortletFooter(PortletRenderRequest request,
                                    ParameterMap params)
        throws PortletException
    {
        renderPortletFooter(request, convertParameterMap(params));
    }

    /**
     *  Renders the header for the portlet SHOW mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderShowHeader(PortletRenderRequest, 
     *                                           PrintWriter,
     *                                           Map)}
     */
    public void renderShowHeader(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        renderShowHeader(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the footer for the portlet SHOW mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderShowFooter(PortletRenderRequest, 
     *                                           PrintWriter,
     *                                           Map)}
     */
    public void renderShowFooter(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        renderShowFooter(request, out, convertParameterMap(params));
    }

    /**
     *  Renders the header for the portlet PREVIEW mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderPreviewHeader(PortletRenderRequest, 
     *                                              PrintWriter,
     *                                              Map)}
     */
    public void renderPreviewHeader(PortletRenderRequest request,
                                    PrintWriter out,
                                    ParameterMap params)
        throws PortletException, IOException
    {
        renderPreviewHeader(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the footer for the portlet PREVIEW mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderPreviewFooter(PortletRenderRequest, 
     *                                              PrintWriter,
     *                                              Map)}
     */
    public void renderPreviewFooter(PortletRenderRequest request,
                                    PrintWriter out,
                                    ParameterMap params)
        throws PortletException, IOException
    {
        renderPreviewFooter(request, out, convertParameterMap(params));
    }

    /**
     *  Renders the header for the portlet SHOW_DETAILS mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderDetailsHeader(PortletRenderRequest, 
     *                                              PrintWriter,
     *                                              Map)}
     */
    public void renderDetailsHeader(PortletRenderRequest request,
                                    PrintWriter out,
                                    ParameterMap params)
        throws PortletException, IOException
    {
        renderDetailsHeader(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the footer for the portlet SHOW_DETAILS mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderDetailsFooter(PortletRenderRequest, 
     *                                              PrintWriter,
     *                                              Map)}
     */
    public void renderDetailsFooter(PortletRenderRequest request,
                                    PrintWriter out,
                                    ParameterMap params)
        throws PortletException, IOException
    {
        renderDetailsFooter(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the header for the portlet EDIT mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderEditHeader(PortletRenderRequest, 
     *                                           PrintWriter,
     *                                           Map)}
     */
    public void renderEditHeader(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        renderEditHeader(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the footer for the portlet EDIT mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderEditFooter(PortletRenderRequest, 
     *                                           PrintWriter,
     *                                           Map)}
     */
    public void renderEditFooter(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        renderEditFooter(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the header for the portlet EDIT_DEFAULTS mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderEditDefaultsHeader(PortletRenderRequest, 
     *                                                   PrintWriter,
     *                                                   Map)}
     */
    public void renderEditDefaultsHeader(PortletRenderRequest request,
                                         PrintWriter out,
                                         ParameterMap params)
        throws PortletException, IOException
    {
        renderEditDefaultsHeader(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the footer for the portlet EDIT_DEFAULTS mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderEditDefaultsFooter(PortletRenderRequest, 
     *                                                   PrintWriter,
     *                                                   Map)}
     */
    public void renderEditDefaultsFooter(PortletRenderRequest request,
                                            PrintWriter out,
                                            ParameterMap params)
        throws PortletException, IOException
    {
        renderEditDefaultsFooter(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the header for the portlet HELP mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderHelpHeader(PortletRenderRequest, 
     *                                           PrintWriter,
     *                                           Map)}
     */
    public void renderHelpHeader(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        renderHelpHeader(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the footer for the portlet HELP mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderHelpFooter(PortletRenderRequest, 
     *                                           PrintWriter,
     *                                           Map)}
     */
    public void renderHelpFooter(PortletRenderRequest request,
                                 PrintWriter out,
                                 ParameterMap params)
        throws PortletException, IOException
    {
        renderHelpFooter(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the header for the portlet ABOUT mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderAboutHeader(PortletRenderRequest, 
     *                                            PrintWriter,
     *                                            Map)}
     */
    public void renderAboutHeader(PortletRenderRequest request,
                                  PrintWriter out,
                                  ParameterMap params)
        throws PortletException, IOException
    {
        renderAboutHeader(request, out, convertParameterMap(params));
    }


    /**
     *  Renders the footer for the portlet ABOUT mode
     *
     *  @param request the portlet render request
     *  @param out PrintWriter that should be used to write the portlet header
     *  @param params additional parameters passed in by the PortletRenderer
     * 
     *  @deprecated use {@link #renderAboutFooter(PortletRenderRequest, 
     *                                            PrintWriter,
     *                                            Map)}
     */
    public void renderAboutFooter(PortletRenderRequest request,
                                  PrintWriter out,
                                  ParameterMap params)
        throws PortletException, IOException
    {
        renderAboutFooter(request, out, convertParameterMap(params));
    }

    private PrintWriter getPrintWriter(PortletRenderRequest pr, Map params)
        throws PortletException, IOException
    {
        // Attempt to retrieve the writer object from the supplied
        // map. Handle the case when we are passed a JspWriter (which
        // is not an instance of PrintWriter).
        PrintWriter writer = null;
        Object writerObj = params.get(PRINT_WRITER);
        if (writerObj == null)
        {
            // PrintWriter was not passed, so use the PortletRenderRequest
            writer = pr.getWriter();
        }
        else if (writerObj instanceof PrintWriter)
        {
            // We were passed a PrintWriter, so use it.
            writer = (PrintWriter)writerObj;
        }
        else if (writerObj instanceof Writer)
        {
            // We were passed another type of writer, possibly a
            // JspWriter. Wrap with a new PrintWriter.
            writer = new PrintWriter((Writer)writerObj);
        }
        else
        {
            // Should never happen, but handle due to the untyped
            // nature of the api.
            throw new PortletException("Invalid Writer.");
        }
        return writer;
    }

}
