/*
 * Created on Jan 7, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package gov.va.med.esr.ui.taglib;

import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.NestedNullException;
import org.apache.struts.taglib.TagUtils;

public abstract class BaseDisplayTag extends TagSupport 
{
    private static final long serialVersionUID = -1370346746640850300L;
	
	/**
     * Locate and return the specified bean, from an optionally specified
     * scope, in the specified page context.  If no such bean is found,
     * return <code>null</code> instead.  If an exception is thrown, it will
     * have already been saved via a call to <code>saveException()</code>.
     *
     * @param pageContext Page context to be searched
     * @param name Name of the bean to be retrieved
     * @param scopeName Scope to be searched (page, request, session, application)
     *  or <code>null</code> to use <code>findAttribute()</code> instead
     * @return JavaBean in the specified page context
     * @exception JspException if an invalid scope name
     *  is requested
     */
    private Object getParentBean(PageContext pageContext, String name, String scopeName) throws JspException
	{
        if (scopeName == null)
            return pageContext.findAttribute(name);

        try 
		{
            return pageContext.getAttribute(name, TagUtils.getInstance().getScope(scopeName));
        } catch (JspException e) 
		{
            throw e;
        }
    }

    
    /**
     * Locate and return the specified property of the specified bean, from
     * an optionally specified scope, in the specified page context.  If an
     * exception is thrown, it will have already been saved via a call to
     * <code>saveException()</code>.
     *
     * @param pageContext Page context to be searched
     * @param name Name of the bean to be retrieved
     * @param property Name of the property to be retrieved, or
     *  <code>null</code> to retrieve the bean itself
     * @param scope Scope to be searched (page, request, session, application)
     *  or <code>null</code> to use <code>findAttribute()</code> instead
     * @return property of specified JavaBean
     *
     * @exception JspException if an invalid scope name
     *  is requested
     * @exception JspException if the specified bean is not found
     * @exception JspException if accessing this property causes an
     *  IllegalAccessException, IllegalArgumentException,
     *  InvocationTargetException, or NoSuchMethodException
     */
    protected Object lookup(PageContext pageContext, String name, String property, String scope) throws JspException 
	{
        // Look up the requested bean, and return if requested
        Object bean = getParentBean(pageContext, name, scope);
        if (bean == null) 
          return null;

        if (property == null)
            return bean;

        // Locate and return the specified property
        try 
		{
        	//Test for null parent or sub-parent bean
            PropertyUtils.getProperty(bean, property);
        } 
        catch (NestedNullException e) 
		{
        	return null;
		}
        catch (Exception e)
		{
        	//leave it to TagUtils to handle all other exceptions
		}
        return TagUtils.getInstance().lookup(pageContext, name, property, scope);
    }
    
    

    
    /**
     * Write the specified text as the response to the writer associated with
     * this page.  <strong>WARNING</strong> - If you are writing body content
     * from the <code>doAfterBody()</code> method of a custom tag class that
     * implements <code>BodyTag</code>, you should be calling
     * <code>writePrevious()</code> instead.
     *
     * @param pageContext The PageContext object for this page
     * @param text The text to be written
     * @param filter Flag to indicate whether the output text needs to be filter or not
     *
     * @exception JspException if an input/output error occurs (already saved)
     */
    protected void write(PageContext pageContext, String text, boolean filter) throws JspException 
	{
    	if (filter)
        	//Filter the string result for characters that are senstive to HTML interpreters, returning the string with these characters replaced by the corresponding character entities. (e.g. replace "<" with "&lt;", ">" with "&gt;", "&" with "&amp;", etc.)
            TagUtils.getInstance().write(pageContext, TagUtils.getInstance().filter(text));
        else
            TagUtils.getInstance().write(pageContext, text);
    } 
    
}