# HG changeset patch # User bpatel # Date 1494637540 25200 # Node ID 18355c879c69a33167f1862896738a7b9a4da729 # Parent 77a2d6c1f32116be7454ac98f8be31c1603671b6 8178043: Support grouping modules in unified javadoc Reviewed-by: jjg, ksrini diff -r 77a2d6c1f321 -r 18355c879c69 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java Fri May 12 06:42:37 2017 +0200 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java Fri May 12 18:05:40 2017 -0700 @@ -25,6 +25,7 @@ package jdk.javadoc.internal.doclets.formats.html; +import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.SortedMap; @@ -101,7 +102,7 @@ * @param tableSummary summary for the table * @param body the document tree to which the modules list will be added */ - protected abstract void addModulesList(Map> modules, String text, + protected abstract void addModulesList(Collection modules, String text, String tableSummary, Content body); /** @@ -173,7 +174,7 @@ * @param body the document tree to which the index will be added */ protected void addIndex(Content body) { - addIndexContents(modules, "doclet.Module_Summary", + addIndexContents(configuration.modules, "doclet.Module_Summary", configuration.getText("doclet.Member_Table_Summary", configuration.getText("doclet.Module_Summary"), configuration.getText("doclet.modules")), body); @@ -201,7 +202,7 @@ * @param tableSummary summary for the table * @param body the document tree to which the index contents will be added */ - protected void addIndexContents(Map> modules, String text, + protected void addIndexContents(Collection modules, String text, String tableSummary, Content body) { HtmlTree htmlTree = (configuration.allowTag(HtmlTag.NAV)) ? HtmlTree.NAV() diff -r 77a2d6c1f321 -r 18355c879c69 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexFrameWriter.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexFrameWriter.java Fri May 12 06:42:37 2017 +0200 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexFrameWriter.java Fri May 12 18:05:40 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,6 +25,7 @@ package jdk.javadoc.internal.doclets.formats.html; +import java.util.Collection; import java.util.Map; import java.util.Set; @@ -81,7 +82,7 @@ /** * {@inheritDoc} */ - protected void addModulesList(Map> modules, String text, + protected void addModulesList(Collection modules, String text, String tableSummary, Content body) { Content heading = HtmlTree.HEADING(HtmlConstants.MODULE_HEADING, true, contents.modulesLabel); @@ -90,7 +91,7 @@ : HtmlTree.DIV(HtmlStyle.indexContainer, heading); HtmlTree ul = new HtmlTree(HtmlTag.UL); ul.setTitle(contents.modulesLabel); - for (ModuleElement mdle: modules.keySet()) { + for (ModuleElement mdle: modules) { ul.addContent(getModuleLink(mdle)); } htmlTree.addContent(ul); diff -r 77a2d6c1f321 -r 18355c879c69 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java Fri May 12 06:42:37 2017 +0200 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java Fri May 12 18:05:40 2017 -0700 @@ -30,7 +30,7 @@ import javax.lang.model.element.ModuleElement; import javax.lang.model.element.PackageElement; -import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; @@ -56,11 +56,16 @@ public class ModuleIndexWriter extends AbstractModuleIndexWriter { /** - * Set representing the modules. + * Map representing the group of modules as specified on the command line. * * @see Group */ - private final SortedSet modules; + private final Map> groupModuleMap; + + /** + * List to store the order groups as specified on the command line. + */ + private final List groupList; /** * HTML tree for main tag. @@ -74,7 +79,8 @@ */ public ModuleIndexWriter(ConfigurationImpl configuration, DocPath filename) { super(configuration, filename); - modules = configuration.modules; + groupModuleMap = configuration.group.groupModules(configuration.modules); + groupList = configuration.group.getGroupList(); } /** @@ -96,11 +102,13 @@ */ @Override protected void addIndex(Content body) { - if (modules != null && !modules.isEmpty()) { - addIndexContents(configuration.getText("doclet.Modules"), - configuration.getText("doclet.Member_Table_Summary", - configuration.getText("doclet.Module_Summary"), - configuration.getText("doclet.modules")), body); + for (String groupname : groupList) { + SortedSet list = groupModuleMap.get(groupname); + if (list != null && !list.isEmpty()) { + addIndexContents(list, + groupname, configuration.getText("doclet.Member_Table_Summary", + groupname, configuration.getText("doclet.modules")), body); + } } } @@ -111,7 +119,7 @@ * @param tableSummary summary for the table * @param body the document tree to which the index contents will be added */ - protected void addIndexContents(String title, String tableSummary, Content body) { + protected void addIndexContents(Collection modules, String title, String tableSummary, Content body) { HtmlTree htmltree = (configuration.allowTag(HtmlTag.NAV)) ? HtmlTree.NAV() : new HtmlTree(HtmlTag.DIV); @@ -123,7 +131,7 @@ } htmltree.addContent(ul); body.addContent(htmltree); - addModulesList(title, tableSummary, body); + addModulesList(modules, title, tableSummary, body); } /** @@ -133,15 +141,17 @@ * @param tableSummary the summary of the table tag * @param body the content tree to which the module list will be added */ - protected void addModulesList(String text, String tableSummary, Content body) { + protected void addModulesList(Collection modules, String text, String tableSummary, Content body) { Content table = (configuration.isOutputHtml5()) ? HtmlTree.TABLE(HtmlStyle.overviewSummary, getTableCaption(new RawHtml(text))) : HtmlTree.TABLE(HtmlStyle.overviewSummary, tableSummary, getTableCaption(new RawHtml(text))); table.addContent(getSummaryTableHeader(moduleTableHeader, "col")); Content tbody = new HtmlTree(HtmlTag.TBODY); - addModulesList(tbody); + addModulesList(modules, tbody); table.addContent(tbody); - Content div = HtmlTree.DIV(HtmlStyle.contentContainer, table); + Content anchor = getMarkerAnchor(text); + Content div = HtmlTree.DIV(HtmlStyle.contentContainer, anchor); + div.addContent(table); if (configuration.allowTag(HtmlTag.MAIN)) { htmlTree.addContent(div); } else { @@ -154,7 +164,7 @@ * * @param tbody the documentation tree to which the list will be added */ - protected void addModulesList(Content tbody) { + protected void addModulesList(Collection modules, Content tbody) { boolean altColor = true; for (ModuleElement mdle : modules) { if (!mdle.isUnnamed()) { @@ -260,9 +270,4 @@ protected void addModulePackagesList(Map> modules, String text, String tableSummary, Content body, ModuleElement mdle) { } - - @Override - protected void addModulesList(Map> modules, String text, - String tableSummary, Content body) { - } } diff -r 77a2d6c1f321 -r 18355c879c69 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModulePackageIndexFrameWriter.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModulePackageIndexFrameWriter.java Fri May 12 06:42:37 2017 +0200 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModulePackageIndexFrameWriter.java Fri May 12 18:05:40 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -26,6 +26,7 @@ package jdk.javadoc.internal.doclets.formats.html; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; @@ -175,7 +176,7 @@ protected void addOverviewHeader(Content body) { } - protected void addModulesList(Map> modules, String text, + protected void addModulesList(Collection modules, String text, String tableSummary, Content body) { } diff -r 77a2d6c1f321 -r 18355c879c69 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java Fri May 12 06:42:37 2017 +0200 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java Fri May 12 18:05:40 2017 -0700 @@ -29,11 +29,12 @@ import javax.lang.model.element.PackageElement; -import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 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.RawHtml; +import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; import jdk.javadoc.internal.doclets.toolkit.util.DocPath; @@ -112,8 +113,8 @@ SortedSet list = groupPackageMap.get(groupname); if (list != null && !list.isEmpty()) { addIndexContents(list, - groupname, configuration.getText("doclet.Member_Table_Summary", - groupname, configuration.getText("doclet.packages")), body); + groupname, configuration.getText("doclet.Member_Table_Summary", + groupname, configuration.getText("doclet.packages")), body); } } } @@ -131,7 +132,9 @@ Content tbody = new HtmlTree(HtmlTag.TBODY); addPackagesList(packages, tbody); table.addContent(tbody); - Content div = HtmlTree.DIV(HtmlStyle.contentContainer, table); + Content anchor = getMarkerAnchor(text); + Content div = HtmlTree.DIV(HtmlStyle.contentContainer, anchor); + div.addContent(table); if (configuration.allowTag(HtmlTag.MAIN)) { htmlTree.addContent(div); } else { diff -r 77a2d6c1f321 -r 18355c879c69 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Fri May 12 06:42:37 2017 +0200 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Fri May 12 18:05:40 2017 -0700 @@ -192,9 +192,9 @@ doclet.Window_ClassUse_Header=Uses of {0} {1} doclet.ClassUse_Title=Uses of {0} doclet.navClassUse=Use -doclet.Error_in_packagelist=Error in using -group option: {0} {1} -doclet.Groupname_already_used=In -group option, groupname already used: {0} -doclet.Same_package_name_used=Package name format used twice: {0} +doclet.Error_in_grouplist=Bad -group option: {0} {1} +doclet.Groupname_already_used=In -group option, group name already used: {0} +doclet.Same_element_name_used=Element name or pattern used twice: {0} # option specifiers doclet.usage.d.parameters=\ @@ -274,9 +274,9 @@ Exclude any doc-files subdirectories with given name doclet.usage.group.parameters=\ - :.. + :... doclet.usage.group.description=\ - Group specified packages together in overview page + Group specified elements together in overview page doclet.usage.nocomment.description=\ Suppress description and tags, generate only declarations diff -r 77a2d6c1f321 -r 18355c879c69 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Fri May 12 06:42:37 2017 +0200 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Fri May 12 18:05:40 2017 -0700 @@ -699,7 +699,11 @@ typeElementCatalog = new TypeElementCatalog(includedTypeElements, this); initTagletManager(customTagStrs); groups.stream().forEach((grp) -> { - group.checkPackageGroups(grp.value1, grp.value2); + if (showModules) { + group.checkModuleGroups(grp.value1, grp.value2); + } else { + group.checkPackageGroups(grp.value1, grp.value2); + } }); } diff -r 77a2d6c1f321 -r 18355c879c69 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties Fri May 12 06:42:37 2017 +0200 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties Fri May 12 18:05:40 2017 -0700 @@ -49,6 +49,7 @@ doclet.Packages=Packages doclet.Modules=Modules doclet.Other_Packages=Other Packages +doclet.Other_Modules=Other Modules doclet.Notice_taglet_registered=Registered Taglet {0} ... doclet.Notice_taglet_unseen=Note: Custom tags that were not seen: {0} doclet.Notice_taglet_overriden=Note: Custom tags that override standard tags: {0} diff -r 77a2d6c1f321 -r 18355c879c69 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Group.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Group.java Fri May 12 06:42:37 2017 +0200 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Group.java Fri May 12 18:05:40 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -27,7 +27,7 @@ import java.util.*; -import javax.lang.model.element.Element; +import javax.lang.model.element.ModuleElement; import javax.lang.model.element.PackageElement; import jdk.javadoc.internal.doclets.toolkit.Configuration; @@ -35,7 +35,7 @@ /** - * Process and manage grouping of packages, as specified by "-group" option on + * Process and manage grouping of elements, as specified by "-group" option on * the command line. *

