You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by vs...@apache.org on 2009/07/12 13:07:19 UTC

svn commit: r793331 - in /maven/plugins/trunk/maven-javadoc-plugin: ./ src/main/java/org/apache/maven/plugin/javadoc/ src/test/java/org/apache/maven/plugin/javadoc/ src/test/resources/unit/fix-test/expected/src/main/java/fix/test/ src/test/resources/un...

Author: vsiveton
Date: Sun Jul 12 11:07:19 2009
New Revision: 793331

URL: http://svn.apache.org/viewvc?rev=793331&view=rev
Log:
o add more test cases
o refactor part of code for latest qdox and for tests
o clarify javadoc

Modified:
    maven/plugins/trunk/maven-javadoc-plugin/pom.xml
    maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojo.java
    maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/FixJavadocMojoTest.java
    maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/expected/src/main/java/fix/test/ClassWithJavadoc.java
    maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/src/main/java/fix/test/ClassWithJavadoc.java

Modified: maven/plugins/trunk/maven-javadoc-plugin/pom.xml
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/pom.xml?rev=793331&r1=793330&r2=793331&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/pom.xml (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/pom.xml Sun Jul 12 11:07:19 2009
@@ -192,6 +192,12 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>junit-addons</groupId>
+      <artifactId>junit-addons</artifactId>
+      <version>1.4</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.maven.plugin-testing</groupId>
       <artifactId>maven-plugin-testing-harness</artifactId>
       <version>1.2</version>

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojo.java?rev=793331&r1=793330&r2=793331&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojo.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojo.java Sun Jul 12 11:07:19 2009
@@ -22,12 +22,14 @@
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
 import java.io.Writer;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Method;
@@ -98,31 +100,6 @@
     /** The vm line separator */
     private static final String EOL = System.getProperty( "line.separator" );
 
-    /**
-     * Pattern <code>^\\s*\\*\\s*@\\w{1}.*$</code> to find if a Javadoc line contains Javadoc tag
-     * for instance:
-     * <pre>
-     * &#32;&#42; &#64;param X
-     * </pre>
-     */
-    private static final String JAVADOC_TAG_LINE_PATTERN = "^\\s*\\*\\s*@\\w{1}.*$";
-
-    /**
-     * Pattern <code>^\\s*(\\/\\*\\*)?(\\s*(\\*)?)*(\\{)@inheritDoc\\s*(\\})(\\s*(\\*)?)*(\\*\\/)?$</code> to
-     * find if a Javadoc comment contains inherited tag for instance:
-     * <pre>
-     * &#47;&#42;&#42; {&#64;inheritDoc} &#42;&#47;
-     * </pre>
-     * or
-     * <pre>
-     * &#47;&#42;&#42;
-     * &#32;&#42; {&#64;inheritDoc}
-     * &#32;&#42;&#47;
-     * </pre>
-     */
-    private static final String INHERITED_TAG_PATTERN =
-        "^\\s*(\\/\\*\\*)?(\\s*(\\*)?)*(\\{)@inheritDoc\\s*(\\})(\\s*(\\*)?)*(\\*\\/)?$";
-
     /** Tag name for &#64;author **/
     private static final String AUTHOR_TAG = "author";
 
@@ -669,13 +646,18 @@
         PrintStream ps;
         try
         {
-            ps = new PrintStream( invokerLogFile );
+            ps = new PrintStream( new FileOutputStream( invokerLogFile ), true, "UTF-8" );
         }
         catch ( FileNotFoundException e )
         {
             getLog().error( "FileNotFoundException: " + e.getMessage() + ". Using System.out to log the invoker." );
             ps = System.out;
         }
+        catch ( UnsupportedEncodingException e )
+        {
+            getLog().error( "UnsupportedEncodingException: " + e.getMessage() + ". Using System.out to log the invoker." );
+            ps = System.out;
+        }
 
         InvocationOutputHandler outputHandler = new PrintStreamHandler( ps, false );
         request.setOutputHandler( outputHandler );
@@ -1570,7 +1552,7 @@
                 String javadoc = getJavadocComment( originalContent, javaMethod );
 
                 // case: /** {@inheritDoc} */ or no tags
-                if ( Pattern.matches( INHERITED_TAG_PATTERN, StringUtils.removeDuplicateWhitespace( javadoc ) )
+                if ( hasInheritedTag( javadoc )
                     && ( javaMethod.getTags() == null || javaMethod.getTags().length == 0 ) )
                 {
                     sb.append( indent ).append( INHERITED_JAVADOC );
@@ -1624,7 +1606,7 @@
                 sb.append( indent ).append( " " ).append( END_JAVADOC );
                 sb.append( EOL );
 
-                if ( Pattern.matches( INHERITED_TAG_PATTERN, StringUtils.removeDuplicateWhitespace( sb.toString().trim() ) ) )
+                if ( hasInheritedTag( sb.toString().trim() ) )
                 {
                     sb = new StringBuffer();
                     sb.append( indent ).append( INHERITED_JAVADOC );
@@ -2858,10 +2840,10 @@
     /**
      * @param javaFile not null
      * @param encoding not null
-     * @return the content of javaFile using the wanted encoding.
+     * @return the content with unified line separator of the given javaFile using the given encoding.
      * @throws IOException if any
      */
-    private static String readFile( File javaFile, String encoding )
+    private static String readFile( final File javaFile, final String encoding )
         throws IOException
     {
         Reader fileReader = null;
@@ -2877,19 +2859,22 @@
     }
 
     /**
+     * Write content into the given javaFile and using the given encoding.
+     * All line separators will be unified.
+     *
      * @param javaFile not null
      * @param encoding not null
      * @param content not null
      * @throws IOException if any
      */
-    private static void writeFile( File javaFile, String encoding, String content )
+    private static void writeFile( final File javaFile, final String encoding, final String content )
         throws IOException
     {
         Writer writer = null;
         try
         {
             writer = WriterFactory.newWriter( javaFile, encoding );
-            writer.write( content );
+            writer.write( StringUtils.unifyLineSeparators( content ) );
         }
         finally
         {
@@ -2925,7 +2910,7 @@
      * @param javaClass not null
      * @return a default comment for class.
      */
-    private static String getDefaultClassJavadocComment( JavaClass javaClass )
+    private static String getDefaultClassJavadocComment( final JavaClass javaClass )
     {
         StringBuffer sb = new StringBuffer();
 
@@ -2957,7 +2942,7 @@
      * @param javaMethod not null
      * @return a default comment for method.
      */
-    private static String getDefaultMethodJavadocComment( JavaMethod javaMethod )
+    private static String getDefaultMethodJavadocComment( final JavaMethod javaMethod )
     {
         StringBuffer sb = new StringBuffer();
 
@@ -3002,15 +2987,57 @@
     }
 
     /**
-     * Work around for QDOX-146 about whitespace.
+     * Try to find if a Javadoc comment has an {@link #INHERITED_TAG} for instance:
+     * <pre>
+     * &#47;&#42;&#42; {&#64;inheritDoc} &#42;&#47;
+     * </pre>
+     * or
+     * <pre>
+     * &#47;&#42;&#42;
+     * &#32;&#42; {&#64;inheritDoc}
+     * &#32;&#42;&#47;
+     * </pre>
+     *
+     * @param content not null
+     * @return <code>true</code> if the content has an inherited tag, <code>false</code> otherwise.
+     */
+    private static boolean hasInheritedTag( final String content )
+    {
+        final String inheritedTagPattern =
+            "^\\s*(\\/\\*\\*)?(\\s*(\\*)?)*(\\{)@inheritDoc\\s*(\\})(\\s*(\\*)?)*(\\*\\/)?$";
+        return Pattern.matches( inheritedTagPattern, StringUtils.removeDuplicateWhitespace( content ) );
+    }
+
+    /**
+     * Workaround for QDOX-146 about whitespace.
      * Ideally we want to use <code>entity.getComment()</code>
+     * <br/>
+     * For instance, with the following snippet:
+     * <br/>
+     *
+     * <code>
+     * <font color="#808080">1</font>&nbsp;<font color="#ffffff"></font><br />
+     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#47;&#42;&#42;&#32;</font><br />
+     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
+     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font><font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
+     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&#47;</font><br />
+     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">dummyMethod</font><font color="#000000">(&nbsp;</font><font color="#000000">String&nbsp;s&nbsp;</font><font color="#000000">){}</font><br />
+     * </code>
+     *
+     * <br/>
+     * The return will be:
+     * <br/>
+     *
+     * <code>
+     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
+     * </code>
      *
      * @param javaClassContent original class content not null
      * @param entity not null
      * @return the javadoc comment for the entity without any tags.
      * @throws IOException if any
      */
-    private static String getJavadocComment( String javaClassContent, AbstractJavaEntity entity )
+    private static String getJavadocComment( final String javaClassContent, final AbstractJavaEntity entity )
         throws IOException
     {
         if ( entity.getComment() == null )
@@ -3018,51 +3045,46 @@
             return "";
         }
 
-        String originalJavadoc = extractOriginalJavadoc( javaClassContent, entity );
-        if ( originalJavadoc.indexOf( START_JAVADOC ) != -1 )
-        {
-            originalJavadoc =
-                trimLeft( originalJavadoc.substring( originalJavadoc.indexOf( START_JAVADOC ) + START_JAVADOC.length() ) );
-        }
-        if ( originalJavadoc.indexOf( END_JAVADOC ) != -1 )
-        {
-            originalJavadoc = trimRight( originalJavadoc.substring( 0, originalJavadoc.indexOf( END_JAVADOC ) ) );
-        }
-        String[] originalJavadocLines = getLines( originalJavadoc );
-
-        if ( originalJavadocLines.length == 1 )
-        {
-            return originalJavadocLines[0];
-        }
-
-        List originalJavadocLinesAsList = new LinkedList();
-        originalJavadocLinesAsList.addAll( Arrays.asList( originalJavadocLines ) );
+        String originalJavadoc = extractOriginalJavadocContent( javaClassContent, entity );
 
-        boolean toremove = false;
-        for ( Iterator it = originalJavadocLinesAsList.iterator(); it.hasNext(); )
+        StringBuffer sb = new StringBuffer();
+        BufferedReader lr = new BufferedReader( new StringReader( originalJavadoc ) );
+        String line;
+        while ( ( line = lr.readLine() ) != null )
         {
-            String line = (String) it.next();
-
-            if ( toremove )
+            if ( StringUtils.removeDuplicateWhitespace( line ).startsWith( " * @" ) )
             {
-                it.remove();
-                continue;
-            }
-
-            if ( Pattern.matches( JAVADOC_TAG_LINE_PATTERN, line ) )
-            {
-                it.remove();
-                toremove = true;
-                continue;
+                break;
             }
+            sb.append( line ).append( EOL );
         }
 
-        return StringUtils.join( originalJavadocLinesAsList.iterator(), EOL );
+        return trimRight( sb.toString() );
     }
 
     /**
      * Work around for QDOX-146 about whitespace.
      * Ideally we want to use <code>docletTag.getValue()</code>
+     * <br/>
+     * For instance, with the following snippet:
+     * <br/>
+     *
+     * <code>
+     * <font color="#808080">1</font>&nbsp;<font color="#ffffff"></font><br />
+     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#47;&#42;&#42;&#32;</font><br />
+     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
+     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font><font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
+     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&#47;</font><br />
+     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">dummyMethod</font><font color="#000000">(&nbsp;</font><font color="#000000">String&nbsp;s&nbsp;</font><font color="#000000">){}</font><br />
+     * </code>
+     *
+     * <br/>
+     * The return will be:
+     * <br/>
+     *
+     * <code>
+     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font><font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
+     * </code>
      *
      * @param javaClassContent original class content not null
      * @param entity not null
@@ -3070,85 +3092,83 @@
      * @return the javadoc comment for the entity without Javadoc tags.
      * @throws IOException if any
      */
-    private static String getJavadocComment( String javaClassContent, AbstractInheritableJavaEntity entity,
-                                             DocletTag docletTag )
+    private static String getJavadocComment( final String javaClassContent, final AbstractInheritableJavaEntity entity,
+                                             final DocletTag docletTag )
         throws IOException
     {
         if ( docletTag.getValue() == null )
         {
             return "";
         }
-
-        String originalJavadoc = extractOriginalJavadoc( javaClassContent, entity );
-        if ( originalJavadoc.indexOf( START_JAVADOC ) != -1 )
-        {
-            originalJavadoc =
-                originalJavadoc.substring( originalJavadoc.indexOf( START_JAVADOC ) + START_JAVADOC.length() );
-        }
-        if ( originalJavadoc.indexOf( END_JAVADOC ) != -1 )
-        {
-            originalJavadoc = originalJavadoc.substring( 0, originalJavadoc.indexOf( END_JAVADOC ) );
-        }
-        String[] originalJavadocLines = getLines( originalJavadoc );
-
-        if ( originalJavadocLines.length == 1 )
+        if ( docletTag.getParameters().length == 0 )
         {
-            return originalJavadocLines[0];
+            return "";
         }
 
-        // Note: docletTag.getValue() removes duplicate whitespace
-        String[] docletTagLines = getLines( docletTag.getValue() );
-        if ( docletTagLines.length == 0 )
-        {
-            docletTagLines = new String[] { "" };
-        }
+        String originalJavadoc = extractOriginalJavadocContent( javaClassContent, entity );
 
         StringBuffer sb = new StringBuffer();
-        int start = 0;
-        int end = originalJavadocLines.length;
-        for ( int i = 0; i < originalJavadocLines.length; i++ )
-        {
-            String originalJavadocLine = originalJavadocLines[i];
-
-            if ( Pattern.matches( JAVADOC_TAG_LINE_PATTERN, originalJavadocLine ) )
+        BufferedReader lr = new BufferedReader( new StringReader( originalJavadoc ) );
+        String line;
+        boolean found = false;
+        while ( ( line = lr.readLine() ) != null )
+        {
+            if ( StringUtils.removeDuplicateWhitespace( line ).startsWith(
+                                                                           " * @" + docletTag.getName() + " "
+                                                                               + docletTag.getParameters()[0] ) )
             {
-                if ( start != 0 )
+                sb.append( line ).append( EOL );
+                found = true;
+            }
+            else
+            {
+                if ( StringUtils.removeDuplicateWhitespace( line ).startsWith( " * @" ) )
                 {
-                    end = i;
-                    break;
+                    found = false;
                 }
-
-                if ( StringUtils.removeDuplicateWhitespace( originalJavadocLine )
-                                .endsWith( StringUtils.removeDuplicateWhitespace( docletTagLines[0] ) ) )
+                if ( found )
                 {
-                    start = i;
+                    sb.append( line ).append( EOL );
                 }
             }
         }
 
-        for ( int i = start; i < end; i++ )
-        {
-            String originalJavadocLine = trimRight( originalJavadocLines[i] );
-
-            sb.append( originalJavadocLine );
-            if ( i < end - 1 )
-            {
-                sb.append( EOL );
-            }
-        }
-
-        return sb.toString();
+        return trimRight( sb.toString() );
     }
 
     /**
-     * Extract the original Javadoc and others comments up to {@link #START_JAVADOC} form the entity.
+     * Extract the original Javadoc and others comments up to {@link #START_JAVADOC} form the entity. This method
+     * takes care of the Javadoc indentation. All javadoc lines will be trimmed on right.
+     * <br/>
+     * For instance, with the following snippet:
+     * <br/>
+     *
+     * <code>
+     * <font color="#808080">1</font>&nbsp;<font color="#ffffff"></font><br />
+     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#47;&#42;&#42;&#32;</font><br />
+     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
+     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font><font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
+     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&#47;</font><br />
+     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">dummyMethod</font><font color="#000000">(&nbsp;</font><font color="#000000">String&nbsp;s&nbsp;</font><font color="#000000">){}</font><br />
+     * </code>
+     *
+     * <br/>
+     * The return will be:
+     * <br/>
+     *
+     * <code>
+     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#47;&#42;&#42;&#32;</font><br />
+     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
+     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font><font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
+     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&#47;</font><br />
+     * </code>
      *
      * @param javaClassContent not null
      * @param entity not null
      * @return return the original javadoc as String for the current entity
      * @throws IOException if any
      */
-    private static String extractOriginalJavadoc( String javaClassContent, AbstractJavaEntity entity )
+    private static String extractOriginalJavadoc( final String javaClassContent, final AbstractJavaEntity entity )
         throws IOException
     {
         if ( entity.getComment() == null )
@@ -3156,13 +3176,13 @@
             return "";
         }
 
-        List list = new LinkedList();
         String[] javaClassContentLines = getLines( javaClassContent );
+        List list = new LinkedList();
         for ( int i = entity.getLineNumber() - 2; i >= 0; i-- )
         {
             String line = javaClassContentLines[i];
 
-            list.add( line );
+            list.add( trimRight( line ) );
             if ( line.trim().startsWith( START_JAVADOC ) )
             {
                 break;
@@ -3171,16 +3191,76 @@
 
         Collections.reverse( list );
 
-        return trimLeft( StringUtils.join( list.iterator(), EOL ) );
+        return StringUtils.join( list.iterator(), EOL );
+    }
+
+    /**
+     * Extract the Javadoc comment between {@link #START_JAVADOC} and {@link #END_JAVADOC} form the entity. This method
+     * takes care of the Javadoc indentation. All javadoc lines will be trimmed on right.
+     * <br/>
+     * For instance, with the following snippet:
+     * <br/>
+     *
+     * <code>
+     * <font color="#808080">1</font>&nbsp;<font color="#ffffff"></font><br />
+     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#47;&#42;&#42;&#32;</font><br />
+     * <font color="#808080">3</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
+     * <font color="#808080">4</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font><font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
+     * <font color="#808080">5</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&#47;</font><br />
+     * <font color="#808080">6</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">dummyMethod</font><font color="#000000">(&nbsp;</font><font color="#000000">String&nbsp;s&nbsp;</font><font color="#000000">){}</font><br />
+     * </code>
+     *
+     * <br/>
+     * The return will be:
+     * <br/>
+     *
+     * <code>
+     * <font color="#808080">1</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;Dummy&nbsp;Javadoc&nbsp;comment.</font><br />
+     * <font color="#808080">2</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f5fbf">&#42;&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font><font color="#3f5fbf">s&nbsp;a&nbsp;String</font><br />
+     * </code>
+     *
+     * @param javaClassContent not null
+     * @param entity not null
+     * @return return the original javadoc as String for the current entity
+     * @throws IOException if any
+     */
+    private static String extractOriginalJavadocContent( final String javaClassContent, final AbstractJavaEntity entity )
+        throws IOException
+    {
+        if ( entity.getComment() == null )
+        {
+            return "";
+        }
+
+        String originalJavadoc = extractOriginalJavadoc( javaClassContent, entity );
+        if ( originalJavadoc.indexOf( START_JAVADOC ) != -1 )
+        {
+            originalJavadoc =
+                originalJavadoc.substring( originalJavadoc.indexOf( START_JAVADOC ) + START_JAVADOC.length() );
+        }
+        if ( originalJavadoc.indexOf( END_JAVADOC ) != -1 )
+        {
+            originalJavadoc = originalJavadoc.substring( 0, originalJavadoc.indexOf( END_JAVADOC ) );
+        }
+        if ( originalJavadoc.startsWith( "\r\n" ) )
+        {
+            originalJavadoc = originalJavadoc.substring( 2 );
+        }
+        else if ( originalJavadoc.startsWith( "\n" ) || originalJavadoc.startsWith( "\r" ) )
+        {
+            originalJavadoc = originalJavadoc.substring( 1 );
+        }
+
+        return trimRight( originalJavadoc );
     }
 
     /**
      * @param content not null
-     * @return the content without javadoc separator (ie <code> * </code>)
+     * @return the content without last lines containing javadoc separator (ie <code> * </code>)
      * @throws IOException if any
      * @see #getJavadocComment(String, AbstractInheritableJavaEntity, DocletTag)
      */
-    private static String removeLastEmptyJavadocLines( String content )
+    private static String removeLastEmptyJavadocLines( final String content )
         throws IOException
     {
         if ( content.indexOf( EOL ) == -1 )
@@ -3224,7 +3304,7 @@
      * @throws IOException if any
      * @see #getJavadocComment(String, AbstractInheritableJavaEntity, DocletTag)
      */
-    private static String alignIndentationJavadocLines( String content, String indent )
+    private static String alignIndentationJavadocLines( final String content, final String indent )
         throws IOException
     {
         String[] lines = getLines( content );
@@ -3232,7 +3312,12 @@
         StringBuffer sb = new StringBuffer();
         for ( int i = 0; i < lines.length; i++ )
         {
-            sb.append( indent ).append( " " ).append( lines[i].trim() );
+            String line = lines[i];
+            if ( !line.trim().startsWith( "*" ) )
+            {
+                line = "*" + line;
+            }
+            sb.append( indent ).append( " " ).append( trimLeft( line ) );
             if ( i < lines.length - 1 )
             {
                 sb.append( EOL );
@@ -3243,18 +3328,25 @@
     }
 
     /**
+     * Autodetect the indentation of a given line:
+     * <pre>
+     * autodetectIndentation( null ) = "";
+     * autodetectIndentation( "a" ) = "";
+     * autodetectIndentation( "    a" ) = "    ";
+     * autodetectIndentation( "\ta" ) = "\t";
+     * </pre>
+     *
      * @param line not null
      * @return the indentation for the given line.
      */
-    private static String autodetectIndentation( String line )
+    private static String autodetectIndentation( final String line )
     {
-        int i = line.indexOf( line.trim() );
-        if ( i == -1 )
+        if ( StringUtils.isEmpty( line ) )
         {
             return "";
         }
 
-        return line.substring( 0, i );
+        return line.substring( 0, line.indexOf( trimLeft( line ) ) );
     }
 
     /**
@@ -3262,7 +3354,7 @@
      * @return an array of all content lines
      * @throws IOException if any
      */
-    private static String[] getLines( String content )
+    private static String[] getLines( final String content )
         throws IOException
     {
         List lines = new LinkedList();
@@ -3279,47 +3371,52 @@
     }
 
     /**
+     * Trim a given line on the left:
+     * <pre>
+     * trimLeft( null ) = "";
+     * trimLeft( "  " ) = "";
+     * trimLeft( "a" ) = "a";
+     * trimLeft( "    a" ) = "a";
+     * trimLeft( "\ta" ) = "a";
+     * trimLeft( "    a    " ) = "a    ";
+     * </pre>
+     *
      * @param text
      * @return the text trimmed on left side or empty if text is null.
      */
-    private static String trimLeft( String text )
+    private static String trimLeft( final String text )
     {
         if ( StringUtils.isEmpty( text ) || StringUtils.isEmpty( text.trim() ) )
         {
             return "";
         }
 
-        for ( int i = 0; i < text.length(); i++ )
-        {
-            if ( !Character.isWhitespace( text.charAt( i ) ) )
-            {
-                return text.substring( i );
-            }
-        }
-
-        return text;
+        String textTrimmed = text.trim();
+        return text.substring( text.indexOf( textTrimmed ), text.length() );
     }
 
     /**
+     * Trim a given line on the right:
+     * <pre>
+     * trimRight( null ) = "";
+     * trimRight( "  " ) = "";
+     * trimRight( "a" ) = "a";
+     * trimRight( "a\t" ) = "a";
+     * trimRight( "    a    " ) = "    a";
+     * </pre>
+     *
      * @param text
      * @return the text trimmed on tight side or empty if text is null.
      */
-    private static String trimRight( String text )
+    private static String trimRight( final String text )
     {
         if ( StringUtils.isEmpty( text ) || StringUtils.isEmpty( text.trim() ) )
         {
             return "";
         }
 
-        for ( int i = text.length() - 1; i > 0; i-- )
-        {
-            if ( !Character.isWhitespace( text.charAt( i ) ) )
-            {
-                return text.substring( 0, i + 1 );
-            }
-        }
-
-        return text;
+        String textTrimmed = text.trim();
+        return text.substring( 0, text.indexOf( textTrimmed ) + textTrimmed.length() );
     }
 
     /**

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/FixJavadocMojoTest.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/FixJavadocMojoTest.java?rev=793331&r1=793330&r2=793331&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/FixJavadocMojoTest.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/FixJavadocMojoTest.java Sun Jul 12 11:07:19 2009
@@ -24,10 +24,13 @@
 import java.io.IOException;
 import java.io.PrintStream;
 import java.io.Reader;
+import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import junitx.util.PrivateAccessor;
+
 import org.apache.commons.lang.SystemUtils;
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
@@ -44,6 +47,13 @@
 import org.codehaus.plexus.util.StringUtils;
 import org.codehaus.plexus.util.cli.CommandLineUtils;
 
+import com.thoughtworks.qdox.JavaDocBuilder;
+import com.thoughtworks.qdox.model.AbstractInheritableJavaEntity;
+import com.thoughtworks.qdox.model.AbstractJavaEntity;
+import com.thoughtworks.qdox.model.DocletTag;
+import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaMethod;
+
 /**
  * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
  * @version $Id$
@@ -51,6 +61,9 @@
 public class FixJavadocMojoTest
     extends AbstractMojoTestCase
 {
+    /** The vm line separator */
+    private static final String EOL = System.getProperty( "line.separator" );
+
     /** The M2_HOME env variable */
     private static final File M2_HOME;
 
@@ -114,6 +127,320 @@
     }
 
     // ----------------------------------------------------------------------
+    // Test private static methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * @throws Throwable if any
+     */
+    public void testAutodetectIndentation()
+        throws Throwable
+    {
+        String s = null;
+        assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
+                                                  new Class[] { String.class }, new Object[] { s } ) );
+
+        s = "no indentation";
+        assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
+                                                  new Class[] { String.class }, new Object[] { s } ) );
+
+        s = "no indentation with right spaces  ";
+        assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
+                                                  new Class[] { String.class }, new Object[] { s } ) );
+
+        s = "    indentation";
+        assertEquals( "    ", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
+                                                      new Class[] { String.class }, new Object[] { s } ) );
+
+        s = "    indentation with right spaces  ";
+        assertEquals( "    ", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
+                                                      new Class[] { String.class }, new Object[] { s } ) );
+
+        s = "\ttab indentation";
+        assertEquals( "\t", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
+                                                    new Class[] { String.class }, new Object[] { s } ) );
+
+        s = "  \n  indentation with right spaces  ";
+        assertEquals( "  \n  ", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "autodetectIndentation",
+                                                        new Class[] { String.class }, new Object[] { s } ) );
+    }
+
+    /**
+     * @throws Throwable if any
+     */
+    public void testTrimLeft()
+        throws Throwable
+    {
+        assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
+                                                  new Class[] { String.class }, new Object[] { null } ) );
+        assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
+                                                  new Class[] { String.class }, new Object[] { "  " } ) );
+        assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
+                                                  new Class[] { String.class }, new Object[] { "  \t  " } ) );
+        assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
+                                                   new Class[] { String.class }, new Object[] { "a" } ) );
+        assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
+                                                   new Class[] { String.class }, new Object[] { "  a" } ) );
+        assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
+                                                   new Class[] { String.class }, new Object[] { "\ta" } ) );
+        assertEquals( "a  ", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
+                                                     new Class[] { String.class }, new Object[] { "  a  " } ) );
+        assertEquals( "a\t", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimLeft",
+                                                     new Class[] { String.class }, new Object[] { "\ta\t" } ) );
+    }
+
+    /**
+     * @throws Throwable if any
+     */
+    public void testTrimRight()
+        throws Throwable
+    {
+        assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
+                                                  new Class[] { String.class }, new Object[] { null } ) );
+        assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
+                                                  new Class[] { String.class }, new Object[] { "  " } ) );
+        assertEquals( "", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
+                                                  new Class[] { String.class }, new Object[] { "  \t  " } ) );
+        assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
+                                                   new Class[] { String.class }, new Object[] { "a" } ) );
+        assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
+                                                   new Class[] { String.class }, new Object[] { "a  " } ) );
+        assertEquals( "a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
+                                                   new Class[] { String.class }, new Object[] { "a\t" } ) );
+        assertEquals( "  a", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
+                                                     new Class[] { String.class }, new Object[] { "  a  " } ) );
+        assertEquals( "\ta", PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "trimRight",
+                                                     new Class[] { String.class }, new Object[] { "\ta\t" } ) );
+    }
+
+    /**
+     * @throws Throwable if any
+     */
+    public void testHasInheritedTag()
+        throws Throwable
+    {
+        String content = "/** {@inheritDoc} */";
+        Boolean has =
+            (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
+                                              new Class[] { String.class }, new Object[] { content } );
+        assertEquals( Boolean.TRUE, has );
+
+        content = "/**{@inheritDoc}*/";
+        has =
+            (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
+                                              new Class[] { String.class }, new Object[] { content } );
+        assertEquals( Boolean.TRUE, has );
+
+        content = "/**{@inheritDoc  }  */";
+        has =
+            (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
+                                              new Class[] { String.class }, new Object[] { content } );
+        assertEquals( Boolean.TRUE, has );
+
+        content = "/**  {@inheritDoc  }  */";
+        has =
+            (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
+                                              new Class[] { String.class }, new Object[] { content } );
+        assertEquals( Boolean.TRUE, has );
+
+        content = "/** */";
+        has =
+            (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
+                                              new Class[] { String.class }, new Object[] { content } );
+        assertEquals( Boolean.FALSE, has );
+
+        content = "/**{  @inheritDoc  }*/";
+        has =
+            (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
+                                              new Class[] { String.class }, new Object[] { content } );
+        assertEquals( Boolean.FALSE, has );
+
+        content = "/**{@ inheritDoc}*/";
+        has =
+            (Boolean) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "hasInheritedTag",
+                                              new Class[] { String.class }, new Object[] { content } );
+        assertEquals( Boolean.FALSE, has );
+    }
+
+    /**
+     * @throws Throwable if any
+     */
+    public void testJavadocComment()
+        throws Throwable
+    {
+        String content = "/**" + EOL +
+                " * Dummy Class." + EOL +
+                " */" + EOL +
+                "public class DummyClass" + EOL +
+                "{" + EOL +
+                "    /**" + EOL +
+                "     *" + EOL +
+                "     * Dummy" + EOL +
+                "     *" + EOL +
+                "     *      Method." + EOL +
+                "     *" + EOL +
+                "     * @param args not" + EOL +
+                "     *" + EOL +
+                "     * null" + EOL +
+                "     * @param i non negative" + EOL +
+                "     * @param object could" + EOL +
+                "     * be" + EOL +
+                "     *      null" + EOL +
+                "     * @return a" + EOL +
+                "     * String" + EOL +
+                "     *" + EOL +
+                "     * @throws Exception if" + EOL +
+                "     * any" + EOL +
+                "     *" + EOL +
+                "     */" + EOL +
+                "    public static String dummyMethod( String[] args, int i, Object object )" + EOL +
+                "        throws Exception" + EOL +
+                "    {" + EOL +
+                "        return null;" + EOL +
+                "    }" + EOL +
+                "}";
+
+        JavaDocBuilder builder = new JavaDocBuilder();
+        builder.setEncoding( "UTF-8" );
+        builder.addSource( new StringReader( content ) );
+
+        JavaClass[] classes = builder.getClasses();
+        JavaClass clazz = classes[0];
+
+        JavaMethod javaMethod = clazz.getMethods()[0];
+
+        String javadoc =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "extractOriginalJavadoc", new Class[] {
+                String.class, AbstractJavaEntity.class }, new Object[] { content, javaMethod } );
+        assertEquals( "    /**" + EOL +
+                "     *" + EOL +
+                "     * Dummy" + EOL +
+                "     *" + EOL +
+                "     *      Method." + EOL +
+                "     *" + EOL +
+                "     * @param args not" + EOL +
+                "     *" + EOL +
+                "     * null" + EOL +
+                "     * @param i non negative" + EOL +
+                "     * @param object could" + EOL +
+                "     * be" + EOL +
+                "     *      null" + EOL +
+                "     * @return a" + EOL +
+                "     * String" + EOL +
+                "     *" + EOL +
+                "     * @throws Exception if" + EOL +
+                "     * any" + EOL +
+                "     *" + EOL +
+                "     */", javadoc );
+
+        String javadocContent =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "extractOriginalJavadocContent",
+                                             new Class[] { String.class, AbstractJavaEntity.class }, new Object[] {
+                                                 content, javaMethod } );
+        assertEquals( "     *" + EOL +
+                      "     * Dummy" + EOL +
+                      "     *" + EOL +
+                      "     *      Method." + EOL +
+                      "     *" + EOL +
+                      "     * @param args not" + EOL +
+                      "     *" + EOL +
+                      "     * null" + EOL +
+                      "     * @param i non negative" + EOL +
+                      "     * @param object could" + EOL +
+                      "     * be" + EOL +
+                      "     *      null" + EOL +
+                      "     * @return a" + EOL +
+                      "     * String" + EOL +
+                      "     *" + EOL +
+                      "     * @throws Exception if" + EOL +
+                      "     * any" + EOL +
+                      "     *", javadocContent );
+
+        String withoutEmptyJavadocLines =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
+                                             new Class[] { String.class }, new Object[] { javadocContent } );
+        assertTrue( withoutEmptyJavadocLines.endsWith( "any" ) );
+
+        String methodJavadoc =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] {
+                String.class, AbstractJavaEntity.class }, new Object[] { content, javaMethod } );
+        assertEquals( "     *" + EOL +
+                "     * Dummy" + EOL +
+                "     *" + EOL +
+                "     *      Method." + EOL +
+                "     *", methodJavadoc );
+        withoutEmptyJavadocLines =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
+                                             new Class[] { String.class }, new Object[] { methodJavadoc } );
+        assertTrue( withoutEmptyJavadocLines.endsWith( "Method." ) );
+
+        assertEquals( 5, javaMethod.getTags().length );
+
+        DocletTag tag = javaMethod.getTags()[0];
+        String tagJavadoc =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] {
+                String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content,
+                javaMethod, tag } );
+        assertEquals( "     * @param args not" + EOL +
+                "     *" + EOL +
+                "     * null", tagJavadoc );
+        withoutEmptyJavadocLines =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
+                                             new Class[] { String.class }, new Object[] { tagJavadoc } );
+        assertTrue( withoutEmptyJavadocLines.endsWith( "null" ) );
+
+        tag = javaMethod.getTags()[1];
+        tagJavadoc =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] {
+                String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content,
+                javaMethod, tag } );
+        assertEquals( "     * @param i non negative", tagJavadoc );
+        withoutEmptyJavadocLines =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
+                                             new Class[] { String.class }, new Object[] { tagJavadoc } );
+        assertTrue( withoutEmptyJavadocLines.endsWith( "negative" ) );
+
+        tag = javaMethod.getTags()[2];
+        tagJavadoc =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] {
+                String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content,
+                javaMethod, tag } );
+        assertEquals( "     * @param object could" + EOL +
+                "     * be" + EOL +
+                "     *      null", tagJavadoc );
+        withoutEmptyJavadocLines =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
+                                             new Class[] { String.class }, new Object[] { tagJavadoc } );
+        assertTrue( withoutEmptyJavadocLines.endsWith( "null" ) );
+
+        tag = javaMethod.getTags()[3];
+        tagJavadoc =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] {
+                String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content,
+                javaMethod, tag } );
+        assertEquals( "     * @return a" + EOL +
+                "     * String" + EOL +
+                "     *", tagJavadoc );
+        withoutEmptyJavadocLines =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
+                                             new Class[] { String.class }, new Object[] { tagJavadoc } );
+        assertTrue( withoutEmptyJavadocLines.endsWith( "String" ) );
+
+        tag = javaMethod.getTags()[4];
+        tagJavadoc =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] {
+                String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content,
+                javaMethod, tag } );
+        assertEquals( "     * @throws Exception if" + EOL +
+                "     * any" + EOL +
+                "     *", tagJavadoc );
+        withoutEmptyJavadocLines =
+            (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "removeLastEmptyJavadocLines",
+                                             new Class[] { String.class }, new Object[] { tagJavadoc } );
+        assertTrue( withoutEmptyJavadocLines.endsWith( "any" ) );
+    }
+
+    // ----------------------------------------------------------------------
     // private methods
     // ----------------------------------------------------------------------
 

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/expected/src/main/java/fix/test/ClassWithJavadoc.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/expected/src/main/java/fix/test/ClassWithJavadoc.java?rev=793331&r1=793330&r2=793331&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/expected/src/main/java/fix/test/ClassWithJavadoc.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/expected/src/main/java/fix/test/ClassWithJavadoc.java Sun Jul 12 11:07:19 2009
@@ -138,6 +138,39 @@
         return null;
     }
 
