Package xdoclet.modules.ejb

Source Code of xdoclet.modules.ejb.EjbTagsHandler

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

import java.util.*;

import org.apache.commons.logging.Log;

import xjavadoc.*;

import xdoclet.DocletContext;
import xdoclet.DocletSupport;
import xdoclet.DocletTask;
import xdoclet.SubTask;
import xdoclet.XDocletException;
import xdoclet.XDocletTagSupport;
import xdoclet.modules.ejb.entity.*;
import xdoclet.modules.ejb.home.HomeInterfaceSubTask;
import xdoclet.modules.ejb.home.LocalHomeInterfaceSubTask;
import xdoclet.modules.ejb.intf.LocalInterfaceSubTask;
import xdoclet.modules.ejb.intf.RemoteInterfaceSubTask;
import xdoclet.modules.ejb.mdb.MdbSubTask;
import xdoclet.modules.ejb.mdb.MdbTagsHandler;
import xdoclet.modules.ejb.session.SessionSubTask;
import xdoclet.modules.ejb.session.SessionTagsHandler;
import xdoclet.tagshandler.PackageTagsHandler;
import xdoclet.util.LogUtil;
import xdoclet.util.Translator;
import xdoclet.util.TypeConversionUtil;

/**
* @author               Ara Abrahamian (ara_e@email.com)
* @author               Christoph G. Jung (christoph.jung@infor.de)
* @created              Oct 15, 2001
* @xdoclet.taghandler   namespace="Ejb"
* @version              $Revision: 1.30 $
*/
public class EjbTagsHandler extends XDocletTagSupport
{
    // further constants related to J2EE1.4
    public final static String SERVICE_ENDPOINT = "service-endpoint";
    public final static String ALL = "all";
    public final static String SERVICE_ENDPOINT_SUFFIX = "Service";

    protected final static String LOCAL_SUFFIX = "Local";

    private XClass  currentEjbClass;

    /**
     * Gets the AConcreteEJBean attribute of the EjbTagsHandler class
     *
     * @param clazz                 Describe what the parameter does
     * @return                      The AConcreteEJBean value
     * @exception XDocletException
     */
    public static boolean isAConcreteEJBean(XClass clazz) throws XDocletException
    {
        XTag beanTag = clazz.getDoc().getTag("ejb:bean");

        if (beanTag != null) {
            String generateStr = beanTag.getAttributeValue("generate");

            if (generateStr != null) {
                boolean generate = TypeConversionUtil.stringToBoolean(generateStr, true);

                // generate="true" specifically
                if (generate == true) {
                    return true;
                }
                else {
                    // generate="false" specifically
                    return false;
                }
            }

            // ejb:beam name specified, so it's a concrete ejb
            if (beanTag.getAttributeValue("name") != null) {
                return true;
            }
        }

        // now try to guess because it wasn't specifically specified whether
        // it should be generated or not
        SubTask subtask = getSubTaskClassForClass(clazz);

        if (clazz.isAbstract() == true) {
            if (hasANonDocletGeneratedSubClass(clazz) == true) {
                return false;
            }

            // an abstract mdb/etc?
            if (subtask == null) {
                return false;
            }

            // if <entitycmp/bmp/session/> is on, then do the best to guess correctly
            if (DocletContext.getInstance().isSubTaskDefined(subtask.getSubTaskName()) == true) {
                //none of the above guesses worked, assume it's concrete!
                return true;
            }
            else {
                // if <entitycmp/bmp/session/> is off, so if class is abstract then the bean is abstract except for entity cmp beans in ejb2 cmp2
                if (CmpTagsHandler.isEntityCmp(clazz) && CmpTagsHandler.isUsingCmp2Impl(clazz)) {
                    return true;
                }

                return false;
            }
        }
        else {
            // if <entitycmp/bmp/> is on, then it's an error or not specify the class abstract, except for <session/> that non-abstract is also legal
            if (subtask != null && DocletContext.getInstance().isSubTaskDefined(subtask.getSubTaskName())) {
                if (subtask.getSubTaskName().equals(DocletTask.getSubTaskName(SessionSubTask.class))) {
                    return true;
                }

                String currentClassName = clazz.getQualifiedName();

                throw new XDocletException(Translator.getString("xdoclet.modules.ejb.Messages", "class_not_abstract",
                    new String[]{currentClassName, DocletTask.getSubTaskName(SessionSubTask.class)}));
            }
            else {
                return true;
            }
        }
    }

