Erik
I did not read method comments :(
What I have corrected is that if parameters is not specified then he
search for a method with no parameters at all.
Here attached the correction (hopefully)
I will put that in CVS when possible.
Vincent


--- Erik Hatcher <[EMAIL PROTECTED]> wrote:
> Vincent,
> 
> I thanked you (offline) before trying it, but this fix is not working
> for
> me.  It is still having the same behavior (not picking up a method if
> parameters is not specified).
> 
> I've verified that I'm running the latest from CVS.
> 
>     Erik
> 
> 
> ----- Original Message -----
> From: "Vincent Harcq" <[EMAIL PROTECTED]>
> To: "'Erik Hatcher'" <[EMAIL PROTECTED]>;
> <[EMAIL PROTECTED]>
> Sent: Tuesday, February 26, 2002 1:05 AM
> Subject: RE: [Xdoclet-devel] Re: [Xdoclet-user] XDtMethod:ifHasMethod
> ????
> 
> 
> Hi,
> There was a bug.
> This has been fixed in CVS.
> Thanks for reporting.
> Vincent.
> 
> > -----Original Message-----
> > From: [EMAIL PROTECTED]
> > [mailto:[EMAIL PROTECTED]] On Behalf
> > Of Erik Hatcher
> > Sent: mardi 26 f�vrier 2002 0:33
> > To: [EMAIL PROTECTED]
> > Subject: [Xdoclet-devel] Re: [Xdoclet-user] XDtMethod:ifHasMethod
> ????
> >
> >
> > Now posting this over to -devel.  It seems that ifHasMethod
> > is broken.  Or is it just me?
> >
> >
> >
> > ----- Original Message -----
> > From: "Erik Hatcher" <[EMAIL PROTECTED]>
> >
> > >   <XDtMethod:ifHasMethod name="setValue">
> > >         without parameters
> > >   </XDtMethod:ifHasMethod>
> > >
> > >   <XDtMethod:ifHasMethod name="setValue"
> > parameters="java.lang.String">
> > >     with parameters
> > >   </XDtMethod:ifHasMethod>
> > >
> > > All I get generated is "with parameters".  That is not what the
> > > documentation says about ifHasMethod:
> > >
> > > "Evaluate the body if current class has a method with the
> specified
> > > name+parameters. If parameters not specified then any
> > method with the
> > given
> > > name and any set of parameters is considered equal to the
> > given method
> > name
> > > and so the test result is positive and the body is evaluated.
> This
> > > method does not change the current method to the one specified."
> > >
> > > Clearly I have a setValue method - so why doesn't the first
> > > ifHasMethod
> > pick
> > > it up?  Shouldn't it?
> > >
> > > I tried replacing the first 'ifHasMethod' with
> > 'setCurrentMethod' and
> > > it still did not get picked up.
> >
> >
> >
> > _______________________________________________
> > Xdoclet-devel mailing list
> > [EMAIL PROTECTED]
> > https://lists.sourceforge.net/lists/listinfo/xdoclet-devel
> >
> >
> 
> 
> 
> 
> 
> _______________________________________________
> Xdoclet-devel mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/xdoclet-devel
> 
> 
> 


__________________________________________________
Do You Yahoo!?
Yahoo! Sports - Coverage of the 2002 Olympic Games
http://sports.yahoo.com
package xdoclet.tags;

import com.sun.javadoc.*;

import xdoclet.XDocletException;
import xdoclet.ejb.DataObjectSubTask;
import xdoclet.template.PrettyPrintWriter;
import xdoclet.util.DocletUtil;
import xdoclet.util.TypeConversionUtil;
import xdoclet.util.Log;
import xdoclet.util.Translator;

import java.beans.Introspector;
import java.util.*;

import org.apache.log4j.Category;

/**
 * @author    Ara Abrahamian ([EMAIL PROTECTED])
 * @created   Oct 15, 2001
 * @version   $Revision: 1.23 $
 */
public class MethodTagsHandler extends AbstractProgramElementTagsHandler
{
        public static String getMethodTypeFor( MethodDoc method ) throws 
XDocletException
        {
                return method.returnType().qualifiedTypeName() + 
method.returnType().dimension();
        }

        /**
         * Merge with modified SubTask.methodNameWithoutPrefix
         *
         * @param cur_method  Description of Parameter
         * @return            Description of the Returned Value
         */
        public static String getMethodNameWithoutPrefixFor( MethodDoc cur_method )
        {
                String str = cur_method.name();

                if( str.startsWith( "get" ) || str.startsWith( "set" ) )
                        return str.substring( 3 );
                else if( str.startsWith( "is" ) )
                        return str.substring( 2 );
                else
                        return str;
        }

        public static String getPropertyNameFor( MethodDoc method )
        {
                String name = getMethodNameWithoutPrefixFor( method );
                int len = name.length();

                if( len == 0 )
                        return name;

                if( len == 1 )
                        return name.toLowerCase();

                //Turn first letter to lower case (only if it's currently uppercase)
                char c = name.charAt( 0 );

                if( c >= 'A' && c <= 'Z' )
                        return ( ( char ) ( c + ( 'a' - 'A' ) ) ) + name.substring( 1 
);
                return name;
        }

        /**
         * Returns true if the str string starts with a getter prefix ("get" or "is").
         *
         * @param str  Description of Parameter
         * @return     The Getter value
         */
        public static boolean isGetter( String str )
        {
                return str.startsWith( "get" ) || str.startsWith( "is" );
        }

        /**
         * Returns true if a method with the specified methodName+parameters is found
         * in the class clazz. The parameters array can be empty, if so any method with
         * any set of parameters is considered equal to the method we're searching for.
         * if not empty all parameters of the method must be equal to the ones
         * specified in parameters array to have "method equality".
         *
         * @param clazz       Description of Parameter
         * @param methodName  Description of Parameter
         * @param parameters  Description of Parameter
         * @return            Description of the Returned Value
         */
        protected static boolean hasMethod( ClassDoc clazz, String methodName, 
String[] parameters )
        {
                Category cat = Log.getCategory( MethodTagsHandler.class, "hasMethod" );

                while( clazz != null )
                {
                        MethodDoc[] methods = clazz.methods();

                        methodLoop :
                        for( int i = 0; i < methods.length; i++ )
                        {
                                if( methods[i].name().equals( methodName ) )
                                {
                                        // All parameters must be equal to have 
"method equality"
                                        Parameter[] params = methods[i].parameters();

                                        cat.debug( "params.length=" + params.length );

                                        for( int j = 0; j < params.length; j++ )
                                        {
                                                cat.debug( "params[j].typeName()=" + 
params[j].typeName() );
                                                cat.debug( "parameters[j]=" + 
parameters[j] );

                                                if( parameters == null || 
!params[j].typeName().equals( parameters[j] ) )
                                                        continue methodLoop;
                                        }

                                        // The class has the given method
                                        return true;
                                }
                        }

                        // Check super class info
                        clazz = clazz.superclass();
                }

                return false;
        }

        /**
         * Returns 'get' or 'is' getter prefix part of the current method. Returns
         * empty string if the method doesn't start with either of the two getter
         * prefixes.
         *
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="content"
         */
        public String getterPrefix() throws XDocletException
        {
                String prefix = "";

                if( getCurrentMethod().name().startsWith( "get" ) )
                        prefix = "get";
                else if( getCurrentMethod().name().startsWith( "is" ) )
                        prefix = "is";
                else if( getCurrentMethod().name().startsWith( "set" ) )
                {
                        // For boolean here we don't know if it is get or is, lets 
find it
                        String[] params = {getCurrentMethod().returnType().typeName()};

                        if( hasMethod( getCurrentClass(), "is" + 
methodNameWithoutPrefix(), params, false ) )
                                prefix = "is";
                        else
                                return prefix = "get";
                }

                return prefix;
        }

        /**
         * Returns the getter method name for the current method by prefixing the
         * method name with the proper getter prefix.
         *
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @see                         #methodNameWithoutPrefix()
         * @see                         #setterMethod()
         * @see                         #getterPrefix()
         * @doc:tag                     type="content"
         */
        public String getterMethod() throws XDocletException
        {
                return getterPrefix() + methodNameWithoutPrefix();
        }

        /**
         * Returns the setter method name for the current method by prefixing the
         * method name with a 'set' and removing the getter method's 'get' or 'is'
         * prefixes, if any.
         *
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @see                         #methodNameWithoutPrefix()
         * @see                         #getterMethod()
         * @doc:tag                     type="content"
         */
        public String setterMethod() throws XDocletException
        {
                return "set" + methodNameWithoutPrefix();
        }

        /**
         * Evaluate the body if current class has a method with the specified
         * name+parameters. If parameters not specified then any method with the given
         * name and any set of parameters is considered equal to the given method name
         * and so the test result is positive and the body is evaluated. This method
         * change the current method to the one specified.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @see                         
#ifHasMethod(java.lang.String,java.util.Properties)
         * @doc:tag                     type="block"
         * @doc:param                   name="name" optional="false" description="The
         *      name of the method we're searching for its existence in current class."
         * @doc:param                   name="parameters" optional="true"
         *      description="We're searching for a method that has the exact set of
         *      parameters specified in parameters param."
         * @doc:param                   name="delimiter" optional="true"
         *      description="The parameters param is delimited by the string specified
         *      in delimiter parameter."
         */
        public void setCurrentMethod( String template, Properties attributes ) throws 
XDocletException
        {
                String methodName = attributes.getProperty( "name" );
                String parametersStr = attributes.getProperty( "parameters" );
                String delimiter = attributes.getProperty( "delimiter" );

                String[] parameters = null;

                if( parametersStr != null )
                {
                        if( delimiter == null )
                                delimiter = PARAMETER_DELIMITER;

                        parameters = DocletUtil.tokenizeDelimitedToArray( 
parametersStr, delimiter );
                }

                MethodDoc oldMethod = getCurrentMethod();

                if( hasMethod( getCurrentClass(), methodName, parameters, true ) == 
true )
                {
                        generate( template );
                }

                setCurrentMethod( oldMethod );
        }

        /**
         * The comment for the current method.
         *
         * @param attributes            The attributes of the template tag
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @see                         
ClassTagsHandler#classComment(java.util.Properties)
         * @doc:tag                     type="content"
         * @doc:param                   name="no-comment-signs" optional="true"
         *      values="true,false" description="If true then don't decorate the
         *      comment with comment signs."
         */
        public String methodComment( Properties attributes ) throws XDocletException
        {
                String no_comment_signs = attributes.getProperty( "no-comment-signs" );

                if( no_comment_signs != null && no_comment_signs.equalsIgnoreCase( 
"true" ) )
                        return getCurrentMethod().commentText();

                char[] spaces = getIndentChars( attributes );
                Tag[] method_tags = getCurrentMethod().tags();

                if( method_tags.length > 0 )
                {
                        StringBuffer result = new StringBuffer();

                        //add user comments
                        StringTokenizer st = new StringTokenizer( 
getCurrentMethod().commentText().trim(), "\n", false );

                        if( st.countTokens() > 0 )
                        {
                                result.append( spaces ).append( "/**" ).append( 
PrettyPrintWriter.LINE_SEPARATOR );
                                while( st.hasMoreTokens() )
                                {
                                        result.append( spaces ).append( " * " 
).append( st.nextToken().trim() ).append( PrettyPrintWriter.LINE_SEPARATOR );
                                }

                                for( int i = 0; i < method_tags.length; i++ )
                                {
                                        //all of our xdoclet-specific tags have a ":"
                                        if( method_tags[i].name().lastIndexOf( ':' ) 
== -1 )
                                        {
                                                result.append( spaces ).append( " * " )
                                                        .append( method_tags[i].name() 
).append( ' ' )
                                                        .append( method_tags[i].text() 
);

                                                //for all lines but not the last line
                                                if( i < method_tags.length - 1 )
                                                        result.append( 
PrettyPrintWriter.LINE_SEPARATOR );
                                        }
                                }

                                result.append( spaces ).append( " */" );
                        }

                        return result.toString();
                }
                else
                        return "";
        }

        /**
         * Iterates over all exceptions thrown by the current method and returns a
         * string containing definition of all those exceptions.
         *
         * @param attributes            The attributes of the template tag
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         * @doc:param                   name="method" optional="true" description="The
         *      method name of which exceptions list is extracted. If not specified
         *      then current method is used."
         * @doc:param                   name="skip" optional="true" description="A
         *      comma-separated list of exceptions that should be skipped and not put
         *      into the list."
         * @doc:param                   name="append" optional="true" description="A
         *      comma-separated list of exceptions that should be always appended
         *      regardless if current method has that method defined or not."
         */
        public String exceptionList( Properties attributes ) throws XDocletException
        {
                String skip_exceptions = attributes.getProperty( "skip" );
                String append_exceptions = attributes.getProperty( "append" );
                String method_name = attributes.getProperty( "method" );
                ClassDoc[] exceptions = null;

                if( getCurrentMethod() == null && method_name == null )
                        return "";

                if( method_name == null )
                        exceptions = getCurrentMethod().thrownExceptions();
                else
                {
                        MethodDoc method_doc = getMethodDocForMethodName( method_name, 
true );

                        //no method with the specified name found in class
                        if( method_doc == null )
                                return "";

                        exceptions = method_doc.thrownExceptions();
                }

                StringBuffer st = new StringBuffer();
                String type = null;

                for( int i = 0; i < exceptions.length; i++ )
                {
                        type = exceptions[i].toString();

                        if( isInSkipExceptionsList( skip_exceptions, type ) == false &&
                                isInAppendExceptionsList( append_exceptions, type ) == 
false )
                        {
                                appendException( st, type );
                        }
                }

                //append all exceptions specfied to be always appended by default
                if( append_exceptions != null )
                        appendException( st, append_exceptions );

                return st.toString();
        }

        /**
         * Evaluate the body block if current method is abstract.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @see                         
#ifIsNotAbstract(java.lang.String,java.util.Properties)
         * @doc:tag                     type="block"
         * @doc:param                   name="method" optional="true" description="The
         *      method name of which exceptions list is extracted. If not specified
         *      then current method is used."
         */
        public void ifIsAbstract( String template, Properties attributes ) throws 
XDocletException
        {
                String method_name = attributes.getProperty( "method" );

                if( method_name == null )
                {
                        if( getCurrentMethod().isAbstract() )
                                generate( template );
                }
                else
                {
                        MethodDoc method_doc = getMethodDocForMethodName( method_name, 
false );

                        //no method with the specified name found in class
                        if( method_doc == null )
                                throw new XDocletException( Translator.getString( 
"method_not_found", new String[]{method_name} ) );

                        if( method_doc.isAbstract() )
                                generate( template );
                }
        }

        /**
         * Evaluates the body block if current method is not abstract.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @see                         
#ifIsAbstract(java.lang.String,java.util.Properties)
         * @doc:tag                     type="block"
         * @doc:param                   name="method" optional="true" description="The
         *      method name of which exceptions list is extracted. If not specified
         *      then current method is used."
         */
        public void ifIsNotAbstract( String template, Properties attributes ) throws 
XDocletException
        {
                String method_name = attributes.getProperty( "method" );

                if( method_name == null )
                {
                        if( !getCurrentMethod().isAbstract() )
                                generate( template );
                }
                else
                {
                        MethodDoc method_doc = getMethodDocForMethodName( method_name, 
false );

                        //no method with the specified name found in class
                        if( method_doc == null )
                                throw new XDocletException( Translator.getString( 
"method_not_found", new String[]{method_name} ) );

                        if( !method_doc.isAbstract() )
                                generate( template );
                }
        }

        /**
         * Loops through all methods for all classes after first sorting all the
         * methods.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         * @doc:param                   name="type" optional="true" description="For
         *      all classes by the type."
         * @doc:param                   name="extent" optional="true"
         *      values="concrete-type,superclass,hierarchy" description="Specifies the
         *      extent of the type search. If concrete-type then only check the
         *      concrete type, if superclass then check also superclass, if hierarchy
         *      then search the whole hierarchy and find if the class is of the
         *      specified type. Default is hierarchy."
         */
        public void forAllClassMethods( String template, Properties attributes ) 
throws XDocletException
        {
                String type_name = attributes.getProperty( "type" );
                int extent = TypeTagsHandler.extractExtentType( 
attributes.getProperty( "extent" ) );

                ClassDoc[] classes = getAllClasses();
                SortedSet methods = new TreeSet();

                for( int i = 0; i < classes.length; i++ )
                {
                        if( type_name == null || TypeTagsHandler.isOfType( classes[i], 
type_name, extent ) )
                        {
                                MethodDoc[] classMethods = classes[i].methods();

                                for( int j = 0; j < classMethods.length; j++ )
                                        methods.add( classMethods[j] );

                        }
                }

                Iterator methodsIterator = methods.iterator();

                while( methodsIterator.hasNext() )
                {
                        MethodDoc current = ( MethodDoc ) methodsIterator.next();

                        setCurrentClass( current.containingClass() );
                        setCurrentMethod( current );

                        generate( template );
                }
        }

        /**
         * Iterates over all methods of current class and evaluates the body of the tag
         * for each method.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         * @doc:param                   name="superclasses" optional="true"
         *      values="true,false" description="If true then traverse superclasses
         *      also, otherwise look up the tag in current concrete class only."
         * @doc:param                   name="sort" optional="true" values="true,false"
         *      description="If true then sort the methods list."
         */
        public void forAllMethods( String template, Properties attributes ) throws 
XDocletException
        {
                boolean superclasses = TypeConversionUtil.stringToBoolean( 
attributes.getProperty( "superclasses" ), true );
                boolean sort = TypeConversionUtil.stringToBoolean( 
attributes.getProperty( "sort" ), true );
                ClassDoc cur_class = getCurrentClass();
                Map already = new HashMap();

                do
                {
                        MethodDoc[] methods = cur_class.methods();

                        if( sort == true )
                        {
                                List the_list = Arrays.asList( methods );

                                //sort methods
                                Collections.sort( the_list,
                                        new Comparator()
                                        {
                                                public int compare( Object o1, Object 
o2 )
                                                {
                                                        MethodDoc m1 = ( MethodDoc ) 
o1;
                                                        MethodDoc m2 = ( MethodDoc ) 
o2;

                                                        return m1.name().compareTo( 
m2.name() );
                                                }

                                                public boolean equals( Object obj )
                                                {
                                                        //dumb
                                                        return obj == this;
                                                }
                                        } );

                                methods = ( MethodDoc[] ) the_list.toArray( methods );
                        }

                        for( int j = 0; j < methods.length; j++ )
                        {
                                if( superclasses == false || ( superclasses == true && 
methods[j].containingClass() == cur_class ) )
                                {
                                        if( already.containsKey( methods[j] ) == false 
)
                                        {
                                                setCurrentMethod( methods[j] );
                                                already.put( methods[j], methods[j] );
                                                generate( template );
                                        }
                                }
                        }

                        if( superclasses == true )
                                cur_class = cur_class.superclass();
                        else
                                break;
                }while ( cur_class != null );
        }

        /**
         * Evaluates the body if current method doesn't have at least one tag with the
         * specified name.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         * @doc:param                   name="tagName" optional="false"
         *      description="The tag name."
         * @doc:param                   name="paramName" description="The parameter
         *      name. If not specified, then the raw content of the tag is returned."
         * @doc:param                   name="paramNum" description="The zero-based
         *      parameter number. It's used if the user used the space-separated format
         *      for specifying parameters."
         * @doc:param                   name="error" description="Show this error
         *      message if no tag found."
         */
        public void ifDoesntHaveMethodTag( String template, Properties attributes ) 
throws XDocletException
        {
                if( !ifHasTag_Impl( template, attributes, FOR_METHOD ) )
                        generate( template );
                else
                {
                        String error = attributes.getProperty( "error" );

                        if( error != null )
                                getEngine().print( error );
                }
        }

        /**
         * Evaluates the body if current method has at least one tag with the specified
         * name.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         * @doc:param                   name="tagName" optional="false"
         *      description="The tag name."
         * @doc:param                   name="paramName" description="The parameter
         *      name. If not specified, then the raw content of the tag is returned."
         * @doc:param                   name="paramNum" description="The zero-based
         *      parameter number. It's used if the user used the space-separated format
         *      for specifying parameters."
         * @doc:param                   name="error" description="Show this error
         *      message if no tag found."
         */
        public void ifHasMethodTag( String template, Properties attributes ) throws 
XDocletException
        {
                if( ifHasTag_Impl( template, attributes, FOR_METHOD ) )
                        generate( template );
                else
                {
                        String error = attributes.getProperty( "error" );

                        if( error != null )
                                getEngine().print( error );
                }
        }

        /**
         * Evaluate the current block, and then restore the current method before
         * continuing.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         */
        public void executeAndRestoreMethod( String template, Properties attributes ) 
throws XDocletException
        {
                MethodDoc method = getCurrentMethod();

                generate( template );
                setCurrentMethod( method );
        }

        /**
         * Evaluates the body if value for the method tag equals the specified value.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         * @doc:param                   name="tagName" optional="false"
         *      description="The tag name."
         * @doc:param                   name="paramName" description="The parameter
         *      name. If not specified, then the raw content of the tag is returned."
         * @doc:param                   name="paramNum" description="The zero-based
         *      parameter number. It's used if the user used the space-separated format
         *      for specifying parameters."
         */
        public void ifMethodTagValueEquals( String template, Properties attributes ) 
throws XDocletException
        {
                if( ifTagValueEquals_Impl( template, attributes, FOR_METHOD ) )
                        generate( template );
        }

        /**
         * Evaluates the body if value for the method tag not equals the specified
         * value.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         * @doc:param                   name="tagName" optional="false"
         *      description="The tag name."
         * @doc:param                   name="paramName" description="The parameter
         *      name. If not specified, then the raw content of the tag is returned."
         * @doc:param                   name="paramNum" description="The zero-based
         *      parameter number. It's used if the user used the space-separated format
         *      for specifying parameters."
         */
        public void ifMethodTagValueNotEquals( String template, Properties attributes 
) throws XDocletException
        {
                if( !ifTagValueEquals_Impl( template, attributes, FOR_METHOD ) )
                        generate( template );
        }

        /**
         * Iterates over all method tags with the specified tagName for the current
         * method probably inside of a forAllMethodTags body.
         *
         * @param attributes            The attributes of the template tag
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="content"
         * @doc:param                   name="tagName" optional="false"
         *      description="The tag name."
         * @doc:param                   name="paramName" description="The parameter
         *      name. If not specified, then the raw content of the tag is returned."
         * @doc:param                   name="paramNum" description="The zero-based
         *      parameter number. It's used if the user used the space-separated format
         *      for specifying parameters."
         * @doc:param                   name="values" description="The valid values for
         *      the parameter, comma separated. An error message is printed if the
         *      parameter value is not one of the values."
         * @doc:param                   name="default" description="The default value
         *      is returned if parameter not specified by user for the tag."
         */
        public String methodTagValue( Properties attributes ) throws XDocletException
        {
                return getTagValue( attributes, FOR_METHOD );
        }

        /**
         * Iterates over all tags of current method and evaluates the body of the tag
         * for each method.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         * @doc:param                   name="tagName" optional="false"
         *      description="The tag name."
         */
        public void forAllMethodTags( String template, Properties attributes ) throws 
XDocletException
        {
                if( getCurrentMethod() == null )
                        throw new XDocletException( Translator.getString( 
"only_call_method_not_null", new String[]{"forAllMethodTags"} ) );

                Tag[] tags = getCurrentMethod().tags( attributes.getProperty( 
"tagName" ) );

                for( int i = 0; i < tags.length; i++ )
                {
                        setCurrentTag( tags[i] );

                        String m = getTagValue( attributes, FOR_METHOD );

                        if( matchPattern == null )
                                generate( template );
                        else if( matchPattern != null && ( matchPattern.equals( m ) || 
m.equals( "*" ) ) )
                                generate( template );
                }

                setCurrentTag( null );
        }

        /**
         * Iterates over all tokens in current method tag with the name tagName and
         * evaluates the body for every token.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="block"
         * @doc:param                   name="tagName" optional="false"
         *      description="The tag name."
         * @doc:param                   name="delimiter" description="delimiter for the
         *      StringTokenizer. consult javadoc for java.util.StringTokenizer default
         *      is ','"
         * @doc:param                   name="skip" description="how many tokens to
         *      skip on start"
         */
        public void forAllMethodTagTokens( String template, Properties attributes ) 
throws XDocletException
        {
                Category cat = Log.getCategory( MethodTagsHandler.class, 
"forAllMethodTagTokens" );

                // get method tag value to iterate over
                String tagValue = getTagValue( attributes, FOR_METHOD );
                String delimiter = attributes.getProperty( "delimiter" );
                String s = attributes.getProperty( "skip" );
                int skip;

                try
                {
                        skip = Integer.valueOf( attributes.getProperty( "skip" ) 
).intValue();
                }
                catch( Throwable t )
                {
                        skip = 0;
                }

                if( delimiter == null )
                {
                        if( cat.isDebugEnabled() )
                                cat.debug( "got null delimiter - 
forAllMethodTagTokens" );

                        delimiter = PARAMETER_DELIMITER;
                }

                tagTokenizer = new StringTokenizer( tagValue, delimiter, false );
                currentToken = "";
                matchPattern = null;

                for( int i = 0; tagTokenizer.hasMoreTokens() && i < skip; i++ )
                        tagTokenizer.nextToken();

                while( tagTokenizer.hasMoreTokens() )
                {
                        currentToken = tagTokenizer.nextToken();

                        if( cat.isDebugEnabled() )
                                cat.debug( "generate current token: " + currentToken );

                        generate( template );
                }

                currentToken = null;
                tagTokenizer = null;
                matchPattern = null;
        }

        /**
         * Return standard javadoc of current method.
         *
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="content"
         */
        public String firstSentenceDescriptionOfCurrentMethod() throws XDocletException
        {
                return getCurrentMethod().firstSentenceTags().length > 0 ? 
getCurrentMethod().firstSentenceTags()[0].text().trim() : "";
        }

        /**
         * Returns the return type of the current method.
         *
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="content"
         */
        public String methodType() throws XDocletException
        {
                return getMethodTypeFor( getCurrentMethod() );
        }

        /**
         * Returns the name of the current method.
         *
         * @param attributes            The attributes of the template tag
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="content"
         */
        public String methodName( Properties attributes ) throws XDocletException
        {
                if( attributes != null )
                {
                        String value = ( String ) attributes.get( "value" );

                        if( value != null )
                        {
                                String m = getCurrentMethod().name().substring( 
Integer.parseInt( value ) );
                                // replace first character to lowercase
                                char firstU = m.charAt( 0 );
                                char firstL = Character.toLowerCase( firstU );

                                return firstL + m.substring( 1 );
                        }
                }

                return getCurrentMethod() != null ? getCurrentMethod().name() : "";
        }

        /**
         * Returns the name of the current method without the first three characters.
         * Used for cases where the method name without the get/set prefix is needed.
         *
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="content"
         */
        public String methodNameWithoutPrefix() throws XDocletException
        {
                return getMethodNameWithoutPrefixFor( getCurrentMethod() );
        }

        /**
         * Returns the current method name. Used inside block elements.
         *
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         */
        public String currentMethodName() throws XDocletException
        {
                return getCurrentMethod().name();
        }

        /**
         * Returns the property name extracted from the current method name. Remove any
         * getter/setter prefix from method name and decapitalize it.
         *
         * @return                      Description of the Returned Value
         * @exception XDocletException  Description of Exception
         * @doc:tag                     type="content"
         */
        public String propertyName() throws XDocletException
        {
                return getPropertyNameFor( getCurrentMethod() );
        }

        /**
         * Evaluate the body if current class has a method with the specified
         * name+parameters. If parameters not specified then any method with the given
         * name and any set of parameters is considered equal to the given method name
         * and so the test result is positive and the body is evaluated. This method
         * does not change the current method to the one specified.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @see                         
#ifDoesntHaveMethod(java.lang.String,java.util.Properties)
         * @doc:tag                     type="block"
         * @doc:param                   name="name" optional="false" description="The
         *      name of the method we're searching for its existence in current class."
         * @doc:param                   name="parameters" optional="true"
         *      description="We're searching for a method that has the exact set of
         *      parameters specified in parameters param."
         * @doc:param                   name="delimiter" optional="true"
         *      description="The parameters param is delimited by the string specified
         *      in delimiter parameter."
         */
        public void ifHasMethod( String template, Properties attributes ) throws 
XDocletException
        {
                ifHasMethod_Impl( template, attributes, true );
        }

        /**
         * Evaluate the body if current class doesn't have a method with the specified
         * name+parameters. If parameters not specified then any method with the given
         * name and any set of parameters is considered equal to the given method name
         * and so the test result is positive and the body is evaluated.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @exception XDocletException  Description of Exception
         * @see                         
#ifHasMethod(java.lang.String,java.util.Properties)
         * @doc:tag                     type="block"
         * @doc:param                   name="name" optional="false" description="The
         *      name of the method we're searching for its existence in current class."
         * @doc:param                   name="parameters" optional="true"
         *      description="We're searching for a method that has the exact set of
         *      parameters specified in parameters param."
         * @doc:param                   name="delimiter" optional="true"
         *      description="The parameters param is delimited by the string specified
         *      in delimiter parameter."
         */
        public void ifDoesntHaveMethod( String template, Properties attributes ) 
throws XDocletException
        {
                ifHasMethod_Impl( template, attributes, false );
        }

        /**
         * Searches for the MethodDoc of the method with name methodName and returns
         * it.
         *
         * @param methodName  Description of Parameter
         * @return            The MethodDocForMethodName value
         */
        protected MethodDoc getMethodDocForMethodName( String methodName )
        {
                if( methodName != null )
                        return extractMethodDoc( getCurrentClass(), methodName );

                return null;
        }

        /**
         * Searches for the MethodDoc of the method with name methodName and returns
         * it.
         *
         * @param methodName    The method to return MethodDoc for.
         * @param superclasses  Search superclasses.
         * @return              The MethodDoc for the method named value
         */
        protected MethodDoc getMethodDocForMethodName( String methodName, boolean 
superclasses )
        {
                if( !superclasses )
                        return getMethodDocForMethodName( methodName );

                for( ClassDoc clazz = getCurrentClass(); clazz != null; clazz = 
clazz.superclass() )
                {
                        MethodDoc method = extractMethodDoc( clazz, methodName );

                        if( method != null )
                                return method;
                }
                return null;
        }

        /**
         * Returns true if a method with the specified methodName+parameters is found
         * in the class clazz. The parameters array can be empty, if so any method with
         * any set of parameters is considered equal to the method we're searching for.
         * if not empty all parameters of the method must be equal to the ones
         * specified in parameters array to have "method equality".
         *
         * @param clazz             Description of Parameter
         * @param methodName        Description of Parameter
         * @param parameters        Description of Parameter
         * @param setCurrentMethod  Description of Parameter
         * @return                  Description of the Returned Value
         */
        protected boolean hasMethod( ClassDoc clazz, String methodName, String[] 
parameters, boolean setCurrentMethod )
        {
                Category cat = Log.getCategory( MethodTagsHandler.class, "hasMethod" );

                if( cat.isDebugEnabled() )
                        cat.debug( "Search for method " + methodName + " in " + 
clazz.name() );

                while( clazz != null )
                {
                        MethodDoc[] methods = clazz.methods();

                        methodLoop :
                        for( int i = 0; i < methods.length; i++ )
                        {
                                if( methods[i].name().equals( methodName ) )
                                {
                                        // All parameters must be equal to have 
"method equality"
                                        Parameter[] params = methods[i].parameters();

                                        if( parameters == null )
                                        {
                                                // The class has the given method
                                                if( setCurrentMethod )
                                                        setCurrentMethod( methods[i] );
                                                return true;
                                        }
                                        if( parameters != null && params == null )
                                                continue methodLoop;
                                        if( parameters.length != params.length )
                                                continue methodLoop;
                                        for( int j = 0; j < params.length; j++ )
                                        {
                                                if( !params[j].typeName().equals( 
parameters[j] ) )
                                                        continue methodLoop;
                                        }
                                        // we have to handle the inverse order as well
                                        for( int j = 0; j < parameters.length; j++ )
                                        {
                                                if( !params[j].typeName().equals( 
parameters[j] ) )
                                                        continue methodLoop;
                                        }
                                        if( cat.isDebugEnabled() )
                                                cat.debug( "Method found in " + 
clazz.name() );

                                        // The class has the given method
                                        if( setCurrentMethod )
                                                setCurrentMethod( methods[i] );
                                        return true;
                                }
                        }

                        // Check super class info
                        clazz = clazz.superclass();
                }
                if( cat.isDebugEnabled() )
                        cat.debug( "Method not found" );

                return false;
        }

        private boolean isInAppendExceptionsList( String append_exceptions, String 
type )
        {
                if( append_exceptions == null )
                        return false;
                else
                        return append_exceptions.indexOf( type ) != -1;
        }

        private boolean isInSkipExceptionsList( String skip_exceptions, String type )
        {
                if( skip_exceptions == null )
                        return false;
                else
                        return skip_exceptions.indexOf( type ) != -1;
        }

        private MethodDoc extractMethodDoc( ClassDoc clazz, String methodName )
        {
                MethodDoc[] methods = clazz.methods();

                for( int i = 0; i < methods.length; i++ )
                {
                        if( methods[i].name().equals( methodName ) )
                                return methods[i];
                }

                return null;
        }

        private void appendException( StringBuffer st, String type )
        {
                if( st.length() == 0 )
                        st.append( "throws " );
                else
                        st.append( ", " );

                st.append( type );
        }

        /**
         * The implementation of ifHasMethod and ifDoesntHaveMethod tags.
         *
         * @param template              The body of the block tag
         * @param attributes            The attributes of the template tag
         * @param has_method            Description of Parameter
         * @exception XDocletException  Description of Exception
         * @see                         
#ifHasMethod(java.lang.String,java.util.Properties)
         * @see                         
#ifDoesntHaveMethod(java.lang.String,java.util.Properties)
         * @see                         
#hasMethod(com.sun.javadoc.ClassDoc,java.lang.String,java.lang.String[],boolean)
         */
        private void ifHasMethod_Impl( String template, Properties attributes, boolean 
has_method ) throws XDocletException
        {
                Category cat = Log.getCategory( MethodTagsHandler.class, 
"ifHasMethod_Impl" );

                String methodName = attributes.getProperty( "name" );
                String parametersStr = attributes.getProperty( "parameters" );
                String delimiter = attributes.getProperty( "delimiter" );

                String[] parameters = null;

                if( cat.isDebugEnabled() )
                {
                        cat.debug( "methodName=" + methodName );
                        cat.debug( "parametersStr=" + parametersStr );
                        cat.debug( "delimiter=" + delimiter );
                        cat.debug( "has_method=" + has_method );
                        cat.debug( "getCurrentClass()=" + getCurrentClass() );
                }

                if( parametersStr != null )
                {
                        if( delimiter == null )
                                delimiter = PARAMETER_DELIMITER;

                        parameters = DocletUtil.tokenizeDelimitedToArray( 
parametersStr, delimiter );

                        if( cat.isDebugEnabled() )
                        {
                                cat.debug( "parameters.length=" + parameters.length );
                                cat.debug( "parameters[0]=" + parameters[0] );
                        }
                }
                if( hasMethod( getCurrentClass(), methodName, parameters, false ) == 
has_method )
                {
                        if( cat.isDebugEnabled() )
                                cat.debug( "method found." );
                        generate( template );
                }
                else
                {
                        if( cat.isDebugEnabled() )
                                cat.debug( "method not found." );
                }
        }
}

Reply via email to