Package xdoclet.modules.spring

Source Code of xdoclet.modules.spring.SpringValidatorTagsHandler

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

import java.beans.Introspector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.collections.SequencedHashMap;
import xjavadoc.XClass;
import xjavadoc.XMethod;
import xjavadoc.XParameter;
import xjavadoc.XTag;

import xdoclet.DocletSupport;
import xdoclet.XDocletException;
import xdoclet.tagshandler.AbstractProgramElementTagsHandler;
import xdoclet.tagshandler.MethodTagsHandler;

/**
* Spring Validator tag handler tags
*
* @author               Matt Raible (matt@raibledesigns.com)
* @created              April 26, 2004
* @xdoclet.taghandler   namespace="CommonsValidator"
* @version              $Revision: 1.3 $
*/
public class SpringValidatorTagsHandler extends AbstractProgramElementTagsHandler
{
    private final static List supportedTypes = new ArrayList();
    private String  curFieldName;
    private String  currentArgKey;
    private Map     args;

    static {
        supportedTypes.add("java.lang.String");
        supportedTypes.add("java.lang.Integer");
        supportedTypes.add("int");
        supportedTypes.add("java.lang.Float");
        supportedTypes.add("float");
        supportedTypes.add("java.lang.Long");
        supportedTypes.add("long");
        supportedTypes.add("java.lang.Double");
        supportedTypes.add("double");
        supportedTypes.add("java.lang.Boolean");
        supportedTypes.add("boolean");
        supportedTypes.add("java.util.Date");
    }

    /**
     * Iterates over all POJOs and evaluates the body of the tag for each class.
     *
     * @param template              The body of the block tag
     * @param attributes            The attributes of the template tag
     * @exception XDocletException
     * @doc.tag                     type="block"
     */
    public void forAllForms(String template, Properties attributes) throws XDocletException
    {
        Collection classes = getAllClasses();

        for (Iterator i = classes.iterator(); i.hasNext(); ) {
            XClass currentClass = (XClass) i.next();

            setCurrentClass(currentClass);
            if (DocletSupport.isDocletGenerated(getCurrentClass()) || (getCurrentClass().isAbstract())) {
                continue;
            }
            generate(template);
        }
    }

    /**
     * Gets the "name" attribute for the <form> element in the xml descriptor. This should be the "path" form
     * attribute if this is a ValidatorActionForm or the "name" attribute otherwise.
     *
     * @param attributes         The content tag attributes.
     * @return                   form name
     * @throws XDocletException  if anything goes awry.
     * @doc.tag                  type="content"
     */
    public String formName(Properties attributes) throws XDocletException
    {
        return Introspector.decapitalize(getCurrentClass().getTransformedName());
    }

    /**
     * Iterates over all arguments for the current field.
     *
     * @param template           The body of the block tag
     * @param attributes         The attributes of the template tag
     * @throws XDocletException
     * @doc.tag                  type="block"
     */
    public void forAllFieldArgs(String template, Properties attributes) throws XDocletException
    {
        for (Iterator iterator = args.keySet().iterator(); iterator.hasNext(); ) {
            currentArgKey = (String) iterator.next();
            generate(template);
        }
    }

    /**
     * Current argument index number (0 to 3).
     *
     * @param props  The attributes of the template tag
     * @return       argument index
     * @doc.tag      type="content"
     */
    public String argIndex(Properties props)
    {
        return currentArgKey.charAt(3) + "";
    }

    /**
     * Current argument name - only valid if argument is for a specific validator type.
     *
     * @param props  The attributes of the template tag
     * @return       argument name
     * @doc.tag      type="content"
     */
    public String argName(Properties props)
    {
        String name = currentArgKey.substring(currentArgKey.indexOf('_') + 1);

        return name;
    }

    /**
     * Current argument value, which is either an inline value or resource key.
     *
     * @param props  The attributes of the template tag
     * @return       argument value
     * @doc.tag      type="content"
     */
    public String argValue(Properties props)
    {
        return (String) args.get(currentArgKey);
    }

    /**
     * Evaluates body if current argument is a resource key.
     *
     * @param template           The body of the block tag
     * @param attributes         The attributes of the template tag
     * @throws XDocletException
     * @doc.tag                  type="block"
     */
    public void ifArgIsResource(String template, Properties attributes) throws XDocletException
    {
        if (currentArgKey.indexOf("resource") > 0) {
            generate(template);
        }
    }

    /**
     * Evaluates the body if the current argument is an inline value rather than a resource key.
     *
     * @param template           The body of the block tag
     * @param attributes         The attributes of the template tag
     * @throws XDocletException
     * @doc.tag                  type="block"
     */
    public void ifArgIsValue(String template, Properties attributes) throws XDocletException
    {
        if (currentArgKey.indexOf("value") > 0) {
            generate(template);
        }
    }

    /**
     * Evaluates the body if the current argument is a validator-specific argument.
     *
     * @param template           The body of the block tag
     * @param attributes         The attributes of the template tag
     * @throws XDocletException
     * @doc.tag                  type="block"
     */
    public void ifArgIsForType(String template, Properties attributes) throws XDocletException
    {
        if (currentArgKey.indexOf('_') > 0) {
            generate(template);
        }
    }