    /**
     * Returns the EJB name of the clazz by seaching for ejb:bean's name parameter. If that is not found, it uses the
     * class' name minus any suffix from the list in the 'ejbClassNameSuffix' config parameter ("Bean,EJB,Ejb" by
     * default).
     *
     * @param clazz  The EJB bean class for which we want the EJB name
     * @return       The EjbName value
     * @see          #ejbName(java.util.Properties)
     */
    public static String getEjbNameFor(XClass clazz)
    {
        XTag beanTag = clazz.getDoc().getTag("ejb:bean");
        String paramValue = null;

        if (beanTag != null) {
            paramValue = beanTag.getAttributeValue("name");
        }

        if (paramValue == null) {
            String className = clazz.getName();

            // remove any suffix from ejbClassNameSuffix list
            String suffixlist = (String) getDocletContext().getConfigParam("ejbClassNameSuffix");
            StringTokenizer st = new StringTokenizer(suffixlist, ",");

            while (st.hasMoreTokens()) {
                String suffix = st.nextToken();

                if (className.endsWith(suffix)) {
                    int index = className.lastIndexOf(suffix);

                    className = className.substring(0, index);
                    break;
                }
            }

            return className;
        }

        return paramValue;
    }

    /**
     * Returns short version of the EJB name of the clazz.
     *
     * @param clazz  the class we want its short EJB name
     * @return       The shortEjbName value
     * @see          #shortEjbName()
     */
    public static String getShortEjbNameFor(XClass clazz)
    {
        Log log = LogUtil.getLog(EjbTagsHandler.class, "shortEjbName");

        // Find the last part of the name
        StringTokenizer ejbNameTokens = new StringTokenizer(getEjbNameFor(clazz), ":./\\-");
        String name;

        do {
            name = ejbNameTokens.nextToken();
        } while (ejbNameTokens.hasMoreTokens());

        if (log.isDebugEnabled()) {
            log.debug("Name=" + name);
        }

        return name;
    }

    /**
     * @param clazz  Description of Parameter
     * @return       a unique id for clazz
     */
    public static String getEjbIdFor(XClass clazz)
    {
        return getEjbNameFor(clazz).replace('/', '_');
    }

    /**
     * Returns the EJB specification version used. The generated files will be compatible with the version specified.
     *
     * @return   The Ejbspec value
     */
    public static String getEjbSpec()
    {
        return (String) getDocletContext().getConfigParam("EjbSpec");
    }

    public static boolean isLocalEjb(XClass clazz) throws XDocletException
    {
        return isViewtypeEjb(clazz, "local");
    }

    public static boolean isRemoteEjb(XClass clazz) throws XDocletException
    {
        return isViewtypeEjb(clazz, "remote");
    }


    public static boolean isServiceEndpointEjb(XClass clazz) throws XDocletException
    {
        return isViewtypeEjb(clazz, SERVICE_ENDPOINT);
    }

    /**
     * Returns true if clazz is only a local EJB by looking at ejb:bean's view-type parameter.
     *
     * @param clazz                 Description of Parameter
     * @return                      The OnlyLocalEjb value
     * @exception XDocletException
     */
    public static boolean isOnlyLocalEjb(XClass clazz) throws XDocletException
    {
        return isLocalEjb(clazz) && !isRemoteEjb(clazz) && !isServiceEndpointEjb(clazz);
    }

    /**
     * Returns true if clazz is only a remote EJB by looking at ejb:bean's view-type parameter.
     *
     * @param clazz                 Description of Parameter
     * @return                      The OnlyRemoteEjb value
     * @exception XDocletException
     */
    public static boolean isOnlyRemoteEjb(XClass clazz) throws XDocletException
    {
        return isRemoteEjb(clazz) && !isLocalEjb(clazz) && !isServiceEndpointEjb(clazz);
    }

    /**
     * Returns true if clazz is only a service endpoint EJB by looking at ejb:bean's view-type parameter.
     *
     * @param clazz                 Description of Parameter
     * @return                      The OnlyRemoteEjb value
     * @exception XDocletException
     */
    public static boolean isOnlyServiceEndpointEjb(XClass clazz) throws XDocletException
    {
        return isServiceEndpointEjb(clazz) && !isRemoteEjb(clazz) && !isLocalEjb(clazz);
    }

