Package xdoclet.modules.java.javabean

Source Code of xdoclet.modules.java.javabean.JavaBeanTagsHandler

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

import java.beans.Introspector;
import java.text.MessageFormat;
import java.util.Properties;

import org.apache.commons.collections.Predicate;
import org.apache.commons.logging.Log;
import xjavadoc.XClass;
import xjavadoc.XMethod;
import xjavadoc.XParameter;
import xjavadoc.XTag;
import xjavadoc.XType;

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

/**
* Specific tags handler to make the template easy.
*
* @author               Laurent Etiemble (letiemble@users.sourceforge.net)
* @author               Ryan Ovrevik
* @created              June 20, 2002
* @version              $Revision: 1.5 $
* @xdoclet.taghandler   namespace="JavaBean"
*/
public class JavaBeanTagsHandler extends XDocletTagSupport
{
    public static String getBeanInfoClassFor(XClass clazz) throws XDocletException
    {
        XTag beanTag = clazz.getDoc().getTag("javabean.class");
        String className = null;

        if (beanTag != null) {
            // be paranoid...
            className = beanTag.getAttributeValue("class");
        }

        if (className == null) {
            className = clazz.getQualifiedName();
        }

        return MessageFormat.format(BeanInfoSubTask.GENERATED_BEANINFO_CLASS_NAME, new Object[]{className});
    }

    /**
     * Returns true is the current method meets the minimum requirements for a property accessor. Essentially this means
     * that it takes no arguments and does not return void. This different from XMethod.getAccessor() like functionality
     * in that stricly speeking the XMethod is dealling stricly with the "Simple" naming convention.
     *
     * @param method
     * @return
     */
    private static boolean isPossiblePropertyAccessor(XMethod method)
    {
        return (method.getParameters().size() == 0 && !method.getReturnType().getType().isA("void"));
    }

    private static boolean isPossiblePropertyAccessor(XMethod method, XType propertyType)
    {
        return isPossiblePropertyAccessor(method) && method.getReturnType().getType().equals(propertyType);
    }


    /**
     * Returns true is the current method meets the minimum requirements for a property mutator. Essentially this means
     * that it takes one and only one argument and returns void.
     *
     * @param method
     * @return
     */
    private static boolean isPossiblePropertyMutator(XMethod method)
    {
        return (method.getParameters().size() == 1);
    }

    private static boolean isPossiblePropertyMutator(XMethod method, XType propertyType)
    {
        if (isPossiblePropertyMutator(method)) {
            XParameter firstParam = (XParameter) method.getParameters().get(0);

            return firstParam.getType().equals(propertyType);
        }
        return false;
    }

    private static boolean isExplicitlyReadOnlyProperty(XMethod method)
    {
        XTag tag = method.getDoc().getTag("javabean.property");

        return "true".equalsIgnoreCase(tag.getAttributeValue("readonly"));
    }


    /**
     * The current method must be a valid property accessor (return the property type takes not args) or mutator (return
     * void and takes the property type as the single arg)
     *
     * @param method
     * @return
     */
    private static XType getPropertyType(XMethod method)
    {
        XType result = null;

        //does the method have an explicit name attribute
        String name = method.getDoc().getTag("javabean.property").getAttributeValue("name");

        if ((name == null) || (name.length() <= 0)) {
            if (isPossiblePropertyMutator(method)) {
                XParameter parameter = (XParameter) method.getParameters().get(0);

                result = parameter.getType();
            }
            else if (isPossiblePropertyAccessor(method)) {
                result = method.getReturnType().getType();
            }
        }
        else {
            result = method.getPropertyType().getType();
        }
        return result;
    }

