Package xdoclet.tagshandler

Source Code of xdoclet.tagshandler.ConfigTagsHandler

/*
* Copyright (c) 2001, 2002 The XDoclet team
* All rights reserved.
*/
package xdoclet.tagshandler;

import java.beans.Introspector;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;

import xdoclet.ConfigParamIntrospector;
import xdoclet.SubTask;
import xdoclet.XDocletException;
import xdoclet.XDocletTagSupport;
import xdoclet.util.LogUtil;

/**
* @author               Ara Abrahamian (ara_e@email.com)
* @created              Oct 15, 2001
* @xdoclet.taghandler   namespace="Config"
* @version              $Revision: 1.9 $
*/
public class ConfigTagsHandler extends XDocletTagSupport
{
    /**
     * The current config parameter name. forAllConfigParameters sets the value while looping over values of the config
     * parameter. Note that this is only used for config parameters of type java.util.ArrayList. Other tags working with
     * config parameters use current config parameter name to lookup the value of that parameter. For each config
     * parameter there exists a corresponding getter method in the subtask, so all public getter methods can be used as
     * config parameters.
     *
     * @see   #currentConfigParamIndex
     * @see   #getConfigParameter(java.lang.String)
     * @see   #forAllConfigParameters(java.lang.String,java.util.Properties)
     */
    private static String currentConfigParam = null;

    /**
     * The current config parameter index. forAllConfigParameters sets the value while looping over values of the config
     * parameter.
     *
     * @see   #currentConfigParam
     * @see   #getConfigParameter(java.lang.String)
     * @see   #forAllConfigParameters(java.lang.String,java.util.Properties)
     */
    private static int currentConfigParamIndex = -1;

    /**
     * Gets the CurrentConfigParamIndex attribute of the ConfigTagsHandler class
     *
     * @return   The CurrentConfigParamIndex value
     */
    public static int getCurrentConfigParamIndex()
    {
        return currentConfigParamIndex;
    }