+    /**
+     * To take care of same comments.
+     *
+     * @param aString a string
+     * @return a string
+     */
+    public String sameString( String aString )
+    {
+        return null;
+    }
+
+    /**
+     * Empty Javadoc tag.
+     *
+     * @return a string
+     * @param aString a {@link java.lang.String} object.
+     */
+    public String emptyJavadocTag( String aString )
+    {
+        return null;
+    }
+
+    /**
+     * Comment on first line.
+     *
+     * @param aString a string
+     * @return a string
+     */
+    public String javadocCommentOnFirstLine( String aString )
+    {
+        return null;
+    }
+
     // ----------------------------------------------------------------------
     // Inheritance
     // ----------------------------------------------------------------------

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/src/main/java/fix/test/ClassWithJavadoc.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/src/main/java/fix/test/ClassWithJavadoc.java?rev=793331&r1=793330&r2=793331&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/src/main/java/fix/test/ClassWithJavadoc.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/test/resources/unit/fix-test/src/main/java/fix/test/ClassWithJavadoc.java Sun Jul 12 11:07:19 2009
@@ -116,6 +116,38 @@
         return null;
     }
 
+    /**
+     * To take care of same comments.
+     *
+     * @param aString a string
+     * @return a string
+     */
+    public String sameString( String aString )
+    {
+        return null;
+    }
+
+    /**
+     * Empty Javadoc tag.
+     *
+     * @param
+     * @return a string
+     */
+    public String emptyJavadocTag( String aString )
+    {
+        return null;
+    }
+
+    /** Comment on first line.
+     *
+     * @param aString a string
+     * @return a string
+     */
+    public String javadocCommentOnFirstLine( String aString )
+    {
+        return null;
+    }
+
     // ----------------------------------------------------------------------
     // Inheritance
     // ----------------------------------------------------------------------