/* * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * 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 * @bug 8162353 8164747 8173707 * @summary javadoc should provide a way to disable use of frames * @library /tools/lib ../lib * @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 * @build JavadocTester * @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; 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", "This is the overview file"); } enum FrameKind { DEFAULT(), FRAMES("--frames"), NO_FRAMES("--no-frames"); FrameKind(String... opts) { this.opts = Arrays.asList(opts); } final List opts; } enum OverviewKind { DEFAULT(), OVERVIEW("-overview", "overview.html"), NO_OVERVIEW("-nooverview"); OverviewKind(String... opts) { this.opts = Arrays.asList(opts); } final List opts; } enum HtmlKind { HTML4("-html4"), HTML5("-html5"); HtmlKind(String... opts) { this.opts = Arrays.asList(opts); } final List 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()) { for (HtmlKind hk : HtmlKind.values()) { try { out.println("Running test " + m.getName() + " " + fk + " " + ok + " " + hk); Path base = Paths.get(m.getName() + "_" + fk + "_" + ok + "_" + hk); Files.createDirectories(base); m.invoke(this, new Object[]{base, fk, ok, hk}); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); throw (cause instanceof Exception) ? ((Exception) cause) : e; } out.println(); } } } } } printSummary(); } void javadoc(Path outDir, FrameKind fKind, OverviewKind oKind, HtmlKind hKind, String... rest) { List args = new ArrayList<>(); args.add("-d"); args.add(outDir.toString()); args.addAll(fKind.opts); args.addAll(oKind.opts); args.addAll(hKind.opts); args.addAll(Arrays.asList(rest)); javadoc(args.toArray(new String[0])); checkExit(Exit.OK); } @Test void testClass(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws Exception { javadoc(base, fKind, oKind, hKind, gensrcPackages.resolve("p1/P1C1.java").toString()); new Checker(fKind, oKind, hKind) .classes("p1.P1C1") .check(); } @Test void testClasses(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException { javadoc(base, fKind, oKind, hKind, gensrcPackages.resolve("p1/P1C1.java").toString(), gensrcPackages.resolve("p1/P1C2.java").toString(), gensrcPackages.resolve("p1/P1C3.java").toString()); new Checker(fKind, oKind, hKind) .classes("p1.P1C1", "p1.P1C2", "p1.P1C3") .check(); } @Test void testPackage(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException { javadoc(base, fKind, oKind, hKind, "-sourcepath", gensrcPackages.toString(), "p1"); new Checker(fKind, oKind, hKind) .classes("p1.P1C1", "p1.P1C2", "p1.P1C3") .check(); } @Test void testPackages(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException { javadoc(base, fKind, oKind, hKind, "-sourcepath", gensrcPackages.toString(), "p1", "p2", "p3"); new Checker(fKind, oKind, hKind) .classes("p1.P1C1", "p1.P1C2", "p1.P1C3", "p2.P2C1", "p2.P2C2", "p2.P2C3", "p3.P3C1", "p3.P3C2", "p3.P3C3") .check(); } @Test void testModules(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException { javadoc(base, fKind, oKind, hKind, "--module-source-path", gensrcModules.toString(), "--module", "m1,m2,m3"); new Checker(fKind, oKind, hKind) .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; private final HtmlKind hKind; List classes; private boolean frames; private boolean overview; Checker(FrameKind fKind, OverviewKind oKind, HtmlKind hKind) { this.fKind = fKind; this.oKind = oKind; this.hKind = hKind; } Checker classes(String... classes) { this.classes = Arrays.asList(classes); return this; } void check() throws IOException { switch (fKind) { case DEFAULT: case FRAMES: frames = true; break; 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; } checkAllClassesFiles(); checkFrameFiles(); checkOverviewSummary(); checkIndex(); checkNavBar(); checkHelpDoc(); } private void checkAllClassesFiles() { // these files are only generated in frames mode checkFiles(frames, "allclasses-frame.html", "allclasses-noframe.html"); // this file is only generated when not in frames mode checkFiles(!frames, "allclasses.html"); if (frames) { checkOutput("allclasses-frame.html", true, classes.stream() .map(c -> "title=\"class in " + packagePart(c) + "\" target=\"classFrame\">" + classPart(c) + "") .toArray(String[]::new)); checkOutput("allclasses-noframe.html", false, "target=\"classFrame\">"); } else { checkOutput("allclasses.html", false, "target=\"classFrame\">"); } } private void checkFrameFiles() { // these files are all only generated in frames mode // /module-frame.html and /module-type-frame.html files checkFiles(frames, classes.stream() .filter(c -> isInModule(c)) .map(c -> modulePart(c)) .flatMap(m -> Arrays.asList( m + "/module-frame.html", m + "/module-type-frame.html").stream()) .collect(Collectors.toSet())); // /package-frame.html files checkFiles(frames, classes.stream() .map(c -> (isInModule(c) ? (modulePart(c) + "/") : "") + packagePart(c) + "/package-frame.html") .collect(Collectors.toSet())); } private void checkHelpDoc() { // the Help page only describes Frame/NoFrames in frames mode checkOutput("help-doc.html", frames, "

Frames/No Frames

"); } private void checkIndex() { // the index.html page only contains frames and Javascript to default to no-frames view, // in frames mode checkOutput("index.html", frames, "