| /* |
| * Copyright 1997-2008 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.util.*; |
| import com.sun.tools.doclets.internal.toolkit.taglets.*; |
| |
| import com.sun.javadoc.*; |
| import java.util.*; |
| import java.lang.reflect.Modifier; |
| |
| /** |
| * The base class for member writers. |
| * |
| * @author Robert Field |
| * @author Atul M Dambalkar |
| * @author Jamie Ho (Re-write) |
| */ |
| public abstract class AbstractMemberWriter { |
| |
| protected boolean printedSummaryHeader = false; |
| protected final SubWriterHolderWriter writer; |
| protected final ClassDoc classdoc; |
| public final boolean nodepr; |
| |
| public AbstractMemberWriter(SubWriterHolderWriter writer, |
| ClassDoc classdoc) { |
| this.writer = writer; |
| this.nodepr = configuration().nodeprecated; |
| this.classdoc = classdoc; |
| } |
| |
| public AbstractMemberWriter(SubWriterHolderWriter writer) { |
| this(writer, null); |
| } |
| |
| /*** abstracts ***/ |
| |
| public abstract void printSummaryLabel(ClassDoc cd); |
| |
| public abstract void printInheritedSummaryLabel(ClassDoc cd); |
| |
| public abstract void printSummaryAnchor(ClassDoc cd); |
| |
| public abstract void printInheritedSummaryAnchor(ClassDoc cd); |
| |
| protected abstract void printSummaryType(ProgramElementDoc member); |
| |
| protected void writeSummaryLink(ClassDoc cd, ProgramElementDoc member) { |
| writeSummaryLink(LinkInfoImpl.CONTEXT_MEMBER, cd, member); |
| } |
| |
| protected abstract void writeSummaryLink(int context, |
| ClassDoc cd, |
| ProgramElementDoc member); |
| |
| protected abstract void writeInheritedSummaryLink(ClassDoc cd, |
| ProgramElementDoc member); |
| |
| protected abstract void writeDeprecatedLink(ProgramElementDoc member); |
| |
| protected abstract void printNavSummaryLink(ClassDoc cd, boolean link); |
| |
| protected abstract void printNavDetailLink(boolean link); |
| |
| /*** ***/ |
| |
| protected void print(String str) { |
| writer.print(str); |
| writer.displayLength += str.length(); |
| } |
| |
| protected void print(char ch) { |
| writer.print(ch); |
| writer.displayLength++; |
| } |
| |
| protected void bold(String str) { |
| writer.bold(str); |
| writer.displayLength += str.length(); |
| } |
| |
| /** |
| * Return a string describing the access modifier flags. |
| * Don't include native or synchronized. |
| * |
| * The modifier names are returned in canonical order, as |
| * specified by <em>The Java Language Specification</em>. |
| */ |
| protected String modifierString(MemberDoc member) { |
| int ms = member.modifierSpecifier(); |
| int no = Modifier.NATIVE | Modifier.SYNCHRONIZED; |
| return Modifier.toString(ms & ~no); |
| } |
| |
| protected String typeString(MemberDoc member) { |
| String type = ""; |
| if (member instanceof MethodDoc) { |
| type = ((MethodDoc)member).returnType().toString(); |
| } else if (member instanceof FieldDoc) { |
| type = ((FieldDoc)member).type().toString(); |
| } |
| return type; |
| } |
| |
| protected void printModifiers(MemberDoc member) { |
| String mod = modifierString(member); |
| // According to JLS, we should not be showing public modifier for |
| // interface methods. |
| if ((member.isField() || member.isMethod()) && |
| writer instanceof ClassWriterImpl && |
| ((ClassWriterImpl) writer).getClassDoc().isInterface()) { |
| mod = Util.replaceText(mod, "public", "").trim(); |
| } |
| if(mod.length() > 0) { |
| print(mod); |
| print(' '); |
| } |
| } |
| |
| protected String makeSpace(int len) { |
| if (len <= 0) { |
| return ""; |
| } |
| StringBuffer sb = new StringBuffer(len); |
| for(int i = 0; i < len; i++) { |
| sb.append(' '); |
| } |
| return sb.toString(); |
| } |
| |
| /** |
| * Print 'static' if static and type link. |
| */ |
| protected void printStaticAndType(boolean isStatic, Type type) { |
| writer.printTypeSummaryHeader(); |
| if (isStatic) { |
| print("static"); |
| } |
| writer.space(); |
| if (type != null) { |
| writer.printLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_MEMBER, |
| type)); |
| } |
| writer.printTypeSummaryFooter(); |
| } |
| |
| /** |
| * Print the modifier and type for the member in the member summary. |
| * |
| * @param member the member to print the type for. |
| * @param type the type to print. |
| */ |
| protected void printModifierAndType(ProgramElementDoc member, Type type) { |
| writer.printTypeSummaryHeader(); |
| printModifier(member); |
| if (type == null) { |
| writer.space(); |
| if (member.isClass()) { |
| print("class"); |
| } else { |
| print("interface"); |
| } |
| } else { |
| if (member instanceof ExecutableMemberDoc && |
| ((ExecutableMemberDoc) member).typeParameters().length > 0) { |
| //Code to avoid ugly wrapping in member summary table. |
| writer.table(0,0,0); |
| writer.trAlignVAlign("right", ""); |
| writer.tdNowrap(); |
| writer.font("-1"); |
| writer.code(); |
| int displayLength = ((AbstractExecutableMemberWriter) this). |
| writeTypeParameters((ExecutableMemberDoc) member); |
| if (displayLength > 10) { |
| writer.br(); |
| } |
| writer.printLink(new LinkInfoImpl( |
| LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE, type)); |
| writer.codeEnd(); |
| writer.fontEnd(); |
| writer.tdEnd(); |
| writer.trEnd(); |
| writer.tableEnd(); |
| } else { |
| writer.space(); |
| writer.printLink(new LinkInfoImpl( |
| LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE, type)); |
| } |
| |
| } |
| writer.printTypeSummaryFooter(); |
| } |
| |
| private void printModifier(ProgramElementDoc member) { |
| if (member.isProtected()) { |
| print("protected "); |
| } else if (member.isPrivate()) { |
| print("private "); |
| } else if (!member.isPublic()) { // Package private |
| writer.printText("doclet.Package_private"); |
| print(" "); |
| } |
| if (member.isMethod() && ((MethodDoc)member).isAbstract()) { |
| print("abstract "); |
| } |
| if (member.isStatic()) { |
| print("static"); |
| } |
| } |
| |
| protected void printComment(ProgramElementDoc member) { |
| if (member.inlineTags().length > 0) { |
| writer.dd(); |
| writer.printInlineComment(member); |
| } |
| } |
| |
| protected String name(ProgramElementDoc member) { |
| return member.name(); |
| } |
| |
| protected void printHead(MemberDoc member) { |
| writer.h3(); |
| writer.print(member.name()); |
| writer.h3End(); |
| } |
| |
| protected void printFullComment(ProgramElementDoc member) { |
| if(configuration().nocomment){ |
| return; |
| } |
| writer.dl(); |
| print(((TagletOutputImpl) |
| (new DeprecatedTaglet()).getTagletOutput(member, |
| writer.getTagletWriterInstance(false))).toString()); |
| printCommentAndTags(member); |
| writer.dlEnd(); |
| } |
| |
| protected void printCommentAndTags(ProgramElementDoc member) { |
| printComment(member); |
| writer.printTags(member); |
| } |
| |
| /** |
| * Forward to containing writer |
| */ |
| public void printSummaryHeader(ClassDoc cd) { |
| printedSummaryHeader = true; |
| writer.printSummaryHeader(this, cd); |
| } |
| |
| /** |
| * Forward to containing writer |
| */ |
| public void printInheritedSummaryHeader(ClassDoc cd) { |
| writer.printInheritedSummaryHeader(this, cd); |
| } |
| |
| /** |
| * Forward to containing writer |
| */ |
| public void printInheritedSummaryFooter(ClassDoc cd) { |
| writer.printInheritedSummaryFooter(this, cd); |
| } |
| |
| /** |
| * Forward to containing writer |
| */ |
| public void printSummaryFooter(ClassDoc cd) { |
| writer.printSummaryFooter(this, cd); |
| } |
| |
| /** |
| * Return true if the given <code>ProgramElement</code> is inherited |
| * by the class that is being documented. |
| * |
| * @param ped The <code>ProgramElement</code> being checked. |
| * return true if the <code>ProgramElement</code> is being inherited and |
| * false otherwise. |
| */ |
| protected boolean isInherited(ProgramElementDoc ped){ |
| if(ped.isPrivate() || (ped.isPackagePrivate() && |
| ! ped.containingPackage().equals(classdoc.containingPackage()))){ |
| return false; |
| } |
| return true; |
| } |
| |
| |
| /** |
| * Generate the code for listing the deprecated APIs. Create the table |
| * format for listing the API. Call methods from the sub-class to complete |
| * the generation. |
| */ |
| protected void printDeprecatedAPI(List deprmembers, String headingKey) { |
| if (deprmembers.size() > 0) { |
| writer.tableIndexSummary(); |
| writer.tableHeaderStart("#CCCCFF"); |
| writer.boldText(headingKey); |
| writer.tableHeaderEnd(); |
| for (int i = 0; i < deprmembers.size(); i++) { |
| ProgramElementDoc member =(ProgramElementDoc)deprmembers.get(i); |
| writer.trBgcolorStyle("white", "TableRowColor"); |
| writer.summaryRow(0); |
| writeDeprecatedLink(member); |
| writer.br(); |
| writer.printNbsps(); |
| if (member.tags("deprecated").length > 0) |
| writer.printInlineDeprecatedComment(member, member.tags("deprecated")[0]); |
| writer.space(); |
| writer.summaryRowEnd(); |
| writer.trEnd(); |
| } |
| writer.tableEnd(); |
| writer.space(); |
| writer.p(); |
| } |
| } |
| |
| /** |
| * Print use info. |
| */ |
| protected void printUseInfo(List<? extends ProgramElementDoc> mems, String heading) { |
| if (mems == null) { |
| return; |
| } |
| List<? extends ProgramElementDoc> members = mems; |
| if (members.size() > 0) { |
| writer.tableIndexSummary(); |
| writer.tableUseInfoHeaderStart("#CCCCFF"); |
| writer.print(heading); |
| writer.tableHeaderEnd(); |
| for (Iterator<? extends ProgramElementDoc> it = members.iterator(); it.hasNext(); ) { |
| ProgramElementDoc pgmdoc = it.next(); |
| ClassDoc cd = pgmdoc.containingClass(); |
| |
| writer.printSummaryLinkType(this, pgmdoc); |
| if (cd != null && !(pgmdoc instanceof ConstructorDoc) |
| && !(pgmdoc instanceof ClassDoc)) { |
| // Add class context |
| writer.bold(cd.name() + "."); |
| } |
| writeSummaryLink( |
| pgmdoc instanceof ClassDoc ? |
| LinkInfoImpl.CONTEXT_CLASS_USE : LinkInfoImpl.CONTEXT_MEMBER, |
| cd, pgmdoc); |
| writer.printSummaryLinkComment(this, pgmdoc); |
| } |
| writer.tableEnd(); |
| writer.space(); |
| writer.p(); |
| } |
| } |
| |
| protected void navDetailLink(List members) { |
| printNavDetailLink(members.size() > 0? true: false); |
| } |
| |
| |
| protected void navSummaryLink(List members, |
| VisibleMemberMap visibleMemberMap) { |
| if (members.size() > 0) { |
| printNavSummaryLink(null, true); |
| return; |
| } else { |
| ClassDoc icd = classdoc.superclass(); |
| while (icd != null) { |
| List inhmembers = visibleMemberMap.getMembersFor(icd); |
| if (inhmembers.size() > 0) { |
| printNavSummaryLink(icd, true); |
| return; |
| } |
| icd = icd.superclass(); |
| } |
| } |
| printNavSummaryLink(null, false); |
| } |
| |
| protected void serialWarning(SourcePosition pos, String key, String a1, String a2) { |
| if (configuration().serialwarn) { |
| ConfigurationImpl.getInstance().getDocletSpecificMsg().warning(pos, key, a1, a2); |
| } |
| } |
| |
| public ProgramElementDoc[] eligibleMembers(ProgramElementDoc[] members) { |
| return nodepr? Util.excludeDeprecatedMembers(members): members; |
| } |
| |
| public ConfigurationImpl configuration() { |
| return writer.configuration; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void writeMemberSummary(ClassDoc classDoc, ProgramElementDoc member, |
| Tag[] firstSentenceTags, boolean isFirst, boolean isLast) { |
| writer.printSummaryLinkType(this, member); |
| writeSummaryLink(classDoc, member); |
| writer.printSummaryLinkComment(this, member, firstSentenceTags); |
| } |
| } |