001 /*
002 * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package com.sun.tools.doclets.formats.html;
027
028 import com.sun.tools.doclets.internal.toolkit.util.*;
029 import com.sun.javadoc.*;
030 import java.io.*;
031 import java.util.*;
032
033 /**
034 * Generate package usage information.
035 *
036 * @author Robert G. Field
037 */
038 public class PackageUseWriter extends SubWriterHolderWriter {
039
040 final PackageDoc pkgdoc;
041 final SortedMap<String,Set<ClassDoc>> usingPackageToUsedClasses = new TreeMap<String,Set<ClassDoc>>();
042
043 /**
044 * Constructor.
045 *
046 * @param filename the file to be generated.
047 * @throws IOException
048 * @throws DocletAbortException
049 */
050 public PackageUseWriter(ConfigurationImpl configuration,
051 ClassUseMapper mapper, String filename,
052 PackageDoc pkgdoc) throws IOException {
053 super(configuration, DirectoryManager.getDirectoryPath(pkgdoc),
054 filename,
055 DirectoryManager.getRelativePath(pkgdoc.name()));
056 this.pkgdoc = pkgdoc;
057
058 // by examining all classes in this package, find what packages
059 // use these classes - produce a map between using package and
060 // used classes.
061 ClassDoc[] content = pkgdoc.allClasses();
062 for (int i = 0; i < content.length; ++i) {
063 ClassDoc usedClass = content[i];
064 Set<ClassDoc> usingClasses = mapper.classToClass.get(usedClass.qualifiedName());
065 if (usingClasses != null) {
066 for (Iterator<ClassDoc> it = usingClasses.iterator(); it.hasNext(); ) {
067 ClassDoc usingClass = it.next();
068 PackageDoc usingPackage = usingClass.containingPackage();
069 Set<ClassDoc> usedClasses = usingPackageToUsedClasses
070 .get(usingPackage.name());
071 if (usedClasses == null) {
072 usedClasses = new TreeSet<ClassDoc>();
073 usingPackageToUsedClasses.put(Util.getPackageName(usingPackage),
074 usedClasses);
075 }
076 usedClasses.add(usedClass);
077 }
078 }
079 }
080 }
081
082 /**
083 * Generate a class page.
084 *
085 * @param configuration the current configuration of the doclet.
086 * @param mapper the mapping of the class usage.
087 * @param pkgdoc the package doc being documented.
088 */
089 public static void generate(ConfigurationImpl configuration,
090 ClassUseMapper mapper, PackageDoc pkgdoc) {
091 PackageUseWriter pkgusegen;
092 String filename = "package-use.html";
093 try {
094 pkgusegen = new PackageUseWriter(configuration,
095 mapper, filename, pkgdoc);
096 pkgusegen.generatePackageUseFile();
097 pkgusegen.close();
098 } catch (IOException exc) {
099 configuration.standardmessage.error(
100 "doclet.exception_encountered",
101 exc.toString(), filename);
102 throw new DocletAbortException();
103 }
104 }
105
106
107 /**
108 * Print the class use list.
109 */
110 protected void generatePackageUseFile() throws IOException {
111 printPackageUseHeader();
112
113 if (usingPackageToUsedClasses.isEmpty()) {
114 printText("doclet.ClassUse_No.usage.of.0", pkgdoc.name());
115 p();
116 } else {
117 generatePackageUse();
118 }
119
120 printPackageUseFooter();
121 }
122
123 /**
124 * Print the class use list.
125 */
126 protected void generatePackageUse() throws IOException {
127 if (configuration.packages.length > 1) {
128 generatePackageList();
129 }
130 generateClassList();
131 }
132
133 protected void generatePackageList() throws IOException {
134 tableIndexSummary();
135 tableHeaderStart("#CCCCFF");
136 printText("doclet.ClassUse_Packages.that.use.0",
137 getPackageLink(pkgdoc, Util.getPackageName(pkgdoc), false));
138 tableHeaderEnd();
139 Iterator<String> it = usingPackageToUsedClasses.keySet().iterator();
140 while (it.hasNext()) {
141 PackageDoc pkg = configuration.root.packageNamed(it.next());
142 generatePackageUse(pkg);
143 }
144 tableEnd();
145 space();
146 p();
147 }
148
149 protected void generateClassList() throws IOException {
150 Iterator<String> itp = usingPackageToUsedClasses.keySet().iterator();
151 while (itp.hasNext()) {
152 String packageName = itp.next();
153 PackageDoc usingPackage = configuration.root.packageNamed(packageName);
154 if (usingPackage != null) {
155 anchor(usingPackage.name());
156 }
157 tableIndexSummary();
158 tableHeaderStart("#CCCCFF");
159 printText("doclet.ClassUse_Classes.in.0.used.by.1",
160 getPackageLink(pkgdoc, Util.getPackageName(pkgdoc), false),
161 getPackageLink(usingPackage,Util.getPackageName(usingPackage), false));
162 tableHeaderEnd();
163 Iterator<ClassDoc> itc =
164 usingPackageToUsedClasses.get(packageName).iterator();
165 while (itc.hasNext()) {
166 printClassRow(itc.next(), packageName);
167 }
168 tableEnd();
169 space();
170 p();
171 }
172 }
173
174 protected void printClassRow(ClassDoc usedClass, String packageName) {
175 String path = pathString(usedClass,
176 "class-use/" + usedClass.name() + ".html");
177
178 trBgcolorStyle("white", "TableRowColor");
179 summaryRow(0);
180 strong();
181 printHyperLink(path, packageName, usedClass.name(), true);
182 strongEnd();
183 println(); br();
184 printNbsps();
185 printIndexComment(usedClass);
186 summaryRowEnd();
187 trEnd();
188 }
189
190 /**
191 * Print the package use list.
192 */
193 protected void generatePackageUse(PackageDoc pkg) throws IOException {
194 trBgcolorStyle("white", "TableRowColor");
195 summaryRow(0);
196 //Just want an anchor here.
197 printHyperLink("", pkg.name(), Util.getPackageName(pkg), true);
198 summaryRowEnd();
199 summaryRow(0);
200 if (pkg != null) {
201 printSummaryComment(pkg);
202 }
203 space();
204 summaryRowEnd();
205 trEnd();
206 }
207
208 /**
209 * Print the header for the class use Listing.
210 */
211 protected void printPackageUseHeader() {
212 String packageLabel = configuration.getText("doclet.Package");
213 String name = pkgdoc.name();
214 printHtmlHeader(configuration.getText("doclet.Window_ClassUse_Header",
215 packageLabel, name), null, true);
216 printTop();
217 navLinks(true);
218 hr();
219 center();
220 h2();
221 strongText("doclet.ClassUse_Title", packageLabel, name);
222 h2End();
223 centerEnd();
224 }
225
226 /**
227 * Print the footer for the class use Listing.
228 */
229 protected void printPackageUseFooter() {
230 hr();
231 navLinks(false);
232 printBottom();
233 printBodyHtmlEnd();
234 }
235
236
237 /**
238 * Print this package link
239 */
240 protected void navLinkPackage() {
241 navCellStart();
242 printHyperLink("package-summary.html", "", configuration.getText("doclet.Package"),
243 true, "NavBarFont1");
244 navCellEnd();
245 }
246
247 /**
248 * Print class use link
249 */
250 protected void navLinkClassUse() {
251 navCellRevStart();
252 fontStyle("NavBarFont1Rev");
253 strongText("doclet.navClassUse");
254 fontEnd();
255 navCellEnd();
256 }
257
258 protected void navLinkTree() {
259 navCellStart();
260 printHyperLink("package-tree.html", "", configuration.getText("doclet.Tree"),
261 true, "NavBarFont1");
262 navCellEnd();
263 }
264
265 }