Author: rfscholte Date: Sat Jul 16 15:30:31 2011 New Revision: 1147437 URL: http://svn.apache.org/viewvc?rev=1147437&view=rev Log: Fix MJAVADOC-250: Resolve names in {@link} to fully qualified names. Includes: - upgrade QDox from 1.9.2 to 1.12 - add mockito-1.8.5 for strong mocking support in junit tests - add new junit tests for AbstractFixJavadocMojo.replaceLinkTags() - add IT (src/it/MJAVADOC-250)
Added: maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/invoker.properties maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/pom.xml maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/main/ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/main/java/ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/main/java/foo/ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/main/java/foo/bar/ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/main/java/foo/bar/ALotOfLinkTags.java maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/verify.bsh maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojoTest.java 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 Modified: maven/plugins/trunk/maven-javadoc-plugin/pom.xml URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/pom.xml?rev=1147437&r1=1147436&r2=1147437&view=diff ============================================================================== --- maven/plugins/trunk/maven-javadoc-plugin/pom.xml (original) +++ maven/plugins/trunk/maven-javadoc-plugin/pom.xml Sat Jul 16 15:30:31 2011 @@ -170,7 +170,7 @@ under the License. <dependency> <groupId>com.thoughtworks.qdox</groupId> <artifactId>qdox</artifactId> - <version>1.9.2</version> + <version>1.12</version> </dependency> <!-- Plexus --> @@ -243,6 +243,11 @@ under the License. <version>6.1.19</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>1.8.5</version> + </dependency> </dependencies> <build> @@ -381,6 +386,7 @@ under the License. <pomInclude>MJAVADOC-226/pom.xml</pomInclude> <pomInclude>MJAVADOC-97/pom.xml</pomInclude> <!-- pomInclude>**/MJAVADOC-181/pom.xml</pomInclude--><!-- seems to be wrong, see comment in Jira issue --> + <pomInclude>MJAVADOC-250/pom.xml</pomInclude> <pomInclude>MJAVADOC-257/pom.xml</pomInclude> <pomInclude>MJAVADOC-259/pom.xml</pomInclude> <pomInclude>MJAVADOC-262/pom.xml</pomInclude> Added: maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/invoker.properties URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/invoker.properties?rev=1147437&view=auto ============================================================================== --- maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/invoker.properties (added) +++ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/invoker.properties Sat Jul 16 15:30:31 2011 @@ -0,0 +1 @@ +invoker.goals=clean javadoc:fix \ No newline at end of file Added: maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/pom.xml URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/pom.xml?rev=1147437&view=auto ============================================================================== --- maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/pom.xml (added) +++ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/pom.xml Sat Jul 16 15:30:31 2011 @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.maven.plugins.maven-javadoc-plugin.it</groupId> + <artifactId>mjavadoc-250</artifactId> + <version>1.0-SNAPSHOT</version> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>@pom.version@</version> + <configuration> + <force>true</force> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + +</project> Added: maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/main/java/foo/bar/ALotOfLinkTags.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/main/java/foo/bar/ALotOfLinkTags.java?rev=1147437&view=auto ============================================================================== --- maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/main/java/foo/bar/ALotOfLinkTags.java (added) +++ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/src/main/java/foo/bar/ALotOfLinkTags.java Sat Jul 16 15:30:31 2011 @@ -0,0 +1,77 @@ +package foo.bar; + +import java.util.HashSet; +import java.util.*; + +/** + * Test linktag parsing in javaDoc of class + * <ul> + * <li>{@link Double} should be resolved by the system classloader</li> + * <li>{@link Float } should be resolved, despite all the spaces</li> + * <li>{@link HashSet#hashCode()} should be resolved by the explicit import</li> + * <li>{@link Hashtable#clear() } should be resolved by the implicit import</li> + * <li>{@link UNKNOWN} should stay they same as it can't be resolved</li> + * <li>{@link ANestedClass} should be resolved as it is a nested class</li> + * </ul> + */ +public class ALotOfLinkTags +{ + + /** + * Test linktag parsing in javaDoc of field + * <ul> + * <li>{@link Double} should be resolved by the system classloader</li> + * <li>{@link Float } should be resolved, despite all the spaces</li> + * <li>{@link HashSet#hashCode()} should be resolved by the explicit import</li> + * <li>{@link Hashtable#clear() } should be resolved by the implicit import</li> + * <li>{@link UNKNOWN} should stay they same as it can't be resolved</li> + * <li>{@link ANestedClass} should be resolved as it is a nested class</li> + * </ul> + */ + public Object aField; + + /** + * Test linktag parsing in javaDoc of constructor + * <ul> + * <li>{@link Double} should be resolved by the system classloader</li> + * <li>{@link Float } should be resolved, despite all the spaces</li> + * <li>{@link HashSet#hashCode()} should be resolved by the explicit import</li> + * <li>{@link Hashtable#clear() } should be resolved by the implicit import</li> + * <li>{@link UNKNOWN} should stay they same as it can't be resolved</li> + * <li>{@link ANestedClass} should be resolved as it is a nested class</li> + * </ul> + */ + public ALotOfLinkTags() + { + } + + /** + * Test linktag parsing in javaDoc of method + * <ul> + * <li>{@link Double} should be resolved by the system classloader</li> + * <li>{@link Float } should be resolved, despite all the spaces</li> + * <li>{@link HashSet#hashCode()} should be resolved by the explicit import</li> + * <li>{@link Hashtable#clear() } should be resolved by the implicit import</li> + * <li>{@link UNKNOWN} should stay they same as it can't be resolved</li> + * <li>{@link ANestedClass} should be resolved as it is a nested class</li> + * </ul> + */ + public void aMethod( String[] args ) + { + } + + /** + * Test linktag parsing in javaDoc of nested class + * <ul> + * <li>{@link Double} should be resolved by the system classloader</li> + * <li>{@link Float } should be resolved, despite all the spaces</li> + * <li>{@link HashSet#hashCode()} should be resolved by the explicit import</li> + * <li>{@link Hashtable#clear() } should be resolved by the implicit import</li> + * <li>{@link UNKNOWN} should stay they same as it can't be resolved</li> + * <li>{@link ANestedClass} should be resolved as it is a nested class</li> + * </ul> + */ + public class ANestedClass { + + } +} Added: maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/verify.bsh URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/verify.bsh?rev=1147437&view=auto ============================================================================== --- maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/verify.bsh (added) +++ maven/plugins/trunk/maven-javadoc-plugin/src/it/MJAVADOC-250/verify.bsh Sat Jul 16 15:30:31 2011 @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.*; +import org.codehaus.plexus.util.*; + +try +{ + File javaFile = new File( basedir, "/src/main/java/foo/bar/ALotOfLinkTags.java" ); + String content = FileUtils.fileRead( javaFile, "UTF-8" ); + + // @link replacement cover classes, methods and constructors + // it doesn't cover fields and nested classes (yet), neither package or parameters. + + int matches = StringUtils.countMatches( content, "{@link java.lang.Double}" ); + if ( matches != 3 ) + { + System.err.println( "Expected {@link java.lang.Double} 3 times, but was " + matches ); + return false; + } + matches = StringUtils.countMatches( content, "{@link Double}" ); + if ( matches != 2 ) + { + System.err.println( "Expected {@link Double} 2 times, but was " + matches ); + return false; + } + + int matches = StringUtils.countMatches( content, "{@link java.lang.Float}" ); + if ( matches != 3 ) + { + System.err.println( "Expected {@link java.lang.Float} 3 times, but was " + matches ); + return false; + } + + matches = StringUtils.countMatches( content, "{@link java.util.HashSet#hashCode()}" ); + if ( matches != 3 ) + { + System.err.println( "Expected {@link java.util.HashSet#hashCode()} 3 times, but was " + matches ); + return false; + } + + matches = StringUtils.countMatches( content, "{@link java.util.Hashtable#clear()}" ); + if ( matches != 3 ) + { + System.err.println( "Expected {@link java.util.Hashtable#clear()} 3 times, but was " + matches ); + return false; + } + + matches = StringUtils.countMatches( content, "{@link foo.bar.ALotOfLinkTags.ANestedClass}" ); + if ( matches != 3 ) + { + System.err.println( "Expected {@link foo.bar.ALotOfLinkTags.ANestedClass} 3 times, but was " + matches ); + return false; + } + + matches = StringUtils.countMatches( content, "{@link UNKNOWN}" ); + if ( matches != 5 ) + { + System.err.println( "Expected {@link UNKOWN} 5 times, but was " + matches ); + return false; + } + +} +catch( Throwable e ) +{ + e.printStackTrace(); + return false; +} + +return true; 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=1147437&r1=1147436&r2=1147437&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 Sat Jul 16 15:30:31 2011 @@ -41,6 +41,7 @@ import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; +import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.ClassUtils; @@ -106,6 +107,9 @@ public abstract class AbstractFixJavadoc /** Tag name for @throws **/ private static final String THROWS_TAG = "throws"; + /** Tag name for @link **/ + private static final String LINK_TAG = "link"; + /** Tag name for {@inheritDoc} **/ private static final String INHERITED_TAG = "{@inheritDoc}"; @@ -227,6 +231,7 @@ public abstract class AbstractFixJavadoc * <li>param (fix only @param tag)</li> * <li>return (fix only @return tag)</li> * <li>throws (fix only @throws tag)</li> + * <li>link (fix only @link tag)</li> * </ul> * * @parameter expression="${fixTags}" default-value="all" @@ -492,7 +497,7 @@ public abstract class AbstractFixJavadoc { String s = split[j].trim(); if ( JavadocUtil.equalsIgnoreCase( s, FIX_TAGS_ALL, AUTHOR_TAG, VERSION_TAG, SINCE_TAG, PARAM_TAG, - THROWS_TAG ) ) + THROWS_TAG, LINK_TAG ) ) { filtered.add( s ); } @@ -1661,12 +1666,81 @@ public abstract class AbstractFixJavadoc comment = comment.substring( 0, comment.indexOf( END_JAVADOC ) ); } + if ( fixTag( LINK_TAG ) ) + { + comment = replaceLinkTags( comment, entity ); + } + String[] lines = getLines( comment ); for ( int i = 0; i < lines.length; i++ ) { sb.append( indent ).append( " " ).append( lines[i].trim() ); sb.append( EOL ); } + + + } + + private static final String replaceLinkTags( String comment, AbstractInheritableJavaEntity entity ) + { + StringBuffer resolvedComment = new StringBuffer(); + // scan comment for {@link someClassName} and try to resolve this + Matcher linktagMatcher = Pattern.compile( "\\{@link\\s" ).matcher( comment ); + int startIndex = 0; + while ( linktagMatcher.find() ) + { + int startName = linktagMatcher.end(); + resolvedComment.append( comment.substring( startIndex, startName ) ); + int endName = comment.indexOf( "}", startName ); + if ( endName >= 0 ) + { + String name; + String link = comment.substring( startName, endName ); + int hashIndex = link.indexOf( '#' ); + if ( hashIndex >= 0 ) + { + name = link.substring( 0, hashIndex ); + } + else { + name = link; + } + if ( StringUtils.isNotBlank( name )) + { + String typeName; + if ( entity instanceof JavaClass) + { + typeName = ((JavaClass) entity).resolveType( name.trim() ); + } + else + { + typeName = entity.getParentClass().resolveType( name.trim() ); + } + + if ( typeName == null ) + { + typeName = name.trim(); + } + else { + typeName = typeName.replaceAll( "\\$", "." ); + } + //adjust name for inner classes + resolvedComment.append( typeName ); + } + if ( hashIndex >= 0 ) + { + resolvedComment.append( link.substring( hashIndex ).trim() ) ; + } + startIndex = endName; + } + else + { + startIndex = startName; + } + + } + resolvedComment.append( comment.substring( startIndex ) ); + return resolvedComment.toString(); + } /** @@ -2019,7 +2093,7 @@ public abstract class AbstractFixJavadoc sb.append( " if any." ); } } - + /** * Add missing tags not already written. * @@ -3082,7 +3156,7 @@ public abstract class AbstractFixJavadoc * @return the javadoc comment for the entity without Javadoc tags. * @throws IOException if any */ - private static String getJavadocComment( final String javaClassContent, + private String getJavadocComment( final String javaClassContent, final AbstractInheritableJavaEntity entity, final DocletTag docletTag ) throws IOException { @@ -3106,6 +3180,10 @@ public abstract class AbstractFixJavadoc if ( l.startsWith( "* @" + docletTag.getName() + " " + paramValue ) || l.startsWith( "*@" + docletTag.getName() + " " + paramValue ) ) { + if ( fixTag( LINK_TAG ) ) + { + line = replaceLinkTags( line, entity ); + } sb.append( line ).append( EOL ); found = true; } @@ -3117,6 +3195,10 @@ public abstract class AbstractFixJavadoc } if ( found ) { + if ( fixTag( LINK_TAG ) ) + { + line = replaceLinkTags( line, entity ); + } sb.append( line ).append( EOL ); } } Added: maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojoTest.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojoTest.java?rev=1147437&view=auto ============================================================================== --- maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojoTest.java (added) +++ maven/plugins/trunk/maven-javadoc-plugin/src/test/java/org/apache/maven/plugin/javadoc/AbstractFixJavadocMojoTest.java Sat Jul 16 15:30:31 2011 @@ -0,0 +1,207 @@ +package org.apache.maven.plugin.javadoc; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import junit.framework.TestCase; +import junitx.util.PrivateAccessor; + +import com.thoughtworks.qdox.model.AbstractInheritableJavaEntity; +import com.thoughtworks.qdox.model.DocletTag; +import com.thoughtworks.qdox.model.IndentBuffer; +import com.thoughtworks.qdox.model.JavaClass; + +public class AbstractFixJavadocMojoTest + extends TestCase +{ + + public void testReplaceLinkTags_noLinkTag() + throws Throwable + { + String comment = "/** @see ConnectException */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + assertEquals( "/** @see ConnectException */", newComment ); + } + + public void testReplaceLinkTags_oneLinkTag() + throws Throwable + { + String comment = "/** {@link ConnectException} */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + assertEquals( "/** {@link java.net.ConnectException} */", newComment ); + } + + public void testReplaceLinkTags_missingEndBrace() + throws Throwable + { + String comment = "/** {@link ConnectException */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + + assertEquals( "/** {@link ConnectException */", newComment ); + } + + public void testReplaceLinkTags_spacesAfterLinkTag() + throws Throwable + { + String comment = "/** {@link ConnectException} */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + + assertEquals( "/** {@link java.net.ConnectException} */", newComment ); + } + + public void testReplaceLinkTags_spacesAfterClassName() + throws Throwable + { + String comment = "/** {@link ConnectException } */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + + assertEquals( "/** {@link java.net.ConnectException} */", newComment ); + } + + public void testReplaceLinkTags_spacesAfterMethod() + throws Throwable + { + String comment = "/** {@link ConnectException#getMessage() } */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + + assertEquals( "/** {@link java.net.ConnectException#getMessage()} */", newComment ); + } + + public void testReplaceLinkTags_containingHash() + throws Throwable + { + String comment = "/** {@link ConnectException#getMessage()} */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + + assertEquals( "/** {@link java.net.ConnectException#getMessage()} */", newComment ); + } + + public void testReplaceLinkTags_followedByHash() + throws Throwable + { + String comment = "/** {@link ConnectException} ##important## */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + + assertEquals( "/** {@link java.net.ConnectException} ##important## */", newComment ); + } + + public void testReplaceLinkTags_twoLinks() + throws Throwable + { + String comment = "/** Use {@link ConnectException} instead of {@link Exception} */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + when( clazz.resolveType( "Exception" ) ).thenReturn( "java.lang.Exception" ); + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + + assertEquals( "/** Use {@link java.net.ConnectException} instead of {@link java.lang.Exception} */", newComment ); + } + + public void testReplaceLinkTags_OnlyAnchor() + throws Throwable + { + String comment = "/** There's a {@link #getClass()} but no setClass() */"; + AbstractInheritableJavaEntity entity = spy( new PrivateAbstractInheritableJavaEntity() ); + JavaClass clazz = mock( JavaClass.class ); + when( entity.getParentClass() ).thenReturn( clazz ); + when( clazz.resolveType( "ConnectException" ) ).thenReturn( "java.net.ConnectException" ); + when( clazz.resolveType( "Exception" ) ).thenReturn( "java.lang.Exception" ); + + String newComment = + (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "replaceLinkTags", new Class[] { + String.class, AbstractInheritableJavaEntity.class }, new Object[] { comment, entity } ); + + assertEquals( "/** There's a {@link #getClass()} but no setClass() */", newComment ); + } + + protected class PrivateAbstractInheritableJavaEntity + extends AbstractInheritableJavaEntity + { + public int compareTo( Object o ) + { + return 0; + } + + @Override + public DocletTag[] getTagsByName( String arg0, boolean arg1 ) + { + return null; + } + + @Override + protected void writeBody( IndentBuffer arg0 ) + { + } + } +} 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=1147437&r1=1147436&r2=1147437&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 Sat Jul 16 15:30:31 2011 @@ -426,9 +426,12 @@ public class FixJavadocMojoTest assertEquals( 5, javaMethod.getTags().length ); + AbstractFixJavadocMojo mojoInstance = new FixJavadocMojo(); + setVariableValueToObject( mojoInstance, "fixTagsSplitted", new String[] { "all" } ); + DocletTag tag = javaMethod.getTags()[0]; String tagJavadoc = - (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] { + (String) PrivateAccessor.invoke( mojoInstance, "getJavadocComment", new Class[] { String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content, javaMethod, tag } ); assertEquals( " * @param args not" + EOL + @@ -441,7 +444,7 @@ public class FixJavadocMojoTest tag = javaMethod.getTags()[1]; tagJavadoc = - (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] { + (String) PrivateAccessor.invoke( mojoInstance, "getJavadocComment", new Class[] { String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content, javaMethod, tag } ); assertEquals( " * @param i non negative", tagJavadoc ); @@ -452,7 +455,7 @@ public class FixJavadocMojoTest tag = javaMethod.getTags()[2]; tagJavadoc = - (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] { + (String) PrivateAccessor.invoke( mojoInstance, "getJavadocComment", new Class[] { String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content, javaMethod, tag } ); assertEquals( " * @param object could" + EOL + @@ -465,7 +468,7 @@ public class FixJavadocMojoTest tag = javaMethod.getTags()[3]; tagJavadoc = - (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] { + (String) PrivateAccessor.invoke( mojoInstance, "getJavadocComment", new Class[] { String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content, javaMethod, tag } ); assertEquals( " * @return a" + EOL + @@ -478,7 +481,7 @@ public class FixJavadocMojoTest tag = javaMethod.getTags()[4]; tagJavadoc = - (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] { + (String) PrivateAccessor.invoke( mojoInstance, "getJavadocComment", new Class[] { String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content, javaMethod, tag } ); assertEquals( " * @throws Exception if" + EOL + @@ -540,30 +543,33 @@ public class FixJavadocMojoTest assertEquals( 4, javaMethod.getTags().length ); + AbstractFixJavadocMojo mojoInstance = new FixJavadocMojo(); + setVariableValueToObject( mojoInstance, "fixTagsSplitted", new String[] { "all" } ); + DocletTag tag = javaMethod.getTags()[0]; String tagJavadoc = - (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] { + (String) PrivateAccessor.invoke( mojoInstance, "getJavadocComment", new Class[] { String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content, javaMethod, tag } ); assertEquals( " * @param <K> The Key type for the method", tagJavadoc ); tag = javaMethod.getTags()[1]; tagJavadoc = - (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] { + (String) PrivateAccessor.invoke( mojoInstance, "getJavadocComment", new Class[] { String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content, javaMethod, tag } ); assertEquals( " * @param <V> The Value type for the method", tagJavadoc ); tag = javaMethod.getTags()[2]; tagJavadoc = - (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] { + (String) PrivateAccessor.invoke( mojoInstance, "getJavadocComment", new Class[] { String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content, javaMethod, tag } ); assertEquals( " * @param name The name.", tagJavadoc ); tag = javaMethod.getTags()[3]; tagJavadoc = - (String) PrivateAccessor.invoke( AbstractFixJavadocMojo.class, "getJavadocComment", new Class[] { + (String) PrivateAccessor.invoke( mojoInstance, "getJavadocComment", new Class[] { String.class, AbstractInheritableJavaEntity.class, DocletTag.class }, new Object[] { content, javaMethod, tag } ); assertEquals( " * @return A map configured.", tagJavadoc );