    /**
     * Get the getter method for the current method. Will return null if this method is not a property (determined by
     * the getPropertyName method). Will return null if this is a write only property. A property is write only if an
     * accessor method does not exist. Attempt to find a property accessor that matches an explicitly named getter
     * method. The named method must satisfy the requirements of a property accessor (take no params and return the
     * correct type) The current method could be an accessor or a mutator attempt the use the current method if it
     * satisfies Simple property accessor requirements.
     *
     * @param propertyName
     * @param propertyType
     * @param method
     * @return              the method that will serve as the getter method for this property Will return null if the
     *      current method is not a property method
     */
    private static XMethod getGetterMethod(final String propertyName, final XType propertyType, XMethod method)
    {
        Log log = LogUtil.getLog(JavaBeanTagsHandler.class, "getGetterMethod");

        //do some parameter checking
        if ((propertyName == null) || (propertyName.length() == 0)) {
            log.error("invalid property name: " + propertyName);
            return null;
        }
        if (propertyType == null) {
            log.error("invalid property type: " + propertyType);
            return null;
        }
        if (method == null) {
            log.error("invalid method: " + method);
            return null;
        }

        //get on with the real business
        if (log.isInfoEnabled()) {
            log.info("===find getter method===");
            log.info("method name: " + method.getName());
            log.info("property name: " + propertyName);
            log.info("property type: " + propertyType);
        }

        XMethod getterMethod = null;

        //attempt to find an explicitly named getter method
        final String explicitMethodName = method.getDoc().getTag("javabean.property").getAttributeValue("getter");

        if ((explicitMethodName != null) && (explicitMethodName.length() > 0)) {
            //the method has an explicit attribute
            //there must be a bean property method with the given name
            java.util.List methodList = getCurrentClass().getMethods(
                new Predicate()
                {
                    public boolean evaluate(Object obj)
                    {
                        XMethod method = (XMethod) obj;

                        return isPossiblePropertyAccessor(method, propertyType) &&
                            method.getName().equals(explicitMethodName);
                    }
                }, false);

            //the method name, return, and arguments are known... there can be [0, 1]

            if (methodList.size() == 1) {
                getterMethod = (XMethod) methodList.get(0);
                if (log.isInfoEnabled()) {
                    log.info("found explicit getter " + getterMethod.getName());
                }
                if (isPossiblePropertyAccessor(method, propertyType)
                    && (getterMethod != method)) {
                    log.warn("explicit getter " + getterMethod.getName() + " (should be passed method)");
                }
            }
            else {
                //they gave an explicit method name but it could not be found
                log.warn("no explicit getter " + explicitMethodName);
            }
        }
        else if (isPossiblePropertyAccessor(method, propertyType)) {
            //this was put on the an accessor assume it was what they wanted
            getterMethod = method;
            log.info("using the passed method");
        }
        else {
            //attempt to find the standard bean method (Simple property JavaBeans API specification 8.3.1)
            //takes no params (isPropertyAccessor)
            java.util.List methodList = getCurrentClass().getMethods(
                new Predicate()
                {
                    public boolean evaluate(Object obj)
                    {
                        XMethod method = (XMethod) obj;

                        return isPossiblePropertyAccessor(method, propertyType) &&
                            method.getPropertyName().equals(propertyName);
                    }
                }, false);

            if (methodList.size() == 1) {
                getterMethod = (XMethod) methodList.get(0);
                if (log.isInfoEnabled()) {
                    log.info("found standard getter " + getterMethod.getName());
                }
            }
            else {
                log.warn("no standard getter");
            }
        }
        return getterMethod;
    }

    private static XMethod getSetterMethod(final String propertyName, final XType propertyType, XMethod method)
    {
        Log log = LogUtil.getLog(JavaBeanTagsHandler.class, "getSetterMethod");

        //do some parameter checking
        if ((propertyName == null) || (propertyName.length() == 0)) {
            log.error("invalid property name: " + propertyName);
            return null;
        }
        if (propertyType == null) {
            log.error("invalid property type: " + propertyType);
            return null;
        }
        if (method == null) {
            log.error("invalid method: " + method);
            return null;
        }

        //get on with the real business
        XMethod setterMethod = null;

        if (log.isInfoEnabled()) {
            log.info("===find setter method===");
            log.info("method name: " + method.getName());
            log.info("property name: " + propertyName);
            log.info("property type: " + propertyType);
        }

        //attempt to find an explicitly named setter method
        final String explicitMethodName = method.getDoc().getTag("javabean.property").getAttributeValue("setter");

        if (isExplicitlyReadOnlyProperty(method)) {
            log.info("explicit read only");
        }
        else if ((explicitMethodName != null) && (explicitMethodName.length() > 0)) {
            //the method has an explicit attribute
            //there must be a bean property method with the given name
            java.util.List methodList = getCurrentClass().getMethods(
                new Predicate()
                {
                    public boolean evaluate(Object obj)
                    {
                        XMethod method = (XMethod) obj;

                        return isPossiblePropertyMutator(method, propertyType) &&
                            method.getName().equals(explicitMethodName);
                    }
                }, false);

            if (methodList.size() == 1) {
                setterMethod = (XMethod) methodList.get(0);
                if (log.isInfoEnabled()) {
                    log.info("found explicit setter " + setterMethod.getName());
                }
                if (isPossiblePropertyMutator(method, propertyType)
                    && (setterMethod != method)) {
                    log.warn("explicit setter " + setterMethod.getName() + " (should be passed method)");
                }
            }
            else {
                //they gave an explicit method name but it could not be found
                log.warn("no explicit setter " + explicitMethodName);
            }
        }
        else if (isPossiblePropertyMutator(method, propertyType)) {
            //this was put on a mutator assume it was what they wanted?
            setterMethod = method;
            log.info("using the passed method");
        }
        else {
            //attempt to find the standard bean method (Simple property JavaBeans API specification 8.3.1)
            //takes one param
            java.util.List methodList = getCurrentClass().getMethods(
                new Predicate()
                {
                    public boolean evaluate(Object obj)
                    {
                        XMethod method = (XMethod) obj;

                        return isPossiblePropertyMutator(method, propertyType) &&
                            propertyName.equals(method.getPropertyName());
                    }
                }, false);

            if (methodList.size() == 1) {
                setterMethod = (XMethod) methodList.get(0);
                if (log.isInfoEnabled()) {
                    log.info("found standard setter " + setterMethod.getName());
                }
            }
            else {
                log.info("no standard setter (not tagged readonly)");
            }
        }
        return setterMethod;
    }

