FileDocCategorySizeDatePackage
UsePropertyTag.javaAPI DocExample5023Thu Jun 28 16:14:16 BST 2001com.ora.jsp.tags.generic

UsePropertyTag.java

package com.ora.jsp.tags.generic;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

/**
 * This class is a custom action for making a bean property value
 * available to other actions and scripting code as a variable.
 * The property must be a multi-value property. The getter
 * method may take a String argument identifying the one value
 * to return.
 *
 * @author Hans Bergsten, Gefion software <hans@gefionsoftware.com>
 * @version 1.0
 */
public class UsePropertyTag extends TagSupport {
    private String id;
    private String name;
    private String property;
    private String arg;
    private String className;

    /**
     * Sets the id attribute, i.e. the name of the variable to hold the
     * reference to the selected property value.
     *
     * @param id the variable name
     */
    public void setId(String id) {
        this.id = id;
    }
    
    /**
     * Sets the name attribute, i.e. the name of the variable holding the
     * reference to the bean with the property to retrieve.
     *
     * @param name the bean name
     */
    public void setName(String name) {
        this.name = name;
    }
    
    /**
     * Sets the property attribute, i.e. the name of the property to
     * retrieve.
     *
     * @param property the property name
     */
    public void setProperty(String property) {
        this.property = property;
    }
    
    /**
     * Sets the arg attribute, i.e. the String argument value used
     * by the property getter method to select on of multiple property
     * values.
     *
     * @param arg the String argument value
     */
    public void setArg(String arg) {
        this.arg = arg;
    }

    /**
     * Sets the class attribute, i.e. the class name for the property
     * value.
     *
     * @param className the property class name
     */
    public void setClassName(String className) {
        this.className = className;
    }

    /**
     * Retrieves one value of a multi-valued property in the specified
     * bean using a getter method with a String argument. The value is
     * saved with the specified variable name in the page scope.
     */
    public int doEndTag() throws JspException {
        Object obj = pageContext.findAttribute(name);
        if (obj == null) {
            throw new JspException("Variable " + name + " not found");
        }
        Object propObj = getProperty(obj, property, className);
        pageContext.setAttribute(id, propObj);
    	return SKIP_BODY;
    }
    
    /**
     * Releases all instance variables.
     */
    public void release() {
        id = null;
        name = null;
        property = null;
        arg = null;
        className = null;
        super.release();
    }
    
    /**
     * Returns the value of the specified property from the
     * specified bean.
     *
     * @param bean the bean
     * @param property the property name
     * @param propertyClassName the property class name (type)
     */
    private Object getProperty(Object bean, String property, 
        String propClassName) throws JspException {
        Object propObj = null;
        Class beanClass = bean.getClass();
        Class[] params = null;
        if (arg != null) {
            // If an arg is specified, it must be a String arg
            params = new Class[1];
            params[0] = String.class;
        }
        Method method = null;
        try {
            /*
             * Since the method may have an arg, look for it explicitly
             * instead of using the standard property lookup method
             */
            method = beanClass.getMethod("get" +
                property.substring(0, 1).toUpperCase() + property.substring(1),
                params);
        }
        catch (NoSuchMethodException e) {
            throw new JspException("A property getter for " + property +
                (arg != null ? " with a String argument" : "") +
                " not found in " + name);
        }
        Class propClass = null;
        try {
          propClass = Class.forName(propClassName);
        }
        catch (ClassNotFoundException e) {
            throw new JspException("Property class " + propClassName + " not found");
        }

        Class returnType = method.getReturnType();
        if (!propClass.isAssignableFrom(returnType)) {
            throw new JspException("Property " + property + " is not a " + className);
        }
        Object[] args = null;
        if (arg != null) {
            args = new Object[1];
            args[0] = arg;
        }
        try {
            propObj = method.invoke(bean, args);
        }
        catch (Exception e) {
            throw new JspException("Failed to get property " + property + " from " + name);
        }
        return propObj;
    }
}