/* Copyright (c) 2001, 2003 Oracle Corporation */
package oracle.portal.provider.v2.render.http;

import oracle.portal.provider.v2.render.RenderManager;
import oracle.portal.provider.v2.render.PortletRenderRequest;
import oracle.portal.provider.v2.utils.ValidationError;
import oracle.portal.provider.v2.PortletException;
import oracle.portal.utils.xml.v2.NodeHandlerException;
import oracle.portal.provider.v2.http.HttpCommonConstants;
import oracle.portal.log.LogManager;

import oracle.webdb.utils.SimpleStringBuffer;

/**
 * When maintained by a {@link oracle.portal.provider.v2.render.RenderManager},
 * a <code>ResourceRenderer</code> renders a single page's contents from
 * resource known to the servlet container. Examples of such resources include
 * JSPs, servlets and static HTML files. Any resource can be used as long as
 * the servlet container can return a valid
 * <code>javax.servlet.RequestDispatcher</code> for it. The resource can be
 * located in the same servlet context as the current provider or a different
 * one. The resource path is defined by a call to <code>setResourcePath</code>.
 */
public class ResourceRenderer extends AbstractResourceRenderer
{

    // URI identifying the resource
    private String mResourcePath = null;

    /**
     * Null Constructor. The {@link BaseManagedRenderer#preInitialize(Object)}
     * method should be called after creating an object with this constructor
     * and the {@link BaseManagedRenderer#postInitialize()} method should be
     * called after setting up page properties with the various accessor
     * methods. Normally a {@link DefaultNodeHandler} takes care of these
     * details.
     */
    public ResourceRenderer()
    {
        super();
    }

    /**
     * Creates and initializes a <code>ResourceRenderer</code> owned by the
     * given {@link RenderManager}, to render from the resource at the
     * given path. This constructor is called by <code>RenderManager</code>
     * when no renderer has been specified in the provider definition and
     * <code>ResourceRenderer</code> is used by default to render page content.
     *
     * @param <code>RenderManager</code> that owns this page
     * @param path the path to the resource.
     * @exception PortletException if an error occurs while initializing the
     * object
     */
    public ResourceRenderer(RenderManager parent, String path)
        throws PortletException
    {
        try
        {
            preInitialize(parent);
            setResourcePath(path);
            postInitialize();
        }
        catch (NodeHandlerException e)
        {
            throw new PortletException(e);
        }
    }

    /**
     * Gets the path to the resource used for rendering. This path is relative
     * to the context root of the J2EE Application.
     *
     * @return the resource path, relative to the context root.
     */
    public String getResourcePath()
    {
        return mResourcePath;
    }

    /**
     * Sets the path of the resource used for rendering. This path should be
     * relative to the context root of the J2EE Application. It should fully
     * locate the resource so, in the case of JSPs and static files, should
     * include the file name.
     *
     * @param path resource location.
     */
    public void setResourcePath(String path)
    {
        mResourcePath = path;
        // Make sure the string starts with a separator
        if(!mResourcePath.startsWith("/"))
        {
            mResourcePath = "/" + mResourcePath;
        }
    }

    /**
     * Performs the extra steps required to initialize and validate a
     * <code>ResourceRenderer</code> object once its properties have been set
     * with the appropriate accessor methods. A <code>ResourceRenderer</code>
     * object must be supplied with a non null resource path.
     *
     * @exception NodeHandlerException if a resource path has not been
     * specified.
     */
    public void postInitialize() throws NodeHandlerException
    {
        super.postInitialize();
        if (mResourcePath == null)
        {
            throw new NodeHandlerException("A ResourceRenderer must be " +
                                           "supplied with a resource path");
        }
    }

    /**
     * Validates the internal state of this <code>ResourceRenderer</code>
     * instance. Errors found are reported using the supplied {@link
     * oracle.portal.provider.v2.utils.ValidationError} instance.
     *
     * @param context The context of the calling instance.
     * @param errors The current list of errors.
     */
    public void validate(String context, ValidationError errors)            
    {                                                                       
        String ctx = ValidationError.newContext(context, "ResourceRenderer",
                                                null);
                            
        // call super type
        super.validate(ctx, errors);
                                                                            
        // Check the validity of the member variables                       
        if (mResourcePath == null)
        {                                                                   
            errors.addError(ctx, "resource path must not be null", null);
        }  
    }

    /**
     * This method returns the path of the resource to be rendered as set by
     * <code>setResourcePath</code>.
     * 
     * @param prr the request object
     * 
     * @exception PortletException
     */
    public String getRequestResourcePath(PortletRenderRequest prr)
      //throws PortletException
    {
        // Just return the resource path in the provider definition file.
        return mResourcePath;
    }

    /**
     * Sets the context root of the <code>javax.servlet.ServletContext</code>
     * containing the resource. This should only be set if the resource is
     * located in a <i>different</i> servlet context than the current
     * provider.
     *
     * @param context context root known to the server.
     */
    public void setContext(String context)
    {
        mContext = context;
        // Make sure the string starts with a separator, and doesn't end with
        // one
        if(!mContext.startsWith("/"))
        {
            mContext = "/" + mContext;
        }
        if(mContext.endsWith("/"))
        {
            mContext = mContext.substring(0, mContext.length()-1);
        }
    }    
}
