001: /*
002: * Copyright 1998-2005 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 class usage information.
035: *
036: * @author Robert G. Field
037: */
038: public class ClassUseWriter extends SubWriterHolderWriter {
039:
040: final ClassDoc classdoc;
041: Set pkgToPackageAnnotations = null;
042: final Map pkgToClassTypeParameter;
043: final Map pkgToClassAnnotations;
044: final Map pkgToMethodTypeParameter;
045: final Map pkgToMethodArgTypeParameter;
046: final Map pkgToMethodReturnTypeParameter;
047: final Map pkgToMethodAnnotations;
048: final Map pkgToMethodParameterAnnotations;
049: final Map pkgToFieldTypeParameter;
050: final Map pkgToFieldAnnotations;
051: final Map pkgToSubclass;
052: final Map pkgToSubinterface;
053: final Map pkgToImplementingClass;
054: final Map pkgToField;
055: final Map pkgToMethodReturn;
056: final Map pkgToMethodArgs;
057: final Map pkgToMethodThrows;
058: final Map pkgToConstructorAnnotations;
059: final Map pkgToConstructorParameterAnnotations;
060: final Map pkgToConstructorArgs;
061: final Map pkgToConstructorArgTypeParameter;
062: final Map pkgToConstructorThrows;
063: final SortedSet pkgSet;
064: final MethodWriterImpl methodSubWriter;
065: final ConstructorWriterImpl constrSubWriter;
066: final FieldWriterImpl fieldSubWriter;
067: final NestedClassWriterImpl classSubWriter;
068:
069: /**
070: * Constructor.
071: *
072: * @param filename the file to be generated.
073: * @throws IOException
074: * @throws DocletAbortException
075: */
076: public ClassUseWriter(ConfigurationImpl configuration,
077: ClassUseMapper mapper, String path, String filename,
078: String relpath, ClassDoc classdoc) throws IOException {
079: super (configuration, path, filename, relpath);
080: this .classdoc = classdoc;
081: if (mapper.classToPackageAnnotations.containsKey(classdoc
082: .qualifiedName()))
083: pkgToPackageAnnotations = new HashSet(
084: (List) mapper.classToPackageAnnotations
085: .get(classdoc.qualifiedName()));
086: configuration.currentcd = classdoc;
087: this .pkgSet = new TreeSet();
088: this .pkgToClassTypeParameter = pkgDivide(mapper.classToClassTypeParam);
089: this .pkgToClassAnnotations = pkgDivide(mapper.classToClassAnnotations);
090: this .pkgToMethodTypeParameter = pkgDivide(mapper.classToExecMemberDocTypeParam);
091: this .pkgToMethodArgTypeParameter = pkgDivide(mapper.classToExecMemberDocArgTypeParam);
092: this .pkgToFieldTypeParameter = pkgDivide(mapper.classToFieldDocTypeParam);
093: this .pkgToFieldAnnotations = pkgDivide(mapper.annotationToFieldDoc);
094: this .pkgToMethodReturnTypeParameter = pkgDivide(mapper.classToExecMemberDocReturnTypeParam);
095: this .pkgToMethodAnnotations = pkgDivide(mapper.classToExecMemberDocAnnotations);
096: this .pkgToMethodParameterAnnotations = pkgDivide(mapper.classToExecMemberDocParamAnnotation);
097: this .pkgToSubclass = pkgDivide(mapper.classToSubclass);
098: this .pkgToSubinterface = pkgDivide(mapper.classToSubinterface);
099: this .pkgToImplementingClass = pkgDivide(mapper.classToImplementingClass);
100: this .pkgToField = pkgDivide(mapper.classToField);
101: this .pkgToMethodReturn = pkgDivide(mapper.classToMethodReturn);
102: this .pkgToMethodArgs = pkgDivide(mapper.classToMethodArgs);
103: this .pkgToMethodThrows = pkgDivide(mapper.classToMethodThrows);
104: this .pkgToConstructorAnnotations = pkgDivide(mapper.classToConstructorAnnotations);
105: this .pkgToConstructorParameterAnnotations = pkgDivide(mapper.classToConstructorParamAnnotation);
106: this .pkgToConstructorArgs = pkgDivide(mapper.classToConstructorArgs);
107: this .pkgToConstructorArgTypeParameter = pkgDivide(mapper.classToConstructorDocArgTypeParam);
108: this .pkgToConstructorThrows = pkgDivide(mapper.classToConstructorThrows);
109: //tmp test
110: if (pkgSet.size() > 0
111: && mapper.classToPackage.containsKey(classdoc
112: .qualifiedName())
113: && !pkgSet.equals(mapper.classToPackage.get(classdoc
114: .qualifiedName()))) {
115: configuration.root
116: .printWarning("Internal error: package sets don't match: "
117: + pkgSet
118: + " with: "
119: + mapper.classToPackage.get(classdoc
120: .qualifiedName()));
121: }
122: methodSubWriter = new MethodWriterImpl(this );
123: constrSubWriter = new ConstructorWriterImpl(this );
124: fieldSubWriter = new FieldWriterImpl(this );
125: classSubWriter = new NestedClassWriterImpl(this );
126: }
127:
128: /**
129: * Write out class use pages.
130: * @throws DocletAbortException
131: */
132: public static void generate(ConfigurationImpl configuration,
133: ClassTree classtree) {
134: ClassUseMapper mapper = new ClassUseMapper(configuration.root,
135: classtree);
136: ClassDoc[] classes = configuration.root.classes();
137: for (int i = 0; i < classes.length; i++) {
138: ClassUseWriter.generate(configuration, mapper, classes[i]);
139: }
140: PackageDoc[] pkgs = configuration.packages;
141: for (int i = 0; i < pkgs.length; i++) {
142: PackageUseWriter.generate(configuration, mapper, pkgs[i]);
143: }
144: }
145:
146: private Map pkgDivide(Map classMap) {
147: Map map = new HashMap();
148: List list = (List) classMap.get(classdoc.qualifiedName());
149: if (list != null) {
150: Collections.sort(list);
151: Iterator it = list.iterator();
152: while (it.hasNext()) {
153: ProgramElementDoc doc = (ProgramElementDoc) it.next();
154: PackageDoc pkg = doc.containingPackage();
155: pkgSet.add(pkg);
156: List inPkg = (List) map.get(pkg.name());
157: if (inPkg == null) {
158: inPkg = new ArrayList();
159: map.put(pkg.name(), inPkg);
160: }
161: inPkg.add(doc);
162: }
163: }
164: return map;
165: }
166:
167: /**
168: * Generate a class page.
169: */
170: public static void generate(ConfigurationImpl configuration,
171: ClassUseMapper mapper, ClassDoc classdoc) {
172: ClassUseWriter clsgen;
173: String path = DirectoryManager.getDirectoryPath(classdoc
174: .containingPackage());
175: if (path.length() > 0) {
176: path += File.separator;
177: }
178: path += "class-use";
179: String filename = classdoc.name() + ".html";
180: String pkgname = classdoc.containingPackage().name();
181: pkgname += (pkgname.length() > 0) ? ".class-use" : "class-use";
182: String relpath = DirectoryManager.getRelativePath(pkgname);
183: try {
184: clsgen = new ClassUseWriter(configuration, mapper, path,
185: filename, relpath, classdoc);
186: clsgen.generateClassUseFile();
187: clsgen.close();
188: } catch (IOException exc) {
189: configuration.standardmessage.error(
190: "doclet.exception_encountered", exc.toString(),
191: filename);
192: throw new DocletAbortException();
193: }
194: }
195:
196: /**
197: * Print the class use list.
198: */
199: protected void generateClassUseFile() throws IOException {
200:
201: printClassUseHeader();
202:
203: if (pkgSet.size() > 0) {
204: generateClassUse();
205: } else {
206: printText("doclet.ClassUse_No.usage.of.0", classdoc
207: .qualifiedName());
208: p();
209: }
210:
211: printClassUseFooter();
212: }
213:
214: protected void generateClassUse() throws IOException {
215: if (configuration.packages.length > 1) {
216: generatePackageList();
217: generatePackageAnnotationList();
218: }
219: generateClassList();
220: }
221:
222: protected void generatePackageList() throws IOException {
223: tableIndexSummary();
224: tableHeaderStart("#CCCCFF");
225: printText("doclet.ClassUse_Packages.that.use.0",
226: getLink(new LinkInfoImpl(
227: LinkInfoImpl.CONTEXT_CLASS_USE_HEADER,
228: classdoc, false)));
229: tableHeaderEnd();
230:
231: for (Iterator it = pkgSet.iterator(); it.hasNext();) {
232: PackageDoc pkg = (PackageDoc) it.next();
233: generatePackageUse(pkg);
234: }
235: tableEnd();
236: space();
237: p();
238: }
239:
240: protected void generatePackageAnnotationList() throws IOException {
241: if ((!classdoc.isAnnotationType())
242: || pkgToPackageAnnotations == null
243: || pkgToPackageAnnotations.size() == 0)
244: return;
245: tableIndexSummary();
246: tableHeaderStart("#CCCCFF");
247: printText("doclet.ClassUse_PackageAnnotation",
248: getLink(new LinkInfoImpl(
249: LinkInfoImpl.CONTEXT_CLASS_USE_HEADER,
250: classdoc, false)));
251: tableHeaderEnd();
252: for (Iterator it = pkgToPackageAnnotations.iterator(); it
253: .hasNext();) {
254: PackageDoc pkg = (PackageDoc) it.next();
255: trBgcolorStyle("white", "TableRowColor");
256: summaryRow(0);
257: //Just want an anchor here.
258: printPackageLink(pkg, pkg.name(), true);
259: summaryRowEnd();
260: summaryRow(0);
261: printSummaryComment(pkg);
262: space();
263: summaryRowEnd();
264: trEnd();
265: }
266: tableEnd();
267: space();
268: p();
269: }
270:
271: protected void generateClassList() throws IOException {
272: for (Iterator it = pkgSet.iterator(); it.hasNext();) {
273: PackageDoc pkg = (PackageDoc) it.next();
274: anchor(pkg.name());
275: tableIndexSummary();
276: tableHeaderStart("#CCCCFF");
277: printText("doclet.ClassUse_Uses.of.0.in.1",
278: getLink(new LinkInfoImpl(
279: LinkInfoImpl.CONTEXT_CLASS_USE_HEADER,
280: classdoc, false)), getPackageLink(pkg, Util
281: .getPackageName(pkg), false));
282: tableHeaderEnd();
283: tableEnd();
284: space();
285: p();
286: generateClassUse(pkg);
287: }
288: }
289:
290: /**
291: * Print the package use list.
292: */
293: protected void generatePackageUse(PackageDoc pkg)
294: throws IOException {
295: trBgcolorStyle("white", "TableRowColor");
296: summaryRow(0);
297: //Just want an anchor here.
298: printHyperLink("", pkg.name(), Util.getPackageName(pkg), true);
299: summaryRowEnd();
300: summaryRow(0);
301: printSummaryComment(pkg);
302: space();
303: summaryRowEnd();
304: trEnd();
305: }
306:
307: /**
308: * Print the class use list.
309: */
310: protected void generateClassUse(PackageDoc pkg) throws IOException {
311: String classLink = getLink(new LinkInfoImpl(
312: LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc, false));
313: String pkgLink = getPackageLink(pkg, Util.getPackageName(pkg),
314: false);
315: classSubWriter.printUseInfo(pkgToClassAnnotations.get(pkg
316: .name()), configuration.getText(
317: "doclet.ClassUse_Annotation", classLink, pkgLink));
318:
319: classSubWriter.printUseInfo(pkgToClassTypeParameter.get(pkg
320: .name()), configuration.getText(
321: "doclet.ClassUse_TypeParameter", classLink, pkgLink));
322: classSubWriter.printUseInfo(pkgToSubclass.get(pkg.name()),
323: configuration.getText("doclet.ClassUse_Subclass",
324: classLink, pkgLink));
325: classSubWriter.printUseInfo(pkgToSubinterface.get(pkg.name()),
326: configuration.getText("doclet.ClassUse_Subinterface",
327: classLink, pkgLink));
328: classSubWriter.printUseInfo(pkgToImplementingClass.get(pkg
329: .name()), configuration
330: .getText("doclet.ClassUse_ImplementingClass",
331: classLink, pkgLink));
332: fieldSubWriter.printUseInfo(pkgToField.get(pkg.name()),
333: configuration.getText("doclet.ClassUse_Field",
334: classLink, pkgLink));
335: fieldSubWriter
336: .printUseInfo(pkgToFieldAnnotations.get(pkg.name()),
337: configuration.getText(
338: "doclet.ClassUse_FieldAnnotations",
339: classLink, pkgLink));
340: fieldSubWriter.printUseInfo(pkgToFieldTypeParameter.get(pkg
341: .name()), configuration.getText(
342: "doclet.ClassUse_FieldTypeParameter", classLink,
343: pkgLink));
344: methodSubWriter.printUseInfo(pkgToMethodAnnotations.get(pkg
345: .name()), configuration
346: .getText("doclet.ClassUse_MethodAnnotations",
347: classLink, pkgLink));
348: methodSubWriter.printUseInfo(pkgToMethodParameterAnnotations
349: .get(pkg.name()), configuration.getText(
350: "doclet.ClassUse_MethodParameterAnnotations",
351: classLink, pkgLink));
352: methodSubWriter.printUseInfo(pkgToMethodTypeParameter.get(pkg
353: .name()), configuration.getText(
354: "doclet.ClassUse_MethodTypeParameter", classLink,
355: pkgLink));
356: methodSubWriter.printUseInfo(pkgToMethodReturn.get(pkg.name()),
357: configuration.getText("doclet.ClassUse_MethodReturn",
358: classLink, pkgLink));
359: methodSubWriter.printUseInfo(pkgToMethodReturnTypeParameter
360: .get(pkg.name()), configuration.getText(
361: "doclet.ClassUse_MethodReturnTypeParameter", classLink,
362: pkgLink));
363: methodSubWriter.printUseInfo(pkgToMethodArgs.get(pkg.name()),
364: configuration.getText("doclet.ClassUse_MethodArgs",
365: classLink, pkgLink));
366: methodSubWriter.printUseInfo(pkgToMethodArgTypeParameter
367: .get(pkg.name()), configuration.getText(
368: "doclet.ClassUse_MethodArgsTypeParameters", classLink,
369: pkgLink));
370: methodSubWriter.printUseInfo(pkgToMethodThrows.get(pkg.name()),
371: configuration.getText("doclet.ClassUse_MethodThrows",
372: classLink, pkgLink));
373: constrSubWriter.printUseInfo(pkgToConstructorAnnotations
374: .get(pkg.name()), configuration.getText(
375: "doclet.ClassUse_ConstructorAnnotations", classLink,
376: pkgLink));
377: constrSubWriter
378: .printUseInfo(
379: pkgToConstructorParameterAnnotations.get(pkg
380: .name()),
381: configuration
382: .getText(
383: "doclet.ClassUse_ConstructorParameterAnnotations",
384: classLink, pkgLink));
385: constrSubWriter.printUseInfo(pkgToConstructorArgs.get(pkg
386: .name()), configuration.getText(
387: "doclet.ClassUse_ConstructorArgs", classLink, pkgLink));
388: constrSubWriter.printUseInfo(pkgToConstructorArgTypeParameter
389: .get(pkg.name()), configuration.getText(
390: "doclet.ClassUse_ConstructorArgsTypeParameters",
391: classLink, pkgLink));
392: constrSubWriter.printUseInfo(pkgToConstructorThrows.get(pkg
393: .name()), configuration
394: .getText("doclet.ClassUse_ConstructorThrows",
395: classLink, pkgLink));
396: }
397:
398: /**
399: * Print the header for the class use Listing.
400: */
401: protected void printClassUseHeader() {
402: String cltype = configuration
403: .getText(classdoc.isInterface() ? "doclet.Interface"
404: : "doclet.Class");
405: String clname = classdoc.qualifiedName();
406: printHtmlHeader(configuration.getText(
407: "doclet.Window_ClassUse_Header", cltype, clname), null,
408: true);
409: printTop();
410: navLinks(true);
411: hr();
412: center();
413: h2();
414: boldText("doclet.ClassUse_Title", cltype, clname);
415: h2End();
416: centerEnd();
417: }
418:
419: /**
420: * Print the footer for the class use Listing.
421: */
422: protected void printClassUseFooter() {
423: hr();
424: navLinks(false);
425: printBottom();
426: printBodyHtmlEnd();
427: }
428:
429: /**
430: * Print this package link
431: */
432: protected void navLinkPackage() {
433: navCellStart();
434: printHyperLink("../package-summary.html", "", configuration
435: .getText("doclet.Package"), true, "NavBarFont1");
436: navCellEnd();
437: }
438:
439: /**
440: * Print class page indicator
441: */
442: protected void navLinkClass() {
443: navCellStart();
444: printLink(new LinkInfoImpl(
445: LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc, "",
446: configuration.getText("doclet.Class"), true,
447: "NavBarFont1"));
448: navCellEnd();
449: }
450:
451: /**
452: * Print class use link
453: */
454: protected void navLinkClassUse() {
455: navCellRevStart();
456: fontStyle("NavBarFont1Rev");
457: boldText("doclet.navClassUse");
458: fontEnd();
459: navCellEnd();
460: }
461:
462: protected void navLinkTree() {
463: navCellStart();
464: if (classdoc.containingPackage().isIncluded()) {
465: printHyperLink("../package-tree.html", "", configuration
466: .getText("doclet.Tree"), true, "NavBarFont1");
467: } else {
468: printHyperLink(relativePath + "overview-tree.html", "",
469: configuration.getText("doclet.Tree"), true,
470: "NavBarFont1");
471: }
472: navCellEnd();
473: }
474:
475: }
|