    /**
     * Returns the class with the specified ejb name
     *
     * @param name
     * @return
     * @exception XDocletException
     */
    public static XClass getEjb(String name) throws XDocletException
    {
        Collection classes = getXJavaDoc().getSourceClasses();

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

            if (name.equals(getEjbNameFor(clazz))) {
                return clazz;
            }
        }
        return null;
    }

    /**
     * Returns true of clazz is an EJB (derived from an EJB type), false otherwise.
     *
     * @param clazz                 Description of Parameter
     * @return                      The Ejb value
     * @exception XDocletException
     */
    public static boolean isEjb(XClass clazz) throws XDocletException
    {
        return clazz.isA("javax.ejb.SessionBean")
            || clazz.isA("javax.ejb.EntityBean")
            || clazz.isA("javax.ejb.MessageDrivenBean");
    }

    /**
     * Returns modified package name for a package name. If package name ends with one of the toReplace Strings, then
     * it's substituted by the replaceWith String. If packagePattern not null then it's roughly used.
     *
     * @param packageName     The name of the package name the new package name will be derived from
     * @param packagePattern  The package pattern to use. Can be null
     * @param subtask
     * @return                Description of the Returned Value
     * @todo                  this method is really an utility method that should be deprecated here and moved to
     *      PackageTagsHandler or even somewhere else
     */
    public static String choosePackage(String packageName, String packagePattern, String subtask)
    {
        Log log = LogUtil.getLog(EjbTagsHandler.class, "choosePackage");

        ArrayList packageSubstitutions = PackageTagsHandler.getPackageSubstitutions(subtask);

        if (log.isDebugEnabled()) {
            log.debug("Package name=" + packageName + " - Pattern=" + packagePattern);
        }

        if (packagePattern != null) {
            // later we may do some parametric {0} fancy stuff here
            return packagePattern;
        }
        else {
            for (int i = 0; i < packageSubstitutions.size(); i++) {
                PackageTagsHandler.PackageSubstitution ps = (PackageTagsHandler.PackageSubstitution) packageSubstitutions.get(i);
                StringTokenizer st = new StringTokenizer(ps.getPackages(), ",", false);

                if (ps.getUseFirst() == false) {
                    while (st.hasMoreTokens()) {
                        String packages = st.nextToken();
                        String suffix = "." + packages;

                        if (packageName.endsWith(suffix)) {
                            packageName = packageName.substring(0, packageName.length() - suffix.length()) + '.' + ps.getSubstituteWith();
                            break;
                        }
                    }
                }
                else {
                    packageName = PackageTagsHandler.replaceInline(packageName, ps.getPackages(), ps.getSubstituteWith());
                }
            }
        }

        if (log.isDebugEnabled()) {
            log.debug("packageName=" + packageName);
        }

        return packageName;
    }

    /**
     * Returns the name of EJB ref.
     *
     * @return                      The name of current EJB bean.
     * @exception XDocletException
     * @doc.tag                     type="content"
     */
    public static String ejbRefName() throws XDocletException
    {
        return ejbRefName(getCurrentClassTag(), getCurrentClass());
    }

    /**
     * Returns the name of EJB ref.
     *
     * @param tag
     * @param clazz
     * @return                      The name of current EJB bean.
     * @exception XDocletException
     * @doc.tag                     type="content"
     */
    public static String ejbRefName(XTag tag, XClass clazz) throws XDocletException
    {
        String ejbRefName = null;

        String refName = tag.getAttributeValue("ref-name");

        if (refName != null) {
            ejbRefName = refName;
        }
        else {
            ejbRefName = prefixWithEjbSlash(getEjbNameFor(clazz));

            String type = tag.getAttributeValue("view-type");

            if (type != null) {
                if (type.equals("local") && isLocalEjb(clazz)) {
                    ejbRefName = ejbRefName + LOCAL_SUFFIX;
                }
            }
            else {
                if (isLocalEjb(getCurrentClass()) && !isRemoteEjb(clazz)) {
                    ejbRefName = ejbRefName + LOCAL_SUFFIX;
                }
            }
        }

        return ejbRefName;
    }

    /**
     * Replace &quot;.&quot; by &quot;/&quot; and add &quot;ejb/&quot; to the parameter.
     *
     * @param ejbName  The string to parse
     * @return         The parsed String
     */
    protected static String prefixWithEjbSlash(String ejbName)
    {
        ejbName = ejbName.replace('.', '/');
        if (ejbName.startsWith("ejb/")) {
            return ejbName;
        }
        else {
            return "ejb/" + ejbName;
        }
    }

    private static boolean isViewtypeEjb(XClass clazz, String viewtype) throws XDocletException
    {
        // EJB 1.1 beans have only the remote view type
        if (getEjbSpec().equals("1.1")) {
            return "remote".equals(viewtype);
        }

        String value = getTagValue(
            FOR_CLASS,
            clazz.getDoc(),
            "ejb:bean",
            "view-type",
            "remote,local,both," + SERVICE_ENDPOINT + ",local-" + SERVICE_ENDPOINT + ",remote-" + SERVICE_ENDPOINT + "," + ALL,
            null,
            true,
            false
            );

        if (value == null) {
            //default is both if ejb2, remote if ejb1.1
            if (!viewtype.equals(SERVICE_ENDPOINT)) {
                return true;
            }
            else {
                return false;
            }
        }
        else {
            if (value.indexOf(viewtype) != -1) {
                return true;
            }
            else {
                if (value.indexOf(ALL) != -1) {
                    return true;
                }
                else if (!viewtype.equals(SERVICE_ENDPOINT) && value.indexOf("both") != -1) {
                    return true;
                }
                else {
                    return false;
                }
            }
        }
    }


    /**
     * Gets the SubTaskClassForClass attribute of the EjbTagsHandler class
     *
     * @param clazz                 Describe what the parameter does
     * @return                      The SubTaskClassForClass value
     * @exception XDocletException
     */
    private static SubTask getSubTaskClassForClass(XClass clazz) throws XDocletException
    {
        if (CmpTagsHandler.isEntityCmp(clazz)) {
            return DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(EntityCmpSubTask.class));
        }

        else if (MdbTagsHandler.isMessageDriven(clazz)) {
            return DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(MdbSubTask.class));
        }
        else if (BmpTagsHandler.isEntityBmp(clazz)) {
            return DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(EntityBmpSubTask.class));
        }
        else if (SessionTagsHandler.isSession(clazz)) {
            return DocletContext.getInstance().getSubTaskBy(DocletTask.getSubTaskName(SessionSubTask.class));
        }
        else {
            return null;
        }
    }

    /**
     * Describe what the method does
     *
     * @param currentClass  Describe what the parameter does
     * @return              Describe the return value
     */
    private static boolean hasANonDocletGeneratedSubClass(XClass currentClass)
    {
        // check if it's abstract and has a non-xdoclet-generated derived class
        String fullClassName = currentClass.getQualifiedName();
        Collection classes = getXJavaDoc().getSourceClasses();

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

            if (fullClassName.equals(clazz.getQualifiedName()) == false &&
                !clazz.getDoc().hasTag("xdoclet-generated") &&
                clazz.isA(fullClassName)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Returns the name of current EJB bean.
     *
     * @param attributes            The attributes of the template tag
     * @return                      The name of current EJB bean.
     * @exception XDocletException
     * @see                         #getEjbNameFor(xjavadoc.XClass)
     * @doc.tag                     type="content"
     * @doc.param                   name="prefixWithEjbSlash" optional="true" values="true,false" description="Specifies
     *      whether to prefix it with ejb/ or not. False by default."
     */
    public String ejbName(Properties attributes) throws XDocletException
    {
        String prefixWithEjbSlashStr = attributes.getProperty("prefixWithEjbSlash");
        boolean prefixWithEjbSlash = TypeConversionUtil.stringToBoolean(prefixWithEjbSlashStr, false);
        String ejbName = getEjbNameFor(currentEjbClass == null ? getCurrentClass() : currentEjbClass);

        if (prefixWithEjbSlash == true) {
            return prefixWithEjbSlash(ejbName);
        }
        else {
            return ejbName;
        }
    }

    /**
     * Returns the name of EJB ref.
     *
     * @return                      The name of current EJB bean.
     * @exception XDocletException
     * @doc.tag                     type="content"
     */
    public String ejbExternalRefName() throws XDocletException
    {
        String ejbRefName = null;
        String refName = getCurrentClassTag().getAttributeValue("ref-name");

        if (refName != null) {
            ejbRefName = refName;
        }
        else {
            ejbRefName = prefixWithEjbSlash(getCurrentClassTag().getAttributeValue("ejb-name"));
        }

        return ejbRefName;
    }

    /**
     * Returns the symbolic name of the current class. For an EJBean it's the value of ejb:bean's name parameter.
     *
     * @return                      The symbolic name of the current class
     * @exception XDocletException
     * @see                         #shortEjbName()
     * @doc.tag                     type="content"
     */
    public String symbolicClassName() throws XDocletException
    {
        return shortEjbName();
    }

    /**
     * Returns short version of ejbName(). Example: "foo.bar.MyBean" ->"MyBean", "foo/bar/MyBean" ->"MyBean"
     *
     * @return                      Description of the Returned Value
     * @exception XDocletException
     * @see                         #getShortEjbNameFor(xjavadoc.XClass)
     * @doc.tag                     type="content"
     */
    public String shortEjbName() throws XDocletException
    {
        return getShortEjbNameFor(getCurrentClass());
    }

    /**
     * Evaluates the body block for each EJBean derived from one of the three EJB types: EntityBean, SessionBean or
     * MessageDrivenBean.
     *
     * @param template              The body of the block tag
     * @exception XDocletException
     * @see                         xdoclet.modules.ejb.entity.EntityTagsHandler#isEntity(xjavadoc.XClass)
     * @see                         xdoclet.modules.ejb.session.SessionTagsHandler#isSession(xjavadoc.XClass)
     * @see                         xdoclet.modules.ejb.mdb.MdbTagsHandler#isMessageDriven(xjavadoc.XClass)
     * @doc.tag                     type="block"
     */
    public void forAllBeans(String template) throws XDocletException
    {
        Collection classes = getXJavaDoc().getSourceClasses();

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

            setCurrentClass(clazz);

            if (DocletSupport.isDocletGenerated(getCurrentClass())) {
                continue;
            }

            if (EntityTagsHandler.isEntity(getCurrentClass()) || SessionTagsHandler.isSession(getCurrentClass()) ||
                MdbTagsHandler.isMessageDriven(getCurrentClass())) {
                currentEjbClass = getCurrentClass();
                generate(template);
                currentEjbClass = null;
            }
        }
    }

    /**
     * Evaluates the body block if current bean is a concrete bean meaning the generate parameter of ejb:bean is either
     * not specified or equals to "true", otherwise the bean is just an abstract base class bean not meant to be used as
     * a EJBean but serve as the base for other EJBeans.
     *
     * @param template              The body of the block tag
     * @param attributes            The attributes of the template tag
     * @exception XDocletException
     * @doc.tag                     type="block"
     */
    public void ifIsAConcreteEJBean(String template, Properties attributes) throws XDocletException
    {
        if (isAConcreteEJBean(getCurrentClass()) == true) {
            generate(template);
        }
    }

    /**
     * Returns Bean type : "Entity", "Session" or "Message Driven".
     *
     * @return                      "Entity", "Session" or "Message Driven".
     * @exception XDocletException
     * @see                         xdoclet.modules.ejb.entity.EntityTagsHandler#isEntity(xjavadoc.XClass)
     * @see                         xdoclet.modules.ejb.session.SessionTagsHandler#isSession(xjavadoc.XClass)
     * @see                         xdoclet.modules.ejb.mdb.MdbTagsHandler#isMessageDriven(xjavadoc.XClass)
     * @doc.tag                     type="content"
     */
    public String beanType() throws XDocletException
    {
        if (EntityTagsHandler.isEntity(getCurrentClass())) {
            return "Entity";
        }
        else if (SessionTagsHandler.isSession(getCurrentClass())) {
            return "Session";
        }
        else if (MdbTagsHandler.isMessageDriven(getCurrentClass())) {
            return "Message Driven";
        }
        else {
            return "Unknown";
        }
    }

    /**
     * Returns the full-qualified name of the current class's concrete class. This is the class that is generated and is
     * derived from current class.
     *
     * @return                      The full-qualified name of the current class's concrete class
     * @exception XDocletException
     * @see                         xdoclet.modules.ejb.session.SessionTagsHandler#sessionClass()
     * @see                         xdoclet.modules.ejb.entity.BmpTagsHandler#entityBmpClass()
     * @see                         xdoclet.modules.ejb.entity.CmpTagsHandler#entityCmpClass()
     * @see                         xdoclet.modules.ejb.mdb.MdbTagsHandler#messageDrivenClass()
     * @doc.tag                     type="content"
     */
    public String concreteFullClassName() throws XDocletException
    {
        XTag beanTag = getCurrentClass().getDoc().getTag("ejb.bean");
        String paramValue = null;

        if (beanTag != null) {
            paramValue = beanTag.getAttributeValue("impl-class-name");
        }

        if (SessionTagsHandler.isSession(getCurrentClass())) {
            if (DocletContext.getInstance().isSubTaskDefined(DocletTask.getSubTaskName(SessionSubTask.class))) {
                return SessionTagsHandler.getSessionClassFor(getCurrentClass());
            }
            else {
                return (paramValue != null) ? paramValue : getCurrentClass().getQualifiedName();
            }
        }
        else if (BmpTagsHandler.isEntityBmp(getCurrentClass())) {
            if (DocletContext.getInstance().isSubTaskDefined(DocletTask.getSubTaskName(EntityBmpSubTask.class))) {
                return BmpTagsHandler.getEntityBmpClassFor(getCurrentClass());
            }
            else {
                return (paramValue != null) ? paramValue : getCurrentClass().getQualifiedName();
            }
        }

        else if (CmpTagsHandler.isEntityCmp(getCurrentClass())) {
            if (DocletContext.getInstance().isSubTaskDefined(DocletTask.getSubTaskName(EntityCmpSubTask.class))) {
                return CmpTagsHandler.getEntityCmpClassFor(getCurrentClass());
            }
            else {
                return (paramValue != null) ? paramValue : getCurrentClass().getQualifiedName();
            }
        }
        else if (MdbTagsHandler.isMessageDriven(getCurrentClass())) {

            if (DocletContext.getInstance().isSubTaskDefined(DocletTask.getSubTaskName(MdbSubTask.class))) {
                return MdbTagsHandler.getMessageDrivenClassFor(getCurrentClass());
            }
            else {
                return (paramValue != null) ? paramValue : getCurrentClass().getQualifiedName();
            }
        }
        else {
            return null;
        }
    }

    /**
     * Returns unique id for current ejb.
     *
     * @return                      Description of the Returned Value
     * @exception XDocletException
     * @doc.tag                     type="content"
     */
    public String id() throws XDocletException
    {
        return getEjbIdFor(getCurrentClass());
    }

    /**
     * @param template              Description of Parameter
     * @exception XDocletException
     * @doc.tag                     type="block"
     */
    public void ifLocalEjb(String template) throws XDocletException
    {
        if (isLocalEjb(getCurrentClass())) {
            generate(template);
        }
    }

    /**
     * @param template              Description of Parameter
     * @exception XDocletException
     * @doc.tag                     type="block"
     */
    public void ifRemoteEjb(String template) throws XDocletException
    {
        if (isRemoteEjb(getCurrentClass())) {
            generate(template);
        }
    }

    /**
     * @param template              Description of Parameter
     * @exception XDocletException
     * @doc.tag                     type="block"
     */
    public void ifServiceEndpointEjb(String template) throws XDocletException
    {
        if (isServiceEndpointEjb(getCurrentClass())) {
            generate(template);
        }
    }


    /**
     * @param template
     * @exception XDocletException
     * @doc.tag                     type="block"
     */
    public void ifNotLocalEjb(String template) throws XDocletException
    {
        if (!isLocalEjb(getCurrentClass())) {
            generate(template);
        }
    }

    /**
     * @param template
     * @exception XDocletException
     * @doc.tag                     type="block"
     */
    public void ifNotRemoteEjb(String template) throws XDocletException
    {
        if (!isRemoteEjb(getCurrentClass())) {
            generate(template);
        }
    }

    /**
     * @param template
     * @exception XDocletException
     * @doc.tag                     type="block"
     */
    public void ifNotServiceEndpointEjb(String template) throws XDocletException
    {
        if (!isServiceEndpointEjb(getCurrentClass())) {
            generate(template);
        }
    }

    /**
     * sub-classes which deal with patternized class names return a reasonable value
     *
     * @param clazz                 the class
     * @param type                  type value used for view-type of remote/local
     * @return                      dependent class name for the class and type
     * @exception XDocletException
     */
    protected String getDependentClassFor(XClass clazz, String type) throws XDocletException
    {
        return null;
    }

    /**
     * Gets the DependentClassTagName attribute of the EjbTagsHandler object
     *
     * @return   The DependentClassTagName value
     */
    protected String getDependentClassTagName()
    {
        //it's too much dependency, we should find a better way
        if (getDocletContext().getActiveSubTask().getSubTaskName().equals(DocletTask.getSubTaskName(DataObjectSubTask.class))) {
            return "ejb:data-object";
        }
        else if (getDocletContext().getActiveSubTask().getSubTaskName().equals(DocletTask.getSubTaskName(EntityBmpSubTask.class)) ||
            getDocletContext().getActiveSubTask().getSubTaskName().equals(DocletTask.getSubTaskName(EntityCmpSubTask.class))) {
            return "ejb:bean";
        }
        else if (getDocletContext().getActiveSubTask().getSubTaskName().equals(DocletTask.getSubTaskName(RemoteInterfaceSubTask.class)) ||
            getDocletContext().getActiveSubTask().getSubTaskName().equals(DocletTask.getSubTaskName(LocalInterfaceSubTask.class))) {
            return "ejb:interface";
        }
        else if (getDocletContext().getActiveSubTask().getSubTaskName().equals(DocletTask.getSubTaskName(HomeInterfaceSubTask.class)) ||
            getDocletContext().getActiveSubTask().getSubTaskName().equals(DocletTask.getSubTaskName(LocalHomeInterfaceSubTask.class))) {
            return "ejb:interface";
        }
        else if (getDocletContext().getActiveSubTask().getSubTaskName().equals(DocletTask.getSubTaskName(EntityPkSubTask.class))) {
            return "ejb:pk";
        }
        else {
            return null;
        }
    }

    /**
     * Returns true if class/method denoted by doc has ejb:transaction tag, false otherwise.
     *
     * @param doc                   Description of Parameter
     * @return                      Description of the Returned Value
     * @exception XDocletException
     */
    protected boolean hasTransaction(XDoc doc) throws XDocletException
    {
        return doc.hasTag("ejb:transaction");
    }

    /**
     * Returns the name of the class pk/etc class extends.
     *
     * @param clazz                 the class
     * @param tagName               name of the tag (ejb:bean for example, used for getting generate parameter)
     * @param type                  type value used for view type of remote/local
     * @param extendsParamName      extends parameter name (is "extends" for ejb:bean but is "local-extends" for local)
     * @param defaultBaseClassName  default base class name, returned when not deriving from another base class
     * @return                      correct value for the extends statement of a generated class
     * @exception XDocletException
     */
    protected String extendsFromFor(XClass clazz, String tagName, String type, String extendsParamName, String defaultBaseClassName) throws XDocletException
    {
        Log log = LogUtil.getLog(EjbTagsHandler.class, "extendsFromFor");

        log.debug("Looking " + type + " extendsFrom for class " + clazz.getName());

        // see ejb:pk/etc generate="?" in superclass
        XClass superclass = clazz.getSuperclass();

        boolean generateSuper;

        if (superclass.getDoc().hasTag(tagName)) {
            String generateSuperStr = getTagValue(
                FOR_CLASS,
                superclass.getDoc(),
                tagName,
                "generate",
                null,
                null,
                false,
                false
                );

            generateSuper = TypeConversionUtil.stringToBoolean(generateSuperStr, true);
        }
        else {
            // Two Cases : PersonBean and BaseEntityBean
            generateSuper = false;

            Collection interfaces = clazz.getSuperclass().getInterfaces();

            for (Iterator i = interfaces.iterator(); i.hasNext(); ) {
                XClass intf = (XClass) i.next();

                // if superclass is not javax.ejb.EntityBean then we have a superclass which
                // is itself deriving from javax.ejb.EntityBean
                if (intf.getQualifiedName().equals("javax.ejb.EntityBean") ||
                    intf.getQualifiedName().equals("javax.ejb.SessionBean") ||
                    intf.getQualifiedName().equals("javax.ejb.MessageDrivenBean")) {
                    //it derives from javax.ejb.*Bean and no superclass for pk/etc class is explicitly defined
                    generateSuper = true;
                }
            }
        }

        log.debug(clazz.getName() + " superclass is generatable? " + generateSuper);


        // note: look for ejb:pk/etc extends in superclasses also only if generate="false" in superclass
        // so extends attribute is inherited only if superclass's pk/etc is not to be generated
        String extendsValue = getTagValue(
            FOR_CLASS,
            clazz.getDoc(),
            tagName,
            extendsParamName,
            null,
            null,
            !generateSuper,
            false
            );

        // if explicitly specified
        if (extendsValue != null) {
            log.debug(clazz.getName() + " contains an explicit extends. Returning " + extendsValue);
            return extendsValue;
        }
        else {
            // now try to guess if we are deriving from another ejb bean, and if so, then derive from
            // that bean's pk class too (if generate="true" for superclass's pk/etc class)
            log.debug(clazz.getName() + " does not contains an explicit extends. Trying to guess it");

            // java.lang.Object (the only that have no superclass)
            if (superclass.getSuperclass() == null) {
                log.debug("Top of class hierachy reached. Returning default extends: " + defaultBaseClassName);
                return defaultBaseClassName;
            }
            // if a superclass with generate="true"
            else if (generateSuper == true) {
                String className = getDependentClassFor(superclass, type);

                if (className != null) {
                    log.debug("Superclass " + superclass.getName() + " has a dependent class: " + className);
                    return className;
                }
                else {
                    log.debug("No dependent class for " + superclass.getName() + ". Returning default extends: " + defaultBaseClassName);
                    return defaultBaseClassName;
                }
            }
            else {
                // so we have a superclass with pk-generate="false", look at superclass of that superclass!
                log.debug("Can't guess now. Going deeper into class hierarchy");
                return extendsFromFor(superclass, tagName, type, extendsParamName, defaultBaseClassName);
            }
        }
    }

    /**
     * Describe what the method does
     *
     * @param clazz                 Describe what the parameter does
     * @param tagName               Describe what the parameter does
     * @return                      Describe the return value
     * @exception XDocletException
     */
    protected boolean shouldTraverseSuperclassForDependentClass(XClass clazz, String tagName) throws XDocletException
    {
        Log log = LogUtil.getLog(EjbTagsHandler.class, "shouldTraverseSuperclassForDependentClass");

        if (clazz.getQualifiedName().equals("java.lang.Object")) {
            log.debug("clazz = java.lang.Object");

            return true;
        }

        if (!clazz.isA("javax.ejb.EntityBean")
            && !clazz.isA("javax.ejb.SessionBean")) {
            log.debug(clazz.getQualifiedName() + " is _not_ of type javax.ejb.EntityBean,javax.ejb.SessionBean");

            return true;
        }
        else {
            log.debug(clazz.getQualifiedName() + " _is_ of type javax.ejb.EntityBean,javax.ejb.SessionBean");
        }

        // see ejb:bean generate="?" in superclass
        String generateBeanStr = getTagValue(
            FOR_CLASS,
            clazz.getDoc(),
            "ejb:bean",
            "generate",
            null,
            "true",
            false,
            false
            );

        boolean generateBean = TypeConversionUtil.stringToBoolean(generateBeanStr, true);

        if (generateBean == false) {
            log.debug("generateBean == false");

            return true;
        }

        boolean generate = false;

        if (tagName != null) {
            // see ejb:pk/etc generate="?" in superclass
            String generateStr = getTagValue(
                FOR_CLASS,
                clazz.getDoc(),
                tagName,
                "generate",
                null,
                "true",
                false,
                false
                );

            generate = TypeConversionUtil.stringToBoolean(generateStr, true);
        }

        if (generate == false) {
            log.debug("generate == false");

            return true;
        }
        else {
            log.debug("generate == true");

            return false;
        }
    }
}
TOP

Related Classes of xdoclet.modules.ejb.EjbTagsHandler

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.