This is an automated email from the ASF dual-hosted git repository. kwin pushed a commit to branch bugfix/binary-name-of-nested-class in repository https://gitbox.apache.org/repos/asf/maven-plugin-tools.git
commit d7a187f25eca750bb6d3aa111a321ded6b0a81b3 Author: Konrad Windszus <[email protected]> AuthorDate: Sun Nov 20 17:49:46 2022 +0100 [MPLUGIN-444] JavadocLinkGenerator.createLink: Support nested binary class names --- ...JavaAnnotationsMojoDescriptorExtractorTest.java | 6 ----- .../converter/JavaClassConverterContextTest.java | 5 +++- .../maven/tools/plugin/javadoc/JavadocSite.java | 31 ++++++++++++++++------ .../plugin/javadoc/JavadocLinkGeneratorTest.java | 10 +++++-- .../maven/tools/plugin/javadoc/JavadocSiteIT.java | 9 +++++++ .../tools/plugin/javadoc/JavadocSiteTest.java | 15 +++++++++++ 6 files changed, 59 insertions(+), 17 deletions(-) diff --git a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/JavaAnnotationsMojoDescriptorExtractorTest.java b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/JavaAnnotationsMojoDescriptorExtractorTest.java index 2545889a..6a27987d 100644 --- a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/JavaAnnotationsMojoDescriptorExtractorTest.java +++ b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/JavaAnnotationsMojoDescriptorExtractorTest.java @@ -19,24 +19,18 @@ package org.apache.maven.tools.plugin.extractor.annotations; * under the License. */ -import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor; -import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.project.MavenProject; import org.apache.maven.tools.plugin.DefaultPluginToolsRequest; import org.apache.maven.tools.plugin.extractor.ExtractionException; diff --git a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/converter/JavaClassConverterContextTest.java b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/converter/JavaClassConverterContextTest.java index c5db83fe..04c568e7 100644 --- a/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/converter/JavaClassConverterContextTest.java +++ b/maven-plugin-tools-annotations/src/test/java/org/apache/maven/tools/plugin/extractor/annotations/converter/JavaClassConverterContextTest.java @@ -22,7 +22,6 @@ import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; -import java.util.Objects; import com.thoughtworks.qdox.JavaProjectBuilder; import com.thoughtworks.qdox.model.JavaClass; @@ -101,6 +100,10 @@ class JavaClassConverterContextTest assertEquals( new FullyQualifiedJavadocReference( "org.apache.maven.tools.plugin.extractor.annotations.converter.test.other", "OtherClassOtherPackage.EmbeddedEnum", false ), context.resolveReference( ( JavadocReference.parse( "OtherClassOtherPackage.EmbeddedEnum" ) ) ) ); + + // nested class from JDK + assertEquals( new FullyQualifiedJavadocReference( "java.util", "Map.Entry", true ), + context.resolveReference( JavadocReference.parse( "java.util.Map.Entry" ) ) ); } @Test diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/javadoc/JavadocSite.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/javadoc/JavadocSite.java index 93fddaa8..fce6aeda 100644 --- a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/javadoc/JavadocSite.java +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/javadoc/JavadocSite.java @@ -277,6 +277,8 @@ class JavadocSite } } + private static final Pattern NESTED_CLASS_PATTERN = Pattern.compile( "([^\\$])(\\$[\\d]*)(.*)" ); + /** * Splits up a given binary name into package name and class name part. * @param binaryName a binary name according to @@ -286,25 +288,38 @@ class JavadocSite */ static Map.Entry<String, String> getPackageAndClassName( String binaryName ) { - // assume binary name according to https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1 + // assume binary name according to https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1 int indexOfDollar = binaryName.indexOf( '$' ); + int indexOfDotBetweenPackageAndClass; if ( indexOfDollar >= 0 ) { - // emit some warning, as non resolvable: unclear which type of member follows if it is non digit - throw new IllegalArgumentException( "Can only resolve binary names of top level classes" ); + // check following character + if ( !Character.isDigit( binaryName.charAt( indexOfDollar + 1 ) ) ) + { + // emit some warning, as non resolvable: unclear which type of member follows if it is non digit + throw new IllegalArgumentException( "Can only resolve binary names of (nested) classes, " + + "but not members" ); + } + // nested class + indexOfDotBetweenPackageAndClass = binaryName.lastIndexOf( '.', indexOfDollar ); + // strip digits and replace by dot + binaryName = NESTED_CLASS_PATTERN.matcher( binaryName ).replaceAll( "$1.$3" ); + } + else + { + indexOfDotBetweenPackageAndClass = binaryName.lastIndexOf( '.' ); } - int indexOfLastDot = binaryName.lastIndexOf( '.' ); - if ( indexOfLastDot < 0 ) + if ( indexOfDotBetweenPackageAndClass < 0 ) { throw new IllegalArgumentException( "Resolving primitives is not supported. " + "Binary name must contain at least one dot: " + binaryName ); } - if ( indexOfLastDot == binaryName.length() - 1 ) + if ( indexOfDotBetweenPackageAndClass == binaryName.length() - 1 ) { throw new IllegalArgumentException( "Invalid binary name ending with a dot: " + binaryName ); } - String packageName = binaryName.substring( 0, indexOfLastDot ); - String className = binaryName.substring( indexOfLastDot + 1, binaryName.length() ); + String packageName = binaryName.substring( 0, indexOfDotBetweenPackageAndClass ); + String className = binaryName.substring( indexOfDotBetweenPackageAndClass + 1, binaryName.length() ); return new AbstractMap.SimpleEntry<>( packageName, className ); } diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocLinkGeneratorTest.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocLinkGeneratorTest.java index 620128bf..88a8f41a 100644 --- a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocLinkGeneratorTest.java +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocLinkGeneratorTest.java @@ -91,14 +91,20 @@ class JavadocLinkGeneratorTest throws URISyntaxException { URI javadocBaseUri = getClass().getResource( "/javadoc/" + jdkName + "/" ).toURI(); + JavadocLinkGenerator linkGenerator = new JavadocLinkGenerator( javadocBaseUri, version ); - // invalid link for primitives + /*// invalid link for primitives assertThrows( IllegalArgumentException.class, () -> linkGenerator.createLink( "boolean" ) ); // link for array assertEquals( javadocBaseUri.resolve( new URI( null, "java/lang/String.html", null ) ), - linkGenerator.createLink( "java.lang.String[]" ) ); + linkGenerator.createLink( "java.lang.String[]" ) );*/ + // link for nested class + assertEquals( javadocBaseUri.resolve( new URI( null, + "java/util/Map.Entry.html", + null ) ), + linkGenerator.createLink( "java.util.Map$123Entry" ) ); } diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocSiteIT.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocSiteIT.java index 24fda84b..f331265f 100644 --- a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocSiteIT.java +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocSiteIT.java @@ -82,4 +82,13 @@ class JavadocSiteIT "CASE_INSENSITIVE_ORDER", MemberType.FIELD, true ) ) ); } + + @ParameterizedTest + @MethodSource( "javadocBaseUrls" ) + void testNestedClass( URI javadocBaseUrl ) + throws IOException + { + JavadocSite site = new JavadocSite( javadocBaseUrl, null ); + JavadocSiteTest.assertUrlValid( site.createLink( new FullyQualifiedJavadocReference( "java.util", "Map.Entry", true ) ) ); + } } diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocSiteTest.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocSiteTest.java index d276507b..6f16d63c 100644 --- a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocSiteTest.java +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/javadoc/JavadocSiteTest.java @@ -22,15 +22,20 @@ import java.io.BufferedReader; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.util.AbstractMap; import java.util.regex.Pattern; import java.util.stream.Stream; import org.apache.maven.tools.plugin.javadoc.FullyQualifiedJavadocReference.MemberType; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.opentest4j.AssertionFailedError; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + /** * Tests against the locally available javadoc sites. Doesn't require internet connectivity. */ @@ -96,6 +101,16 @@ class JavadocSiteTest assertUrlValid( site.createLink( new FullyQualifiedJavadocReference( "org.apache.maven.tools.plugin.extractor.annotations.converter.test", "CurrentClass", false ) ) ); } + @Test + void testGetPackageAndClassName() + { + assertEquals( new AbstractMap.SimpleEntry<>( "java.util", "Map" ), JavadocSite.getPackageAndClassName( "java.util.Map" ) ); + assertEquals( new AbstractMap.SimpleEntry<>( "java.util", "Map.Entry" ), JavadocSite.getPackageAndClassName( "java.util.Map$0001Entry" ) ); + assertThrows( IllegalArgumentException.class, () -> JavadocSite.getPackageAndClassName( "java.util." ) ); + assertThrows( IllegalArgumentException.class, () -> JavadocSite.getPackageAndClassName( "java.lang.String$chars()" ) ); + assertThrows( IllegalArgumentException.class, () -> JavadocSite.getPackageAndClassName( "int" ) ); + } + static JavadocSite getLocalJavadocSite( String name, JavadocLinkGenerator.JavadocToolVersionRange version ) throws IOException, URISyntaxException {
