# HG changeset patch # User ksrini # Date 1501279253 25200 # Node ID 059faa5e1267fbe3e723dd5fde53f355dfe5a2c8 # Parent 35994b07ed5e65bc8c9da80934888d094ff348ce 8184969: Cannot specify multiple -link to jdk9 javadoc Reviewed-by: jjg diff -r 35994b07ed5e -r 059faa5e1267 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java Fri Jul 28 14:29:29 2017 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java Fri Jul 28 15:00:53 2017 -0700 @@ -55,6 +55,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.SimpleDocletException; import jdk.javadoc.internal.doclets.toolkit.util.TypeElementCatalog; import jdk.javadoc.internal.doclets.toolkit.util.Utils; +import jdk.javadoc.internal.doclets.toolkit.util.Utils.Pair; import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap; import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.GetterSetter; import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.Kind; @@ -66,11 +67,11 @@ * BaseConfiguration, to configure and add their own options. This class contains * all user options which are supported by the 1.1 doclet and the standard * doclet. - * - *

This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own risk. - * This code and its internal interfaces are subject to change or - * deletion without notice. + *

+ *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. * * @author Robert Field. * @author Atul Dambalkar. @@ -240,7 +241,6 @@ /** * Sourcepath from where to read the source files. Default is classpath. - * */ public String sourcepath = ""; @@ -266,7 +266,7 @@ * True if user wants to suppress time stamp in output. * Default is false. */ - public boolean notimestamp= false; + public boolean notimestamp = false; /** * The package grouping instance. @@ -278,7 +278,7 @@ */ public final Extern extern = new Extern(this); - public Reporter reporter; + public Reporter reporter; public Locale locale; @@ -287,21 +287,21 @@ */ public boolean quiet = false; - private String urlForLink; - - private String pkglistUrlForLink; + // A list containing urls + private final List linkList = new ArrayList<>(); - private String urlForLinkOffline; + // A list of pairs containing urls and package list + private final List> linkOfflineList = new ArrayList<>(); - private String pkglistUrlForLinkOffline; public boolean dumpOnError = false; - private List groups; + private List> groupPairs; private final Map>> typeElementMemberCache; public abstract Messages getMessages(); + public abstract Resources getResources(); /** @@ -342,15 +342,17 @@ */ public SortedMap> modulePackages; - /** - * The list of known modules, that should be documented. - */ + /** + * The list of known modules, that should be documented. + */ public SortedSet modules; protected static final String sharedResourceBundleName = "jdk.javadoc.internal.doclets.toolkit.resources.doclets"; + /** * Constructs the configurations needed by the doclet. + * * @param doclet the doclet that created this configuration */ public BaseConfiguration(Doclet doclet) { @@ -359,7 +361,7 @@ excludedQualifiers = new HashSet<>(); setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH); metakeywords = new MetaKeywords(this); - groups = new ArrayList<>(0); + groupPairs = new ArrayList<>(0); typeElementMemberCache = new HashMap<>(); } @@ -400,31 +402,37 @@ } private Set specifiedModuleElements; + public Set getSpecifiedModuleElements() { return specifiedModuleElements; } private Set specifiedPackageElements; + public Set getSpecifiedPackageElements() { return specifiedPackageElements; } private Set specifiedTypeElements; + public Set getSpecifiedTypeElements() { return specifiedTypeElements; } private Set includedModuleElements; + public Set getIncludedModuleElements() { return includedModuleElements; } private Set includedPackageElements; + public Set getIncludedPackageElements() { return includedPackageElements; } private Set includedTypeElements; + public Set getIncludedTypeElements() { return includedTypeElements; } @@ -435,7 +443,7 @@ modules.addAll(getSpecifiedModuleElements()); modulePackages = new TreeMap<>(utils.makeModuleComparator()); - for (PackageElement p: packages) { + for (PackageElement p : packages) { ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p); if (mdle != null && !mdle.isUnnamed()) { Set s = modulePackages @@ -444,7 +452,7 @@ } } - for (PackageElement p: getIncludedPackageElements()) { + for (PackageElement p : getIncludedPackageElements()) { ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p); if (mdle != null && !mdle.isUnnamed()) { Set s = modulePackages @@ -474,207 +482,205 @@ public Set getSupportedOptions() { Resources resources = getResources(); Doclet.Option[] options = { - new Option(resources, "-author") { - @Override - public boolean process(String opt, List args) { - showauthor = true; - return true; - } - }, - new Option(resources, "-d", 1) { - @Override - public boolean process(String opt, List args) { - destDirName = addTrailingFileSep(args.get(0)); - return true; - } - }, - new Option(resources, "-docencoding", 1) { - @Override - public boolean process(String opt, List args) { - docencoding = args.get(0); - return true; - } - }, - new Option(resources, "-docfilessubdirs") { - @Override - public boolean process(String opt, List args) { - copydocfilesubdirs = true; - return true; - } - }, - new Hidden(resources, "-encoding", 1) { - @Override - public boolean process(String opt, List args) { - encoding = args.get(0); - return true; - } - }, - new Option(resources, "-excludedocfilessubdir", 1) { - @Override - public boolean process(String opt, List args) { - addToSet(excludedDocFileDirs, args.get(0)); - return true; - } - }, - new Option(resources, "-group", 2) { - @Override - public boolean process(String opt, List args) { - groups.add(new GroupContainer(args.get(0), args.get(1))); - return true; - } - }, - new Option(resources, "--javafx -javafx") { - @Override - public boolean process(String opt, List args) { - javafx = true; - return true; - } - }, - new Option(resources, "-keywords") { - @Override - public boolean process(String opt, List args) { - keywords = true; - return true; - } - }, - new Option(resources, "-link", 1) { - @Override - public boolean process(String opt, List args) { - urlForLink = args.get(0); - pkglistUrlForLink = urlForLink; - return true; - } - }, - new Option(resources, "-linksource") { - @Override - public boolean process(String opt, List args) { - linksource = true; - return true; - } - }, - new Option(resources, "-linkoffline", 2) { - @Override - public boolean process(String opt, List args) { - urlForLinkOffline = args.get(0); - pkglistUrlForLinkOffline = args.get(1); - return true; - } - }, - new Option(resources, "-nocomment") { - @Override - public boolean process(String opt, List args) { - nocomment = true; - return true; - } - }, - new Option(resources, "-nodeprecated") { - @Override - public boolean process(String opt, List args) { - nodeprecated = true; - return true; + new Option(resources, "-author") { + @Override + public boolean process(String opt, List args) { + showauthor = true; + return true; + } + }, + new Option(resources, "-d", 1) { + @Override + public boolean process(String opt, List args) { + destDirName = addTrailingFileSep(args.get(0)); + return true; + } + }, + new Option(resources, "-docencoding", 1) { + @Override + public boolean process(String opt, List args) { + docencoding = args.get(0); + return true; + } + }, + new Option(resources, "-docfilessubdirs") { + @Override + public boolean process(String opt, List args) { + copydocfilesubdirs = true; + return true; + } + }, + new Hidden(resources, "-encoding", 1) { + @Override + public boolean process(String opt, List args) { + encoding = args.get(0); + return true; + } + }, + new Option(resources, "-excludedocfilessubdir", 1) { + @Override + public boolean process(String opt, List args) { + addToSet(excludedDocFileDirs, args.get(0)); + return true; + } + }, + new Option(resources, "-group", 2) { + @Override + public boolean process(String opt, List args) { + groupPairs.add(new Pair<>(args.get(0), args.get(1))); + return true; + } + }, + new Option(resources, "--javafx -javafx") { + @Override + public boolean process(String opt, List args) { + javafx = true; + return true; + } + }, + new Option(resources, "-keywords") { + @Override + public boolean process(String opt, List args) { + keywords = true; + return true; + } + }, + new Option(resources, "-link", 1) { + @Override + public boolean process(String opt, List args) { + linkList.add(args.get(0)); + return true; + } + }, + new Option(resources, "-linksource") { + @Override + public boolean process(String opt, List args) { + linksource = true; + return true; + } + }, + new Option(resources, "-linkoffline", 2) { + @Override + public boolean process(String opt, List args) { + linkOfflineList.add(new Pair(args.get(0), args.get(1))); + return true; + } + }, + new Option(resources, "-nocomment") { + @Override + public boolean process(String opt, List args) { + nocomment = true; + return true; + } + }, + new Option(resources, "-nodeprecated") { + @Override + public boolean process(String opt, List args) { + nodeprecated = true; + return true; + } + }, + new Option(resources, "-nosince") { + @Override + public boolean process(String opt, List args) { + nosince = true; + return true; + } + }, + new Option(resources, "-notimestamp") { + @Override + public boolean process(String opt, List args) { + notimestamp = true; + return true; + } + }, + new Option(resources, "-noqualifier", 1) { + @Override + public boolean process(String opt, List args) { + addToSet(excludedQualifiers, args.get(0)); + return true; + } + }, + new Hidden(resources, "-quiet") { + @Override + public boolean process(String opt, List args) { + quiet = true; + return true; + } + }, + new Option(resources, "-serialwarn") { + @Override + public boolean process(String opt, List args) { + serialwarn = true; + return true; + } + }, + new Option(resources, "-sourcetab", 1) { + @Override + public boolean process(String opt, List args) { + linksource = true; + try { + setTabWidth(Integer.parseInt(args.get(0))); + } catch (NumberFormatException e) { + //Set to -1 so that warning will be printed + //to indicate what is valid argument. + sourcetab = -1; + } + if (sourcetab <= 0) { + getMessages().warning("doclet.sourcetab_warning"); + setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH); + } + return true; + } + }, + new Option(resources, "-tag", 1) { + @Override + public boolean process(String opt, List args) { + ArrayList list = new ArrayList<>(); + list.add(opt); + list.add(args.get(0)); + customTagStrs.add(list); + return true; + } + }, + new Option(resources, "-taglet", 1) { + @Override + public boolean process(String opt, List args) { + ArrayList list = new ArrayList<>(); + list.add(opt); + list.add(args.get(0)); + customTagStrs.add(list); + return true; + } + }, + new Option(resources, "-tagletpath", 1) { + @Override + public boolean process(String opt, List args) { + tagletpath = args.get(0); + return true; + } + }, + new Option(resources, "-version") { + @Override + public boolean process(String opt, List args) { + showversion = true; + return true; + } + }, + new Hidden(resources, "--dump-on-error") { + @Override + public boolean process(String opt, List args) { + dumpOnError = true; + return true; + } + }, + new Option(resources, "--allow-script-in-comments") { + @Override + public boolean process(String opt, List args) { + allowScriptInComments = true; + return true; + } } - }, - new Option(resources, "-nosince") { - @Override - public boolean process(String opt, List args) { - nosince = true; - return true; - } - }, - new Option(resources, "-notimestamp") { - @Override - public boolean process(String opt, List args) { - notimestamp = true; - return true; - } - }, - new Option(resources, "-noqualifier", 1) { - @Override - public boolean process(String opt, List args) { - addToSet(excludedQualifiers, args.get(0)); - return true; - } - }, - new Hidden(resources, "-quiet") { - @Override - public boolean process(String opt, List args) { - quiet = true; - return true; - } - }, - new Option(resources, "-serialwarn") { - @Override - public boolean process(String opt, List args) { - serialwarn = true; - return true; - } - }, - new Option(resources, "-sourcetab", 1) { - @Override - public boolean process(String opt, List args) { - linksource = true; - try { - setTabWidth(Integer.parseInt(args.get(0))); - } catch (NumberFormatException e) { - //Set to -1 so that warning will be printed - //to indicate what is valid argument. - sourcetab = -1; - } - if (sourcetab <= 0) { - getMessages().warning("doclet.sourcetab_warning"); - setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH); - } - return true; - } - }, - new Option(resources, "-tag", 1) { - @Override - public boolean process(String opt, List args) { - ArrayList list = new ArrayList<>(); - list.add(opt); - list.add(args.get(0)); - customTagStrs.add(list); - return true; - } - }, - new Option(resources, "-taglet", 1) { - @Override - public boolean process(String opt, List args) { - ArrayList list = new ArrayList<>(); - list.add(opt); - list.add(args.get(0)); - customTagStrs.add(list); - return true; - } - }, - new Option(resources, "-tagletpath", 1) { - @Override - public boolean process(String opt, List args) { - tagletpath = args.get(0); - return true; - } - }, - new Option(resources, "-version") { - @Override - public boolean process(String opt, List args) { - showversion = true; - return true; - } - }, - new Hidden(resources, "--dump-on-error") { - @Override - public boolean process(String opt, List args) { - dumpOnError = true; - return true; - } - }, - new Option(resources, "--allow-script-in-comments") { - @Override - public boolean process(String opt, List args) { - allowScriptInComments = true; - return true; - } - } }; Set set = new TreeSet<>(); set.addAll(Arrays.asList(options)); @@ -689,20 +695,22 @@ */ private void finishOptionSettings0() throws DocletException { initDestDirectory(); - if (urlForLink != null && pkglistUrlForLink != null) - extern.link(urlForLink, pkglistUrlForLink, reporter, false); - if (urlForLinkOffline != null && pkglistUrlForLinkOffline != null) - extern.link(urlForLinkOffline, pkglistUrlForLinkOffline, reporter, true); + for (String link : linkList) { + extern.link(link, reporter); + } + for (Pair linkOfflinePair : linkOfflineList) { + extern.link(linkOfflinePair.first, linkOfflinePair.second, reporter); + } if (docencoding == null) { docencoding = encoding; } typeElementCatalog = new TypeElementCatalog(includedTypeElements, this); initTagletManager(customTagStrs); - groups.stream().forEach((grp) -> { + groupPairs.stream().forEach((grp) -> { if (showModules) { - group.checkModuleGroups(grp.value1, grp.value2); + group.checkModuleGroups(grp.first, grp.second); } else { - group.checkPackageGroups(grp.value1, grp.value2); + group.checkPackageGroups(grp.first, grp.second); } }); } @@ -748,12 +756,12 @@ * be in the following format: "[tag name]:[location str]:[heading]". * * @param customTagStrs the set two dimensional arrays of strings. These arrays contain - * either -tag or -taglet arguments. + * either -tag or -taglet arguments. */ private void initTagletManager(Set> customTagStrs) { tagletManager = tagletManager == null ? - new TagletManager(nosince, showversion, showauthor, javafx, this) : - tagletManager; + new TagletManager(nosince, showversion, showauthor, javafx, this) : + tagletManager; for (List args : customTagStrs) { if (args.get(0).equals("-taglet")) { tagletManager.addCustomTag(args.get(1), getFileManager(), tagletpath); @@ -793,12 +801,11 @@ * @param maxTokens the maximum number of tokens returned. If the * max is reached, the remaining part of s is appended * to the end of the last token. - * * @return an array of tokens. */ private List tokenize(String s, char separator, int maxTokens) { List tokens = new ArrayList<>(); - StringBuilder token = new StringBuilder (); + StringBuilder token = new StringBuilder(); boolean prevIsEscapeChar = false; for (int i = 0; i < s.length(); i += Character.charCount(i)) { int currentChar = s.codePointAt(i); @@ -806,7 +813,7 @@ // Case 1: escaped character token.appendCodePoint(currentChar); prevIsEscapeChar = false; - } else if (currentChar == separator && tokens.size() < maxTokens-1) { + } else if (currentChar == separator && tokens.size() < maxTokens - 1) { // Case 2: separator tokens.add(token.toString()); token = new StringBuilder(); @@ -824,10 +831,10 @@ return tokens; } - private void addToSet(Set s, String str){ + private void addToSet(Set s, String str) { StringTokenizer st = new StringTokenizer(str, ":"); String current; - while(st.hasMoreTokens()){ + while (st.hasMoreTokens()) { current = st.nextToken(); s.add(current); } @@ -847,7 +854,7 @@ int indexDblfs; while ((indexDblfs = path.indexOf(dblfs, 1)) >= 0) { path = path.substring(0, indexDblfs) + - path.substring(indexDblfs + fs.length()); + path.substring(indexDblfs + fs.length()); } if (!path.endsWith(fs)) path += fs; @@ -855,7 +862,6 @@ } /** - * * This checks for the validity of the options used by the user. * As of this writing, this checks only docencoding. * @@ -883,7 +889,7 @@ * @param reporter used to report errors. */ private boolean checkOutputFileEncoding(String docencoding) { - OutputStream ost= new ByteArrayOutputStream(); + OutputStream ost = new ByteArrayOutputStream(); OutputStreamWriter osw = null; try { osw = new OutputStreamWriter(ost, docencoding); @@ -908,7 +914,7 @@ * @param docfilesubdir the doc-files subdirectory to check. * @return true if the directory is excluded. */ - public boolean shouldExcludeDocFileDir(String docfilesubdir){ + public boolean shouldExcludeDocFileDir(String docfilesubdir) { return excludedDocFileDirs.contains(docfilesubdir); } @@ -918,10 +924,10 @@ * @param qualifier the qualifier to check. * @return true if the qualifier should be excluded */ - public boolean shouldExcludeQualifier(String qualifier){ + public boolean shouldExcludeQualifier(String qualifier) { if (excludedQualifiers.contains("all") || - excludedQualifiers.contains(qualifier) || - excludedQualifiers.contains(qualifier + ".*")) { + excludedQualifiers.contains(qualifier) || + excludedQualifiers.contains(qualifier + ".*")) { return true; } else { int index = -1; @@ -956,7 +962,7 @@ * @param key the key for the desired string * @return the string for the given key * @throws MissingResourceException if the key is not found in either - * bundle. + * bundle. */ public abstract String getText(String key); @@ -965,11 +971,11 @@ * {@link Resources resources}. * Equivalent to getResources.getText(key, args);. * - * @param key the key for the desired string + * @param key the key for the desired string * @param args values to be substituted into the resulting string * @return the string for the given key * @throws MissingResourceException if the key is not found in either - * bundle. + * bundle. */ public abstract String getText(String key, String... args); @@ -997,8 +1003,8 @@ * {@link Resources resources} as a {@code Content} object. * * @param key the key for the desired string - * @param o1 resource argument - * @param o2 resource argument + * @param o1 resource argument + * @param o2 resource argument * @return a content tree for the text */ public abstract Content getContent(String key, Object o1, Object o2); @@ -1045,8 +1051,8 @@ */ public InputStream getBuilderXML() throws DocFileIOException { return builderXMLPath == null ? - BaseConfiguration.class.getResourceAsStream(DEFAULT_BUILDER_XML) : - DocFile.createFileForInput(this, builderXMLPath).openInputStream(); + BaseConfiguration.class.getResourceAsStream(DEFAULT_BUILDER_XML) : + DocFile.createFileForInput(this, builderXMLPath).openInputStream(); } /** @@ -1203,18 +1209,6 @@ } /* - * Stores a pair of Strings. - */ - protected static class GroupContainer { - final String value1; - final String value2; - public GroupContainer(String value1, String value2) { - this.value1 = value1; - this.value2 = value2; - } - } - - /* * Splits the elements in a collection to its individual * collection. */ @@ -1267,6 +1261,7 @@ /** * Returns whether or not to allow JavaScript in comments. * Default is off; can be set true from a command line option. + * * @return the allowScriptInComments */ public boolean isAllowScriptInComments() { diff -r 35994b07ed5e -r 059faa5e1267 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java Fri Jul 28 14:29:29 2017 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java Fri Jul 28 15:00:53 2017 -0700 @@ -170,6 +170,36 @@ } /** + * Build the extern package list from given URL or the directory path, + * as specified with the "-link" flag. + * Flag error if the "-link" or "-linkoffline" option is already used. + * + * @param url URL or Directory path. + * @param reporter The DocErrorReporter used to report errors. + * @return true if successful, false otherwise + * @throws DocFileIOException if there is a problem reading a package list file + */ + public boolean link(String url, Reporter reporter) throws DocFileIOException { + return link(url, url, reporter, false); + } + + /** + * Build the extern package list from given URL or the directory path, + * as specified with the "-linkoffline" flag. + * Flag error if the "-link" or "-linkoffline" option is already used. + * + * @param url URL or Directory path. + * @param pkglisturl This can be another URL for "package-list" or ordinary + * file. + * @param reporter The DocErrorReporter used to report errors. + * @return true if successful, false otherwise + * @throws DocFileIOException if there is a problem reading a package list file + */ + public boolean link(String url, String pkglisturl, Reporter reporter) throws DocFileIOException { + return link(url, pkglisturl, reporter, true); + } + + /* * Build the extern package list from given URL or the directory path. * Flag error if the "-link" or "-linkoffline" option is already used. * @@ -181,7 +211,7 @@ * @return true if successful, false otherwise * @throws DocFileIOException if there is a problem reading a package list file */ - public boolean link(String url, String pkglisturl, Reporter reporter, boolean linkoffline) + private boolean link(String url, String pkglisturl, Reporter reporter, boolean linkoffline) throws DocFileIOException { this.linkoffline = linkoffline; try { @@ -245,8 +275,7 @@ readPackageList(link.openStream(), urlpath, false); } catch (URISyntaxException | MalformedURLException exc) { throw new Fault(configuration.getText("doclet.MalformedURL", pkglisturlpath.toString()), exc); - } - catch (IOException exc) { + } catch (IOException exc) { throw new Fault(configuration.getText("doclet.URL_error", pkglisturlpath.toString()), exc); } } diff -r 35994b07ed5e -r 059faa5e1267 langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Fri Jul 28 14:29:29 2017 -0700 +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Fri Jul 28 15:00:53 2017 -0700 @@ -3328,4 +3328,19 @@ return out; } } + + /** + * A simple pair container. + * @param first a value + * @param second another value + */ + public static class Pair { + public final K first; + public final L second; + + public Pair(K first, L second) { + this.first = first; + this.second = second; + } + } } diff -r 35994b07ed5e -r 059faa5e1267 langtools/test/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java --- a/langtools/test/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java Fri Jul 28 14:29:29 2017 -0700 +++ b/langtools/test/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java Fri Jul 28 15:00:53 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4720957 5020118 8026567 8038976 + * @bug 4720957 5020118 8026567 8038976 8184969 * @summary Test to make sure that -link and -linkoffline link to * right files, and URLs with and without trailing slash are accepted. * @author jamieh @@ -135,6 +135,46 @@ // this is the text that is given when there is a problem with a URL checkOutput(Output.OUT, false, "warning - Error fetching URL"); + + // check multiple link options + javadoc("-d", "out5", + "-sourcepath", testSrc, + "-link", "../" + "out1", + "-link", "../" + "out2", + "pkg3"); + checkExit(Exit.OK); + checkOutput("pkg3/A.html", true, + "