    /**
     * Returns the value for the specified configuration parameter. Null if the config parameter not found.
     *
     * @param paramName             Description of Parameter
     * @return                      The ConfigParameter value
     * @exception XDocletException  Description of Exception
     * @todo                        When searching for param part of a subtask.element.param config param we rely on
     *      bare reflection mechanism, so if we had getMyParam and we specified myparam for example (case mismatch) it
     *      fails (in Class.getMethod). We should provide a case-insensitive solution.
     */
    public Object getConfigParameter(String paramName) throws XDocletException
    {
        Log log = LogUtil.getLog(ConfigTagsHandler.class, "getConfigParameter");

        paramName = Introspector.decapitalize(paramName);

        SubTask subtask = getDocletContext().getActiveSubTask();

        if (log.isDebugEnabled()) {
            log.debug("subtask=" + subtask.getClass());
            log.debug("currentConfigParamIndex=" + currentConfigParamIndex);
            log.debug("currentConfigParam=" + currentConfigParam);
            log.debug("paramName=" + paramName);
        }

        String configName = paramName;
        Object configValue = null;
        int index = 0;

        index = configName.indexOf('.');

        if (index != -1) {
            // so it's not in global namespace or activesubtask.param

            int index2 = paramName.indexOf('.', index + 1);

            // has one dot. subtaskname.param or activesubtask.element.param format
            if (configValue == null && index2 == -1) {
                // 1. is in subtaskname.param format
                configName = paramName;
                configValue = getDocletContext().getConfigParam(configName);

                // 2. is in activesubtask.element.param format
                if (configValue == null) {
                    String elemname = paramName.substring(0, index);
                    String paramname = paramName.substring(index + 1);

                    configName = subtask.getSubTaskName() + '.' + elemname;
                    configValue = getDocletContext().getConfigParam(configName);

                    // ok we have activesubtask.element value, use reflection to get
                    // the param inside the element
                    if (configValue != null) {
                        // we're in a forAllConfigParams loop for a ArrayList-based config parameter
                        if (currentConfigParamIndex != -1) {
                            log.debug("In a forAllConfigParams loop for an ArrayList-based config parameter.");
                            // param_value = element at currentConfigParamIndex index of the ArrayList
                            configValue = ((java.util.ArrayList) configValue).get(currentConfigParamIndex);
                        }

                        Method getterMethod = ConfigParamIntrospector.findGetterMethod(configValue, paramname);

                        if (getterMethod == null) {
                            configValue = null;
                        }

                        try {
                            configValue = getterMethod.invoke(configValue, null);
                        }
                        catch (Exception e) {
                            log.debug("not found", e);
                        }
                    }
                }
            }
            else {
                // has more than one dot. subtaskname.elem.param format

                // lookup subtaskname.elem
                int lastDotIndex = paramName.lastIndexOf('.');
                String paramname = paramName.substring(lastDotIndex + 1);

                configName = paramName.substring(0, lastDotIndex);
                configValue = getDocletContext().getConfigParam(configName);

                if (configValue != null) {
                    // we're in a forAllConfigParams loop for a ArrayList-based config parameter
                    if (currentConfigParamIndex != -1) {
                        log.debug("In a forAllConfigParams loop for an ArrayList-based config parameter.");

                        // param_value = element at currentConfigParamIndex index of the ArrayList
                        configValue = ((java.util.ArrayList) configValue).get(currentConfigParamIndex);
                    }

                    Method getterMethod = ConfigParamIntrospector.findGetterMethod(configValue, paramname);

                    if (getterMethod == null) {
                        configValue = null;
                    }

                    try {
                        configValue = getterMethod.invoke(configValue, null);
                    }
                    catch (Exception e) {
                        log.debug("not found", e);
                    }
                }
            }
        }
        else {
            // is either in global namespace or activesubtask.param

            // 1. search active subtask
            configName = subtask.getSubTaskName() + '.' + paramName;
            configValue = getDocletContext().getConfigParam(configName);

            // 2. search DocletTask global namespace
            if (configValue == null) {
                configName = paramName;
                configValue = getDocletContext().getConfigParam(paramName);
            }
        }

        // not found at all
        if (configValue == null) {
            return null;
        }
        else {
            if (log.isDebugEnabled()) {
                log.debug("Config param found:" + paramName);
            }
        }

        // NULL is used instead of null because you can't put a null in a hashtable
        if (configValue.equals(ConfigParamIntrospector.NULL)) {
            configValue = null;
        }

        log.debug("configValue=" + configValue);

        return configValue;
    }

    /**
     * Evaluates the body if config parameter specified is not null.
     *
     * @param template              The body of the block tag
     * @param attributes            The attributes of the template tag
     * @exception XDocletException  Description of Exception
     * @doc.tag                     type="block"
     * @doc.param                   name="paramName" optional="false" description="The config parameter name, it's a
     *      parameter settable from within build file."
     */
    public void ifHasConfigParam(String template, Properties attributes) throws XDocletException
    {
        if (!configParameterValue(attributes).equals("")) {
            generate(template);
        }
    }

    /**
     * Returns the values of a configuration parameter with the name paramName.
     *
     * @param attributes            The attributes of the template tag
     * @return                      Description of the Returned Value
     * @exception XDocletException  Description of Exception
     * @doc.tag                     type="content"
     * @doc.param                   name="paramName" optional="false" description="The config parameter name, it's a
     *      parameter settable from within build file."
     */
    public String configParameterValue(Properties attributes) throws XDocletException
    {
        String paramName = attributes.getProperty("paramName");
        Object configParam = getConfigParameter(paramName);

        // if empty collection, treat as no value
        if (configParam instanceof Collection && ((Collection) configParam).isEmpty()) {
            return "";
        }
        // or if zero length array treat as no value
        else if (configParam instanceof Object[] && ((Object[]) configParam).length == 0) {
            return "";
        }
        // otherwise get the value
        else if (configParam != null) {
            return configParam.toString();
        }
        // if nothing there, return empty string
        else {
            return "";
        }
    }

