View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.tools.plugin.extractor.annotations.converter;
20  
21  import java.io.File;
22  import java.net.URI;
23  import java.net.URISyntaxException;
24  import java.util.Collections;
25  
26  import com.thoughtworks.qdox.JavaProjectBuilder;
27  import com.thoughtworks.qdox.model.JavaClass;
28  import org.apache.maven.tools.plugin.extractor.annotations.converter.test.CurrentClass;
29  import org.apache.maven.tools.plugin.extractor.annotations.converter.test.OtherClass;
30  import org.apache.maven.tools.plugin.extractor.annotations.datamodel.MojoAnnotationContent;
31  import org.apache.maven.tools.plugin.extractor.annotations.scanner.MojoAnnotatedClass;
32  import org.apache.maven.tools.plugin.javadoc.FullyQualifiedJavadocReference;
33  import org.apache.maven.tools.plugin.javadoc.FullyQualifiedJavadocReference.MemberType;
34  import org.apache.maven.tools.plugin.javadoc.JavadocLinkGenerator;
35  import org.apache.maven.tools.plugin.javadoc.JavadocReference;
36  import org.junit.jupiter.api.Test;
37  
38  import static org.junit.jupiter.api.Assertions.assertEquals;
39  import static org.junit.jupiter.api.Assertions.assertFalse;
40  import static org.junit.jupiter.api.Assertions.assertThrows;
41  import static org.junit.jupiter.api.Assertions.assertTrue;
42  
43  class JavaClassConverterContextTest {
44  
45      private ConverterContext context;
46  
47      private final String currentPackageName;
48  
49      private final JavaProjectBuilder builder;
50  
51      private final JavaClass contextClass;
52  
53      private JavadocLinkGenerator linkGenerator;
54  
55      private URI javadocBaseUri;
56  
57      public JavaClassConverterContextTest() throws URISyntaxException {
58          builder = new JavaProjectBuilder();
59          builder.addSourceFolder(new File("src/test/java"));
60  
61          contextClass = builder.getClassByName(CurrentClass.class.getName());
62          currentPackageName = contextClass.getPackageName();
63          javadocBaseUri = new URI("http://localhost/apidocs");
64          linkGenerator = new JavadocLinkGenerator(javadocBaseUri, "11");
65          context = new JavaClassConverterContext(contextClass, builder, Collections.emptyMap(), linkGenerator, 10);
66      }
67  
68      @Test
69      void testResolveReference() throws URISyntaxException {
70          // test fully qualified unresolvable reference
71          assertThrows(
72                  IllegalArgumentException.class,
73                  () -> context.resolveReference(JavadocReference.parse("my.package.InvalidClass")));
74  
75          // test unresolvable reference
76          assertThrows(
77                  IllegalArgumentException.class, () -> context.resolveReference(JavadocReference.parse("InvalidClass")));
78  
79          // test resolvable reference
80          assertEquals(
81                  new FullyQualifiedJavadocReference(currentPackageName, "OtherClass", false),
82                  context.resolveReference((JavadocReference.parse(OtherClass.class.getName()))));
83  
84          // already fully resolved class
85          assertEquals(
86                  new FullyQualifiedJavadocReference(currentPackageName, "OtherClass", false),
87                  context.resolveReference((JavadocReference.parse(OtherClass.class.getName()))));
88          // already fully resolved package
89          assertEquals(
90                  new FullyQualifiedJavadocReference(currentPackageName, false),
91                  context.resolveReference((JavadocReference.parse(currentPackageName))));
92  
93          // Class from java's standard import "java.lang"
94          assertEquals(
95                  new FullyQualifiedJavadocReference("java.lang", "String", true),
96                  context.resolveReference(JavadocReference.parse("String")));
97  
98          // nested class from import
99          assertEquals(
100                 new FullyQualifiedJavadocReference(
101                         "org.apache.maven.tools.plugin.extractor.annotations.converter.test.other",
102                         "OtherClassOtherPackage.EmbeddedEnum",
103                         false),
104                 context.resolveReference((JavadocReference.parse("OtherClassOtherPackage.EmbeddedEnum"))));
105 
106         // nested class from JDK
107         assertEquals(
108                 new FullyQualifiedJavadocReference("java.util", "Map.Entry", true),
109                 context.resolveReference(JavadocReference.parse("java.util.Map.Entry")));
110     }
111 
112     @Test
113     void testResolveReferenceWithMembers() {
114         // field
115         assertEquals(
116                 new FullyQualifiedJavadocReference(
117                         currentPackageName, "CurrentClass", "field1", MemberType.FIELD, false),
118                 context.resolveReference((JavadocReference.parse("#field1"))));
119         // field from super class
120         assertEquals(
121                 new FullyQualifiedJavadocReference(
122                         currentPackageName, "SuperClass", "superField1", MemberType.FIELD, false),
123                 context.resolveReference((JavadocReference.parse("#superField1"))));
124         // method
125         assertEquals(
126                 new FullyQualifiedJavadocReference(
127                         currentPackageName, "CurrentClass", "noParamMethod()", MemberType.METHOD, false),
128                 context.resolveReference((JavadocReference.parse("#noParamMethod()"))));
129         // method without parentheses
130         assertEquals(
131                 new FullyQualifiedJavadocReference(
132                         currentPackageName, "CurrentClass", "noParamMethod()", MemberType.METHOD, false),
133                 context.resolveReference((JavadocReference.parse("#noParamMethod"))));
134 
135         // method with unresolved java.lang argument
136         assertEquals(
137                 new FullyQualifiedJavadocReference(
138                         currentPackageName,
139                         "CurrentClass",
140                         "simpleParamMethod(java.lang.Integer)",
141                         MemberType.METHOD,
142                         false),
143                 context.resolveReference((JavadocReference.parse("#simpleParamMethod(Integer)"))));
144 
145         // method with unresolved java.lang argument with name
146         assertEquals(
147                 new FullyQualifiedJavadocReference(
148                         currentPackageName,
149                         "CurrentClass",
150                         "simpleParamMethod(java.lang.Integer)",
151                         MemberType.METHOD,
152                         false),
153                 context.resolveReference((JavadocReference.parse("#simpleParamMethod(Integer value)"))));
154 
155         // method with primitive arguments
156         assertEquals(
157                 new FullyQualifiedJavadocReference(
158                         currentPackageName,
159                         "CurrentClass",
160                         "complexParamMethod(int,org.apache.maven.tools.plugin.extractor.annotations.converter.test.other.OtherClassOtherPackage.EmbeddedEnum)",
161                         MemberType.METHOD,
162                         false),
163                 context.resolveReference((JavadocReference.parse(
164                         "#complexParamMethod(int value1, OtherClassOtherPackage.EmbeddedEnum value2)"))));
165         // method with array arguments
166         assertEquals(
167                 new FullyQualifiedJavadocReference(
168                         currentPackageName,
169                         "CurrentClass",
170                         "arrayParamMethod(int[],java.lang.String[][][])",
171                         MemberType.METHOD,
172                         false),
173                 context.resolveReference((JavadocReference.parse("#arrayParamMethod(int[], String[][][])"))));
174 
175         // method with generic arguments
176         assertEquals(
177                 new FullyQualifiedJavadocReference(
178                         currentPackageName,
179                         "CurrentClass",
180                         "genericsParamMethod(java.util.Collection,java.util.function.BiConsumer)",
181                         MemberType.METHOD,
182                         false),
183                 context.resolveReference((JavadocReference.parse(
184                         "#genericsParamMethod(Collection something, java.util.function.BiConsumer function)"))));
185 
186         // method with unresolvable type
187         assertThrows(
188                 IllegalArgumentException.class,
189                 () -> context.resolveReference(
190                         (JavadocReference.parse("#genericsParamMethod(Collection something, BiConsumer function)"))));
191         // constructor
192         assertEquals(
193                 new FullyQualifiedJavadocReference(
194                         currentPackageName, "CurrentClass", "CurrentClass()", MemberType.CONSTRUCTOR, false),
195                 context.resolveReference((JavadocReference.parse("#CurrentClass()"))));
196     }
197 
198     @Test
199     void testGetUrl() throws URISyntaxException {
200         MojoAnnotationContent mojoAnnotationContent = new MojoAnnotationContent();
201         mojoAnnotationContent.name("other-goal");
202         MojoAnnotatedClass mojoAnnotatedClass = new MojoAnnotatedClass().setMojo(mojoAnnotationContent);
203         context = new JavaClassConverterContext(
204                 contextClass,
205                 builder,
206                 Collections.singletonMap(
207                         "org.apache.maven.tools.plugin.extractor.annotations.converter.test.OtherClass",
208                         mojoAnnotatedClass),
209                 linkGenerator,
210                 10);
211         // TODO: link to current class without member?
212         // assertEquals( new URI( "" ),
213         //              context.getUrl( new FullyQualifiedJavadocReference(
214         // "org.apache.maven.tools.plugin.extractor.annotations.converter",
215         //                                                                  "JavaClassConverterContextTest" ) ) );
216 
217         // field reference not leaving context
218         assertEquals(
219                 new URI(null, null, "field1"),
220                 context.getUrl(new FullyQualifiedJavadocReference(
221                         currentPackageName, "CurrentClass", "field1", MemberType.FIELD, false)));
222 
223         // field reference in another class
224         assertEquals(
225                 javadocBaseUri.resolve(new URI(
226                         null,
227                         "org/apache/maven/tools/plugin/extractor/annotations/converter/test/other/OtherClassOtherPackage.html",
228                         "field1")),
229                 context.getUrl(new FullyQualifiedJavadocReference(
230                         "org.apache.maven.tools.plugin.extractor.annotations.converter.test.other",
231                         "OtherClassOtherPackage",
232                         "field1",
233                         MemberType.FIELD,
234                         false)));
235 
236         // field reference in another mojo
237         assertEquals(
238                 new URI(null, "./other-goal-mojo.html", "field1"),
239                 context.getUrl(new FullyQualifiedJavadocReference(
240                         currentPackageName, "OtherClass", "field1", MemberType.FIELD, false)));
241 
242         // method reference in current context need to point to regular javadoc as mojo documentation does not include
243         // methods
244         assertEquals(
245                 javadocBaseUri.resolve(new URI(
246                         null,
247                         "org/apache/maven/tools/plugin/extractor/annotations/converter/test/CurrentClass.html",
248                         "noParamMethod()")),
249                 context.getUrl(new FullyQualifiedJavadocReference(
250                         currentPackageName, "CurrentClass", "noParamMethod()", MemberType.METHOD, false)));
251 
252         // method reference with arguments
253 
254         // constructor reference in current context need to point to regular javadoc as mojo documentation does not
255         // include constructors
256         assertEquals(
257                 javadocBaseUri.resolve(new URI(
258                         null,
259                         "org/apache/maven/tools/plugin/extractor/annotations/converter/test/CurrentClass.html",
260                         "CurrentClass()")),
261                 context.getUrl(new FullyQualifiedJavadocReference(
262                         "org.apache.maven.tools.plugin.extractor.annotations.converter.test",
263                         "CurrentClass",
264                         "CurrentClass()",
265                         MemberType.METHOD,
266                         false)));
267 
268         // package reference
269         assertEquals(
270                 javadocBaseUri.resolve(new URI(
271                         null,
272                         "org/apache/maven/tools/plugin/extractor/annotations/converter/test/package-summary.html",
273                         null)),
274                 context.getUrl(new FullyQualifiedJavadocReference(
275                         "org.apache.maven.tools.plugin.extractor.annotations.converter.test", false)));
276     }
277 
278     @Test
279     void testClassContext() {
280         assertTrue(
281                 context.isReferencedBy(new FullyQualifiedJavadocReference(currentPackageName, "CurrentClass", false)));
282         assertTrue(context.isReferencedBy(new FullyQualifiedJavadocReference(currentPackageName, "SuperClass", false)));
283         assertTrue(context.isReferencedBy(new FullyQualifiedJavadocReference(
284                 currentPackageName, "SuperClass", "superField1", MemberType.FIELD, false)));
285         assertFalse(
286                 context.isReferencedBy(new FullyQualifiedJavadocReference(currentPackageName, "OtherClass", false)));
287         assertEquals(currentPackageName, context.getPackageName());
288         assertEquals(
289                 "src/test/java/org/apache/maven/tools/plugin/extractor/annotations/converter/test/CurrentClass.java:10",
290                 context.getLocation());
291     }
292 
293     @Test
294     void testGetStaticFieldValue() {
295         assertEquals(
296                 "\"STATIC 1\"",
297                 context.getStaticFieldValue(new FullyQualifiedJavadocReference(
298                         currentPackageName, "OtherClass", "STATIC_1", MemberType.FIELD, false)));
299         assertEquals(
300                 "\"STATIC 2\"",
301                 context.getStaticFieldValue(new FullyQualifiedJavadocReference(
302                         currentPackageName, "OtherClass", "STATIC_2", MemberType.FIELD, false)));
303         // although not explicitly stated, never used for value javadoc tag, as this only supports string constants
304         assertEquals(
305                 "3l",
306                 context.getStaticFieldValue(new FullyQualifiedJavadocReference(
307                         currentPackageName, "OtherClass", "STATIC_3", MemberType.FIELD, false)));
308         FullyQualifiedJavadocReference reference =
309                 new FullyQualifiedJavadocReference(currentPackageName, "OtherClass", "field1", MemberType.FIELD, false);
310         assertThrows(IllegalArgumentException.class, () -> context.getStaticFieldValue(reference));
311     }
312 }