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    }