    /**
     * Evaluate the body for all configuration parameters with the name paramName. It's basically used for
     * java.util.ArrayList-based parameter types, and the body is evaluated for all items of the ArrayList.
     *
     * @param template              The body of the block tag
     * @param attributes            The attributes of the template tag
     * @exception XDocletException  Description of Exception
     * @doc.tag                     type="block"
     * @doc.param                   name="paramName" optional="false" description="The config parameter name, it's a
     *      parameter settable from within build file."
     */
    public void forAllConfigParameters(String template, Properties attributes) throws XDocletException
    {
        String paramName = attributes.getProperty("paramName");
        ArrayList configParams = (java.util.ArrayList) getConfigParameter(paramName);

        for (int i = 0; i < configParams.size(); i++) {
            currentConfigParam = paramName;
            currentConfigParamIndex = i;

            generate(template);
        }

        currentConfigParam = null;
        currentConfigParamIndex = -1;
    }

    /**
     * Evaluate the body if the value of the configuration parameter is greater or equal to value.
     *
     * @param template              The body of the block tag
     * @param attributes            The attributes of the template tag
     * @exception XDocletException  Description of Exception
     * @doc.tag                     type="block"
     * @doc.param                   name="paramName" optional="false" description="The config parameter name, it's a
     *      parameter settable from within build file."
     * @doc.param                   name="value" optional="false" description="The desired value."
     */
    public void ifConfigParamGreaterOrEquals(String template, Properties attributes) throws XDocletException
    {
        if (ifConfigParamGreaterOrEquals_Impl(attributes)) {
            generate(template);
        }
    }

    /**
     * Evaluate the body if the value of the configuration parameter is not greater or equal to value.
     *
     * @param template              The body of the block tag
     * @param attributes            The attributes of the template tag
     * @exception XDocletException  Description of Exception
     * @doc.tag                     type="block"
     * @doc.param                   name="paramName" optional="false" description="The config parameter name, it's a
     *      parameter settable from within build file."
     * @doc.param                   name="value" optional="false" description="The desired value."
     */
    public void ifConfigParamNotGreaterOrEquals(String template, Properties attributes) throws XDocletException
    {
        if (!ifConfigParamGreaterOrEquals_Impl(attributes)) {
            generate(template);
        }
    }

    /**
     * Evaluate the body if the value of the configuration parameter equals value.
     *
     * @param template              The body of the block tag
     * @param attributes            The attributes of the template tag
     * @exception XDocletException  Description of Exception
     * @doc.tag                     type="block"
     * @doc.param                   name="paramName" optional="false" description="The config parameter name, it's a
     *      parameter settable from within build file."
     * @doc.param                   name="value" optional="false" description="The desired value."
     */
    public void ifConfigParamEquals(String template, Properties attributes) throws XDocletException
    {
        if (ifConfigParamEquals_Impl(attributes)) {
            generate(template);
        }
    }

    /**
     * Evaluate the body if the value of the configuration parameter doesn't equal value.
     *
     * @param template              The body of the block tag
     * @param attributes            The attributes of the template tag
     * @exception XDocletException  Description of Exception
     * @doc.tag                     type="block"
     * @doc.param                   name="paramName" optional="false" description="The config parameter name, it's a
     *      parameter settable from within build file."
     * @doc.param                   name="value" optional="false" description="The desired value."
     */
    public void ifConfigParamNotEquals(String template, Properties attributes) throws XDocletException
    {
        if (!ifConfigParamEquals_Impl(attributes)) {
            generate(template);
        }
    }

