blob: f540ad5b85eccd741632e9e3092bb0d69de03730 [file] [log] [blame]
/*
* 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);
}
}