    /**
     * Return the getter prefix according to the class tag that contains a class.
     *
     * @param attributes            XDoclet attributes
     * @return                      The getter prefix
     * @exception XDocletException  Thrown in case of problem
     */
    public String getterPrefix(Properties attributes) throws XDocletException
    {
        String name = getTagValue(attributes, FOR_CLASS);

        if ("boolean".equals(name)) {
            return "is";
        }
        if ("java.lang.Boolean".equals(name)) {
            return "is";
        }
        return "get";
    }

    /**
     * Get the getter method for the current method
     *
     * @return
     */
    public String getGetterMethodNameQuoted()
    {
        XMethod currentMethod = getCurrentMethod();
        String propertyName = getPropertyName(currentMethod);
        XType propertyType = getPropertyType(currentMethod);

        if (propertyName != null) {
        }

        XMethod getterMethod = getGetterMethod(propertyName, propertyType, currentMethod);


        if (getterMethod == null) {
            return "null";
        }
        else {
            return "\"" + getterMethod.getName() + "\"";
        }
    }

    /**
     * Get the setter method for the current method
     *
     * @return
     */
    public String getSetterMethodNameQuoted()
    {
        XMethod currentMethod = getCurrentMethod();
        String propertyName = getPropertyName(currentMethod);
        XType propertyType = getPropertyType(currentMethod);

        XMethod setterMethod = getSetterMethod(propertyName, propertyType, currentMethod);

        if (setterMethod == null) {
            return "null";
        }
        else {
            return "\"" + setterMethod.getName() + "\"";
        }
    }

    /**
     * Get the property name for the current method xxx rlo the is fucked
     *
     * @return
     */
    public String getPropertyNameQuoted()
    {
        String name = getPropertyName(getCurrentMethod());

        if (name == null) {
            return "null";
        }
        else {
            return "\"" + name + "\"";
        }
    }

    /**
     * return configured bean class name or current class name
     *
     * @param attributes            XDoclet attributes
     * @return                      The getter prefix
     * @exception XDocletException  Thrown in case of problem
     */
    public String beanClass(Properties attributes) throws XDocletException
    {
        if (getTagValue(FOR_CLASS, "javabean.class", "class", null, null, false, false) != null) {
            return getTagValue(FOR_CLASS, "javabean.class", "class", null, null, false, false);
        }
        else {
            return getCurrentClass().getQualifiedName();
        }
    }

    /**
     * Capitalize the first letter of a class tag (i.e countToken => CountToken)
     *
     * @param attributes            XDoclet attributes
     * @return                      The class tag capitalized
     * @exception XDocletException  Thrown in case of problem
     */
    public String capitalizeClassTag(Properties attributes) throws XDocletException
    {
        String name = getTagValue(attributes, FOR_CLASS);

        if (name == null || name.length() == 0) {
            return name;
        }
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
            Character.isUpperCase(name.charAt(0))) {
            return name;
        }

        char chars[] = name.toCharArray();

        chars[0] = Character.toUpperCase(chars[0]);
        return new String(chars);
    }

    /**
     * Get the property name for the current method xxx rlo the is fucked
     *
     * @param currentMethod
     * @return
     */
    private String getPropertyName(XMethod currentMethod)
    {
        String name = null;
        XTag tag = currentMethod.getDoc().getTag("javabean.property");

        if (tag != null) {
            //the method is a property
            name = tag.getAttributeValue("name");
            //does the method have an explicit attribute
            if ((name == null) || (name.length() <= 0)) {
                //figure out the name from the method
                //must be a standard bean method
                name = getCurrentMethod().getPropertyName();
            }
            else {
                name = Introspector.decapitalize(name);
            }
        }
        return name;
    }
}
TOP

Related Classes of xdoclet.modules.java.javabean.JavaBeanTagsHandler

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.