    /**
     * The implementation of ifConfigParamGreaterOrEquals and ifConfigParamNotGreaterOrEquals tags. Currently the value
     * can only be of a float type like "2.0".
     *
     * @param attributes            The attributes of the template tag
     * @return                      Description of the Returned Value
     * @exception XDocletException  Description of Exception
     * @see                         #ifConfigParamGreaterOrEquals(java.lang.String,java.util.Properties)
     * @see                         #ifConfigParamNotGreaterOrEquals(java.lang.String,java.util.Properties)
     */
    protected boolean ifConfigParamGreaterOrEquals_Impl(Properties attributes) throws XDocletException
    {
        Log log = LogUtil.getLog(ConfigTagsHandler.class, "ifConfigParamGreaterOrEquals_Impl");

        String paramName = attributes.getProperty("paramName");
        String paramValue = attributes.getProperty("value");

        Object configParamValue = getConfigParameter(paramName);

        boolean greaterOrEquals = false;

        if (configParamValue != null) {
            greaterOrEquals = configParamValue.equals(paramValue);
            if (!greaterOrEquals) {
                StringTokenizer configParamTokenizer = new StringTokenizer(configParamValue.toString(), ".");
                StringTokenizer paramTokenizer = new StringTokenizer(paramValue, ".");

                boolean greater = false;
                boolean less = false;

                while (!greater && !less && (configParamTokenizer.hasMoreTokens() ||
                    paramTokenizer.hasMoreTokens())) {
                    int i = configParamTokenizer.hasMoreTokens() ? Integer.parseInt(configParamTokenizer.nextToken()) : 0;
                    int j = paramTokenizer.hasMoreTokens() ? Integer.parseInt(paramTokenizer.nextToken()) : 0;

                    greater = i > j;
                    less = i < j;
                }

                greaterOrEquals = greater || !less;
            }
        }

        return greaterOrEquals;
    }

    /**
     * The implementation of ifConfigParamEquals and ifConfigParamEquals tags. Currently the value can only be of a
     * float type like "2.0".
     *
     * @param attributes            The attributes of the template tag
     * @return                      Description of the Returned Value
     * @exception XDocletException  Description of Exception
     * @see                         #ifConfigParamEquals(java.lang.String,java.util.Properties)
     * @see                         #ifConfigParamNotEquals(java.lang.String,java.util.Properties)
     */
    protected boolean ifConfigParamEquals_Impl(Properties attributes) throws XDocletException
    {
        Log log = LogUtil.getLog(ConfigTagsHandler.class, "ifConfigParamEquals_Impl");

        String paramName = attributes.getProperty("paramName");
        String paramValue = attributes.getProperty("value");

        Object configParamValue = getConfigParameter(paramName);

        if (log.isDebugEnabled())
            log.debug("paramName='" + paramName +
                "',paramValue='" + paramValue +
                "',configParamValue='" + configParamValue + '\'');

        if (configParamValue == null)
            return false;

        if (configParamValue instanceof Boolean)
            return configParamValue.equals(Boolean.valueOf(paramValue));
        if (configParamValue instanceof Integer)
            return configParamValue.equals(Integer.valueOf(paramValue));

        // Catch-all for Strings and any other types we don't (yet) check for.
        // Any non-strings that get here should be added to the cases above, or
        // the comparison may not be accurate e.g. "1.000" != "1.0000"
        if (!(configParamValue instanceof String))
            log.warn(configParamValue.getClass() + " needs adding to configParamValue types");
        return configParamValue.toString().equals(paramValue);
    }

    /**
     * Say we had <XDtConfig:forAllConfigParameters paramName="tagLibs">, and now we do a
     * <XDtConfig:configParameterValue paramName="tagLibs.uri"/>. What this method does is
     *
     * @param paramName
     * @return           true if it is the same
     */
    private boolean isSubConfigParamInSameConfigParam(String paramName)
    {
        return paramName.equals(currentConfigParam);
    }
}
TOP

Related Classes of xdoclet.tagshandler.ConfigTagsHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.