2016-08-16 01:00:36 +00:00
|
|
|
/*
|
2019-01-30 11:09:26 +00:00
|
|
|
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
2016-08-16 01:00:36 +00:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
|
|
* accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License version
|
|
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
|
|
* questions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @test
|
2018-11-20 05:20:54 +00:00
|
|
|
* @bug 8162353 8164747 8173707 8196202 8204303 8184205
|
2016-08-16 01:00:36 +00:00
|
|
|
* @summary javadoc should provide a way to disable use of frames
|
2018-12-21 18:38:33 +00:00
|
|
|
* @library /tools/lib ../../lib
|
2016-08-16 01:00:36 +00:00
|
|
|
* @modules
|
|
|
|
* jdk.compiler/com.sun.tools.javac.api
|
|
|
|
* jdk.compiler/com.sun.tools.javac.main
|
|
|
|
* jdk.javadoc/jdk.javadoc.internal.tool
|
|
|
|
* @build toolbox.ModuleBuilder toolbox.ToolBox
|
2018-12-21 18:38:33 +00:00
|
|
|
* @build javadoc.tester.*
|
2016-08-16 01:00:36 +00:00
|
|
|
* @run main TestFramesNoFrames
|
|
|
|
*/
|
|
|
|
|
|
|
|
import java.io.*;
|
|
|
|
import java.lang.annotation.Annotation;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
import java.nio.file.*;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
import toolbox.ModuleBuilder;
|
|
|
|
import toolbox.ToolBox;
|
|
|
|
|
2018-12-21 18:38:33 +00:00
|
|
|
import javadoc.tester.JavadocTester;
|
|
|
|
|
2016-08-16 01:00:36 +00:00
|
|
|
public class TestFramesNoFrames extends JavadocTester {
|
|
|
|
|
|
|
|
public static void main(String... args) throws Exception {
|
|
|
|
TestFramesNoFrames tester = new TestFramesNoFrames();
|
|
|
|
tester.generateSource();
|
|
|
|
tester.runTests();
|
|
|
|
}
|
|
|
|
|
|
|
|
ToolBox tb = new ToolBox();
|
|
|
|
Path gensrcModules = Paths.get("gensrc/modules");
|
|
|
|
Path gensrcPackages = Paths.get("gensrc/packages");
|
|
|
|
|
|
|
|
void generateSource() throws IOException {
|
|
|
|
String[] modules = { "", "m1", "m2", "m3" };
|
|
|
|
String[] packages = { "p1", "p2", "p3" };
|
|
|
|
String[] classes = { "C1", "C2", "C3" };
|
|
|
|
for (String m: modules) {
|
|
|
|
ModuleBuilder mb = m.equals("") ? null : new ModuleBuilder(tb, m);
|
|
|
|
for (String p: packages) {
|
|
|
|
Path pkgRoot;
|
|
|
|
if (m.equals("")) {
|
|
|
|
pkgRoot = gensrcPackages;
|
|
|
|
} else {
|
|
|
|
pkgRoot = gensrcModules.resolve(m);
|
|
|
|
mb.exports(m + p);
|
|
|
|
}
|
|
|
|
for (String c: classes) {
|
|
|
|
tb.writeJavaFiles(pkgRoot,
|
|
|
|
"package " + (m + p) + ";\n"
|
|
|
|
+ "/** class " + (m + p + c).toUpperCase() + ". */\n"
|
|
|
|
+ "public class " + (m + p + c).toUpperCase() + " { }"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!m.equals("")) {
|
|
|
|
mb.write(gensrcModules);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tb.writeFile("overview.html",
|
|
|
|
"<html><body>This is the overview file</body></html>");
|
|
|
|
}
|
|
|
|
|
|
|
|
enum FrameKind {
|
|
|
|
DEFAULT(),
|
|
|
|
FRAMES("--frames"),
|
|
|
|
NO_FRAMES("--no-frames");
|
|
|
|
FrameKind(String... opts) {
|
|
|
|
this.opts = Arrays.asList(opts);
|
|
|
|
}
|
|
|
|
final List<String> opts;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum OverviewKind {
|
|
|
|
DEFAULT(),
|
|
|
|
OVERVIEW("-overview", "overview.html"),
|
|
|
|
NO_OVERVIEW("-nooverview");
|
|
|
|
OverviewKind(String... opts) {
|
|
|
|
this.opts = Arrays.asList(opts);
|
|
|
|
}
|
|
|
|
final List<String> opts;
|
|
|
|
}
|
|
|
|
|
|
|
|
enum HtmlKind {
|
|
|
|
HTML5("-html5");
|
|
|
|
HtmlKind(String... opts) {
|
|
|
|
this.opts = Arrays.asList(opts);
|
|
|
|
}
|
|
|
|
final List<String> opts;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void runTests() throws Exception {
|
|
|
|
for (Method m : getClass().getDeclaredMethods()) {
|
|
|
|
Annotation a = m.getAnnotation(Test.class);
|
|
|
|
if (a != null) {
|
|
|
|
for (FrameKind fk : FrameKind.values()) {
|
|
|
|
for (OverviewKind ok : OverviewKind.values()) {
|
2019-01-30 11:09:26 +00:00
|
|
|
try {
|
|
|
|
out.println("Running test " + m.getName() + " " + fk + " " + ok);
|
|
|
|
Path base = Paths.get(m.getName() + "_" + fk + "_" + ok);
|
|
|
|
Files.createDirectories(base);
|
|
|
|
m.invoke(this, new Object[]{base, fk, ok});
|
|
|
|
} catch (InvocationTargetException e) {
|
|
|
|
Throwable cause = e.getCause();
|
|
|
|
throw (cause instanceof Exception) ? ((Exception)cause) : e;
|
2016-08-16 01:00:36 +00:00
|
|
|
}
|
2019-01-30 11:09:26 +00:00
|
|
|
out.println();
|
2016-08-16 01:00:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printSummary();
|
|
|
|
}
|
|
|
|
|
2019-01-30 11:09:26 +00:00
|
|
|
void javadoc(Path outDir, FrameKind fKind, OverviewKind oKind, String... rest) {
|
2016-08-16 01:00:36 +00:00
|
|
|
List<String> args = new ArrayList<>();
|
|
|
|
args.add("-d");
|
|
|
|
args.add(outDir.toString());
|
|
|
|
args.addAll(fKind.opts);
|
|
|
|
args.addAll(oKind.opts);
|
|
|
|
args.addAll(Arrays.asList(rest));
|
|
|
|
javadoc(args.toArray(new String[0]));
|
|
|
|
checkExit(Exit.OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2019-01-30 11:09:26 +00:00
|
|
|
public void testClass(Path base, FrameKind fKind, OverviewKind oKind) throws Exception {
|
|
|
|
javadoc(base, fKind, oKind, gensrcPackages.resolve("p1/P1C1.java").toString());
|
2016-08-16 01:00:36 +00:00
|
|
|
|
2019-01-30 11:09:26 +00:00
|
|
|
new Checker(fKind, oKind)
|
2016-08-16 01:00:36 +00:00
|
|
|
.classes("p1.P1C1")
|
|
|
|
.check();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2019-01-30 11:09:26 +00:00
|
|
|
public void testClasses(Path base, FrameKind fKind, OverviewKind oKind) throws IOException {
|
|
|
|
javadoc(base, fKind, oKind,
|
2016-08-16 01:00:36 +00:00
|
|
|
gensrcPackages.resolve("p1/P1C1.java").toString(),
|
|
|
|
gensrcPackages.resolve("p1/P1C2.java").toString(),
|
|
|
|
gensrcPackages.resolve("p1/P1C3.java").toString());
|
|
|
|
|
2019-01-30 11:09:26 +00:00
|
|
|
new Checker(fKind, oKind)
|
2016-08-16 01:00:36 +00:00
|
|
|
.classes("p1.P1C1", "p1.P1C2", "p1.P1C3")
|
|
|
|
.check();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2019-01-30 11:09:26 +00:00
|
|
|
public void testPackage(Path base, FrameKind fKind, OverviewKind oKind) throws IOException {
|
|
|
|
javadoc(base, fKind, oKind,
|
2016-08-16 01:00:36 +00:00
|
|
|
"-sourcepath", gensrcPackages.toString(),
|
|
|
|
"p1");
|
|
|
|
|
2019-01-30 11:09:26 +00:00
|
|
|
new Checker(fKind, oKind)
|
2016-08-16 01:00:36 +00:00
|
|
|
.classes("p1.P1C1", "p1.P1C2", "p1.P1C3")
|
|
|
|
.check();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2019-01-30 11:09:26 +00:00
|
|
|
public void testPackages(Path base, FrameKind fKind, OverviewKind oKind) throws IOException {
|
|
|
|
javadoc(base, fKind, oKind,
|
2016-08-16 01:00:36 +00:00
|
|
|
"-sourcepath", gensrcPackages.toString(),
|
|
|
|
"p1", "p2", "p3");
|
|
|
|
|
2019-01-30 11:09:26 +00:00
|
|
|
new Checker(fKind, oKind)
|
2016-08-16 01:00:36 +00:00
|
|
|
.classes("p1.P1C1", "p1.P1C2", "p1.P1C3",
|
|
|
|
"p2.P2C1", "p2.P2C2", "p2.P2C3",
|
|
|
|
"p3.P3C1", "p3.P3C2", "p3.P3C3")
|
|
|
|
.check();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2019-01-30 11:09:26 +00:00
|
|
|
public void testModules(Path base, FrameKind fKind, OverviewKind oKind) throws IOException {
|
|
|
|
javadoc(base, fKind, oKind,
|
2016-08-26 22:54:36 +00:00
|
|
|
"--module-source-path", gensrcModules.toString(),
|
2016-08-18 12:48:35 +00:00
|
|
|
"--module", "m1,m2,m3");
|
2016-08-16 01:00:36 +00:00
|
|
|
|
2019-01-30 11:09:26 +00:00
|
|
|
new Checker(fKind, oKind)
|
2016-08-16 01:00:36 +00:00
|
|
|
.classes("m1/m1p1.M1P1C1", "m1/m1p1.M1P1C2", "m1/m1p1.M1P1C3",
|
|
|
|
"m2/m2p1.M2P1C1", "m2/m2p1.M2P1C2", "m2/m2p1.M2P1C3",
|
|
|
|
"m3/m3p1.M3P1C1", "m3/m3p1.M3P1C2", "m3/m3p1.M3P1C3")
|
|
|
|
.check();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check the contents of the generated output, according to the
|
|
|
|
* specified options.
|
|
|
|
*/
|
|
|
|
class Checker {
|
|
|
|
private final FrameKind fKind;
|
|
|
|
private final OverviewKind oKind;
|
|
|
|
List<String> classes;
|
|
|
|
|
|
|
|
private boolean frames;
|
|
|
|
private boolean overview;
|
2018-05-29 18:20:04 +00:00
|
|
|
private static final String framesWarning
|
|
|
|
= "javadoc: warning - You have specified to generate frames, by using the --frames option.\n"
|
|
|
|
+ "The default is currently to not generate frames and the support for \n"
|
|
|
|
+ "frames will be removed in a future release.\n"
|
|
|
|
+ "To suppress this warning, remove the --frames option and avoid the use of frames.";
|
2016-08-16 01:00:36 +00:00
|
|
|
|
2019-01-30 11:09:26 +00:00
|
|
|
Checker(FrameKind fKind, OverviewKind oKind) {
|
2016-08-16 01:00:36 +00:00
|
|
|
this.fKind = fKind;
|
|
|
|
this.oKind = oKind;
|
|
|
|
}
|
|
|
|
|
|
|
|
Checker classes(String... classes) {
|
|
|
|
this.classes = Arrays.asList(classes);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void check() throws IOException {
|
|
|
|
switch (fKind) {
|
|
|
|
case FRAMES:
|
|
|
|
frames = true;
|
|
|
|
break;
|
|
|
|
|
2018-05-29 18:20:04 +00:00
|
|
|
case DEFAULT:
|
2016-08-16 01:00:36 +00:00
|
|
|
case NO_FRAMES:
|
|
|
|
frames = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (oKind) {
|
|
|
|
case DEFAULT:
|
|
|
|
overview = (getPackageCount() > 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OVERVIEW:
|
|
|
|
overview = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NO_OVERVIEW:
|
|
|
|
overview = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-01-30 11:09:26 +00:00
|
|
|
out.println("Checker: " + fKind + " " + oKind
|
2018-06-06 22:10:12 +00:00
|
|
|
+ ": frames:" + frames + " overview:" + overview);
|
|
|
|
|
2016-08-16 01:00:36 +00:00
|
|
|
checkAllClassesFiles();
|
|
|
|
checkFrameFiles();
|
|
|
|
checkOverviewSummary();
|
|
|
|
|
|
|
|
checkIndex();
|
|
|
|
checkNavBar();
|
|
|
|
checkHelpDoc();
|
|
|
|
|
2018-05-29 18:20:04 +00:00
|
|
|
checkWarning();
|
|
|
|
|
2016-08-16 01:00:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void checkAllClassesFiles() {
|
|
|
|
// these files are only generated in frames mode
|
|
|
|
checkFiles(frames,
|
2018-06-28 22:46:27 +00:00
|
|
|
"allclasses-frame.html");
|
2016-08-16 01:00:36 +00:00
|
|
|
|
2018-06-28 22:46:27 +00:00
|
|
|
checkFiles(false,
|
2016-08-16 01:00:36 +00:00
|
|
|
"allclasses.html");
|
2016-08-24 22:40:35 +00:00
|
|
|
|
2018-06-28 22:46:27 +00:00
|
|
|
checkFiles(false,
|
|
|
|
"allclasses-noframe.html");
|
|
|
|
|
2016-08-24 22:40:35 +00:00
|
|
|
if (frames) {
|
|
|
|
checkOutput("allclasses-frame.html", true,
|
|
|
|
classes.stream()
|
|
|
|
.map(c -> "title=\"class in " + packagePart(c) + "\" target=\"classFrame\">" + classPart(c) + "</a>")
|
|
|
|
.toArray(String[]::new));
|
|
|
|
}
|
2016-08-16 01:00:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void checkFrameFiles() {
|
|
|
|
// these files are all only generated in frames mode
|
|
|
|
|
2018-02-07 19:28:23 +00:00
|
|
|
// <module>/module-frame.html and <module>/module-type-frame.html files
|
2016-08-16 01:00:36 +00:00
|
|
|
checkFiles(frames, classes.stream()
|
|
|
|
.filter(c -> isInModule(c))
|
|
|
|
.map(c -> modulePart(c))
|
|
|
|
.flatMap(m -> Arrays.asList(
|
2018-02-07 19:28:23 +00:00
|
|
|
m + "/module-frame.html",
|
|
|
|
m + "/module-type-frame.html").stream())
|
2016-08-16 01:00:36 +00:00
|
|
|
.collect(Collectors.toSet()));
|
|
|
|
|
|
|
|
// <package>/package-frame.html files
|
|
|
|
checkFiles(frames, classes.stream()
|
2018-02-07 19:28:23 +00:00
|
|
|
.map(c -> (isInModule(c) ? (modulePart(c) + "/") : "")
|
|
|
|
+ packagePart(c)
|
|
|
|
+ "/package-frame.html")
|
2016-08-16 01:00:36 +00:00
|
|
|
.collect(Collectors.toSet()));
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkHelpDoc() {
|
|
|
|
// the Help page only describes Frame/NoFrames in frames mode
|
|
|
|
checkOutput("help-doc.html", frames,
|
|
|
|
"<h2>Frames/No Frames</h2>");
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkIndex() {
|
2017-02-02 22:55:23 +00:00
|
|
|
// the index.html page only contains frames and Javascript to default to no-frames view,
|
|
|
|
// in frames mode
|
2016-08-16 01:00:36 +00:00
|
|
|
checkOutput("index.html", frames,
|
|
|
|
"<iframe ",
|
2017-02-02 22:55:23 +00:00
|
|
|
"</iframe>",
|
|
|
|
"<body onload=\"loadFrames()\">\n"
|
|
|
|
+ "<script type=\"text/javascript\">\n"
|
|
|
|
+ "if (targetPage == \"\" || targetPage == \"undefined\")");
|
2016-08-16 01:00:36 +00:00
|
|
|
|
|
|
|
// the index.html contains the overview if one
|
|
|
|
// has been given, and not in frames mode
|
|
|
|
checkOutput("index.html", !frames && oKind == OverviewKind.OVERVIEW,
|
|
|
|
"This is the overview file");
|
|
|
|
|
|
|
|
// the index.html file contains a summary table
|
|
|
|
// if an overview was generated and not in frames mode
|
|
|
|
checkOutput("index.html", !frames && overview,
|
2018-11-20 05:20:54 +00:00
|
|
|
"<div class=\"overviewSummary\">\n<table");
|
2016-08-16 01:00:36 +00:00
|
|
|
|
|
|
|
// the index.html file contains a redirect if
|
|
|
|
// no frames and no overview
|
|
|
|
checkOutput("index.html", !frames && !overview,
|
|
|
|
"<meta http-equiv=\"Refresh\" content=\"0;",
|
|
|
|
"<script type=\"text/javascript\">window.location.replace(");
|
|
|
|
|
|
|
|
if (!frames && !overview) {
|
2019-01-30 11:09:26 +00:00
|
|
|
checkOutput("index.html", true,
|
2016-08-16 01:00:36 +00:00
|
|
|
"<noscript>\n<meta http-equiv=\"Refresh\" content=\"0;");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkNavBar() {
|
|
|
|
// the files containing a navigation bar should only
|
|
|
|
// contain FRAMES/NO-FRAMES links in frames mode
|
|
|
|
List<String> navbarFiles = new ArrayList<>();
|
|
|
|
navbarFiles.addAll(classes.stream()
|
2018-02-07 19:28:23 +00:00
|
|
|
.map(c -> (isInModule(c) ? (modulePart(c) + "/") : "")
|
|
|
|
+ toHtml(packageClassPart(c)))
|
2016-08-16 01:00:36 +00:00
|
|
|
.collect(Collectors.toSet()));
|
|
|
|
for (String f : navbarFiles) {
|
|
|
|
checkOutput(f, frames,
|
|
|
|
"target=\"_top\">Frames</a>",
|
|
|
|
"target=\"_top\">No Frames</a>");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void checkOverviewSummary() {
|
2018-06-06 22:10:12 +00:00
|
|
|
// To accommodate the historical behavior of generating
|
|
|
|
// overview-summary.html in frames mode, the file
|
|
|
|
// will still be generated in no-frames mode,
|
|
|
|
// but will be a redirect to index.html
|
|
|
|
checkFiles(overview,
|
2016-08-16 01:00:36 +00:00
|
|
|
"overview-summary.html");
|
2018-06-06 22:10:12 +00:00
|
|
|
if (overview) {
|
|
|
|
checkOutput("overview-summary.html", !frames,
|
|
|
|
"<link rel=\"canonical\" href=\"index.html\">",
|
|
|
|
"<script type=\"text/javascript\">window.location.replace('index.html')</script>",
|
|
|
|
"<meta http-equiv=\"Refresh\" content=\"0;index.html\">",
|
|
|
|
"<p><a href=\"index.html\">index.html</a></p>");
|
|
|
|
}
|
2016-08-16 01:00:36 +00:00
|
|
|
}
|
|
|
|
|
2018-05-29 18:20:04 +00:00
|
|
|
private void checkWarning() {
|
|
|
|
checkOutput(Output.OUT, frames, framesWarning);
|
|
|
|
}
|
|
|
|
|
2016-08-16 01:00:36 +00:00
|
|
|
private long getPackageCount() {
|
|
|
|
return this.classes.stream()
|
|
|
|
.filter(name -> name.contains("."))
|
|
|
|
.map(name -> name.substring(0, name.lastIndexOf(".")))
|
|
|
|
.distinct()
|
|
|
|
.count();
|
|
|
|
}
|
|
|
|
|
2016-08-24 22:40:35 +00:00
|
|
|
private String classPart(String className) {
|
|
|
|
int lastDot = className.lastIndexOf(".");
|
|
|
|
return className.substring(lastDot + 1);
|
|
|
|
}
|
|
|
|
|
2016-08-16 01:00:36 +00:00
|
|
|
private String packagePart(String className) {
|
|
|
|
int slash = className.indexOf("/");
|
|
|
|
int lastDot = className.lastIndexOf(".");
|
|
|
|
return className.substring(slash + 1, lastDot);
|
|
|
|
}
|
|
|
|
|
|
|
|
private String packageClassPart(String className) {
|
|
|
|
int slash = className.indexOf("/");
|
|
|
|
return className.substring(slash + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isInModule(String className) {
|
|
|
|
return className.contains("/");
|
|
|
|
}
|
|
|
|
|
|
|
|
private String modulePart(String className) {
|
|
|
|
int slash = className.indexOf("/");
|
|
|
|
return className.substring(0, slash);
|
|
|
|
}
|
|
|
|
|
|
|
|
private String toHtml(String className) {
|
|
|
|
return className.replace(".", "/") + ".html";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|