8162353: javadoc should provide a way to disable use of frames
Reviewed-by: bpatel, ksrini
This commit is contained in:
parent
66ff418a4b
commit
9208c82732
@ -25,7 +25,7 @@
|
||||
|
||||
package jdk.javadoc.internal.doclets.formats.html;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
@ -89,25 +89,32 @@ public class AllClassesFrameWriter extends HtmlDocletWriter {
|
||||
* "allclasses-frame.html" file. Generate the file in the current or the
|
||||
* destination directory.
|
||||
*
|
||||
* @param indexbuilder IndexBuilder object for all classes index.
|
||||
* @param indexBuilder IndexBuilder object for all classes index.
|
||||
* @throws DocletAbortException
|
||||
*/
|
||||
public static void generate(ConfigurationImpl configuration,
|
||||
IndexBuilder indexbuilder) {
|
||||
AllClassesFrameWriter allclassgen;
|
||||
DocPath filename = DocPaths.ALLCLASSES_FRAME;
|
||||
IndexBuilder indexBuilder) {
|
||||
if (configuration.frames) {
|
||||
generate(configuration, indexBuilder, DocPaths.ALLCLASSES_FRAME, true);
|
||||
generate(configuration, indexBuilder, DocPaths.ALLCLASSES_NOFRAME, false);
|
||||
} else {
|
||||
generate(configuration, indexBuilder, DocPaths.ALLCLASSES, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void generate(ConfigurationImpl configuration, IndexBuilder indexBuilder,
|
||||
DocPath fileName, boolean wantFrames) {
|
||||
try {
|
||||
AllClassesFrameWriter allclassgen = new AllClassesFrameWriter(configuration,
|
||||
fileName, indexBuilder);
|
||||
allclassgen.buildAllClassesFile(wantFrames);
|
||||
allclassgen = new AllClassesFrameWriter(configuration,
|
||||
filename, indexbuilder);
|
||||
allclassgen.buildAllClassesFile(true);
|
||||
filename = DocPaths.ALLCLASSES_NOFRAME;
|
||||
allclassgen = new AllClassesFrameWriter(configuration,
|
||||
filename, indexbuilder);
|
||||
fileName, indexBuilder);
|
||||
allclassgen.buildAllClassesFile(false);
|
||||
} catch (IOException exc) {
|
||||
Messages messages = configuration.getMessages();
|
||||
messages.error("doclet.exception_encountered",
|
||||
exc.toString(), filename);
|
||||
exc.toString(), fileName);
|
||||
throw new DocletAbortException(exc);
|
||||
}
|
||||
}
|
||||
|
@ -197,6 +197,12 @@ public class ConfigurationImpl extends Configuration {
|
||||
*/
|
||||
public boolean createoverview = false;
|
||||
|
||||
/**
|
||||
* Specifies whether or not frames should be generated.
|
||||
* Defaults to true; can be set by --frames; can be set to false by --no-frames; last one wins.
|
||||
*/
|
||||
public boolean frames = true;
|
||||
|
||||
/**
|
||||
* This is the HTML version of the generated pages. HTML 4.01 is the default output version.
|
||||
*/
|
||||
@ -414,18 +420,18 @@ public class ConfigurationImpl extends Configuration {
|
||||
* package to document. It will be a class page(first in the sorted order),
|
||||
* if only classes are provided on the command line.
|
||||
*
|
||||
* @param root Root of the program structure.
|
||||
* @param docEnv Root of the program structure.
|
||||
*/
|
||||
protected void setTopFile(DocletEnvironment root) {
|
||||
if (!checkForDeprecation(root)) {
|
||||
protected void setTopFile(DocletEnvironment docEnv) {
|
||||
if (!checkForDeprecation(docEnv)) {
|
||||
return;
|
||||
}
|
||||
if (createoverview) {
|
||||
topFile = DocPaths.OVERVIEW_SUMMARY;
|
||||
topFile = DocPaths.overviewSummary(frames);
|
||||
} else {
|
||||
if (packages.size() == 1 && packages.first().isUnnamed()) {
|
||||
if (!root.getIncludedClasses().isEmpty()) {
|
||||
List<TypeElement> classes = new ArrayList<>(root.getIncludedClasses());
|
||||
if (!docEnv.getIncludedClasses().isEmpty()) {
|
||||
List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedClasses());
|
||||
TypeElement te = getValidClass(classes);
|
||||
topFile = DocPath.forClass(utils, te);
|
||||
}
|
||||
@ -727,6 +733,22 @@ public class ConfigurationImpl extends Configuration {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
new Option(this, "--frames") {
|
||||
@Override
|
||||
public boolean process(String opt, ListIterator<String> args) {
|
||||
optionsProcessed.add(this);
|
||||
frames = true;
|
||||
return true;
|
||||
}
|
||||
},
|
||||
new Option(this, "--no-frames") {
|
||||
@Override
|
||||
public boolean process(String opt, ListIterator<String> args) {
|
||||
optionsProcessed.add(this);
|
||||
frames = false;
|
||||
return true;
|
||||
}
|
||||
},
|
||||
new Hidden(this, "-packagesheader", 1) {
|
||||
@Override
|
||||
public boolean process(String opt, ListIterator<String> args) {
|
||||
|
@ -141,7 +141,7 @@ public class HelpWriter extends HtmlDocletWriter {
|
||||
? HtmlTree.SECTION(overviewHeading)
|
||||
: HtmlTree.LI(HtmlStyle.blockList, overviewHeading);
|
||||
Content line3 = contents.getContent("doclet.Help_line_3",
|
||||
getHyperLink(DocPaths.OVERVIEW_SUMMARY,
|
||||
getHyperLink(DocPaths.overviewSummary(configuration.frames),
|
||||
configuration.getText("doclet.Overview")));
|
||||
Content overviewPara = HtmlTree.P(line3);
|
||||
htmlTree.addContent(overviewPara);
|
||||
@ -362,26 +362,31 @@ public class HelpWriter extends HtmlDocletWriter {
|
||||
} else {
|
||||
ul.addContent(htmlTree);
|
||||
}
|
||||
Content frameHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
|
||||
contents.getContent("doclet.Help_line_25"));
|
||||
htmlTree = (configuration.allowTag(HtmlTag.SECTION))
|
||||
? HtmlTree.SECTION(frameHead)
|
||||
: HtmlTree.LI(HtmlStyle.blockList, frameHead);
|
||||
Content line26 = contents.getContent("doclet.Help_line_26");
|
||||
Content framePara = HtmlTree.P(line26);
|
||||
htmlTree.addContent(framePara);
|
||||
|
||||
if (configuration.frames) {
|
||||
Content frameHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
|
||||
contents.getContent("doclet.Help_line_25"));
|
||||
htmlTree = (configuration.allowTag(HtmlTag.SECTION))
|
||||
? HtmlTree.SECTION(frameHead)
|
||||
: HtmlTree.LI(HtmlStyle.blockList, frameHead);
|
||||
Content line26 = contents.getContent("doclet.Help_line_26");
|
||||
Content framePara = HtmlTree.P(line26);
|
||||
htmlTree.addContent(framePara);
|
||||
}
|
||||
|
||||
if (configuration.allowTag(HtmlTag.SECTION)) {
|
||||
ul.addContent(HtmlTree.LI(HtmlStyle.blockList, htmlTree));
|
||||
} else {
|
||||
ul.addContent(htmlTree);
|
||||
}
|
||||
|
||||
Content allclassesHead = HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING,
|
||||
contents.allClassesLabel);
|
||||
htmlTree = (configuration.allowTag(HtmlTag.SECTION))
|
||||
? HtmlTree.SECTION(allclassesHead)
|
||||
: HtmlTree.LI(HtmlStyle.blockList, allclassesHead);
|
||||
Content line27 = contents.getContent("doclet.Help_line_27",
|
||||
getHyperLink(DocPaths.ALLCLASSES_NOFRAME,
|
||||
getHyperLink(DocPaths.AllClasses(configuration.frames),
|
||||
resources.getText("doclet.All_Classes")));
|
||||
Content allclassesPara = HtmlTree.P(line27);
|
||||
htmlTree.addContent(allclassesPara);
|
||||
|
@ -106,7 +106,7 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
*
|
||||
* For new format.
|
||||
*
|
||||
* @see jdk.doclet.RootDoc
|
||||
* @see jdk.doclet.DocletEnvironment
|
||||
*/
|
||||
@Override // defined by AbstractDoclet
|
||||
protected void generateOtherFiles(DocletEnvironment docEnv, ClassTree classtree)
|
||||
@ -149,7 +149,9 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
AllClassesFrameWriter.generate(configuration,
|
||||
new IndexBuilder(configuration, nodeprecated, true));
|
||||
|
||||
FrameOutputWriter.generate(configuration);
|
||||
if (configuration.frames) {
|
||||
FrameOutputWriter.generate(configuration);
|
||||
}
|
||||
|
||||
if (configuration.createoverview) {
|
||||
if (configuration.showModules) {
|
||||
@ -158,6 +160,11 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
PackageIndexWriter.generate(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
if (!configuration.frames && !configuration.createoverview) {
|
||||
IndexRedirectWriter.generate(configuration);
|
||||
}
|
||||
|
||||
if (configuration.helpfile.length() == 0 &&
|
||||
!configuration.nohelp) {
|
||||
HelpWriter.generate(configuration);
|
||||
@ -270,13 +277,17 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
@Override // defined by AbstractDoclet
|
||||
protected void generateModuleFiles() throws Exception {
|
||||
if (configuration.showModules) {
|
||||
ModuleIndexFrameWriter.generate(configuration);
|
||||
if (configuration.frames) {
|
||||
ModuleIndexFrameWriter.generate(configuration);
|
||||
}
|
||||
ModuleElement prevModule = null, nextModule;
|
||||
List<ModuleElement> mdles = new ArrayList<>(configuration.modulePackages.keySet());
|
||||
int i = 0;
|
||||
for (ModuleElement mdle : mdles) {
|
||||
ModulePackageIndexFrameWriter.generate(configuration, mdle);
|
||||
ModuleFrameWriter.generate(configuration, mdle);
|
||||
if (configuration.frames) {
|
||||
ModulePackageIndexFrameWriter.generate(configuration, mdle);
|
||||
ModuleFrameWriter.generate(configuration, mdle);
|
||||
}
|
||||
nextModule = (i + 1 < mdles.size()) ? mdles.get(i + 1) : null;
|
||||
AbstractBuilder moduleSummaryBuilder =
|
||||
configuration.getBuilderFactory().getModuleSummaryBuilder(
|
||||
@ -304,7 +315,7 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
@Override // defined by AbstractDoclet
|
||||
protected void generatePackageFiles(ClassTree classtree) throws Exception {
|
||||
Set<PackageElement> packages = configuration.packages;
|
||||
if (packages.size() > 1) {
|
||||
if (packages.size() > 1 && configuration.frames) {
|
||||
PackageIndexFrameWriter.generate(configuration);
|
||||
}
|
||||
List<PackageElement> pList = new ArrayList<>(packages);
|
||||
@ -315,7 +326,9 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
// and package-tree.html pages for that package.
|
||||
PackageElement pkg = pList.get(i);
|
||||
if (!(configuration.nodeprecated && utils.isDeprecated(pkg))) {
|
||||
PackageFrameWriter.generate(configuration, pkg);
|
||||
if (configuration.frames) {
|
||||
PackageFrameWriter.generate(configuration, pkg);
|
||||
}
|
||||
int nexti = i + 1;
|
||||
PackageElement next = null;
|
||||
if (nexti < pList.size()) {
|
||||
|
@ -615,12 +615,13 @@ public class HtmlDocletWriter extends HtmlDocWriter {
|
||||
} else {
|
||||
tree.addContent(navDiv);
|
||||
}
|
||||
Content ulNav = HtmlTree.UL(HtmlStyle.navList, getNavLinkPrevious());
|
||||
ulNav.addContent(getNavLinkNext());
|
||||
Content ulNav = HtmlTree.UL(HtmlStyle.navList, getNavLinkPrevious(), getNavLinkNext());
|
||||
Content subDiv = HtmlTree.DIV(HtmlStyle.subNav, ulNav);
|
||||
Content ulFrames = HtmlTree.UL(HtmlStyle.navList, getNavShowLists());
|
||||
ulFrames.addContent(getNavHideLists(filename));
|
||||
subDiv.addContent(ulFrames);
|
||||
if (configuration.frames) {
|
||||
Content ulFrames = HtmlTree.UL(HtmlStyle.navList,
|
||||
getNavShowLists(), getNavHideLists(filename));
|
||||
subDiv.addContent(ulFrames);
|
||||
}
|
||||
HtmlTree ulAllClasses = HtmlTree.UL(HtmlStyle.navList, getNavLinkClassIndex());
|
||||
ulAllClasses.addAttr(HtmlAttr.ID, allClassesId);
|
||||
subDiv.addContent(ulAllClasses);
|
||||
@ -688,7 +689,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkContents() {
|
||||
Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_SUMMARY),
|
||||
Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.overviewSummary(configuration.frames)),
|
||||
contents.overviewLabel, "", "");
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
@ -875,7 +876,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
|
||||
*/
|
||||
protected Content getNavLinkClassIndex() {
|
||||
Content allClassesContent = getHyperLink(pathToRoot.resolve(
|
||||
DocPaths.ALLCLASSES_NOFRAME),
|
||||
DocPaths.AllClasses(configuration.frames)),
|
||||
contents.allClassesLabel, "", "");
|
||||
Content li = HtmlTree.LI(allClassesContent);
|
||||
return li;
|
||||
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package jdk.javadoc.internal.doclets.formats.html;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Comment;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.DocType;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Messages;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocletAbortException;
|
||||
|
||||
import static jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocWriter.CONTENT_TYPE;
|
||||
|
||||
/**
|
||||
* Writes an index.html file that tries to redirect to an alternate page.
|
||||
* The redirect uses JavaSCript, if enabled, falling back on
|
||||
* {@code <meta http-eqiv=refresh content="0,<uri>">}.
|
||||
* If neither are supported/enabled in a browser, the page displays the
|
||||
* standard "JavaScipt not enabled" message, and a link to the alternate page.
|
||||
*/
|
||||
public class IndexRedirectWriter extends HtmlDocletWriter {
|
||||
|
||||
public static void generate(ConfigurationImpl configuration) {
|
||||
IndexRedirectWriter indexRedirect;
|
||||
DocPath filename = DocPath.empty;
|
||||
try {
|
||||
filename = DocPaths.INDEX;
|
||||
indexRedirect = new IndexRedirectWriter(configuration, filename);
|
||||
indexRedirect.generateIndexFile();
|
||||
} catch (IOException exc) {
|
||||
Messages messages = configuration.getMessages();
|
||||
messages.error(
|
||||
"doclet.exception_encountered",
|
||||
exc.toString(), filename);
|
||||
throw new DocletAbortException(exc);
|
||||
}
|
||||
}
|
||||
|
||||
IndexRedirectWriter(ConfigurationImpl configuration, DocPath filename)
|
||||
throws IOException {
|
||||
super(configuration, filename);
|
||||
}
|
||||
|
||||
void generateIndexFile() throws IOException {
|
||||
Content htmlDocType = configuration.isOutputHtml5()
|
||||
? DocType.HTML5
|
||||
: DocType.TRANSITIONAL;
|
||||
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
|
||||
Content head = new HtmlTree(HtmlTag.HEAD);
|
||||
head.addContent(getGeneratedBy(!configuration.notimestamp));
|
||||
|
||||
String title = (configuration.windowtitle.length() > 0)
|
||||
? configuration.windowtitle
|
||||
: configuration.getText("doclet.Generated_Docs_Untitled");
|
||||
|
||||
Content windowTitle = HtmlTree.TITLE(new StringContent(title));
|
||||
head.addContent(windowTitle);
|
||||
Content metaContentType = HtmlTree.META("Content", CONTENT_TYPE,
|
||||
(configuration.charset.length() > 0) ?
|
||||
configuration.charset : HtmlConstants.HTML_DEFAULT_CHARSET);
|
||||
head.addContent(metaContentType);
|
||||
|
||||
String topFilePath = configuration.topFile.getPath();
|
||||
String javaScriptRefresh = "window.location.replace('" + topFilePath + "')";
|
||||
HtmlTree scriptTree = HtmlTree.SCRIPT();
|
||||
scriptTree.addContent(javaScriptRefresh);
|
||||
head.addContent(scriptTree);
|
||||
HtmlTree metaRefresh = new HtmlTree(HtmlTag.META);
|
||||
metaRefresh.addAttr(HtmlAttr.HTTP_EQUIV, "Refresh");
|
||||
metaRefresh.addAttr(HtmlAttr.CONTENT, "0;" + topFilePath);
|
||||
if (configuration.isOutputHtml5()) {
|
||||
head.addContent(HtmlTree.NOSCRIPT(metaRefresh));
|
||||
} else {
|
||||
head.addContent(metaRefresh);
|
||||
}
|
||||
|
||||
head.addContent(getStyleSheetProperties(configuration));
|
||||
|
||||
ContentBuilder bodyContent = new ContentBuilder();
|
||||
bodyContent.addContent(HtmlTree.NOSCRIPT(
|
||||
HtmlTree.P(configuration.getContent("doclet.No_Script_Message"))));
|
||||
|
||||
bodyContent.addContent(HtmlTree.P(HtmlTree.A(topFilePath, new StringContent(topFilePath))));
|
||||
|
||||
Content body = new HtmlTree(HtmlTag.BODY);
|
||||
if (configuration.allowTag(HtmlTag.MAIN)) {
|
||||
HtmlTree main = HtmlTree.MAIN(bodyContent);
|
||||
body.addContent(main);
|
||||
} else {
|
||||
body.addContent(bodyContent);
|
||||
}
|
||||
|
||||
Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
|
||||
head, body);
|
||||
Content htmlDocument = new HtmlDocument(htmlDocType,
|
||||
htmlComment, htmlTree);
|
||||
write(htmlDocument);
|
||||
|
||||
}
|
||||
}
|
@ -88,7 +88,7 @@ public class ModuleIndexWriter extends AbstractModuleIndexWriter {
|
||||
*/
|
||||
public static void generate(ConfigurationImpl configuration) {
|
||||
ModuleIndexWriter mdlgen;
|
||||
DocPath filename = DocPaths.OVERVIEW_SUMMARY;
|
||||
DocPath filename = DocPaths.overviewSummary(configuration.frames);
|
||||
try {
|
||||
mdlgen = new ModuleIndexWriter(configuration, filename);
|
||||
mdlgen.buildModuleIndexFile("doclet.Window_Overview_Summary", true);
|
||||
|
@ -101,7 +101,7 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
|
||||
*/
|
||||
public static void generate(ConfigurationImpl configuration) {
|
||||
PackageIndexWriter packgen;
|
||||
DocPath filename = DocPaths.OVERVIEW_SUMMARY;
|
||||
DocPath filename = DocPaths.overviewSummary(configuration.frames);
|
||||
try {
|
||||
packgen = new PackageIndexWriter(configuration, filename);
|
||||
packgen.buildPackageIndexFile("doclet.Window_Overview_Summary", true);
|
||||
|
@ -833,13 +833,18 @@ public class HtmlTree extends Content {
|
||||
* Generates a UL tag with the style class attribute and some content.
|
||||
*
|
||||
* @param styleClass style for the tag
|
||||
* @param body content for the tag
|
||||
* @param first initial content to be added
|
||||
* @param more a series of additional content nodes to be added
|
||||
* @return an HtmlTree object for the UL tag
|
||||
*/
|
||||
public static HtmlTree UL(HtmlStyle styleClass, Content body) {
|
||||
HtmlTree htmltree = new HtmlTree(HtmlTag.UL, nullCheck(body));
|
||||
htmltree.addStyle(nullCheck(styleClass));
|
||||
return htmltree;
|
||||
public static HtmlTree UL(HtmlStyle styleClass, Content first, Content... more) {
|
||||
HtmlTree htmlTree = new HtmlTree(HtmlTag.UL);
|
||||
htmlTree.addContent(nullCheck(first));
|
||||
for (Content c : more) {
|
||||
htmlTree.addContent(nullCheck(c));
|
||||
}
|
||||
htmlTree.addStyle(nullCheck(styleClass));
|
||||
return htmlTree;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -299,6 +299,10 @@ doclet.usage.stylesheetfile.description=File to change style of the generated\n\
|
||||
doclet.usage.docencoding.parameters=<name>
|
||||
doclet.usage.docencoding.description=Specify the character encoding for the output
|
||||
|
||||
doclet.usage.frames.description=Enable the use of frames in the generated output (default)
|
||||
|
||||
doclet.usage.no-frames.description=Disable the use of frames in the generated output
|
||||
|
||||
doclet.xusage.xdocrootparent.parameters=<url>
|
||||
doclet.xusage.xdocrootparent.description=Replaces all @docRoot followed by /..\n\
|
||||
\ in doc comments with <url>
|
||||
|
@ -37,6 +37,8 @@ import javax.lang.model.element.ModuleElement;
|
||||
*
|
||||
*/
|
||||
public class DocPaths {
|
||||
/** The name of the file for all classes, without using frames, when --no-frames is specified. */
|
||||
public static final DocPath ALLCLASSES = DocPath.create("allclasses.html");
|
||||
|
||||
/** The name of the file for all classes, using frames. */
|
||||
public static final DocPath ALLCLASSES_FRAME = DocPath.create("allclasses-frame.html");
|
||||
@ -44,6 +46,10 @@ public class DocPaths {
|
||||
/** The name of the file for all classes, without using frames. */
|
||||
public static final DocPath ALLCLASSES_NOFRAME = DocPath.create("allclasses-noframe.html");
|
||||
|
||||
public static DocPath AllClasses(boolean frames) {
|
||||
return frames ? ALLCLASSES_NOFRAME : ALLCLASSES;
|
||||
}
|
||||
|
||||
/** The name of the sub-directory for storing class usage info. */
|
||||
public static final DocPath CLASS_USE = DocPath.create("class-use");
|
||||
|
||||
@ -121,6 +127,10 @@ public class DocPaths {
|
||||
/** The name of the file for the overview summary. */
|
||||
public static final DocPath OVERVIEW_SUMMARY = DocPath.create("overview-summary.html");
|
||||
|
||||
public static DocPath overviewSummary(boolean frames) {
|
||||
return frames ? OVERVIEW_SUMMARY : INDEX;
|
||||
}
|
||||
|
||||
/** The name of the file for the overview tree. */
|
||||
public static final DocPath OVERVIEW_TREE = DocPath.create("overview-tree.html");
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2016, 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
|
||||
@ -40,6 +40,7 @@ import java.lang.reflect.Method;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -157,7 +158,7 @@ public abstract class JavadocTester {
|
||||
private final Map<File,SoftReference<String>> fileContentCache = new HashMap<>();
|
||||
|
||||
/** Stream used for logging messages. */
|
||||
private final PrintStream out = System.out;
|
||||
protected final PrintStream out = System.out;
|
||||
|
||||
/** The directory containing the source code for the test. */
|
||||
public static final String testSrc = System.getProperty("test.src");
|
||||
@ -416,6 +417,17 @@ public abstract class JavadocTester {
|
||||
* @param paths the files to check, within the most recent output directory.
|
||||
* */
|
||||
public void checkFiles(boolean expectedFound, String... paths) {
|
||||
checkFiles(expectedFound, Arrays.asList(paths));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for files in (or not in) the generated output.
|
||||
* @param expectedFound true if all of the files are expected
|
||||
* to be found, or false if all of the files are expected to be
|
||||
* not found
|
||||
* @param paths the files to check, within the most recent output directory.
|
||||
* */
|
||||
public void checkFiles(boolean expectedFound, Collection<String> paths) {
|
||||
for (String path: paths) {
|
||||
// log.logCheckFile(path, expectedFound);
|
||||
checking("checkFile");
|
||||
@ -574,7 +586,7 @@ public abstract class JavadocTester {
|
||||
return content;
|
||||
|
||||
content = new String(Files.readAllBytes(file.toPath()));
|
||||
fileContentCache.put(file, new SoftReference(content));
|
||||
fileContentCache.put(file, new SoftReference<>(content));
|
||||
return content;
|
||||
} catch (FileNotFoundException e) {
|
||||
System.err.println(e);
|
||||
@ -613,16 +625,19 @@ public abstract class JavadocTester {
|
||||
* Print a summary of the test results.
|
||||
*/
|
||||
protected void printSummary() {
|
||||
// log.write();
|
||||
String javadocRuns = (javadocRunNum <= 1) ? ""
|
||||
: ", in " + javadocRunNum + " runs of javadoc";
|
||||
|
||||
if (numTestsRun != 0 && numTestsPassed == numTestsRun) {
|
||||
// Test passed
|
||||
out.println();
|
||||
out.println("All " + numTestsPassed + " subtests passed");
|
||||
out.println("All " + numTestsPassed + " subtests passed" + javadocRuns);
|
||||
} else {
|
||||
// Test failed
|
||||
throw new Error((numTestsRun - numTestsPassed)
|
||||
+ " of " + (numTestsRun)
|
||||
+ " subtests failed");
|
||||
+ " subtests failed"
|
||||
+ javadocRuns);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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
|
||||
* @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",
|
||||
"<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 {
|
||||
HTML4("-html4"),
|
||||
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()) {
|
||||
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<String> 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,
|
||||
"-modulesourcepath", gensrcModules.toString(),
|
||||
"-addmods", "m1,m2,m3", // TEMPORARY, SHOULD NOT BE NECESSARY
|
||||
"m1p1", "m1p2", "m1p3",
|
||||
"m2p1", "m2p2", "m2p3",
|
||||
"m3p1", "m3p2", "m3p3");
|
||||
|
||||
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<String> 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");
|
||||
}
|
||||
|
||||
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 + "-frame.html",
|
||||
m + "-type-frame.html").stream())
|
||||
.collect(Collectors.toSet()));
|
||||
|
||||
// <package>/package-frame.html files
|
||||
checkFiles(frames, classes.stream()
|
||||
.map(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,
|
||||
"<h2>Frames/No Frames</h2>");
|
||||
}
|
||||
|
||||
private void checkIndex() {
|
||||
// the index.html page only contains frames in frames mode
|
||||
checkOutput("index.html", frames,
|
||||
"<iframe ",
|
||||
"</iframe>");
|
||||
|
||||
// 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,
|
||||
"<table class=\"overviewSummary\"");
|
||||
|
||||
// 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(");
|
||||
|
||||
// the index.html file <meta> refresh should only use <noscript> in HTML 5
|
||||
if (!frames && !overview) {
|
||||
checkOutput("index.html", hKind == HtmlKind.HTML5,
|
||||
"<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()
|
||||
.map(c -> toHtml(packageClassPart(c)))
|
||||
.collect(Collectors.toSet()));
|
||||
for (String f : navbarFiles) {
|
||||
checkOutput(f, frames,
|
||||
"target=\"_top\">Frames</a>",
|
||||
"target=\"_top\">No Frames</a>");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOverviewSummary() {
|
||||
// the overview-summary.html file only appears if
|
||||
// in frames mode and (overview requested or multiple packages)
|
||||
checkFiles(frames && overview,
|
||||
"overview-summary.html");
|
||||
}
|
||||
|
||||
private long getPackageCount() {
|
||||
return this.classes.stream()
|
||||
.filter(name -> name.contains("."))
|
||||
.map(name -> name.substring(0, name.lastIndexOf(".")))
|
||||
.distinct()
|
||||
.count();
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
@ -165,7 +165,7 @@ public class ModuleBuilder {
|
||||
if (!comment.isEmpty()) {
|
||||
sb.append("/**\n").append(comment.replace("\n", " *")).append(" */\n");
|
||||
}
|
||||
sb.append("module ").append(name).append(" {");
|
||||
sb.append("module ").append(name).append(" {\n");
|
||||
requires.forEach(r -> sb.append(" " + r + "\n"));
|
||||
exports.forEach(e -> sb.append(" " + e + "\n"));
|
||||
uses.forEach(u -> sb.append(" " + u + "\n"));
|
||||
|
Loading…
Reference in New Issue
Block a user