src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Group.java

changeset 0
959103a6100f
child 2525
2eb010b6cb22
equal deleted inserted replaced
-1:000000000000 0:959103a6100f
1 /*
2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.doclets.internal.toolkit.util;
27
28 import java.util.*;
29
30 import com.sun.javadoc.*;
31 import com.sun.tools.doclets.internal.toolkit.*;
32
33 /**
34 * Process and manage grouping of packages, as specified by "-group" option on
35 * the command line.
36 * <p>
37 * For example, if user has used -group option as
38 * -group "Core Packages" "java.*" -group "CORBA Packages" "org.omg.*", then
39 * the packages specified on the command line will be grouped according to their
40 * names starting with either "java." or "org.omg.". All the other packages
41 * which do not fall in the user given groups, are grouped in default group,
42 * named as either "Other Packages" or "Packages" depending upon if "-group"
43 * option used or not at all used respectively.
44 * </p>
45 * <p>
46 * Also the packages are grouped according to the longest possible match of
47 * their names with the grouping information provided. For example, if there
48 * are two groups, like -group "Lang" "java.lang" and -group "Core" "java.*",
49 * will put the package java.lang in the group "Lang" and not in group "Core".
50 * </p>
51 *
52 * <p><b>This is NOT part of any supported API.
53 * If you write code that depends on this, you do so at your own risk.
54 * This code and its internal interfaces are subject to change or
55 * deletion without notice.</b>
56 *
57 * @author Atul M Dambalkar
58 */
59 public class Group {
60
61 /**
62 * Map of regular expressions with the corresponding group name.
63 */
64 private Map<String,String> regExpGroupMap = new HashMap<String,String>();
65
66 /**
67 * List of regular expressions sorted according to the length. Regular
68 * expression with longest length will be first in the sorted order.
69 */
70 private List<String> sortedRegExpList = new ArrayList<String>();
71
72 /**
73 * List of group names in the same order as given on the command line.
74 */
75 private List<String> groupList = new ArrayList<String>();
76
77 /**
78 * Map of non-regular expressions(possible package names) with the
79 * corresponding group name.
80 */
81 private Map<String,String> pkgNameGroupMap = new HashMap<String,String>();
82
83 /**
84 * The global configuration information for this run.
85 */
86 private final Configuration configuration;
87
88 /**
89 * Since we need to sort the keys in the reverse order(longest key first),
90 * the compare method in the implementing class is doing the reverse
91 * comparison.
92 */
93 private static class MapKeyComparator implements Comparator<String> {
94 public int compare(String key1, String key2) {
95 return key2.length() - key1.length();
96 }
97 }
98
99 public Group(Configuration configuration) {
100 this.configuration = configuration;
101 }
102
103 /**
104 * Depending upon the format of the package name provided in the "-group"
105 * option, generate two separate maps. There will be a map for mapping
106 * regular expression(only meta character allowed is '*' and that is at the
107 * end of the regular expression) on to the group name. And another map
108 * for mapping (possible) package names(if the name format doesen't contain
109 * meta character '*', then it is assumed to be a package name) on to the
110 * group name. This will also sort all the regular expressions found in the
111 * reverse order of their lengths, i.e. longest regular expression will be
112 * first in the sorted list.
113 *
114 * @param groupname The name of the group from -group option.
115 * @param pkgNameFormList List of the package name formats.
116 */
117 public boolean checkPackageGroups(String groupname,
118 String pkgNameFormList) {
119 StringTokenizer strtok = new StringTokenizer(pkgNameFormList, ":");
120 if (groupList.contains(groupname)) {
121 configuration.message.warning("doclet.Groupname_already_used", groupname);
122 return false;
123 }
124 groupList.add(groupname);
125 while (strtok.hasMoreTokens()) {
126 String id = strtok.nextToken();
127 if (id.length() == 0) {
128 configuration.message.warning("doclet.Error_in_packagelist", groupname, pkgNameFormList);
129 return false;
130 }
131 if (id.endsWith("*")) {
132 id = id.substring(0, id.length() - 1);
133 if (foundGroupFormat(regExpGroupMap, id)) {
134 return false;
135 }
136 regExpGroupMap.put(id, groupname);
137 sortedRegExpList.add(id);
138 } else {
139 if (foundGroupFormat(pkgNameGroupMap, id)) {
140 return false;
141 }
142 pkgNameGroupMap.put(id, groupname);
143 }
144 }
145 Collections.sort(sortedRegExpList, new MapKeyComparator());
146 return true;
147 }
148
149 /**
150 * Search if the given map has given the package format.
151 *
152 * @param map Map to be searched.
153 * @param pkgFormat The pacakge format to search.
154 *
155 * @return true if package name format found in the map, else false.
156 */
157 boolean foundGroupFormat(Map<String,?> map, String pkgFormat) {
158 if (map.containsKey(pkgFormat)) {
159 configuration.message.error("doclet.Same_package_name_used", pkgFormat);
160 return true;
161 }
162 return false;
163 }
164
165 /**
166 * Group the packages according the grouping information provided on the
167 * command line. Given a list of packages, search each package name in
168 * regular expression map as well as package name map to get the
169 * corresponding group name. Create another map with mapping of group name
170 * to the package list, which will fall under the specified group. If any
171 * package doesen't belong to any specified group on the comamnd line, then
172 * a new group named "Other Packages" will be created for it. If there are
173 * no groups found, in other words if "-group" option is not at all used,
174 * then all the packages will be grouped under group "Packages".
175 *
176 * @param packages Packages specified on the command line.
177 */
178 public Map<String,List<PackageDoc>> groupPackages(PackageDoc[] packages) {
179 Map<String,List<PackageDoc>> groupPackageMap = new HashMap<String,List<PackageDoc>>();
180 String defaultGroupName =
181 (pkgNameGroupMap.isEmpty() && regExpGroupMap.isEmpty())?
182 configuration.message.getText("doclet.Packages") :
183 configuration.message.getText("doclet.Other_Packages");
184 // if the user has not used the default group name, add it
185 if (!groupList.contains(defaultGroupName)) {
186 groupList.add(defaultGroupName);
187 }
188 for (int i = 0; i < packages.length; i++) {
189 PackageDoc pkg = packages[i];
190 String pkgName = pkg.name();
191 String groupName = pkgNameGroupMap.get(pkgName);
192 // if this package is not explicitly assigned to a group,
193 // try matching it to group specified by regular expression
194 if (groupName == null) {
195 groupName = regExpGroupName(pkgName);
196 }
197 // if it is in neither group map, put it in the default
198 // group
199 if (groupName == null) {
200 groupName = defaultGroupName;
201 }
202 getPkgList(groupPackageMap, groupName).add(pkg);
203 }
204 return groupPackageMap;
205 }
206
207 /**
208 * Search for package name in the sorted regular expression
209 * list, if found return the group name. If not, return null.
210 *
211 * @param pkgName Name of package to be found in the regular
212 * expression list.
213 */
214 String regExpGroupName(String pkgName) {
215 for (int j = 0; j < sortedRegExpList.size(); j++) {
216 String regexp = sortedRegExpList.get(j);
217 if (pkgName.startsWith(regexp)) {
218 return regExpGroupMap.get(regexp);
219 }
220 }
221 return null;
222 }
223
224 /**
225 * For the given group name, return the package list, on which it is mapped.
226 * Create a new list, if not found.
227 *
228 * @param map Map to be searched for gorup name.
229 * @param groupname Group name to search.
230 */
231 List<PackageDoc> getPkgList(Map<String,List<PackageDoc>> map, String groupname) {
232 List<PackageDoc> list = map.get(groupname);
233 if (list == null) {
234 list = new ArrayList<PackageDoc>();
235 map.put(groupname, list);
236 }
237 return list;
238 }
239
240 /**
241 * Return the list of groups, in the same order as specified
242 * on the command line.
243 */
244 public List<String> getGroupList() {
245 return groupList;
246 }
247 }

mercurial