--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,600 @@
+/*
+ * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.doclets.formats.html;
+
+import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.*;
+import com.sun.tools.doclets.internal.toolkit.builders.*;
+import com.sun.javadoc.*;
+
+import java.util.*;
+import com.sun.tools.doclets.internal.toolkit.taglets.*;
+
+/**
+ * Generate the Class Information Page.
+ * @see com.sun.javadoc.ClassDoc
+ * @see java.util.Collections
+ * @see java.util.List
+ * @see java.util.ArrayList
+ * @see java.util.HashMap
+ *
+ * @author Atul M Dambalkar
+ * @author Robert Field
+ */
+public class ClassWriterImpl extends SubWriterHolderWriter
+ implements ClassWriter {
+
+ protected ClassDoc classDoc;
+
+ protected ClassTree classtree;
+
+ protected ClassDoc prev;
+
+ protected ClassDoc next;
+
+ /**
+ * @param classDoc the class being documented.
+ * @param prevClass the previous class that was documented.
+ * @param nextClass the next class being documented.
+ * @param classTree the class tree for the given class.
+ */
+ public ClassWriterImpl (ClassDoc classDoc,
+ ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
+ throws Exception {
+ super(ConfigurationImpl.getInstance(),
+ DirectoryManager.getDirectoryPath(classDoc.containingPackage()),
+ classDoc.name() + ".html",
+ DirectoryManager.getRelativePath(classDoc.containingPackage().name()));
+ this.classDoc = classDoc;
+ configuration.currentcd = classDoc;
+ this.classtree = classTree;
+ this.prev = prevClass;
+ this.next = nextClass;
+ }
+
+ /**
+ * Print this package link
+ */
+ protected void navLinkPackage() {
+ navCellStart();
+ printHyperLink("package-summary.html", "",
+ configuration.getText("doclet.Package"), true, "NavBarFont1");
+ navCellEnd();
+ }
+
+ /**
+ * Print class page indicator
+ */
+ protected void navLinkClass() {
+ navCellRevStart();
+ fontStyle("NavBarFont1Rev");
+ boldText("doclet.Class");
+ fontEnd();
+ navCellEnd();
+ }
+
+ /**
+ * Print class use link
+ */
+ protected void navLinkClassUse() {
+ navCellStart();
+ printHyperLink("class-use/" + filename, "",
+ configuration.getText("doclet.navClassUse"), true, "NavBarFont1");
+ navCellEnd();
+ }
+
+ /**
+ * Print previous package link
+ */
+ protected void navLinkPrevious() {
+ if (prev == null) {
+ printText("doclet.Prev_Class");
+ } else {
+ printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, prev, "",
+ configuration.getText("doclet.Prev_Class"), true));
+ }
+ }
+
+ /**
+ * Print next package link
+ */
+ protected void navLinkNext() {
+ if (next == null) {
+ printText("doclet.Next_Class");
+ } else {
+ printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, next, "",
+ configuration.getText("doclet.Next_Class"), true));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeHeader(String header) {
+ String pkgname = (classDoc.containingPackage() != null)?
+ classDoc.containingPackage().name(): "";
+ String clname = classDoc.name();
+ printHtmlHeader(clname,
+ configuration.metakeywords.getMetaKeywords(classDoc), true);
+ printTop();
+ navLinks(true);
+ hr();
+ println("<!-- ======== START OF CLASS DATA ======== -->");
+ h2();
+ if (pkgname.length() > 0) {
+ font("-1"); print(pkgname); fontEnd(); br();
+ }
+ LinkInfoImpl linkInfo = new LinkInfoImpl( LinkInfoImpl.CONTEXT_CLASS_HEADER,
+ classDoc, false);
+ //Let's not link to ourselves in the header.
+ linkInfo.linkToSelf = false;
+ print(header + getTypeParameterLinks(linkInfo));
+ h2End();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeFooter() {
+ println("<!-- ========= END OF CLASS DATA ========= -->");
+ hr();
+ navLinks(false);
+ printBottom();
+ printBodyHtmlEnd();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeClassSignature(String modifiers) {
+ boolean isInterface = classDoc.isInterface();
+ dl();
+ dt();
+ preNoNewLine();
+ writeAnnotationInfo(classDoc);
+ print(modifiers);
+ LinkInfoImpl linkInfo = new LinkInfoImpl(
+ LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, classDoc, false);
+ //Let's not link to ourselves in the signature.
+ linkInfo.linkToSelf = false;
+ String name = classDoc.name() +
+ getTypeParameterLinks(linkInfo);
+ if (configuration().linksource) {
+ printSrcLink(classDoc, name);
+ } else {
+ bold(name);
+ }
+ if (!isInterface) {
+ Type superclass = Util.getFirstVisibleSuperClass(classDoc,
+ configuration());
+ if (superclass != null) {
+ dt();
+ print("extends ");
+ printLink(new LinkInfoImpl(
+ LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
+ superclass));
+ }
+ }
+ Type[] implIntfacs = classDoc.interfaceTypes();
+ if (implIntfacs != null && implIntfacs.length > 0) {
+ int counter = 0;
+ for (int i = 0; i < implIntfacs.length; i++) {
+ ClassDoc classDoc = implIntfacs[i].asClassDoc();
+ if (! (classDoc.isPublic() ||
+ Util.isLinkable(classDoc, configuration()))) {
+ continue;
+ }
+ if (counter == 0) {
+ dt();
+ print(isInterface? "extends " : "implements ");
+ } else {
+ print(", ");
+ }
+ printLink(new LinkInfoImpl(
+ LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
+ implIntfacs[i]));
+ counter++;
+ }
+ }
+ dlEnd();
+ preEnd();
+ p();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeClassDescription() {
+ if(!configuration.nocomment) {
+ // generate documentation for the class.
+ if (classDoc.inlineTags().length > 0) {
+ printInlineComment(classDoc);
+ p();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeClassTagInfo() {
+ if(!configuration.nocomment) {
+ // Print Information about all the tags here
+ printTags(classDoc);
+ hr();
+ p();
+ } else {
+ hr();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeClassDeprecationInfo() {
+ hr();
+ Tag[] deprs = classDoc.tags("deprecated");
+ if (Util.isDeprecated(classDoc)) {
+ boldText("doclet.Deprecated");
+ if (deprs.length > 0) {
+ Tag[] commentTags = deprs[0].inlineTags();
+ if (commentTags.length > 0) {
+ space();
+ printInlineDeprecatedComment(classDoc, deprs[0]);
+ }
+ }
+ p();
+ }
+ }
+
+ /**
+ * Generate the indent and get the line image for the class tree.
+ * For user accessibility, the image includes the alt attribute
+ * "extended by". (This method is not intended for a class
+ * implementing an interface, where "implemented by" would be required.)
+ *
+ * indent integer indicating the number of spaces to indent
+ */
+ private void writeStep(int indent) {
+ print(spaces(4 * indent - 2));
+ print("<IMG SRC=\"" + relativepathNoSlash + "/resources/inherit.gif\" " +
+ "ALT=\"" + configuration.getText("doclet.extended_by") + " \">");
+ }
+
+ /**
+ * Print the class hierarchy tree for the given class.
+ * @param type the class to print the hierarchy for.
+ * @return return the amount that should be indented in
+ * the next level of the tree.
+ */
+ private int writeTreeForClassHelper(Type type) {
+ Type sup = Util.getFirstVisibleSuperClass(
+ type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(),
+ configuration());
+ int indent = 0;
+ if (sup != null) {
+ indent = writeTreeForClassHelper(sup);
+ writeStep(indent);
+ }
+
+ if (type.equals(classDoc)) {
+ String typeParameters = getTypeParameterLinks(
+ new LinkInfoImpl(
+ LinkInfoImpl.CONTEXT_TREE,
+ classDoc, false));
+ if (configuration.shouldExcludeQualifier(
+ classDoc.containingPackage().name())) {
+ bold(type.asClassDoc().name() + typeParameters);
+ } else {
+ bold(type.asClassDoc().qualifiedName() + typeParameters);
+ }
+ } else {
+ print(getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS_TREE_PARENT,
+ type instanceof ClassDoc ? (ClassDoc) type : type,
+ configuration.getClassName(type.asClassDoc()), false)));
+ }
+ println();
+ return indent + 1;
+ }
+
+ /**
+ * Print the class hierarchy tree for this class only.
+ */
+ public void writeClassTree() {
+ if (! classDoc.isClass()) {
+ return;
+ }
+ pre();
+ writeTreeForClassHelper(classDoc);
+ preEnd();
+ }
+
+ /**
+ * Write the type parameter information.
+ */
+ public void writeTypeParamInfo() {
+ if (classDoc.typeParamTags().length > 0) {
+ dl();
+ dt();
+ TagletOutput output = (new ParamTaglet()).getTagletOutput(classDoc,
+ getTagletWriterInstance(false));
+ print(output.toString());
+ dlEnd();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeSubClassInfo() {
+ if (classDoc.isClass()) {
+ if (classDoc.qualifiedName().equals("java.lang.Object") ||
+ classDoc.qualifiedName().equals("org.omg.CORBA.Object")) {
+ return; // Don't generate the list, too huge
+ }
+ List subclasses = classtree.subs(classDoc, false);
+ if (subclasses.size() > 0) {
+ dl();
+ dt();
+ boldText("doclet.Subclasses");
+ writeClassLinks(LinkInfoImpl.CONTEXT_SUBCLASSES,
+ subclasses);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeSubInterfacesInfo() {
+ if (classDoc.isInterface()) {
+ List subInterfaces = classtree.allSubs(classDoc, false);
+ if (subInterfaces.size() > 0) {
+ dl();
+ dt();
+ boldText("doclet.Subinterfaces");
+ writeClassLinks(LinkInfoImpl.CONTEXT_SUBINTERFACES,
+ subInterfaces);
+ }
+ }
+ }
+
+ /**
+ * If this is the interface which are the classes, that implement this?
+ */
+ public void writeInterfaceUsageInfo () {
+ if (! classDoc.isInterface()) {
+ return;
+ }
+ if (classDoc.qualifiedName().equals("java.lang.Cloneable") ||
+ classDoc.qualifiedName().equals("java.io.Serializable")) {
+ return; // Don't generate the list, too big
+ }
+ List implcl = classtree.implementingclasses(classDoc);
+ if (implcl.size() > 0) {
+ dl();
+ dt();
+ boldText("doclet.Implementing_Classes");
+ writeClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_CLASSES,
+ implcl);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeImplementedInterfacesInfo() {
+ //NOTE: we really should be using ClassDoc.interfaceTypes() here, but
+ // it doesn't walk up the tree like we want it to.
+ List interfaceArray = Util.getAllInterfaces(classDoc, configuration);
+ if (classDoc.isClass() && interfaceArray.size() > 0) {
+ dl();
+ dt();
+ boldText("doclet.All_Implemented_Interfaces");
+ writeClassLinks(LinkInfoImpl.CONTEXT_IMPLEMENTED_INTERFACES,
+ interfaceArray);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void writeSuperInterfacesInfo() {
+ //NOTE: we really should be using ClassDoc.interfaceTypes() here, but
+ // it doesn't walk up the tree like we want it to.
+ List interfaceArray = Util.getAllInterfaces(classDoc, configuration);
+ if (classDoc.isInterface() && interfaceArray.size() > 0) {
+ dl();
+ dt();
+ boldText("doclet.All_Superinterfaces");
+ writeClassLinks(LinkInfoImpl.CONTEXT_SUPER_INTERFACES,
+ interfaceArray);
+ }
+ }
+
+ /**
+ * Generate links to the given classes.
+ */
+ private void writeClassLinks(int context, List list) {
+ Object[] typeList = list.toArray();
+ //Sort the list to be printed.
+ print(' ');
+ dd();
+ for (int i = 0; i < list.size(); i++) {
+ if (i > 0) {
+ print(", ");
+ }
+ if (typeList[i] instanceof ClassDoc) {
+ printLink(new LinkInfoImpl(context, (ClassDoc)(typeList[i])));
+
+ } else {
+ printLink(new LinkInfoImpl(context, (Type)(typeList[i])));
+ }
+ }
+ ddEnd();
+ dlEnd();
+ }
+
+ protected void navLinkTree() {
+ navCellStart();
+ printHyperLink("package-tree.html", "",
+ configuration.getText("doclet.Tree"), true, "NavBarFont1");
+ navCellEnd();
+ }
+
+ protected void printSummaryDetailLinks() {
+ try {
+ tr();
+ tdVAlignClass("top", "NavBarCell3");
+ font("-2");
+ print(" ");
+ navSummaryLinks();
+ fontEnd();
+ tdEnd();
+ tdVAlignClass("top", "NavBarCell3");
+ font("-2");
+ navDetailLinks();
+ fontEnd();
+ tdEnd();
+ trEnd();
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new DocletAbortException();
+ }
+ }
+
+ protected void navSummaryLinks() throws Exception {
+ printText("doclet.Summary");
+ space();
+ MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
+ configuration.getBuilderFactory().getMemberSummaryBuilder(this);
+ String[] navLinkLabels = new String[] {
+ "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
+ "doclet.navMethod"
+ };
+ for (int i = 0; i < navLinkLabels.length; i++ ) {
+ if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
+ continue;
+ }
+ if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
+ continue;
+ }
+ AbstractMemberWriter writer =
+ ((AbstractMemberWriter) memberSummaryBuilder.
+ getMemberSummaryWriter(i));
+ if (writer == null) {
+ printText(navLinkLabels[i]);
+ } else {
+ writer.navSummaryLink(
+ memberSummaryBuilder.members(i),
+ memberSummaryBuilder.getVisibleMemberMap(i));
+ }
+ if (i < navLinkLabels.length-1) {
+ navGap();
+ }
+ }
+ }
+
+ /**
+ * Method navDetailLinks
+ *
+ * @throws Exception
+ *
+ */
+ protected void navDetailLinks() throws Exception {
+ printText("doclet.Detail");
+ space();
+ MemberSummaryBuilder memberSummaryBuilder = (MemberSummaryBuilder)
+ configuration.getBuilderFactory().getMemberSummaryBuilder(this);
+ String[] navLinkLabels = new String[] {
+ "doclet.navNested", "doclet.navEnum", "doclet.navField", "doclet.navConstructor",
+ "doclet.navMethod"
+ };
+ for (int i = 1; i < navLinkLabels.length; i++ ) {
+ AbstractMemberWriter writer =
+ ((AbstractMemberWriter) memberSummaryBuilder.
+ getMemberSummaryWriter(i));
+ if (i == VisibleMemberMap.ENUM_CONSTANTS && ! classDoc.isEnum()) {
+ continue;
+ }
+ if (i == VisibleMemberMap.CONSTRUCTORS && classDoc.isEnum()) {
+ continue;
+ }
+ if (writer == null) {
+ printText(navLinkLabels[i]);
+ } else {
+ writer.navDetailLink(memberSummaryBuilder.members(i));
+ }
+ if (i < navLinkLabels.length - 1) {
+ navGap();
+ }
+ }
+ }
+
+ protected void navGap() {
+ space();
+ print('|');
+ space();
+ }
+
+ /**
+ * If this is an inner class or interface, write the enclosing class or
+ * interface.
+ */
+ public void writeNestedClassInfo() {
+ ClassDoc outerClass = classDoc.containingClass();
+ if (outerClass != null) {
+ dl();
+ dt();
+ if (outerClass.isInterface()) {
+ boldText("doclet.Enclosing_Interface");
+ } else {
+ boldText("doclet.Enclosing_Class");
+ }
+ dd();
+ printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, outerClass,
+ false));
+ ddEnd();
+ dlEnd();
+ }
+ }
+
+ /**
+ * Return the classDoc being documented.
+ *
+ * @return the classDoc being documented.
+ */
+ public ClassDoc getClassDoc() {
+ return classDoc;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void completeMemberSummaryBuild() {
+ p();
+ }
+}