Fri, 05 Oct 2012 14:16:32 -0700
7068595: html files in class-use dir do not get loaded correctly when Frames link is clicked
Reviewed-by: jjg
1 /*
2 * Copyright (c) 1998, 2011, 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 */
26 package com.sun.tools.doclets.formats.html;
28 import java.io.*;
29 import java.util.*;
30 import com.sun.javadoc.*;
31 import com.sun.tools.doclets.internal.toolkit.util.*;
32 import com.sun.tools.doclets.formats.html.markup.*;
33 import com.sun.tools.doclets.internal.toolkit.*;
35 /**
36 * Generate package usage information.
37 *
38 * @author Robert G. Field
39 * @author Bhavesh Patel (Modified)
40 */
41 public class PackageUseWriter extends SubWriterHolderWriter {
43 final PackageDoc pkgdoc;
44 final SortedMap<String,Set<ClassDoc>> usingPackageToUsedClasses = new TreeMap<String,Set<ClassDoc>>();
46 /**
47 * Constructor.
48 *
49 * @param filename the file to be generated.
50 * @throws IOException
51 * @throws DocletAbortException
52 */
53 public PackageUseWriter(ConfigurationImpl configuration,
54 ClassUseMapper mapper, String filename,
55 PackageDoc pkgdoc) throws IOException {
56 super(configuration, DirectoryManager.getDirectoryPath(pkgdoc),
57 filename,
58 DirectoryManager.getRelativePath(pkgdoc.name()));
59 this.pkgdoc = pkgdoc;
61 // by examining all classes in this package, find what packages
62 // use these classes - produce a map between using package and
63 // used classes.
64 ClassDoc[] content = pkgdoc.allClasses();
65 for (int i = 0; i < content.length; ++i) {
66 ClassDoc usedClass = content[i];
67 Set<ClassDoc> usingClasses = mapper.classToClass.get(usedClass.qualifiedName());
68 if (usingClasses != null) {
69 for (Iterator<ClassDoc> it = usingClasses.iterator(); it.hasNext(); ) {
70 ClassDoc usingClass = it.next();
71 PackageDoc usingPackage = usingClass.containingPackage();
72 Set<ClassDoc> usedClasses = usingPackageToUsedClasses
73 .get(usingPackage.name());
74 if (usedClasses == null) {
75 usedClasses = new TreeSet<ClassDoc>();
76 usingPackageToUsedClasses.put(Util.getPackageName(usingPackage),
77 usedClasses);
78 }
79 usedClasses.add(usedClass);
80 }
81 }
82 }
83 }
85 /**
86 * Generate a class page.
87 *
88 * @param configuration the current configuration of the doclet.
89 * @param mapper the mapping of the class usage.
90 * @param pkgdoc the package doc being documented.
91 */
92 public static void generate(ConfigurationImpl configuration,
93 ClassUseMapper mapper, PackageDoc pkgdoc) {
94 PackageUseWriter pkgusegen;
95 String filename = "package-use.html";
96 try {
97 pkgusegen = new PackageUseWriter(configuration,
98 mapper, filename, pkgdoc);
99 pkgusegen.generatePackageUseFile();
100 pkgusegen.close();
101 } catch (IOException exc) {
102 configuration.standardmessage.error(
103 "doclet.exception_encountered",
104 exc.toString(), filename);
105 throw new DocletAbortException();
106 }
107 }
110 /**
111 * Generate the package use list.
112 */
113 protected void generatePackageUseFile() throws IOException {
114 Content body = getPackageUseHeader();
115 HtmlTree div = new HtmlTree(HtmlTag.DIV);
116 div.addStyle(HtmlStyle.contentContainer);
117 if (usingPackageToUsedClasses.isEmpty()) {
118 div.addContent(getResource(
119 "doclet.ClassUse_No.usage.of.0", pkgdoc.name()));
120 } else {
121 addPackageUse(div);
122 }
123 body.addContent(div);
124 addNavLinks(false, body);
125 addBottom(body);
126 printHtmlDocument(null, true, body);
127 }
129 /**
130 * Add the package use information.
131 *
132 * @param contentTree the content tree to which the package use information will be added
133 */
134 protected void addPackageUse(Content contentTree) throws IOException {
135 HtmlTree ul = new HtmlTree(HtmlTag.UL);
136 ul.addStyle(HtmlStyle.blockList);
137 if (configuration.packages.length > 1) {
138 addPackageList(ul);
139 }
140 addClassList(ul);
141 contentTree.addContent(ul);
142 }
144 /**
145 * Add the list of packages that use the given package.
146 *
147 * @param contentTree the content tree to which the package list will be added
148 */
149 protected void addPackageList(Content contentTree) throws IOException {
150 Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
151 getTableCaption(configuration().getText(
152 "doclet.ClassUse_Packages.that.use.0",
153 getPackageLinkString(pkgdoc, Util.getPackageName(pkgdoc), false))));
154 table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
155 Content tbody = new HtmlTree(HtmlTag.TBODY);
156 Iterator<String> it = usingPackageToUsedClasses.keySet().iterator();
157 for (int i = 0; it.hasNext(); i++) {
158 PackageDoc pkg = configuration.root.packageNamed(it.next());
159 HtmlTree tr = new HtmlTree(HtmlTag.TR);
160 if (i % 2 == 0) {
161 tr.addStyle(HtmlStyle.altColor);
162 } else {
163 tr.addStyle(HtmlStyle.rowColor);
164 }
165 addPackageUse(pkg, tr);
166 tbody.addContent(tr);
167 }
168 table.addContent(tbody);
169 Content li = HtmlTree.LI(HtmlStyle.blockList, table);
170 contentTree.addContent(li);
171 }
173 /**
174 * Add the list of classes that use the given package.
175 *
176 * @param contentTree the content tree to which the class list will be added
177 */
178 protected void addClassList(Content contentTree) throws IOException {
179 String[] classTableHeader = new String[] {
180 configuration.getText("doclet.0_and_1",
181 configuration.getText("doclet.Class"),
182 configuration.getText("doclet.Description"))
183 };
184 Iterator<String> itp = usingPackageToUsedClasses.keySet().iterator();
185 while (itp.hasNext()) {
186 String packageName = itp.next();
187 PackageDoc usingPackage = configuration.root.packageNamed(packageName);
188 HtmlTree li = new HtmlTree(HtmlTag.LI);
189 li.addStyle(HtmlStyle.blockList);
190 if (usingPackage != null) {
191 li.addContent(getMarkerAnchor(usingPackage.name()));
192 }
193 String tableSummary = configuration.getText("doclet.Use_Table_Summary",
194 configuration.getText("doclet.classes"));
195 Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
196 getTableCaption(configuration().getText(
197 "doclet.ClassUse_Classes.in.0.used.by.1",
198 getPackageLinkString(pkgdoc, Util.getPackageName(pkgdoc), false),
199 getPackageLinkString(usingPackage,Util.getPackageName(usingPackage), false))));
200 table.addContent(getSummaryTableHeader(classTableHeader, "col"));
201 Content tbody = new HtmlTree(HtmlTag.TBODY);
202 Iterator<ClassDoc> itc =
203 usingPackageToUsedClasses.get(packageName).iterator();
204 for (int i = 0; itc.hasNext(); i++) {
205 HtmlTree tr = new HtmlTree(HtmlTag.TR);
206 if (i % 2 == 0) {
207 tr.addStyle(HtmlStyle.altColor);
208 } else {
209 tr.addStyle(HtmlStyle.rowColor);
210 }
211 addClassRow(itc.next(), packageName, tr);
212 tbody.addContent(tr);
213 }
214 table.addContent(tbody);
215 li.addContent(table);
216 contentTree.addContent(li);
217 }
218 }
220 /**
221 * Add a row for the class that uses the given package.
222 *
223 * @param usedClass the class that uses the given package
224 * @param packageName the name of the package to which the class belongs
225 * @param contentTree the content tree to which the row will be added
226 */
227 protected void addClassRow(ClassDoc usedClass, String packageName,
228 Content contentTree) {
229 String path = pathString(usedClass,
230 "class-use/" + usedClass.name() + ".html");
231 Content td = HtmlTree.TD(HtmlStyle.colOne,
232 getHyperLink(path, packageName, new StringContent(usedClass.name())));
233 addIndexComment(usedClass, td);
234 contentTree.addContent(td);
235 }
237 /**
238 * Add the package use information.
239 *
240 * @param pkg the package that used the given package
241 * @param contentTree the content tree to which the information will be added
242 */
243 protected void addPackageUse(PackageDoc pkg, Content contentTree) throws IOException {
244 Content tdFirst = HtmlTree.TD(HtmlStyle.colFirst,
245 getHyperLink("", Util.getPackageName(pkg),
246 new RawHtml(Util.getPackageName(pkg))));
247 contentTree.addContent(tdFirst);
248 HtmlTree tdLast = new HtmlTree(HtmlTag.TD);
249 tdLast.addStyle(HtmlStyle.colLast);
250 if (pkg != null && pkg.name().length() != 0) {
251 addSummaryComment(pkg, tdLast);
252 } else {
253 tdLast.addContent(getSpace());
254 }
255 contentTree.addContent(tdLast);
256 }
258 /**
259 * Get the header for the package use listing.
260 *
261 * @return a content tree representing the package use header
262 */
263 protected Content getPackageUseHeader() {
264 String packageText = configuration.getText("doclet.Package");
265 String name = pkgdoc.name();
266 String title = configuration.getText("doclet.Window_ClassUse_Header",
267 packageText, name);
268 Content bodyTree = getBody(true, getWindowTitle(title));
269 addTop(bodyTree);
270 addNavLinks(true, bodyTree);
271 Content headContent = getResource("doclet.ClassUse_Title", packageText, name);
272 Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
273 HtmlStyle.title, headContent);
274 Content div = HtmlTree.DIV(HtmlStyle.header, heading);
275 bodyTree.addContent(div);
276 return bodyTree;
277 }
279 /**
280 * Get this package link.
281 *
282 * @return a content tree for the package link
283 */
284 protected Content getNavLinkPackage() {
285 Content linkContent = getHyperLink("package-summary.html", "",
286 packageLabel);
287 Content li = HtmlTree.LI(linkContent);
288 return li;
289 }
291 /**
292 * Get the use link.
293 *
294 * @return a content tree for the use link
295 */
296 protected Content getNavLinkClassUse() {
297 Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, useLabel);
298 return li;
299 }
301 /**
302 * Get the tree link.
303 *
304 * @return a content tree for the tree link
305 */
306 protected Content getNavLinkTree() {
307 Content linkContent = getHyperLink("package-tree.html", "",
308 treeLabel);
309 Content li = HtmlTree.LI(linkContent);
310 return li;
311 }
312 }