    /**
     * Evaluates the body if there is no arg0 specified.
     *
     * @param template           The body of the block tag
     * @param attributes         The attributes of the template tag
     * @throws XDocletException
     * @doc.tag                  type="block"
     */
    public void ifNoArg0(String template, Properties attributes) throws XDocletException
    {
        if (args.get("arg0resource") == null && args.get("arg0value") == null) {
            generate(template);
        }
    }

    /**
     * Evaluates the body if form has fields requiring validation.
     *
     * @param template           The body of the block tag
     * @param attributes         The attributes of the template tag
     * @throws XDocletException
     * @doc.tag                  type="block"
     */
    public void ifFormHasFields(String template, Properties attributes) throws XDocletException
    {
        if (getFields(getCurrentClass()).size() > 0) {
            generate(template);
        }
    }

    /**
     * Iterates the body for each field of the current form requiring validation.
     *
     * @param template           The body of the block tag
     * @param attributes         The attributes of the template tag
     * @throws XDocletException
     * @doc.tag                  type="block"
     */
    public void forAllFields(String template, Properties attributes) throws XDocletException
    {
        XClass clazz = getCurrentClass();
        Map setters = getFields(clazz);

        for (Iterator iterator = setters.keySet().iterator(); iterator.hasNext(); ) {
            curFieldName = (String) iterator.next();

            XMethod field = (XMethod) setters.get(curFieldName);

            setCurrentMethod(field);
            loadFieldArguments();
            generate(template);
        }
    }

    /**
     * Returns the current fields name.
     *
     * @param props  The attributes of the template tag
     * @return       current field's name
     * @doc.tag      type="content"
     */
    public String fieldName(Properties props)
    {
        return curFieldName;
    }

    /**
     * Returns a comma-separated list of the specified validator types.
     *
     * @param props  The attributes of the template tag
     * @return       validator type list
     * @doc.tag      type="content"
     */
    public String validatorList(Properties props)
    {
        XMethod method = getCurrentMethod();
        Collection tags = method.getDoc().getTags("spring.validator");
        StringBuffer buffer = new StringBuffer();

        for (Iterator iterator = tags.iterator(); iterator.hasNext(); ) {
            XTag tag = (XTag) iterator.next();

            buffer.append(tag.getAttributeValue("type"));
            if (iterator.hasNext()) {
                buffer.append(",");
            }
        }
        return buffer.toString();
    }

    private Map getFields(XClass clazz) throws XDocletException
    {
        return getFields(clazz, "");
    }

    private Map getFields(XClass clazz, String prefix) throws XDocletException
    {
        Map fields = new SequencedHashMap();

        Collection curFields = clazz.getMethods(true);

        // TODO: nested forms currently won't work unless
        // there is a setter for it, but that is not needed
        // as only the sub-forms must have setters.  The top-level
        // only requires a getter.
        for (Iterator iterator = curFields.iterator(); iterator.hasNext(); ) {
            XMethod setter = (XMethod) iterator.next();

            if (MethodTagsHandler.isSetterMethod(setter)) {
                if (setter.getDoc().getTag("spring.validator") != null) {
                    String name = MethodTagsHandler.getPropertyNameFor(setter);
                    XParameter param = (XParameter) setter.getParameters().iterator().next();
                    String type = param.getType().getQualifiedName();

                    if (supportedTypes.contains(type)) {
                        fields.put(prefix + name, setter);
                    }
                    else {
                        fields.putAll(getFields(param.getType(), prefix + (prefix.length() == 0 ? "" : ".") + name + "."));
                    }
                }
            }
        }

        return fields;
    }

    private void loadFieldArguments()
    {
        /*
         * A bit of explanation is due here.  Rather than come up with
         * some fancy data structure to keep validator arguments stored into,
         * I simply store them into a Map with the value being the value
         * from the parameter.  The name, however, represents the argument
         * index, whether its a resource or an inline value, and whether it
         * is attached to a particular validator type.  The name format is:
         * argN[resource|value][_TYPE]
         * the argN[resource|value] piece is the actual parameter name.
         * N is the argument index.
         * TYPE is added only if the parameter appears on spring.validator tag
         * which indicates its only associated with a specific validator type.
         */
        args = new SequencedHashMap();

        XMethod method = getCurrentMethod();

        // Collect all general args
        Collection argTags = method.getDoc().getTags("spring.validator-args");

        for (Iterator argsIterator = argTags.iterator(); argsIterator.hasNext(); ) {
            XTag tag = (XTag) argsIterator.next();
            Collection attributeNames = tag.getAttributeNames();

            for (Iterator attributesIterator = attributeNames.iterator(); attributesIterator.hasNext(); ) {
                String name = (String) attributesIterator.next();

                if (name.startsWith("arg")) {
                    args.put(name, tag.getAttributeValue(name));
                }
            }
        }

        // Collect all type-specific args
        Collection argTypeTags = method.getDoc().getTags("spring.validator");

        for (Iterator typeTagsIterator = argTypeTags.iterator(); typeTagsIterator.hasNext(); ) {
            XTag tag = (XTag) typeTagsIterator.next();
            Collection attributeNames = tag.getAttributeNames();
            String type = tag.getAttributeValue("type");

            for (Iterator attributesIterator = attributeNames.iterator(); attributesIterator.hasNext(); ) {
                String name = (String) attributesIterator.next();

                if (name.startsWith("arg")) {
                    args.put(name + "_" + type, tag.getAttributeValue(name));
                }
            }
        }
    }
}
TOP

Related Classes of xdoclet.modules.spring.SpringValidatorTagsHandler

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.