1 /* 2 * Copyright (c) 2016, 2017, 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 8178070 27 * @summary Test packages table in module summary pages 28 * @library /tools/lib ../lib 29 * @modules jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.main 31 * jdk.javadoc/jdk.javadoc.internal.tool 32 * @build toolbox.ModuleBuilder toolbox.ToolBox JavadocTester 33 * @run main TestModulePackages 34 */ 35 36 import java.io.IOException; 37 import java.nio.file.Path; 38 import java.nio.file.Paths; 39 import java.util.Set; 40 41 import toolbox.ModuleBuilder; 42 import toolbox.ToolBox; 43 44 public class TestModulePackages extends JavadocTester { 45 enum TabKind { EXPORTS, OPENS, CONCEALED }; 46 enum ColKind { EXPORTED_TO, OPENED_TO }; 47 48 public static void main(String... args) throws Exception { 49 TestModulePackages tester = new TestModulePackages(); 50 tester.runTests(m -> new Object[] { Paths.get(m.getName()) }); 51 } 52 53 private final ToolBox tb; 54 55 public TestModulePackages() { 56 tb = new ToolBox(); 57 } 58 59 // @Test: See: https://bugs.openjdk.java.net/browse/JDK-8193107 60 public void empty(Path base) throws Exception { 61 Path src = base.resolve("src"); 62 new ModuleBuilder(tb, "m") 63 .comment("empty module") 64 .write(src); 65 66 javadoc("-d", base.resolve("out").toString(), 67 "-quiet", 68 "-noindex", 69 "--module-source-path", src.toString(), 70 "--module", "m"); 71 72 checkExit(Exit.OK); 73 checkOutput("m/module-summary.html", false, 74 "<h3>Packages</h3>\n" 75 + "<table class=\"packagesSummary\" summary=\"Packages table, " 76 + "listing packages, and an explanation\">"); 77 } 78 79 @Test 80 public void exportSingle(Path base) throws Exception { 81 Path src = base.resolve("src"); 82 new ModuleBuilder(tb, "m") 83 .comment("exports single package to all") 84 .exports("p") 85 .classes("package p; public class C { }") 86 .write(src); 87 88 javadoc("-d", base.resolve("out").toString(), 89 "-quiet", 90 "-noindex", 91 "--module-source-path", src.toString(), 92 "--module", "m"); 93 94 checkExit(Exit.OK); 95 checkCaption("m", TabKind.EXPORTS); 96 checkTableHead("m"); 97 checkPackageRow("m", "p", "i0", null, null, " "); 98 } 99 100 @Test 101 public void exportMultiple(Path base) throws Exception { 102 Path src = base.resolve("src"); 103 new ModuleBuilder(tb, "m") 104 .comment("exports multiple packages to all") 105 .exports("p") 106 .exports("q") 107 .classes("package p; public class C { }") 108 .classes("package q; public class D { }") 109 .write(src); 110 111 javadoc("-d", base.resolve("out").toString(), 112 "-quiet", 113 "-noindex", 114 "--module-source-path", src.toString(), 115 "--module", "m"); 116 117 checkExit(Exit.OK); 118 checkCaption("m", TabKind.EXPORTS); 119 checkTableHead("m"); 120 checkPackageRow("m", "p", "i0", null, null, " "); 121 checkPackageRow("m", "q", "i1", null, null, " "); 122 } 123 124 @Test 125 public void exportSomeQualified(Path base) throws Exception { 126 Path src = base.resolve("src"); 127 new ModuleBuilder(tb, "m") 128 .comment("exports multiple packages, some qualified") 129 .exports("p") 130 .exportsTo("q", "other") 131 .classes("package p; public class C { }") 132 .classes("package q; public class D { }") 133 .write(src); 134 135 new ModuleBuilder(tb, "other") 136 .comment("dummy module for target of export") 137 .write(src); 138 139 javadoc("-d", base.resolve("out-api").toString(), 140 "-quiet", 141 "-noindex", 142 "--module-source-path", src.toString(), 143 "--module", "m,other"); 144 145 checkExit(Exit.OK); 146 checkCaption("m", TabKind.EXPORTS); 147 checkTableHead("m"); 148 checkPackageRow("m", "p", "i0", null, null, " "); 149 150 javadoc("-d", base.resolve("out-all").toString(), 151 "-quiet", 152 "-noindex", 153 "--show-module-contents", "all", 154 "--module-source-path", src.toString(), 155 "--module", "m,other"); 156 157 checkExit(Exit.OK); 158 checkCaption("m", TabKind.EXPORTS); 159 checkTableHead("m", ColKind.EXPORTED_TO); 160 checkPackageRow("m", "p", "i0", "All Modules", null, " "); 161 checkPackageRow("m", "q", "i1", 162 "<a href=\"../other/module-summary.html\">other</a>", null, " "); 163 } 164 165 @Test 166 public void exportWithConcealed(Path base) throws Exception { 167 Path src = base.resolve("src"); 168 new ModuleBuilder(tb, "m") 169 .comment("exports package, has concealed package") 170 .exports("p") 171 .classes("package p; public class C { }") 172 .classes("package q; public class D { }") 173 .write(src); 174 175 javadoc("-d", base.resolve("out-api").toString(), 176 "-quiet", 177 "-noindex", 178 "--module-source-path", src.toString(), 179 "--module", "m"); 180 181 checkExit(Exit.OK); 182 checkCaption("m", TabKind.EXPORTS); 183 checkTableHead("m"); 184 checkPackageRow("m", "p", "i0", null, null, " "); 185 186 javadoc("-d", base.resolve("out-all").toString(), 187 "-quiet", 188 "-noindex", 189 "--show-module-contents", "all", 190 "--show-packages", "all", 191 "--module-source-path", src.toString(), 192 "--module", "m"); 193 194 checkExit(Exit.OK); 195 checkCaption("m", TabKind.EXPORTS, TabKind.CONCEALED); 196 checkTableHead("m", ColKind.EXPORTED_TO); 197 checkPackageRow("m", "p", "i0", "All Modules", null, " "); 198 checkPackageRow("m", "q", "i1", "None", null, " "); 199 } 200 201 @Test 202 public void exportOpenWithConcealed(Path base) throws Exception { 203 Path src = base.resolve("src"); 204 new ModuleBuilder(tb, "m") 205 .comment("exports and opens qual and unqual, with concealed") 206 .exports("e.all") 207 .exportsTo("e.other", "other") 208 .opens("o.all") 209 .opensTo("o.other", "other") 210 .exports("eo") 211 .opens("eo") 212 .classes("package e.all; public class CEAll { }") 213 .classes("package e.other; public class CEOther { }") 214 .classes("package o.all; public class COAll { }") 215 .classes("package o.other; public class COOther { }") 216 .classes("package eo; public class CEO { }") 217 .classes("package c; public class C { }") 218 .write(src); 219 220 new ModuleBuilder(tb, "other") 221 .comment("dummy module for target of export and open") 222 .write(src); 223 224 javadoc("-d", base.resolve("out-api").toString(), 225 "-quiet", 226 "-noindex", 227 "--module-source-path", src.toString(), 228 "--module", "m,other"); 229 230 checkExit(Exit.OK); 231 checkCaption("m", TabKind.EXPORTS, TabKind.OPENS); 232 checkTableHead("m", ColKind.EXPORTED_TO, ColKind.OPENED_TO); 233 checkPackageRow("m", "e.all", "i0", "All Modules", "None", " "); 234 checkPackageRow("m", "eo", "i1", "All Modules", "All Modules", " "); 235 236 javadoc("-d", base.resolve("out-all").toString(), 237 "-quiet", 238 "-noindex", 239 "--show-module-contents", "all", 240 "--show-packages", "all", 241 "--module-source-path", src.toString(), 242 "--module", "m,other"); 243 244 checkExit(Exit.OK); 245 checkCaption("m", TabKind.EXPORTS, TabKind.OPENS, TabKind.CONCEALED); 246 checkTableHead("m", ColKind.EXPORTED_TO, ColKind.OPENED_TO); 247 checkPackageRow("m", "c", "i0", "None", "None", " "); 248 checkPackageRow("m", "e.all", "i1", "All Modules", "None", " "); 249 checkPackageRow("m", "e.other", "i2", 250 "<a href=\"../other/module-summary.html\">other</a>", "None", " "); 251 checkPackageRow("m", "eo", "i3", "All Modules", "All Modules", " "); 252 checkPackageRow("m", "o.all", "i4", "None", "All Modules", " "); 253 checkPackageRow("m", "o.other", "i5", "None", 254 "<a href=\"../other/module-summary.html\">other</a>", " "); 255 } 256 257 @Test 258 public void openModule(Path base) throws Exception { 259 Path src = base.resolve("src"); 260 new ModuleBuilder(tb, true, "m") 261 .comment("open module") 262 .classes("/** implicitly open package */ package p;") 263 .classes("package p; public class C { } ") 264 .classes("/** implicitly open package */ package q;") 265 .classes("package q; public class D { }") 266 .write(src); 267 268 javadoc("-d", base.resolve("out").toString(), 269 "-quiet", 270 "-noindex", 271 "--show-packages", "all", // required, to show open packages; see JDK-8193107 272 "--module-source-path", src.toString(), 273 "--module", "m"); 274 275 checkExit(Exit.OK); 276 checkCaption("m", TabKind.OPENS); 277 checkTableHead("m"); 278 checkPackageRow("m", "p", "i0", null, null, 279 "\n<div class=\"block\">implicitly open package</div>\n"); 280 checkPackageRow("m", "q", "i1", null, null, 281 "\n<div class=\"block\">implicitly open package</div>\n"); 282 } 283 @Test 284 public void openSingle(Path base) throws Exception { 285 Path src = base.resolve("src"); 286 new ModuleBuilder(tb, "m") 287 .comment("opens single package to all") 288 .opens("p") 289 .classes("package p; public class C { }") 290 .write(src); 291 292 javadoc("-d", base.resolve("out").toString(), 293 "-quiet", 294 "-noindex", 295 "--show-packages", "all", // required, to show open packages; see JDK-8193107 296 "--module-source-path", src.toString(), 297 "--module", "m"); 298 299 checkExit(Exit.OK); 300 checkCaption("m", TabKind.OPENS); 301 checkTableHead("m"); 302 checkPackageRow("m", "p", "i0", null, null, " "); 303 } 304 305 @Test 306 public void openMultiple(Path base) throws Exception { 307 Path src = base.resolve("src"); 308 new ModuleBuilder(tb, "m") 309 .comment("opens multiple packages to all") 310 .opens("p") 311 .opens("q") 312 .classes("package p; public class C { }") 313 .classes("package q; public class D { }") 314 .write(src); 315 316 javadoc("-d", base.resolve("out").toString(), 317 "-quiet", 318 "-noindex", 319 "--show-packages", "all", // required, to show open packages; see JDK-8193107 320 "--module-source-path", src.toString(), 321 "--module", "m"); 322 323 checkExit(Exit.OK); 324 checkCaption("m", TabKind.OPENS); 325 checkTableHead("m"); 326 checkPackageRow("m", "p", "i0", null, null, " "); 327 checkPackageRow("m", "q", "i1", null, null, " "); 328 } 329 330 @Test 331 public void openSomeQualified(Path base) throws Exception { 332 Path src = base.resolve("src"); 333 new ModuleBuilder(tb, "m") 334 .comment("opens multiple packages, some qualified") 335 .opens("p") 336 .opensTo("q", "other") 337 .classes("package p; public class C { }") 338 .classes("package q; public class D { }") 339 .write(src); 340 341 new ModuleBuilder(tb, "other") 342 .comment("dummy module for target of export") 343 .write(src); 344 345 javadoc("-d", base.resolve("out-api").toString(), 346 "-quiet", 347 "-noindex", 348 "--show-packages", "all", // required, to show open packages; see JDK-8193107 349 "--module-source-path", src.toString(), 350 "--module", "m,other"); 351 352 checkExit(Exit.OK); 353 checkCaption("m", TabKind.OPENS); 354 checkTableHead("m"); 355 checkPackageRow("m", "p", "i0", null, null, " "); 356 357 javadoc("-d", base.resolve("out-all").toString(), 358 "-quiet", 359 "-noindex", 360 "--show-packages", "all", // required, to show open packages; see JDK-8193107 361 "--show-module-contents", "all", 362 "--module-source-path", src.toString(), 363 "--module", "m,other"); 364 365 checkExit(Exit.OK); 366 checkCaption("m", TabKind.OPENS); 367 checkTableHead("m", ColKind.OPENED_TO); 368 checkPackageRow("m", "p", "i0", null, "All Modules", " "); 369 checkPackageRow("m", "q", "i1", null, 370 "<a href=\"../other/module-summary.html\">other</a>", " "); 371 } 372 373 @Test 374 public void openWithConcealed(Path base) throws Exception { 375 Path src = base.resolve("src"); 376 new ModuleBuilder(tb, "m") 377 .comment("opens package, has concealed package") 378 .opens("p") 379 .classes("package p; public class C { }") 380 .classes("package q; public class D { }") 381 .write(src); 382 383 javadoc("-d", base.resolve("out-api").toString(), 384 "-quiet", 385 "-noindex", 386 "--show-packages", "all", // required, to show open packages; see JDK-8193107 387 "--module-source-path", src.toString(), 388 "--module", "m"); 389 390 checkExit(Exit.OK); 391 checkCaption("m", TabKind.OPENS); 392 checkTableHead("m"); 393 checkPackageRow("m", "p", "i0", null, null, " "); 394 395 javadoc("-d", base.resolve("out-all").toString(), 396 "-quiet", 397 "-noindex", 398 "--show-module-contents", "all", 399 "--show-packages", "all", 400 "--module-source-path", src.toString(), 401 "--module", "m"); 402 403 checkExit(Exit.OK); 404 checkCaption("m", TabKind.OPENS, TabKind.CONCEALED); 405 checkTableHead("m", ColKind.OPENED_TO); 406 checkPackageRow("m", "p", "i0", null, "All Modules", " "); 407 checkPackageRow("m", "q", "i1", null, "None", " "); 408 } 409 410 411 private void checkCaption(String moduleName, TabKind... kinds) { 412 String expect; 413 if (kinds.length > 1) { 414 Set<TabKind> kindSet = Set.of(kinds); 415 StringBuilder sb = new StringBuilder(); 416 sb.append("<caption>" 417 + "<span id=\"t0\" class=\"activeTableTab\">" 418 + "<span>All Packages</span>" 419 + "<span class=\"tabEnd\"> </span></span>"); 420 if (kindSet.contains(TabKind.EXPORTS)) { 421 sb.append("<span id=\"t1\" class=\"tableTab\">" 422 + "<span><a href=\"javascript:showPkgs(1);\">Exports</a></span>" 423 + "<span class=\"tabEnd\"> </span></span>"); 424 } 425 if (kindSet.contains(TabKind.OPENS)) { 426 sb.append("<span id=\"t2\" class=\"tableTab\">" 427 + "<span><a href=\"javascript:showPkgs(2);\">Opens</a></span>" 428 + "<span class=\"tabEnd\"> </span></span>"); 429 } 430 if (kindSet.contains(TabKind.CONCEALED)) { 431 sb.append("<span id=\"t3\" class=\"tableTab\"><span>" 432 + "<a href=\"javascript:showPkgs(4);\">Concealed</a></span>" 433 + "<span class=\"tabEnd\"> </span></span>"); 434 } 435 sb.append("</caption>"); 436 expect = sb.toString(); 437 } else { 438 TabKind k = kinds[0]; 439 String name = k.toString().charAt(0) + k.toString().substring(1).toLowerCase(); 440 expect = "<caption>" 441 + "<span>" + name + "</span>" 442 + "<span class=\"tabEnd\"> </span>" 443 + "</caption>"; 444 } 445 446 checkOutput(moduleName + "/module-summary.html", true, expect); 447 } 448 449 450 private void checkTableHead(String moduleName, ColKind... kinds) { 451 Set<ColKind> kindSet = Set.of(kinds); 452 StringBuilder sb = new StringBuilder(); 453 sb.append("<tr>\n" 454 + "<th class=\"colFirst\" scope=\"col\">Package</th>\n"); 455 if (kindSet.contains(ColKind.EXPORTED_TO)) { 456 sb.append("<th class=\"colSecond\" scope=\"col\">Exported To Modules</th>\n"); 457 } 458 if (kindSet.contains(ColKind.OPENED_TO)) { 459 sb.append("<th class=\"colSecond\" scope=\"col\">Opened To Modules</th>\n"); 460 } 461 sb.append("<th class=\"colLast\" scope=\"col\">Description</th>\n" 462 + "</tr>"); 463 464 checkOutput(moduleName + "/module-summary.html", true, sb.toString()); 465 } 466 467 private void checkPackageRow(String moduleName, String packageName, 468 String id, String exportedTo, String openedTo, String desc) { 469 StringBuilder sb = new StringBuilder(); 470 int idNum = Integer.parseInt(id.substring(1)); 471 String color = (idNum % 2 == 1 ? "rowColor" : "altColor"); 472 sb.append("<tr class=\"" + color + "\" id=\"" + id + "\">\n" 473 + "<th class=\"colFirst\" scope=\"row\">" 474 + "<a href=\"" + packageName.replace('.', '/') + "/package-summary.html\">" 475 + packageName + "</a></th>\n"); 476 if (exportedTo != null) { 477 sb.append("<td class=\"colSecond\">" + exportedTo + "</td>\n"); 478 } 479 if (openedTo != null) { 480 sb.append("<td class=\"colSecond\">" + openedTo + "</td>\n"); 481 } 482 sb.append("<td class=\"colLast\">" + desc + "</td>"); 483 484 checkOutput(moduleName + "/module-summary.html", true, sb.toString()); 485 } 486 487 } 488