public class A\n"
+                + "extends java.lang.Object
\n" + + "
Test links.\n" + + "
\n" + + " link to pkg2.C2\n" + + "
\n" + + " " + + "link to mylib.lang.StringBuilderChild.
\n" + ); + + // check multiple linkoffline options + javadoc("-d", "out6", + "-sourcepath", testSrc, + "-linkoffline", "../copy/out1", "out1", + "-linkoffline", "../copy/out2", "out2", + "pkg3"); + checkExit(Exit.OK); + checkOutput("pkg3/A.html", true, + "
public class A\n"
+                        + "extends java.lang.Object
\n" + + "
Test links.\n" + + "
\n" + + " link to pkg2.C2\n" + + "
\n" + + " " + + "link to mylib.lang.StringBuilderChild.
\n" + ); } /* diff -r 35994b07ed5e -r 059faa5e1267 langtools/test/jdk/javadoc/doclet/testLinkOption/pkg3/A.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/jdk/javadoc/doclet/testLinkOption/pkg3/A.java Fri Jul 28 15:00:53 2017 -0700 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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. + */ + +package pkg3; + +/** + * Test links. + *
+ * {@link pkg2.C2 link to pkg2.C2} + *
+ * {@link mylib.lang.StringBuilderChild link to mylib.lang.StringBuilderChild}. + */ + +public class A {}