1 /*
2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 8164408
27  * @summary Add module support for see, link and linkplain javadoc tags
28  * @library /tools/lib ../../lib
29  * @modules
30  *      jdk.javadoc/jdk.javadoc.internal.tool
31  *      jdk.compiler/com.sun.tools.javac.api
32  *      jdk.compiler/com.sun.tools.javac.main
33  * @build javadoc.tester.*
34  * @run main TestLinkTagletWithModule
35  */
36 
37 import java.nio.file.Path;
38 import java.nio.file.Paths;
39 
40 import builder.ClassBuilder;
41 import builder.ClassBuilder.*;
42 import toolbox.ModuleBuilder;
43 import toolbox.ToolBox;
44 
45 import javadoc.tester.JavadocTester;
46 
47 public class TestLinkTagletWithModule extends JavadocTester {
48 
49     final ToolBox tb;
50     private final Path src;
51 
main(String... args)52     public static void main(String... args) throws Exception {
53         TestLinkTagletWithModule tester = new TestLinkTagletWithModule();
54         tester.runTests(m -> new Object[]{Paths.get(m.getName())});
55     }
56 
TestLinkTagletWithModule()57     TestLinkTagletWithModule() throws Exception {
58         tb = new ToolBox();
59         src = Paths.get("src");
60         generateSources();
61     }
62 
63     @Test
testLinkModuleInternal(Path base)64     public void testLinkModuleInternal(Path base) throws Exception {
65         Path out = base.resolve("out");
66 
67         javadoc("-d", out.toString(),
68                 "--module-source-path", src.toString(),
69                 "--module", "m1,m2,m3",
70                 "m2/com.m2.lib");
71 
72         checkExit(Exit.OK);
73         checkOutput("m3/com/m3/app/App.html", true,
74                 """
75                     <div class="block"><a href="../../../../m1/module-summary.html"><code>m1</code></a>
76                      <a href="../../../../m1/module-summary.html"><code>m1</code></a>
77                      <a href="../../../../m1/com/m1/lib/package-summary.html"><code>package link</code></a>
78                      <a href="../../../../m1/com/m1/lib/Lib.html" title="class in com.m1.lib"><code>Lib</code></a>
79                      <a href="../../../../m1/com/m1/lib/Lib.html#method(java.lang.String)"><code>Lib.method(java.lang.String)</code></a>
80                      <a href="../../../../m1/com/m1/lib/Lib.html#method(java.lang.String)"><code>Lib.method(String)</code></a>
81                      <a href="../../../../m2/module-summary.html">m2</a>
82                      <a href="../../../../m2/module-summary.html">m2</a>
83                      <a href="../../../../m2/com/m2/lib/package-summary.html">com.m2.lib</a>
84                      <a href="../../../../m2/com/m2/lib/Lib.html" title="class in com.m2.lib">Lib</a>
85                      <a href="../../../../m2/com/m2/lib/Lib.html#method(java.lang.String)">class link</a>
86                      <a href="../../../../m2/com/m2/lib/Lib.html#method(java.lang.String)">Lib.method(String)</a></div>
87                     """);
88     }
89 
90     @Test
testLinkModuleExternal(Path base)91     public void testLinkModuleExternal(Path base) throws Exception {
92         Path out1 = base.resolve("out1"), out2 = base.resolve("out2");
93 
94         javadoc("-d", out1.toString(),
95                 "--module-source-path", src.toString(),
96                 "--module", "m1,m2",
97                 "m2/com.m2.lib");
98         javadoc("-d", out2.toString(),
99                 "--module-source-path", src.toString(),
100                 "--add-modules", "m2",
101                 "--module", "m3",
102                 "-link", "../" + out1.getFileName());
103 
104         checkExit(Exit.OK);
105         checkOutput("m3/com/m3/app/App.html", true,
106                 """
107                     <div class="block"><a href="../../../../../out1/m1/module-summary.html" class="external-link"><code>m1</code></a>
108                      <a href="../../../../../out1/m1/module-summary.html" class="external-link"><code>m1</code></a>
109                      <a href="../../../../../out1/m1/com/m1/lib/package-summary.html" class="external-link"><code>package link</code></a>
110                      <a href="../../../../../out1/m1/com/m1/lib/Lib.html" title="class or interface in com.m1.lib"\
111                      class="external-link"><code>Lib</code></a>
112                      <a href="../../../../../out1/m1/com/m1/lib/Lib.html#method(java.lang.String)" title="class or\
113                      interface in com.m1.lib" class="external-link"><code>Lib.method(java.lang.String)</code></a>
114                      <a href="../../../../../out1/m1/com/m1/lib/Lib.html#method(java.lang.String)" title="class or\
115                      interface in com.m1.lib" class="external-link"><code>Lib.method(String)</code></a>
116                      <a href="../../../../../out1/m2/module-summary.html" class="external-link">m2</a>
117                      <a href="../../../../../out1/m2/module-summary.html" class="external-link">m2</a>
118                      <a href="../../../../../out1/m2/com/m2/lib/package-summary.html" class="external-link">m2/com.m2.lib</a>
119                      <a href="../../../../../out1/m2/com/m2/lib/Lib.html" title="class or interface in com.m2.lib" class="external-link">Lib</a>
120                      <a href="../../../../../out1/m2/com/m2/lib/Lib.html#method(java.lang.String)" title="class or\
121                      interface in com.m2.lib" class="external-link">class link</a>
122                      <a href="../../../../../out1/m2/com/m2/lib/Lib.html#method(java.lang.String)" title="class or\
123                      interface in com.m2.lib" class="external-link">Lib.method(String)</a></div>
124                     """);
125     }
126 
127     @Test
testLinkModuleSameNameInternal(Path base)128     public void testLinkModuleSameNameInternal(Path base) throws Exception {
129         Path out = base.resolve("out");
130 
131         javadoc("-d", out.toString(),
132                 "--module-source-path", src.toString(),
133                 "--module", "com.ex1,com.ex2");
134 
135         checkExit(Exit.OK);
136         checkOutput("com.ex2/com/ex2/B.html", true,
137                 """
138                     <div class="block"><a href="../../../com.ex1/com/ex1/package-summary.html"><code>package link</code></a>
139                      <a href="../../../com.ex1/module-summary.html"><code>module link</code></a>
140                      <a href="../../../com.ex1/com/ex1/package-summary.html"><code>com.ex1</code></a>
141                      <a href="../../../com.ex1/com/ex1/A.html" title="class in com.ex1"><code>class link</code></a>
142                      <a href="../../../com.ex1/com/ex1/A.html#m()"><code>A.m()</code></a>
143                      <a href="../../../com.ex1/com/ex1/A.html#m()"><code>A.m()</code></a>
144                      <a href="package-summary.html"><code>com.ex2</code></a>
145                      <a href="../../module-summary.html"><code>com.ex2</code></a></div>
146                     """);
147     }
148 
149     @Test
testLinkModuleSameNameExternal(Path base)150     public void testLinkModuleSameNameExternal(Path base) throws Exception {
151         Path out1 = base.resolve("out1"), out2 = base.resolve("out2");
152 
153         javadoc("-d", out1.toString(),
154                 "--module-source-path", src.toString(),
155                 "--module", "com.ex1");
156         javadoc("-d", out2.toString(),
157                 "--module-source-path", src.toString(),
158                 "--module", "com.ex2",
159                 "-link", "../" + out1.getFileName());
160 
161         checkExit(Exit.OK);
162         checkOutput("com.ex2/com/ex2/B.html", true,
163                 """
164                     <div class="block"><a href="../../../../out1/com.ex1/com/ex1/package-summary.html" class="external-link"><code>package link</code></a>
165                      <a href="../../../../out1/com.ex1/module-summary.html" class="external-link"><code>module link</code></a>
166                      <a href="../../../../out1/com.ex1/com/ex1/package-summary.html" class="external-link"><code>com.ex1/com.ex1</code></a>
167                      <a href="../../../../out1/com.ex1/com/ex1/A.html" title="class or interface in com.ex1" class="external-link"><code>class link</code></a>
168                      <a href="../../../../out1/com.ex1/com/ex1/A.html#m()" title="class or interface in com.ex1" class="external-link"><code>A.m()</code></a>
169                      <a href="../../../../out1/com.ex1/com/ex1/A.html#m()" title="class or interface in com.ex1" class="external-link"><code>A.m()</code></a>
170                      <a href="package-summary.html"><code>com.ex2</code></a>
171                      <a href="../../module-summary.html"><code>com.ex2</code></a></div>
172                     """);
173     }
generateSources()174     void generateSources() throws Exception {
175         new ModuleBuilder(tb, "m1")
176                 .exports("com.m1.lib")
177                 .classes("""
178                     package com.m1.lib;
179                     public class Lib {
180                     public String method(String s) {
181                         return s;
182                     }
183                     }""")
184                 .write(src);
185         new ModuleBuilder(tb, "m2")
186                 .classes("""
187                     package com.m2.lib;
188                     public class Lib {
189                     public String method(String s) {
190                         return s;
191                     }
192                     }""")
193                 .write(src);
194         new ModuleBuilder(tb, "m3")
195                 .exports("com.m3.app")
196                 .requires("m1")
197                 .classes("""
198                     package com.m3.app;\s
199                     public class App{
200                     /**
201                      * {@link m1}
202                      * {@link m1/}
203                      * {@link m1/com.m1.lib package link}
204                      * {@link m1/com.m1.lib.Lib}
205                      * {@link m1/com.m1.lib.Lib#method}
206                      * {@link m1/com.m1.lib.Lib#method(String)}
207                      * {@linkplain m2}
208                      * {@linkplain m2/}
209                      * {@linkplain m2/com.m2.lib}
210                      * {@linkplain m2/com.m2.lib.Lib}
211                      * {@linkplain m2/com.m2.lib.Lib#method class link}
212                      * {@linkplain m2/com.m2.lib.Lib#method(String)}
213                      */
214                     public App(){}
215                     }
216                     """)
217                 .write(src);
218 
219         new ModuleBuilder(tb, "com.ex1")
220                 .exports("com.ex1")
221                 .classes("""
222                     package com.ex1;
223                     public class A{
224                     public void m() {}
225                     }""",
226                     """
227                     package com.ex1;
228                     public class B {}""")
229                 .write(src);
230 
231         new ModuleBuilder(tb, "com.ex2")
232                 .requires("com.ex1")
233                 .exports("com.ex2")
234                 .classes("""
235                     package com.ex2;\s
236                     import com.ex1.A;
237                     public class B{
238                     /**
239                      * {@link com.ex1 package link}
240                      * {@link com.ex1/ module link}
241                      * {@link com.ex1/com.ex1}
242                      * {@link com.ex1/com.ex1.A class link}
243                      * {@link com.ex1/com.ex1.A#m}
244                      * {@link com.ex1/com.ex1.A#m()}
245                      * {@link com.ex2}
246                      * {@link com.ex2/}
247                      */
248                     public B(A obj){}
249                     }
250                     """)
251                 .write(src);
252 
253     }
254 
255 }
256