package jdk.javadoc.internal.doclets.formats.html;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.SortedSet;
import javax.lang.model.element.Element;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import com.sun.source.doctree.DocTree;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder.DeprElementKind;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
public class DeprecatedListWriter extends SubWriterHolderWriter {
private String getAnchorName(DeprElementKind kind) {
switch (kind) {
case REMOVAL:
return "forRemoval";
case MODULE:
return "module";
case PACKAGE:
return "package";
case INTERFACE:
return "interface";
case CLASS:
return "class";
case ENUM:
return "enum";
case EXCEPTION:
return "exception";
case ERROR:
return "error";
case ANNOTATION_TYPE:
return "annotation.type";
case FIELD:
return "field";
case METHOD:
return "method";
case CONSTRUCTOR:
return "constructor";
case ENUM_CONSTANT:
return "enum.constant";
case ANNOTATION_TYPE_MEMBER:
return "annotation.type.member";
default:
throw new AssertionError("unknown kind: " + kind);
}
}
private String getHeadingKey(DeprElementKind kind) {
switch (kind) {
case REMOVAL:
return "doclet.Deprecated_For_Removal";
case MODULE:
return "doclet.Deprecated_Modules";
case PACKAGE:
return "doclet.Deprecated_Packages";
case INTERFACE:
return "doclet.Deprecated_Interfaces";
case CLASS:
return "doclet.Deprecated_Classes";
case ENUM:
return "doclet.Deprecated_Enums";
case EXCEPTION:
return "doclet.Deprecated_Exceptions";
case ERROR:
return "doclet.Deprecated_Errors";
case ANNOTATION_TYPE:
return "doclet.Deprecated_Annotation_Types";
case FIELD:
return "doclet.Deprecated_Fields";
case METHOD:
return "doclet.Deprecated_Methods";
case CONSTRUCTOR:
return "doclet.Deprecated_Constructors";
case ENUM_CONSTANT:
return "doclet.Deprecated_Enum_Constants";
case ANNOTATION_TYPE_MEMBER:
return "doclet.Deprecated_Annotation_Type_Members";
default:
throw new AssertionError("unknown kind: " + kind);
}
}
private String getSummaryKey(DeprElementKind kind) {
switch (kind) {
case REMOVAL:
return "doclet.deprecated_for_removal";
case MODULE:
return "doclet.deprecated_modules";
case PACKAGE:
return "doclet.deprecated_packages";
case INTERFACE:
return "doclet.deprecated_interfaces";
case CLASS:
return "doclet.deprecated_classes";
case ENUM:
return "doclet.deprecated_enums";
case EXCEPTION:
return "doclet.deprecated_exceptions";
case ERROR:
return "doclet.deprecated_errors";
case ANNOTATION_TYPE:
return "doclet.deprecated_annotation_types";
case FIELD:
return "doclet.deprecated_fields";
case METHOD:
return "doclet.deprecated_methods";
case CONSTRUCTOR:
return "doclet.deprecated_constructors";
case ENUM_CONSTANT:
return "doclet.deprecated_enum_constants";
case ANNOTATION_TYPE_MEMBER:
return "doclet.deprecated_annotation_type_members";
default:
throw new AssertionError("unknown kind: " + kind);
}
}
private String (DeprElementKind kind) {
switch (kind) {
case REMOVAL:
return "doclet.Element";
case MODULE:
return "doclet.Module";
case PACKAGE:
return "doclet.Package";
case INTERFACE:
return "doclet.Interface";
case CLASS:
return "doclet.Class";
case ENUM:
return "doclet.Enum";
case EXCEPTION:
return "doclet.Exceptions";
case ERROR:
return "doclet.Errors";
case ANNOTATION_TYPE:
return "doclet.AnnotationType";
case FIELD:
return "doclet.Field";
case METHOD:
return "doclet.Method";
case CONSTRUCTOR:
return "doclet.Constructor";
case ENUM_CONSTANT:
return "doclet.Enum_Constant";
case ANNOTATION_TYPE_MEMBER:
return "doclet.Annotation_Type_Member";
default:
throw new AssertionError("unknown kind: " + kind);
}
}
private EnumMap<DeprElementKind, AbstractMemberWriter> writerMap;
private ConfigurationImpl configuration;
public DeprecatedListWriter(ConfigurationImpl configuration, DocPath filename) {
super(configuration, filename);
this.configuration = configuration;
NestedClassWriterImpl classW = new NestedClassWriterImpl(this);
writerMap = new EnumMap<>(DeprElementKind.class);
for (DeprElementKind kind : DeprElementKind.values()) {
switch (kind) {
case REMOVAL:
case MODULE:
case PACKAGE:
case INTERFACE:
case CLASS:
case ENUM:
case EXCEPTION:
case ERROR:
case ANNOTATION_TYPE:
writerMap.put(kind, classW);
break;
case FIELD:
writerMap.put(kind, new FieldWriterImpl(this));
break;
case METHOD:
writerMap.put(kind, new MethodWriterImpl(this));
break;
case CONSTRUCTOR:
writerMap.put(kind, new ConstructorWriterImpl(this));
break;
case ENUM_CONSTANT:
writerMap.put(kind, new EnumConstantWriterImpl(this));
break;
case ANNOTATION_TYPE_MEMBER:
writerMap.put(kind, new AnnotationTypeOptionalMemberWriterImpl(this, null));
break;
default:
throw new AssertionError("unknown kind: " + kind);
}
}
}
public static void generate(ConfigurationImpl configuration) throws DocFileIOException {
DocPath filename = DocPaths.DEPRECATED_LIST;
DeprecatedListWriter depr = new DeprecatedListWriter(configuration, filename);
depr.generateDeprecatedListFile(
new DeprecatedAPIListBuilder(configuration));
}
protected void generateDeprecatedListFile(DeprecatedAPIListBuilder deprapi)
throws DocFileIOException {
HtmlTree body = getHeader();
HtmlTree htmlTree = (configuration.allowTag(HtmlTag.MAIN))
? HtmlTree.MAIN()
: body;
htmlTree.addContent(getContentsList(deprapi));
String memberTableSummary;
HtmlTree div = new HtmlTree(HtmlTag.DIV);
div.addStyle(HtmlStyle.contentContainer);
for (DeprElementKind kind : DeprElementKind.values()) {
if (deprapi.hasDocumentation(kind)) {
addAnchor(deprapi, kind, div);
memberTableSummary
= resources.getText("doclet.Member_Table_Summary",
resources.getText(getHeadingKey(kind)),
resources.getText(getSummaryKey(kind)));
List<String> memberTableHeader = new ArrayList<>();
memberTableHeader.add(resources.getText(getHeaderKey(kind)));
memberTableHeader.add(resources.getText("doclet.Description"));
addDeprecatedAPI(deprapi.getSet(kind),
getHeadingKey(kind), memberTableSummary, memberTableHeader, div);
}
}
if (configuration.allowTag(HtmlTag.MAIN)) {
htmlTree.addContent(div);
body.addContent(htmlTree);
} else {
body.addContent(div);
}
htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
? HtmlTree.FOOTER()
: body;
addNavLinks(false, htmlTree);
addBottom(htmlTree);
if (configuration.allowTag(HtmlTag.FOOTER)) {
body.addContent(htmlTree);
}
printHtmlDocument(null, true, body);
}
private void addIndexLink(DeprecatedAPIListBuilder builder,
DeprElementKind kind, Content contentTree) {
if (builder.hasDocumentation(kind)) {
Content li = HtmlTree.LI(getHyperLink(getAnchorName(kind),
contents.getContent(getHeadingKey(kind))));
contentTree.addContent(li);
}
}
public Content getContentsList(DeprecatedAPIListBuilder deprapi) {
Content headContent = contents.deprecatedAPI;
Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
HtmlStyle.title, headContent);
Content div = HtmlTree.DIV(HtmlStyle.header, heading);
Content headingContent = contents.contentsHeading;
div.addContent(HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, true,
headingContent));
Content ul = new HtmlTree(HtmlTag.UL);
for (DeprElementKind kind : DeprElementKind.values()) {
addIndexLink(deprapi, kind, ul);
}
div.addContent(ul);
return div;
}
private void addAnchor(DeprecatedAPIListBuilder builder, DeprElementKind kind, Content htmlTree) {
if (builder.hasDocumentation(kind)) {
htmlTree.addContent(getMarkerAnchor(getAnchorName(kind)));
}
}
public HtmlTree () {
String title = configuration.getText("doclet.Window_Deprecated_List");
HtmlTree bodyTree = getBody(true, getWindowTitle(title));
HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
? HtmlTree.HEADER()
: bodyTree;
addTop(htmlTree);
addNavLinks(true, htmlTree);
if (configuration.allowTag(HtmlTag.HEADER)) {
bodyTree.addContent(htmlTree);
}
return bodyTree;
}
@Override
protected Content getNavLinkDeprecated() {
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.deprecatedLabel);
return li;
}
protected void addDeprecatedAPI(SortedSet<Element> deprList, String headingKey,
String tableSummary, List<String> tableHeader, Content contentTree) {
if (deprList.size() > 0) {
Content caption = getTableCaption(configuration.getContent(headingKey));
Content table = (configuration.isOutputHtml5())
? HtmlTree.TABLE(HtmlStyle.deprecatedSummary, caption)
: HtmlTree.TABLE(HtmlStyle.deprecatedSummary, tableSummary, caption);
table.addContent(getSummaryTableHeader(tableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
boolean altColor = true;
for (Element e : deprList) {
HtmlTree thRow;
switch (e.getKind()) {
case MODULE:
ModuleElement m = (ModuleElement)e;
thRow = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst,
getModuleLink(m, new StringContent(m.getQualifiedName())));
break;
case PACKAGE:
PackageElement pkg = (PackageElement)e;
thRow = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst,
getPackageLink(pkg, getPackageName(pkg)));
break;
default:
thRow = getDeprecatedLink(e);
}
HtmlTree tr = HtmlTree.TR(thRow);
HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
tdDesc.addStyle(HtmlStyle.colLast);
List<? extends DocTree> tags = utils.getDeprecatedTrees(e);
if (!tags.isEmpty()) {
addInlineDeprecatedComment(e, tags.get(0), tdDesc);
}
tr.addContent(tdDesc);
tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
altColor = !altColor;
tbody.addContent(tr);
}
table.addContent(tbody);
Content li = HtmlTree.LI(HtmlStyle.blockList, table);
Content ul = HtmlTree.UL(HtmlStyle.blockList, li);
contentTree.addContent(ul);
}
}
protected HtmlTree getDeprecatedLink(Element e) {
AbstractMemberWriter writer;
switch (e.getKind()) {
case INTERFACE:
case CLASS:
case ENUM:
case ANNOTATION_TYPE:
writer = new NestedClassWriterImpl(this);
break;
case FIELD:
writer = new FieldWriterImpl(this);
break;
case METHOD:
writer = new MethodWriterImpl(this);
break;
case CONSTRUCTOR:
writer = new ConstructorWriterImpl(this);
break;
case ENUM_CONSTANT:
writer = new EnumConstantWriterImpl(this);
break;
default:
writer = new AnnotationTypeOptionalMemberWriterImpl(this, null);
}
return HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, writer.getDeprecatedLink(e));
}
}