Package xdoclet.modules.ejb.entity

Source Code of xdoclet.modules.ejb.entity.DataObjectTagsHandler

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

////import xdoclet.util.serialveruid.*;

import java.text.MessageFormat;
import java.util.*;

import org.apache.commons.logging.Log;

import xjavadoc.*;

import xdoclet.DocletContext;
import xdoclet.DocletTask;
import xdoclet.XDocletException;
import xdoclet.modules.ejb.EjbTagsHandler;
import xdoclet.modules.ejb.XDocletModulesEjbMessages;
import xdoclet.modules.ejb.entity.DataObjectSubTask;
import xdoclet.modules.ejb.intf.InterfaceTagsHandler;
import xdoclet.tagshandler.MethodTagsHandler;
import xdoclet.util.LogUtil;
import xdoclet.util.Translator;

import xdoclet.util.TypeConversionUtil;

/**
* @author               Ara Abrahamian (ara_e@email.com)
* @created              13. juni 2002
* @xdoclet.taghandler   namespace="EjbDataObj"
* @version              $Revision: 1.12 $
*/
public class DataObjectTagsHandler extends EjbTagsHandler
{
    protected static HashMap dataObjectClassnames = new HashMap();

    protected static String currentDataObjectClassname = "";

    /**
     * @param clazz                 Description of Parameter
     * @return                      the full qualified data-object class name
     * @exception XDocletException
     */
    public static String getDataMostSuperObjectClass(XClass clazz) throws XDocletException
    {
        String currentDataClass = (String) dataObjectClassnames.get(clazz.getName());
        // Begin at the first super class

        XClass cur_clazz = clazz;

        currentDataClass = generateDataObjectClass(cur_clazz);

        loopa :
        do {
            // Find if we have an abstract data class definition to generate
            Collection methods = cur_clazz.getMethods();
            boolean found = false;

            for (Iterator j = methods.iterator(); j.hasNext(); ) {
                XMethod method = (XMethod) j.next();

                if (method.getName().equals("getData")) {
                    found = true;
                    currentDataClass = generateDataObjectClass(cur_clazz);
                }

                if (found) {
                    break loopa;
                }
            }
            cur_clazz = cur_clazz.getSuperclass();
        } while (cur_clazz != null);

        if (currentDataClass == null) {
            throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.DATACLASS_NOT_FOUND));
        }
        return currentDataClass;
    }

    /**
     * Gets the DataObjectMethod attribute of the DataObjectTagsHandler class
     *
     * @param method                Describe what the parameter does
     * @return                      The DataObjectMethod value
     * @exception XDocletException
     */
    public static boolean isDataObjectMethod(XMethod method) throws XDocletException
    {
        if (EntityTagsHandler.isEntity(method.getContainingClass()) == false) {
            return false;
        }

        boolean is_getData = isGetDataMethod(method);

        if (is_getData) {
            return true;
        }
        else {
            return isSetDataMethod(method);
        }
    }

    /**
     * @param clazz  Description of Parameter
     * @return       the full qualified data-object class name
     */
    public static String getDataObjectClassFor(XClass clazz)
    {
        if (dataObjectClassnames.get(clazz.getQualifiedName()) != null) {
            return (String) dataObjectClassnames.get(clazz.getQualifiedName());
        }

        String fileName = clazz.getContainingPackage().getName();
        String name_pattern = null;
        String package_pattern = null;

        String dataObjectClass = clazz.getDoc().getTagAttributeValue("ejb:data-object", "class", false);

        if (dataObjectClass != null) {
            return dataObjectClass;
        }

        name_pattern = clazz.getDoc().getTagAttributeValue("ejb:data-object", "pattern", false);

        if (name_pattern == null) {
            name_pattern = getDataObjectClassPattern();
        }

        package_pattern = clazz.getDoc().getTagAttributeValue("ejb:data-object", "package", false);

        String dataObjectClass_name = null;

        if (name_pattern.indexOf("{0}") != -1) {
            dataObjectClass_name = MessageFormat.format(name_pattern, new Object[]{getShortEjbNameFor(clazz)});
        }
        else {
            dataObjectClass_name = name_pattern;
        }

        // Fix package name
        fileName = choosePackage(fileName, package_pattern, DocletTask.getSubTaskName(DataObjectSubTask.class));
        if (fileName.length() > 0) {
            fileName += ".";
        }

        fileName += dataObjectClass_name;

        return fileName;
    }

    /**
     * @return   the current data-object class name
     */
    public static String getCurrentDataObjectClassname()
    {
        return currentDataObjectClassname;
    }

    /**
     * Returns true if ejb:data-object defined and generate param is true, false if not true.
     *
     * @param clazz  Description of Parameter
     * @return       Description of the Returned Value
     */
    public static boolean isGenerationNeeded(XClass clazz)
    {
        if (isDataObjectSubTaskActive() == false) {
            return false;
        }

        // When the tag is there and is set to "false" then return false
        if (clazz.getDoc().hasTag("ejb:data-object")) {
            String generate_str = clazz.getDoc().getTagAttributeValue("ejb:data-object", "generate", false);
            boolean generate = TypeConversionUtil.stringToBoolean(generate_str, true);

            return generate;
        }
        else {
            return true;
        }
    }

    /**
     * @param current_data_object_classname
     */
    public static void setCurrentDataObjectClassname(String current_data_object_classname)
    {
        currentDataObjectClassname = current_data_object_classname;
    }

    /**
     * @param name   Description of Parameter
     * @param value  Description of Parameter
     */
    public static void putDataObjectClassnames(String name, String value)
    {
        dataObjectClassnames.put(name, value);
    }

    /**
     * Used by dataMostSuperObjectClass() to get the data object's full qualified class name. If name and package
     * parameters of ejb:data-object defined, theire values are used, otherwise defaults are used.
     *
     * @param clazz  Description of Parameter
     * @return       Description of the Returned Value
     * @see          #dataMostSuperObjectClass()
     */
    public static String generateDataObjectClass(XClass clazz)
    {
        String fileName = clazz.getContainingPackage().getName();
        String name_pattern = null;
        String package_pattern = null;

        name_pattern = clazz.getDoc().getTagAttributeValue("ejb:data-object", "name", false);
        if (name_pattern == null) {
            name_pattern = getDataObjectClassPattern();
        }

        package_pattern = clazz.getDoc().getTagAttributeValue("ejb:data-object", "package", false);

        String dataobject_name = null;

        if (name_pattern.indexOf("{0}") != -1) {
            dataobject_name = MessageFormat.format(name_pattern, new Object[]{getShortEjbNameFor(clazz)});
        }
        else {
            dataobject_name = name_pattern;
        }

        // Fix package name
        fileName = choosePackage(fileName, package_pattern, DocletTask.getSubTaskName(DataObjectSubTask.class));
        fileName += "." + dataobject_name;

        return fileName;
    }

    /**
     * @param clazz  Description of Parameter
     * @return       Description of the Returned Value
     */
    public static boolean hasCustomBulkData(XClass clazz)
    {
        Log log = LogUtil.getLog(DataObjectSubTask.class, "hasCustomBulkData");

        if (log.isDebugEnabled()) {
            log.debug("Searching @ejb:bulk-data in Class " + clazz);
        }

        if (isDataObjectSubTaskActive() == false) {
            return false;
        }

        return clazz.getDoc().hasTag("ejb:bulk-data");
    }

    /**
     * @return   the data-object class pattern
     */
    protected static String getDataObjectClassPattern()
    {
        final DataObjectSubTask dataobject_subtask = ((DataObjectSubTask) DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(DataObjectSubTask.class)));

        if (dataobject_subtask != null) {
            return dataobject_subtask.getDataObjectClassPattern();
        }
        else {
            return DataObjectSubTask.DEFAULT_DATAOBJECT_CLASS_PATTERN;
        }
    }

    /**
     * @param clazz
     * @return                      True if there is a Data Container equals() needed because user set tag "data-equals"
     *      to true or ommitted it
     * @exception XDocletException
     */
    protected static boolean hasDataEquals(XClass clazz) throws XDocletException
    {
        Log log = LogUtil.getLog(DataObjectSubTask.class, "hasDataEquals");

        if (log.isDebugEnabled()) {
            log.debug("Searching @ejb:data-object equals for Class " + clazz.getQualifiedName());
        }

        if (isDataObjectSubTaskActive() == false) {
            return false;
        }

        String value = getTagValue(
            FOR_CLASS,
            clazz.getDoc(),
            "ejb:data-object",
            "equals",
            "true,false",
            "true",
            true,
            false
            );

        return TypeConversionUtil.stringToBoolean(value, true);
    }

    /**
     * Gets the DataObjectSubTaskActive attribute of the DataObjectTagsHandler class
     *
     * @return   The DataObjectSubTaskActive value
     */
    private static boolean isDataObjectSubTaskActive()
    {
        return DocletContext.getInstance().isSubTaskDefined(DocletTask.getSubTaskName(DataObjectSubTask.class));
    }

    /**
     * Returns true if method is getData()
     *
     * @param method                Description of Parameter
     * @return                      The GetDataMethod value
     * @exception XDocletException
     */
    private static boolean isGetDataMethod(XMethod method) throws XDocletException
    {
        if (isDataObjectSubTaskActive() == false) {
            return false;
        }

        return method.isAbstract() && method.getName().equals("getData") && DataObjectTagsHandler.getDataMostSuperObjectClass(method.getContainingClass()).equals(method.getReturnType().getType());
    }

    /**
     * Returns true if method is setData()
     *
     * @param method  Description of Parameter
     * @return        The SetDataMethod value
     */
    private static boolean isSetDataMethod(XMethod method)
    {
        if (isDataObjectSubTaskActive() == false) {
            return false;
        }

        if (method.isAbstract() && method.getName().equals("setData")) {
            Collection params = method.getParameters();

            if (params.size() == 1 &&
                ((XParameter) params.iterator().next()).getType().getQualifiedName().equals(DataObjectTagsHandler.getDataObjectClassFor(method.getContainingClass()))
                ) {
                return true;
            }
            else {
                return false;
            }
        }
        else {
            return false;
        }
    }

    /**
     * Returns true if ejb:data-object defined and setdata param is true, false if not true.
     *
     * @param clazz
     * @return                      Description of the Returned Value
     * @exception XDocletException
     */
    private static boolean hasDataMethod(XClass clazz) throws XDocletException
    {
        if (isDataObjectSubTaskActive() == false) {
            return false;
        }

        String value = getTagValue(
            FOR_CLASS,
            clazz.getDoc(),
            "ejb:data-object",
            "setdata",
            "true,false",
            "true",
            true,
            false
            );

        boolean result = TypeConversionUtil.stringToBoolean(value, false);

        return result;
    }

    /**
     * @param pTemplate             Description of Parameter
     * @exception XDocletException
     */
    public void isDataContentEquals(String pTemplate) throws XDocletException
    {
        if (hasDataEquals(getCurrentClass())) {
            generate(pTemplate);
        }
    }

    /**
     * Returns data-object class name for the bean.
     *
     * @return                      The data-object class name for the bean.
     * @exception XDocletException
     * @doc.tag                     type="content"
     */
    public String dataObjectClass() throws XDocletException
    {
        return getDataObjectClassFor(getCurrentClass());
    }

    /**
     * Returns the data-object class name highest in the hierarchy of derived beans. Because of possible inheritance
     * between entity bean, the type of the generated getData method must be the one of the most super class of the
     * current entity bean. The current Data class must extend the corresponding super Data class.
     *
     * @return                      The data-object class name highest in the hierarchy of derived beans.
     * @exception XDocletException
     * @doc.tag                     type="content"
     */
    public String dataMostSuperObjectClass() throws XDocletException
    {
        return getDataMostSuperObjectClass(getCurrentClass());
    }

    /**
     * @return                      Description of the Returned Value
     * @exception XDocletException
     * @doc.tag                     type="content"
     */
    public String generateDataObjectClass() throws XDocletException
    {
        return generateDataObjectClass(getCurrentClass());
    }

    /**
     * Evaluate the body block if ejb:data-object setdata="true". If not defined then default is true.
     *
     * @param pTemplate             Description of Parameter
     * @exception XDocletException
     * @see                         #ifIsWithDataContainer(java.lang.String)
     * @doc.tag                     type="block"
     */
    public void ifIsWithDataMethod(String pTemplate) throws XDocletException
    {
        if (hasDataMethod(getCurrentClass())) {
            generate(pTemplate);
        }
    }

    /**
     * Evaluate the body block if ejb:data-object container="true". If not defined then default is true.
     *
     * @param pTemplate             Description of Parameter
     * @exception XDocletException
     * @doc.tag                     type="block"
     */
    public void ifIsWithDataContainer(String pTemplate) throws XDocletException
    {
        if (isGenerationNeeded(getCurrentClass())) {
            generate(pTemplate);
        }
        // We can also have a generate false because we use the same dataclass
        // that the super class (e.g. BMP extends CMP)
        else {
            String hasClass = getTagValue(
                FOR_CLASS,
                getCurrentClass().getDoc(),
                "ejb:data-object",
                "class",
                null,
                null,
                false,
                false
                );

            if (hasClass != null) {
                generate(pTemplate);
            }
        }
    }

    /**
     * Evaluate the body block if ejb:aggregate is defined for current getter method, denoting that the specified getter
     * method returns an aggregated object.
     *
     * @param template              The body of the block tag
     * @exception XDocletException
     * @see                         #ifIsNotAggregate(java.lang.String)
     * @see                         #isAggregate(xjavadoc.XMethod)
     * @doc.tag                     type="block"
     */
    public void ifIsAggregate(String template) throws XDocletException
    {
        if (isAggregate(getCurrentMethod())) {
            generate(template);
        }
    }

    /**
     * Evaluate the body block if ejb:aggregate is not defined for current getter method.
     *
     * @param template              The body of the block tag
     * @exception XDocletException
     * @see                         #ifIsAggregate(java.lang.String)
     * @see                         #isAggregate(xjavadoc.XMethod)
     * @doc.tag                     type="block"
     */
    public void ifIsNotAggregate(String template) throws XDocletException
    {
        if (!isAggregate(getCurrentMethod())) {
            generate(template);
        }
    }

    /**
     * Evaluates the body block for each setData method.
     *
     * @param template              The body of the block tag
     * @exception XDocletException
     * @see                         #forAllSuper(java.lang.String,java.lang.String)
     * @doc.tag                     type="block"
     */
    public void forAllSuperSetData(String template) throws XDocletException
    {
        forAllSuper(template, "setData");
    }

    /**
     * @return                      Description of the Returned Value
     * @exception XDocletException
     */
    public String parentDataObjectClass() throws XDocletException
    {
        Log log = LogUtil.getLog(DataObjectSubTask.class, "parentDataObjectClass");

        if (log.isDebugEnabled()) {
            log.debug("Searching for @ejb:data-object in Current/Super Class " + getCurrentClass().getName());
        }

        if (getCurrentClass().getDoc().hasTag("ejb:data-object", false)) {
            String extends_class = getCurrentClass().getDoc().getTagAttributeValue("ejb:data-object", "extends", false);

            return extends_class != null ? extends_class : "java.lang.Object";
        }

        if (getCurrentClass().getSuperclass() != null && isEjb(getCurrentClass().getSuperclass())) {
            pushCurrentClass(getCurrentClass().getSuperclass());

            String clazz = dataObjectClass();

            popCurrentClass();

            if (clazz == null) {
                return "java.lang.Object";
            }

            return clazz;
        }
        else {
            return "java.lang.Object";
        }
    }

    /**
     * Returns the name of the class dataobject class extends.
     *
     * @return                      The name of generated PK class.
     * @exception XDocletException
     * @doc.tag                     type="content"
     */
    public String extendsFrom() throws XDocletException
    {
        return extendsFromFor(getCurrentClass(), "ejb:data-object", null, "extends", "java.lang.Object");
    }

    /**
     * Return the dataobject class name from interface name.
     *
     * @return                      the data-object class name
     * @exception XDocletException
     * @doc.tag                     type="content"
     */
    public String dataObjectClassNameFromInterfaceName() throws XDocletException
    {
        String return_type = MethodTagsHandler.getMethodTypeFor(getCurrentMethod());

        if (return_type == null) {
            throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.INTERFACE_NOT_FOUND, new String[]{getCurrentMethod().getName()}));
        }

        String bean_class_name = InterfaceTagsHandler.getBeanClassNameFromInterfaceNameFor(return_type);

        if (bean_class_name == null) {
            throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.INTERFACE_IMPL_NOT_FOUND, new String[]{return_type}));
        }

        XClass bean_class = getXJavaDoc().getXClass(bean_class_name);

        if (bean_class == null) {
            throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.INTERFACE_IMPL_COULDNT_LOAD, new String[]{return_type}));
        }

        String dataobject_class_name = DataObjectTagsHandler.getDataObjectClassFor(bean_class);

        if (dataobject_class_name == null) {
            throw new XDocletException(Translator.getString(XDocletModulesEjbMessages.class, XDocletModulesEjbMessages.INTERFACE_DATAOBJECT_NOT_KNOWN, new String[]{return_type}));
        }

        return dataobject_class_name;
    }

    /**
     * Returns true if method has ejb:aggregate, false otherwise.
     *
     * @param method                Description of Parameter
     * @return                      The Aggregate value
     * @exception XDocletException
     */
    protected boolean isAggregate(XMethod method) throws XDocletException
    {
        if (isDataObjectSubTaskActive() == false) {
            return false;
        }

        return method.getDoc().hasTag("ejb:aggregate");
    }

    /**
     * Gets the DependentClassFor attribute of the DataObjectTagsHandler object
     *
     * @param clazz                 Describe what the parameter does
     * @param type                  Describe what the parameter does
     * @return                      The DependentClassFor value
     * @exception XDocletException
     */
    protected String getDependentClassFor(XClass clazz, String type) throws XDocletException
    {
        return getDataObjectClassFor(clazz);
    }

    /**
     * Browse all super classes and search for a special method to generate it in the current CMP/BMP class.
     *
     * @param template              The body of the block tag
     * @param methodName            Description of Parameter
     * @exception XDocletException
     */
    protected void forAllSuper(String template, String methodName) throws XDocletException
    {
        XClass oldClass = getCurrentClass();
        XClass superclass = null;
        List already = new ArrayList();

        // Begin at the first super class
        //pushCurrentClass( getCurrentClass().superclass() );

        do {
            // Find if we have an abstract data class definition to generate
            Collection methods = getCurrentClass().getMethods();
            XMethod methodFound = null;

            for (Iterator j = methods.iterator(); j.hasNext(); ) {
                XMethod method = (XMethod) j.next();

                if (method.getName().equals(methodName)) {
                    methodFound = method;
                }

                if (methodFound != null) {
                    break;
                }
            }

            if (methodFound != null) {
                // We can not use contains because it is based on equals() and
                // we need to compare based on compareTo()
                Iterator i = already.iterator();
                boolean contained = false;

                while (i.hasNext()) {
                    if (((XMethod) i.next()).compareTo(methodFound) == 0) {
                        contained = true;
                    }

                    if (contained) {
                        break;
                    }
                }

                if (contained == false) {
                    generate(template);
                    already.add(methodFound);
                }
            }

            superclass = getCurrentClass().getSuperclass();

            if (superclass != null) {
                pushCurrentClass(superclass);
            }

        } while (superclass != null);

        setCurrentClass(oldClass);
    }
}
TOP

Related Classes of xdoclet.modules.ejb.entity.DataObjectTagsHandler

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.