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

import oracle.portal.provider.v2.PortletException;
import oracle.portal.provider.v2.PortletNotFoundException;
import oracle.portal.provider.v2.render.PortletRenderRequest;
import oracle.portal.provider.v2.http.HttpCommonConstants;

/**
 * ResourceValidateRenderer is an abstract class which should be used as the
 * basis for a {@link oracle.portal.provider.v2.render.ManagedRenderer} which
 * has responsibility for rendering a single mode from a web container resource
 * using validation based caching. Since this requires control over the HTTP
 * headers of the renderer's response, this must be achieved by overriding the
 * {@link
 * oracle.portal.provider.v2.render.ManagedRenderer#prepareResponse(PortletRenderRequest)}
 * method.<p>
 *
 * Users should provide their own implementations of {@link
 * #isValid(PortletRenderRequest,String)} and {@link
 * #getNewVersion(PortletRenderRequest)} in order to enforce their own
 * validation criteria.
*/
public abstract class ResourceValidateRenderer extends ResourceRenderer
{

    /**
     * Performs any protocol specific preparation that is needed before the
     * page is generated. If the request contains a cached version string for
     * the current page, the {@link #isValid(PortletRenderRequest,String)}
     * method is called in order to decide whether the cached page with this
     * version is still valid. If so, the page is marked as valid, and
     * <code>false</code> is returned to indicate that the page need not be
     * generated. Otherwise, {@link #getNewVersion(PortletRenderRequest)} is
     * called in order to derive a new version string the page, and
     * <code>true</code> is returned to indicate that the page body should be
     * generated.<p>
     *
     * @param pr a {@link PortletRenderRequest}
     * @return boolean flag indicating whether or not to render the portlet's
     * contents
     */
    public boolean prepareResponse(PortletRenderRequest pr)
        throws PortletException, PortletNotFoundException
    {
        if(super.prepareResponse(pr))
        {
            int level = HttpCommonConstants.USER_LEVEL;
            String oldVersion = HttpPortletRendererUtil.getCachedVersion(pr);
            if(oldVersion != null)
            {
                if(isValid(pr, oldVersion))
                {
                    HttpPortletRendererUtil.useCachedVersion(pr);
                    return false;
                }
                level = HttpPortletRendererUtil.getCachedLevel(pr);
            }
            // set cached version
            HttpPortletRendererUtil.setCachedVersion(pr, getNewVersion(pr), level);
            return true;
        }
        return false;
    }

    /**
     * Determine whether the given version of the page to be generated is still
     * valid. Users implementing this method may want to compare the given
     * version string with the one returned by {@link
     * #getNewVersion(PortletRenderRequest)}.
     * @param pr the request object containing the current request details.
     * @param oldVersion String identifying the cached version of the page to
     * be generated.
     * @return <code>true</code> if the given version is still valid.
     */
    public abstract boolean isValid(PortletRenderRequest pr, String oldVersion);

    /**
     * Decide the current version of the page to be generated.
     *
     * @param pr the request object containing the current request details.
     * @return the current version of the page to be generated.
     */
    public abstract String getNewVersion(PortletRenderRequest pr);
}
