| /* |
| * Copyright (c) 1997, 2017, Oracle and/or its affiliates. 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. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package jdk.javadoc.internal.doclets.formats.html; |
| |
| import jdk.javadoc.internal.doclets.formats.html.markup.Table; |
| import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; |
| |
| 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.ContentBuilder; |
| 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.Navigation; |
| import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode; |
| 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; |
| |
| /** |
| * Generate File to list all the deprecated classes and class members with the |
| * appropriate links. |
| * |
| * <p><b>This is NOT part of any supported API. |
| * If you write code that depends on this, you do so at your own risk. |
| * This code and its internal interfaces are subject to change or |
| * deletion without notice.</b> |
| * |
| * @see java.util.List |
| * @author Atul M Dambalkar |
| * @author Bhavesh Patel (Modified) |
| */ |
| 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.For_Removal"; |
| case MODULE: |
| return "doclet.Modules"; |
| case PACKAGE: |
| return "doclet.Packages"; |
| case INTERFACE: |
| return "doclet.Interfaces"; |
| case CLASS: |
| return "doclet.Classes"; |
| case ENUM: |
| return "doclet.Enums"; |
| case EXCEPTION: |
| return "doclet.Exceptions"; |
| case ERROR: |
| return "doclet.Errors"; |
| case ANNOTATION_TYPE: |
| return "doclet.Annotation_Types"; |
| case FIELD: |
| return "doclet.Fields"; |
| case METHOD: |
| return "doclet.Methods"; |
| case CONSTRUCTOR: |
| return "doclet.Constructors"; |
| case ENUM_CONSTANT: |
| return "doclet.Enum_Constants"; |
| case ANNOTATION_TYPE_MEMBER: |
| return "doclet.Annotation_Type_Members"; |
| default: |
| throw new AssertionError("unknown kind: " + kind); |
| } |
| } |
| |
| private String getSummaryKey(DeprElementKind kind) { |
| switch (kind) { |
| case REMOVAL: |
| return "doclet.for_removal"; |
| case MODULE: |
| return "doclet.modules"; |
| case PACKAGE: |
| return "doclet.packages"; |
| case INTERFACE: |
| return "doclet.interfaces"; |
| case CLASS: |
| return "doclet.classes"; |
| case ENUM: |
| return "doclet.enums"; |
| case EXCEPTION: |
| return "doclet.exceptions"; |
| case ERROR: |
| return "doclet.errors"; |
| case ANNOTATION_TYPE: |
| return "doclet.annotation_types"; |
| case FIELD: |
| return "doclet.fields"; |
| case METHOD: |
| return "doclet.methods"; |
| case CONSTRUCTOR: |
| return "doclet.constructors"; |
| case ENUM_CONSTANT: |
| return "doclet.enum_constants"; |
| case ANNOTATION_TYPE_MEMBER: |
| return "doclet.annotation_type_members"; |
| default: |
| throw new AssertionError("unknown kind: " + kind); |
| } |
| } |
| |
| private String getHeaderKey(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 HtmlConfiguration configuration; |
| |
| private final Navigation navBar; |
| |
| /** |
| * Constructor. |
| * |
| * @param configuration the configuration for this doclet |
| * @param filename the file to be generated |
| */ |
| |
| public DeprecatedListWriter(HtmlConfiguration configuration, DocPath filename) { |
| super(configuration, filename); |
| this.configuration = configuration; |
| this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.DEPRECATED, path); |
| 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); |
| } |
| } |
| } |
| |
| /** |
| * Get list of all the deprecated classes and members in all the Packages |
| * specified on the Command Line. |
| * Then instantiate DeprecatedListWriter and generate File. |
| * |
| * @param configuration the current configuration of the doclet. |
| * @throws DocFileIOException if there is a problem writing the deprecated list |
| */ |
| public static void generate(HtmlConfiguration configuration) throws DocFileIOException { |
| DocPath filename = DocPaths.DEPRECATED_LIST; |
| DeprecatedListWriter depr = new DeprecatedListWriter(configuration, filename); |
| depr.generateDeprecatedListFile( |
| new DeprecatedAPIListBuilder(configuration)); |
| } |
| |
| /** |
| * Generate the deprecated API list. |
| * |
| * @param deprapi list of deprecated API built already. |
| * @throws DocFileIOException if there is a problem writing the deprecated list |
| */ |
| 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.setStyle(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))); |
| TableHeader memberTableHeader = new TableHeader( |
| contents.getContent(getHeaderKey(kind)), contents.descriptionLabel); |
| 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; |
| navBar.setUserFooter(getUserHeaderFooter(false)); |
| htmlTree.addContent(navBar.getContent(false)); |
| addBottom(htmlTree); |
| if (configuration.allowTag(HtmlTag.FOOTER)) { |
| body.addContent(htmlTree); |
| } |
| printHtmlDocument(null, true, body); |
| } |
| |
| /** |
| * Add the index link. |
| * |
| * @param builder the deprecated list builder |
| * @param type the type of list being documented |
| * @param contentTree the content tree to which the index link will be added |
| */ |
| private void addIndexLink(DeprecatedAPIListBuilder builder, |
| DeprElementKind kind, Content contentTree) { |
| if (builder.hasDocumentation(kind)) { |
| Content li = HtmlTree.LI(links.createLink(getAnchorName(kind), |
| contents.getContent(getHeadingKey(kind)))); |
| contentTree.addContent(li); |
| } |
| } |
| |
| /** |
| * Get the contents list. |
| * |
| * @param deprapi the deprecated list builder |
| * @return a content tree for the contents list |
| */ |
| 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; |
| } |
| |
| /** |
| * Add the anchor. |
| * |
| * @param builder the deprecated list builder |
| * @param type the type of list being documented |
| * @param htmlTree the content tree to which the anchor will be added |
| */ |
| private void addAnchor(DeprecatedAPIListBuilder builder, DeprElementKind kind, Content htmlTree) { |
| if (builder.hasDocumentation(kind)) { |
| htmlTree.addContent(links.createAnchor(getAnchorName(kind))); |
| } |
| } |
| |
| /** |
| * Get the header for the deprecated API Listing. |
| * |
| * @return a content tree for the header |
| */ |
| public HtmlTree getHeader() { |
| 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); |
| navBar.setUserHeader(getUserHeaderFooter(true)); |
| htmlTree.addContent(navBar.getContent(true)); |
| if (configuration.allowTag(HtmlTag.HEADER)) { |
| bodyTree.addContent(htmlTree); |
| } |
| return bodyTree; |
| } |
| |
| /** |
| * Add deprecated information to the documentation tree |
| * |
| * @param deprList list of deprecated API elements |
| * @param headingKey the caption for the deprecated table |
| * @param tableSummary the summary for the deprecated table |
| * @param tableHeader table headers for the deprecated table |
| * @param contentTree the content tree to which the deprecated table will be added |
| */ |
| protected void addDeprecatedAPI(SortedSet<Element> deprList, String headingKey, |
| String tableSummary, TableHeader tableHeader, Content contentTree) { |
| if (deprList.size() > 0) { |
| Content caption = contents.getContent(headingKey); |
| Table table = new Table(configuration.htmlVersion, HtmlStyle.deprecatedSummary) |
| .setSummary(tableSummary) |
| .setCaption(caption) |
| .setHeader(tableHeader) |
| .setColumnStyles(HtmlStyle.colDeprecatedItemName, HtmlStyle.colLast); |
| for (Element e : deprList) { |
| Content link; |
| switch (e.getKind()) { |
| case MODULE: |
| ModuleElement m = (ModuleElement) e; |
| link = getModuleLink(m, new StringContent(m.getQualifiedName())); |
| break; |
| case PACKAGE: |
| PackageElement pkg = (PackageElement) e; |
| link = getPackageLink(pkg, getPackageName(pkg)); |
| break; |
| default: |
| link = getDeprecatedLink(e); |
| } |
| Content desc = new ContentBuilder(); |
| List<? extends DocTree> tags = utils.getDeprecatedTrees(e); |
| if (!tags.isEmpty()) { |
| addInlineDeprecatedComment(e, tags.get(0), desc); |
| } else { |
| desc.addContent(HtmlTree.EMPTY); |
| } |
| table.addRow(link, desc); |
| } |
| Content li = HtmlTree.LI(HtmlStyle.blockList, table.toContent()); |
| Content ul = HtmlTree.UL(HtmlStyle.blockList, li); |
| contentTree.addContent(ul); |
| } |
| } |
| |
| protected Content 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 writer.getDeprecatedLink(e); |
| } |
| } |