* For example, if user has used -group option as @@ -79,10 +79,10 @@ private List groupList = new ArrayList<>(); /** - * Map of non-regular expressions(possible package names) with the + * Map of non-regular expressions(possible package or module names) with the * corresponding group name. */ - private Map pkgNameGroupMap = new HashMap<>(); + private Map elementNameGroupMap = new HashMap<>(); /** * The global configuration information for this run. @@ -107,11 +107,57 @@ } /** + * Depending upon the format of the module name provided in the "-group" + * option, generate two separate maps. There will be a map for mapping + * regular expression(only meta character allowed is '*' and that is at the + * end of the regular expression) on to the group name. And another map + * for mapping (possible) module names(if the name format doesn't contain + * meta character '*', then it is assumed to be a module name) on to the + * group name. This will also sort all the regular expressions found in the + * reverse order of their lengths, i.e. longest regular expression will be + * first in the sorted list. + * + * @param groupname The name of the group from -group option. + * @param moduleNameFormList List of the module name formats. + */ + public boolean checkModuleGroups(String groupname, String moduleNameFormList) { + String[] mdlPatterns = moduleNameFormList.split(":"); + if (groupList.contains(groupname)) { + initMessages(); + messages.warning("doclet.Groupname_already_used", groupname); + return false; + } + groupList.add(groupname); + for (String mdlPattern : mdlPatterns) { + if (mdlPattern.length() == 0) { + initMessages(); + messages.warning("doclet.Error_in_grouplist", groupname, moduleNameFormList); + return false; + } + if (mdlPattern.endsWith("*")) { + mdlPattern = mdlPattern.substring(0, mdlPattern.length() - 1); + if (foundGroupFormat(regExpGroupMap, mdlPattern)) { + return false; + } + regExpGroupMap.put(mdlPattern, groupname); + sortedRegExpList.add(mdlPattern); + } else { + if (foundGroupFormat(elementNameGroupMap, mdlPattern)) { + return false; + } + elementNameGroupMap.put(mdlPattern, groupname); + } + } + Collections.sort(sortedRegExpList, new MapKeyComparator()); + return true; + } + + /** * Depending upon the format of the package name provided in the "-group" * option, generate two separate maps. There will be a map for mapping * regular expression(only meta character allowed is '*' and that is at the * end of the regular expression) on to the group name. And another map - * for mapping (possible) package names(if the name format doesen't contain + * for mapping (possible) package names(if the name format doesn't contain * meta character '*', then it is assumed to be a package name) on to the * group name. This will also sort all the regular expressions found in the * reverse order of their lengths, i.e. longest regular expression will be @@ -121,32 +167,31 @@ * @param pkgNameFormList List of the package name formats. */ public boolean checkPackageGroups(String groupname, String pkgNameFormList) { - StringTokenizer strtok = new StringTokenizer(pkgNameFormList, ":"); + String[] pkgPatterns = pkgNameFormList.split(":"); if (groupList.contains(groupname)) { initMessages(); messages.warning("doclet.Groupname_already_used", groupname); return false; } groupList.add(groupname); - while (strtok.hasMoreTokens()) { - String id = strtok.nextToken(); - if (id.length() == 0) { + for (String pkgPattern : pkgPatterns) { + if (pkgPattern.length() == 0) { initMessages(); - messages.warning("doclet.Error_in_packagelist", groupname, pkgNameFormList); + messages.warning("doclet.Error_in_grouplist", groupname, pkgNameFormList); return false; } - if (id.endsWith("*")) { - id = id.substring(0, id.length() - 1); - if (foundGroupFormat(regExpGroupMap, id)) { + if (pkgPattern.endsWith("*")) { + pkgPattern = pkgPattern.substring(0, pkgPattern.length() - 1); + if (foundGroupFormat(regExpGroupMap, pkgPattern)) { return false; } - regExpGroupMap.put(id, groupname); - sortedRegExpList.add(id); + regExpGroupMap.put(pkgPattern, groupname); + sortedRegExpList.add(pkgPattern); } else { - if (foundGroupFormat(pkgNameGroupMap, id)) { + if (foundGroupFormat(elementNameGroupMap, pkgPattern)) { return false; } - pkgNameGroupMap.put(id, groupname); + elementNameGroupMap.put(pkgPattern, groupname); } } Collections.sort(sortedRegExpList, new MapKeyComparator()); @@ -162,39 +207,82 @@ } /** - * Search if the given map has given the package format. + * Search if the given map has the given element format. * * @param map Map to be searched. - * @param pkgFormat The pacakge format to search. + * @param elementFormat The format to search. * - * @return true if package name format found in the map, else false. + * @return true if element name format found in the map, else false. */ - boolean foundGroupFormat(Map map, String pkgFormat) { - if (map.containsKey(pkgFormat)) { + boolean foundGroupFormat(Map map, String elementFormat) { + if (map.containsKey(elementFormat)) { initMessages(); - messages.error("doclet.Same_package_name_used", pkgFormat); + messages.error("doclet.Same_element_name_used", elementFormat); return true; } return false; } /** + * Group the modules according the grouping information provided on the + * command line. Given a list of modules, search each module name in + * regular expression map as well as module name map to get the + * corresponding group name. Create another map with mapping of group name + * to the module list, which will fall under the specified group. If any + * module doesn't belong to any specified group on the command line, then + * a new group named "Other Modules" will be created for it. If there are + * no groups found, in other words if "-group" option is not at all used, + * then all the modules will be grouped under group "Modules". + * + * @param modules Specified modules. + * @return map of group names and set of module elements. + */ + public Map> groupModules(Set modules) { + Map> groupModuleMap = new HashMap<>(); + String defaultGroupName = + (elementNameGroupMap.isEmpty() && regExpGroupMap.isEmpty())? + configuration.getResources().getText("doclet.Modules") : + configuration.getResources().getText("doclet.Other_Modules"); + // if the user has not used the default group name, add it + if (!groupList.contains(defaultGroupName)) { + groupList.add(defaultGroupName); + } + for (ModuleElement mdl : modules) { + String moduleName = mdl.isUnnamed() ? null : mdl.getQualifiedName().toString(); + String groupName = mdl.isUnnamed() ? null : elementNameGroupMap.get(moduleName); + // if this module is not explicitly assigned to a group, + // try matching it to group specified by regular expression + if (groupName == null) { + groupName = regExpGroupName(moduleName); + } + // if it is in neither group map, put it in the default + // group + if (groupName == null) { + groupName = defaultGroupName; + } + getModuleList(groupModuleMap, groupName).add(mdl); + } + return groupModuleMap; + } + + /** * Group the packages according the grouping information provided on the * command line. Given a list of packages, search each package name in * regular expression map as well as package name map to get the * corresponding group name. Create another map with mapping of group name * to the package list, which will fall under the specified group. If any - * package doesen't belong to any specified group on the comamnd line, then + * package doesn't belong to any specified group on the command line, then * a new group named "Other Packages" will be created for it. If there are * no groups found, in other words if "-group" option is not at all used, * then all the packages will be grouped under group "Packages". * * @param packages Packages specified on the command line. + * @return map of group names and set of package elements */ public Map> groupPackages(Set packages) { Map> groupPackageMap = new HashMap<>(); String defaultGroupName = - (pkgNameGroupMap.isEmpty() && regExpGroupMap.isEmpty())? + (elementNameGroupMap.isEmpty() && regExpGroupMap.isEmpty())? configuration.getResources().getText("doclet.Packages") : configuration.getResources().getText("doclet.Other_Packages"); // if the user has not used the default group name, add it @@ -203,7 +291,7 @@ } for (PackageElement pkg : packages) { String pkgName = pkg.isUnnamed() ? null : configuration.utils.getPackageName(pkg); - String groupName = pkg.isUnnamed() ? null : pkgNameGroupMap.get(pkgName); + String groupName = pkg.isUnnamed() ? null : elementNameGroupMap.get(pkgName); // if this package is not explicitly assigned to a group, // try matching it to group specified by regular expression if (groupName == null) { @@ -220,15 +308,15 @@ } /** - * Search for package name in the sorted regular expression + * Search for element name in the sorted regular expression * list, if found return the group name. If not, return null. * - * @param pkgName Name of package to be found in the regular + * @param elementName Name of element to be found in the regular * expression list. */ - String regExpGroupName(String pkgName) { + String regExpGroupName(String elementName) { for (String regexp : sortedRegExpList) { - if (pkgName.startsWith(regexp)) { + if (elementName.startsWith(regexp)) { return regExpGroupMap.get(regexp); } } @@ -239,7 +327,7 @@ * For the given group name, return the package list, on which it is mapped. * Create a new list, if not found. * - * @param map Map to be searched for gorup name. + * @param map Map to be searched for group name. * @param groupname Group name to search. */ SortedSet getPkgList(Map> map, @@ -248,6 +336,18 @@ } /** + * For the given group name, return the module list, on which it is mapped. + * Create a new list, if not found. + * + * @param map Map to be searched for group name. + * @param groupname Group name to search. + */ + SortedSet getModuleList(Map> map, + String groupname) { + return map.computeIfAbsent(groupname, g -> new TreeSet<>(configuration.utils.makeModuleComparator())); + } + + /** * Return the list of groups, in the same order as specified * on the command line. */ diff -r 77a2d6c1f321 -r 18355c879c69 test/jdk/javadoc/doclet/testModules/TestModules.java --- a/test/jdk/javadoc/doclet/testModules/TestModules.java Fri May 12 06:42:37 2017 +0200 +++ b/test/jdk/javadoc/doclet/testModules/TestModules.java Fri May 12 18:05:40 2017 -0700 @@ -25,6 +25,7 @@ * @test * @bug 8154119 8154262 8156077 8157987 8154261 8154817 8135291 8155995 8162363 * 8168766 8168688 8162674 8160196 8175799 8174974 8176778 8177562 8175218 8175823 8166306 + * 8178043 * @summary Test modules support in javadoc. * @author bpatel * @library ../lib @@ -326,6 +327,54 @@ checkAllModulesLink(false); } + /** + * Test -group option for modules. The overview-summary.html page should group the modules accordingly. + */ + @Test + void testGroupOption() { + javadoc("-d", "out-group", "--show-module-contents=all", + "-tag", "regular:a:Regular Tag:", + "-tag", "moduletag:s:Module Tag:", + "--module-source-path", testSrc, + "-group", "Module Group A", "moduleA*", + "-group", "Module Group B & C", "moduleB*:moduleC*", + "-group", "Java SE Modules", "java*", + "--module", "moduleA,moduleB,moduleC,moduletags", + "moduleA/concealedpkgmdlA", "testpkgmdlA", "testpkg2mdlB", "testpkgmdlB", "testpkgmdlC", + "testpkgmdltags"); + checkExit(Exit.OK); + checkGroupOption(); + } + + /** + * Test -group option for unnamed modules. The overview-summary.html page should group the packages accordingly. + */ + @Test + void testUnnamedModuleGroupOption() { + javadoc("-d", "out-groupnomodule", "-use", + "-overview", testSrc("overview.html"), + "-sourcepath", testSrc, + "-group", "Package Group 0", "testpkgnomodule", + "-group", "Package Group 1", "testpkgnomodule1", + "testpkgnomodule", "testpkgnomodule1"); + checkExit(Exit.OK); + checkUnnamedModuleGroupOption(); + } + + /** + * Test -group option for a single module. + */ + @Test + void testGroupOptionSingleModule() { + javadoc("-d", "out-groupsinglemodule", "-use", + "--module-source-path", testSrc, + "-group", "Module Group B", "moduleB*", + "--module", "moduleB", + "testpkg2mdlB", "testpkgmdlB"); + checkExit(Exit.OK); + //checkOverviewSummaryPackages(); + } + void checkDescription(boolean found) { checkOutput("moduleA-summary.html", found, "\n" @@ -346,8 +395,10 @@ + "

\n" + "
The overview summary page header.
\n" + "
\n" - + "
\n" - + "\n" + + "
\n" + ""); checkOutput("overview-summary.html", false, "
Modules 
\n" @@ -355,8 +406,10 @@ + "
\n" + "
The overview summary page header.
\n" + "
\n" - + "
\n" - + "\n" + + "
\n" + ""); } @@ -405,7 +458,9 @@ + "
\n" + "
The overview summary page header.
\n" + "
\n" - + "
\n" + + "
Modules 
\n" + ""); checkOutput("overview-summary.html", false, @@ -416,7 +471,9 @@ + "
\n" + "
The overview summary page header.
\n" + "
\n" - + "
\n" + + "
Modules 
\n" + ""); } @@ -495,7 +552,7 @@ void checkOverviewSummaryModules() { checkOutput("overview-summary.html", true, - "
Modules 
\n" + "
\n" + "\n" + "\n" + "\n" @@ -512,7 +569,7 @@ void checkOverviewSummaryPackages() { checkOutput("overview-summary.html", false, - "
Modules 
Module
\n" + "
\n" + "\n" + "\n" + "\n" @@ -523,7 +580,9 @@ + "
\n" + "
The overview summary page header.
\n" + "
\n" - + "
\n" + + "
Modules 
Module
\n" + ""); checkOutput("overview-summary.html", true, @@ -537,7 +596,9 @@ + "
\n" + "
The overview summary page header.
\n" + "
\n" - + "
\n" + + "
Packages 
\n" + ""); } @@ -574,7 +635,9 @@ + "
\n" + "
The overview summary page header.
\n" + "
\n" - + "
\n" + + "
Packages 
\n" + ""); checkOutput("overview-summary.html", true, @@ -591,7 +654,9 @@ + "
\n" + "
The overview summary page header.
\n" + "
\n" - + "
\n" + + "
Packages 
\n" + ""); } @@ -974,4 +1039,54 @@ + "", ""); } + + void checkGroupOption() { + checkOutput("overview-summary.html", true, + "
Packages Concealed 
\n" + + "", + "
Module Group A 
\n" + + "", + "
Module Group B & C 
\n" + + ""); + checkOutput("overview-summary.html", false, + "
Other Modules 
\n" + + "", + "Java SE Modules"); + } + + void checkUnnamedModuleGroupOption() { + checkOutput("overview-summary.html", true, + "
Modules 
\n" + + "\n" + + "", + "
Package Group 0 
\n" + + ""); + } + + void checkGroupOptionSingleModule() { + checkOutput("overview-summary.html", true, + "
Package Group 1 
\n" + + ""); + checkOutput("overview-summary.html", false, + "
Module Group B 
\n" + + ""); + } }
Modules