DeprecatedListWriter.java revision 3792:d516975e8110
1221345Sdim/*
2207619Srdivacky * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3207619Srdivacky * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4207619Srdivacky *
5207619Srdivacky * This code is free software; you can redistribute it and/or modify it
6207619Srdivacky * under the terms of the GNU General Public License version 2 only, as
7207619Srdivacky * published by the Free Software Foundation.  Oracle designates this
8207619Srdivacky * particular file as subject to the "Classpath" exception as provided
9207619Srdivacky * by Oracle in the LICENSE file that accompanied this code.
10207619Srdivacky *
11207619Srdivacky * This code is distributed in the hope that it will be useful, but WITHOUT
12207619Srdivacky * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13207619Srdivacky * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14207619Srdivacky * version 2 for more details (a copy is included in the LICENSE file that
15207619Srdivacky * accompanied this code).
16207619Srdivacky *
17226633Sdim * You should have received a copy of the GNU General Public License version
18221345Sdim * 2 along with this work; if not, write to the Free Software Foundation,
19224145Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20226633Sdim *
21249423Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22249423Sdim * or visit www.oracle.com if you need additional information or have any
23249423Sdim * questions.
24207619Srdivacky */
25207619Srdivacky
26207619Srdivackypackage jdk.javadoc.internal.doclets.formats.html;
27207619Srdivacky
28207619Srdivackyimport java.util.ArrayList;
29207619Srdivackyimport java.util.EnumMap;
30207619Srdivackyimport java.util.List;
31207619Srdivackyimport java.util.SortedSet;
32207619Srdivacky
33207619Srdivackyimport javax.lang.model.element.Element;
34226633Sdimimport javax.lang.model.element.ModuleElement;
35207619Srdivackyimport javax.lang.model.element.PackageElement;
36207619Srdivacky
37207619Srdivackyimport com.sun.source.doctree.DocTree;
38207619Srdivackyimport jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
39207619Srdivackyimport jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
40207619Srdivackyimport jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
41207619Srdivackyimport jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
42226633Sdimimport jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
43207619Srdivackyimport jdk.javadoc.internal.doclets.toolkit.Content;
44207619Srdivackyimport jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder;
45207619Srdivackyimport jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder.DeprElementKind;
46207619Srdivackyimport jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
47207619Srdivackyimport jdk.javadoc.internal.doclets.toolkit.util.DocPath;
48207619Srdivackyimport jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
49207619Srdivacky
50207619Srdivacky/**
51207619Srdivacky * Generate File to list all the deprecated classes and class members with the
52207619Srdivacky * appropriate links.
53207619Srdivacky *
54207619Srdivacky *  <p><b>This is NOT part of any supported API.
55218893Sdim *  If you write code that depends on this, you do so at your own risk.
56218893Sdim *  This code and its internal interfaces are subject to change or
57218893Sdim *  deletion without notice.</b>
58207619Srdivacky *
59218893Sdim * @see java.util.List
60218893Sdim * @author Atul M Dambalkar
61218893Sdim * @author Bhavesh Patel (Modified)
62218893Sdim */
63218893Sdimpublic class DeprecatedListWriter extends SubWriterHolderWriter {
64218893Sdim
65207619Srdivacky    private String getAnchorName(DeprElementKind kind) {
66207619Srdivacky        switch (kind) {
67207619Srdivacky            case MODULE:
68207619Srdivacky                return "module";
69207619Srdivacky            case PACKAGE:
70226633Sdim                return "package";
71207619Srdivacky            case INTERFACE:
72226633Sdim                return "interface";
73226633Sdim            case CLASS:
74207619Srdivacky                return "class";
75207619Srdivacky            case ENUM:
76226633Sdim                return "enum";
77207619Srdivacky            case EXCEPTION:
78226633Sdim                return "exception";
79226633Sdim            case ERROR:
80207619Srdivacky                return "error";
81207619Srdivacky            case ANNOTATION_TYPE:
82207619Srdivacky                return "annotation.type";
83207619Srdivacky            case FIELD:
84207619Srdivacky                return "field";
85207619Srdivacky            case METHOD:
86207619Srdivacky                return "method";
87207619Srdivacky            case CONSTRUCTOR:
88207619Srdivacky                return "constructor";
89207619Srdivacky            case ENUM_CONSTANT:
90207619Srdivacky                return "enum.constant";
91207619Srdivacky            case ANNOTATION_TYPE_MEMBER:
92207619Srdivacky                return "annotation.type.member";
93207619Srdivacky            default:
94207619Srdivacky                throw new AssertionError("unknown kind: " + kind);
95207619Srdivacky        }
96207619Srdivacky    }
97207619Srdivacky
98207619Srdivacky    private String getHeadingKey(DeprElementKind kind) {
99207619Srdivacky        switch (kind) {
100207619Srdivacky            case MODULE:
101207619Srdivacky                return "doclet.Deprecated_Modules";
102207619Srdivacky            case PACKAGE:
103207619Srdivacky                return "doclet.Deprecated_Packages";
104207619Srdivacky            case INTERFACE:
105207619Srdivacky                return "doclet.Deprecated_Interfaces";
106207619Srdivacky            case CLASS:
107207619Srdivacky                return "doclet.Deprecated_Classes";
108207619Srdivacky            case ENUM:
109207619Srdivacky                return "doclet.Deprecated_Enums";
110207619Srdivacky            case EXCEPTION:
111221345Sdim                return "doclet.Deprecated_Exceptions";
112207619Srdivacky            case ERROR:
113207619Srdivacky                return "doclet.Deprecated_Errors";
114218893Sdim            case ANNOTATION_TYPE:
115218893Sdim                return "doclet.Deprecated_Annotation_Types";
116218893Sdim            case FIELD:
117218893Sdim                return "doclet.Deprecated_Fields";
118218893Sdim            case METHOD:
119218893Sdim                return "doclet.Deprecated_Methods";
120218893Sdim            case CONSTRUCTOR:
121218893Sdim                return "doclet.Deprecated_Constructors";
122218893Sdim            case ENUM_CONSTANT:
123208600Srdivacky                return "doclet.Deprecated_Enum_Constants";
124208600Srdivacky            case ANNOTATION_TYPE_MEMBER:
125208600Srdivacky                return "doclet.Deprecated_Annotation_Type_Members";
126249423Sdim            default:
127249423Sdim                throw new AssertionError("unknown kind: " + kind);
128249423Sdim        }
129249423Sdim    }
130249423Sdim
131249423Sdim    private String getSummaryKey(DeprElementKind kind) {
132249423Sdim        switch (kind) {
133207619Srdivacky            case MODULE:
134207619Srdivacky                return "doclet.deprecated_modules";
135207619Srdivacky            case PACKAGE:
136207619Srdivacky                return "doclet.deprecated_packages";
137207619Srdivacky            case INTERFACE:
138                return "doclet.deprecated_interfaces";
139            case CLASS:
140                return "doclet.deprecated_classes";
141            case ENUM:
142                return "doclet.deprecated_enums";
143            case EXCEPTION:
144                return "doclet.deprecated_exceptions";
145            case ERROR:
146                return "doclet.deprecated_errors";
147            case ANNOTATION_TYPE:
148                return "doclet.deprecated_annotation_types";
149            case FIELD:
150                return "doclet.deprecated_fields";
151            case METHOD:
152                return "doclet.deprecated_methods";
153            case CONSTRUCTOR:
154                return "doclet.deprecated_constructors";
155            case ENUM_CONSTANT:
156                return "doclet.deprecated_enum_constants";
157            case ANNOTATION_TYPE_MEMBER:
158                return "doclet.deprecated_annotation_type_members";
159            default:
160                throw new AssertionError("unknown kind: " + kind);
161        }
162    }
163
164    private String getHeaderKey(DeprElementKind kind) {
165        switch (kind) {
166            case MODULE:
167                return "doclet.Module";
168            case PACKAGE:
169                return "doclet.Package";
170            case INTERFACE:
171                return "doclet.Interface";
172            case CLASS:
173                return "doclet.Class";
174            case ENUM:
175                return "doclet.Enum";
176            case EXCEPTION:
177                return "doclet.Exceptions";
178            case ERROR:
179                return "doclet.Errors";
180            case ANNOTATION_TYPE:
181                return "doclet.AnnotationType";
182            case FIELD:
183                return "doclet.Field";
184            case METHOD:
185                return "doclet.Method";
186            case CONSTRUCTOR:
187                return "doclet.Constructor";
188            case ENUM_CONSTANT:
189                return "doclet.Enum_Constant";
190            case ANNOTATION_TYPE_MEMBER:
191                return "doclet.Annotation_Type_Member";
192            default:
193                throw new AssertionError("unknown kind: " + kind);
194        }
195    }
196
197    private EnumMap<DeprElementKind, AbstractMemberWriter> writerMap;
198
199    private ConfigurationImpl configuration;
200
201    /**
202     * Constructor.
203     *
204     * @param configuration the configuration for this doclet
205     * @param filename the file to be generated
206     */
207
208    public DeprecatedListWriter(ConfigurationImpl configuration, DocPath filename) {
209        super(configuration, filename);
210        this.configuration = configuration;
211        NestedClassWriterImpl classW = new NestedClassWriterImpl(this);
212        writerMap = new EnumMap<>(DeprElementKind.class);
213        for (DeprElementKind kind : DeprElementKind.values()) {
214            switch (kind) {
215                case MODULE:
216                case PACKAGE:
217                case INTERFACE:
218                case CLASS:
219                case ENUM:
220                case EXCEPTION:
221                case ERROR:
222                case ANNOTATION_TYPE:
223                    writerMap.put(kind, classW);
224                    break;
225                case FIELD:
226                    writerMap.put(kind, new FieldWriterImpl(this));
227                    break;
228                case METHOD:
229                    writerMap.put(kind, new MethodWriterImpl(this));
230                    break;
231                case CONSTRUCTOR:
232                    writerMap.put(kind, new ConstructorWriterImpl(this));
233                    break;
234                case ENUM_CONSTANT:
235                    writerMap.put(kind, new EnumConstantWriterImpl(this));
236                    break;
237                case ANNOTATION_TYPE_MEMBER:
238                    writerMap.put(kind, new AnnotationTypeOptionalMemberWriterImpl(this, null));
239                    break;
240                default:
241                   throw new AssertionError("unknown kind: " + kind);
242            }
243        }
244    }
245
246    /**
247     * Get list of all the deprecated classes and members in all the Packages
248     * specified on the Command Line.
249     * Then instantiate DeprecatedListWriter and generate File.
250     *
251     * @param configuration the current configuration of the doclet.
252     * @throws DocFileIOException if there is a problem writing the deprecated list
253     */
254    public static void generate(ConfigurationImpl configuration) throws DocFileIOException {
255        DocPath filename = DocPaths.DEPRECATED_LIST;
256        DeprecatedListWriter depr = new DeprecatedListWriter(configuration, filename);
257        depr.generateDeprecatedListFile(
258               new DeprecatedAPIListBuilder(configuration));
259    }
260
261    /**
262     * Generate the deprecated API list.
263     *
264     * @param deprapi list of deprecated API built already.
265     * @throws DocFileIOException if there is a problem writing the deprecated list
266     */
267    protected void generateDeprecatedListFile(DeprecatedAPIListBuilder deprapi)
268            throws DocFileIOException {
269        HtmlTree body = getHeader();
270        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.MAIN))
271                ? HtmlTree.MAIN()
272                : body;
273        htmlTree.addContent(getContentsList(deprapi));
274        String memberTableSummary;
275        HtmlTree div = new HtmlTree(HtmlTag.DIV);
276        div.addStyle(HtmlStyle.contentContainer);
277        for (DeprElementKind kind : DeprElementKind.values()) {
278            if (deprapi.hasDocumentation(kind)) {
279                addAnchor(deprapi, kind, div);
280                memberTableSummary
281                        = resources.getText("doclet.Member_Table_Summary",
282                                resources.getText(getHeadingKey(kind)),
283                                resources.getText(getSummaryKey(kind)));
284                List<String> memberTableHeader = new ArrayList<>();
285                memberTableHeader.add(resources.getText(getHeaderKey(kind)));
286                memberTableHeader.add(resources.getText("doclet.Description"));
287                if (kind == DeprElementKind.MODULE) {
288                    addModuleDeprecatedAPI(deprapi.getSet(kind),
289                            getHeadingKey(kind), memberTableSummary, memberTableHeader, div);
290                } else if (kind == DeprElementKind.PACKAGE) {
291                    addPackageDeprecatedAPI(deprapi.getSet(kind),
292                            getHeadingKey(kind), memberTableSummary, memberTableHeader, div);
293                } else {
294                    writerMap.get(kind).addDeprecatedAPI(deprapi.getSet(kind),
295                            getHeadingKey(kind), memberTableSummary, memberTableHeader, div);
296                }
297            }
298        }
299        if (configuration.allowTag(HtmlTag.MAIN)) {
300            htmlTree.addContent(div);
301            body.addContent(htmlTree);
302        } else {
303            body.addContent(div);
304        }
305        htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
306                ? HtmlTree.FOOTER()
307                : body;
308        addNavLinks(false, htmlTree);
309        addBottom(htmlTree);
310        if (configuration.allowTag(HtmlTag.FOOTER)) {
311            body.addContent(htmlTree);
312        }
313        printHtmlDocument(null, true, body);
314    }
315
316    /**
317     * Add the index link.
318     *
319     * @param builder the deprecated list builder
320     * @param type the type of list being documented
321     * @param contentTree the content tree to which the index link will be added
322     */
323    private void addIndexLink(DeprecatedAPIListBuilder builder,
324            DeprElementKind kind, Content contentTree) {
325        if (builder.hasDocumentation(kind)) {
326            Content li = HtmlTree.LI(getHyperLink(getAnchorName(kind),
327                    contents.getContent(getHeadingKey(kind))));
328            contentTree.addContent(li);
329        }
330    }
331
332    /**
333     * Get the contents list.
334     *
335     * @param deprapi the deprecated list builder
336     * @return a content tree for the contents list
337     */
338    public Content getContentsList(DeprecatedAPIListBuilder deprapi) {
339        Content headContent = contents.deprecatedAPI;
340        Content heading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
341                HtmlStyle.title, headContent);
342        Content div = HtmlTree.DIV(HtmlStyle.header, heading);
343        Content headingContent = contents.contentsHeading;
344        div.addContent(HtmlTree.HEADING(HtmlConstants.CONTENT_HEADING, true,
345                headingContent));
346        Content ul = new HtmlTree(HtmlTag.UL);
347        for (DeprElementKind kind : DeprElementKind.values()) {
348            addIndexLink(deprapi, kind, ul);
349        }
350        div.addContent(ul);
351        return div;
352    }
353
354    /**
355     * Add the anchor.
356     *
357     * @param builder the deprecated list builder
358     * @param type the type of list being documented
359     * @param htmlTree the content tree to which the anchor will be added
360     */
361    private void addAnchor(DeprecatedAPIListBuilder builder, DeprElementKind kind, Content htmlTree) {
362        if (builder.hasDocumentation(kind)) {
363            htmlTree.addContent(getMarkerAnchor(getAnchorName(kind)));
364        }
365    }
366
367    /**
368     * Get the header for the deprecated API Listing.
369     *
370     * @return a content tree for the header
371     */
372    public HtmlTree getHeader() {
373        String title = configuration.getText("doclet.Window_Deprecated_List");
374        HtmlTree bodyTree = getBody(true, getWindowTitle(title));
375        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
376                ? HtmlTree.HEADER()
377                : bodyTree;
378        addTop(htmlTree);
379        addNavLinks(true, htmlTree);
380        if (configuration.allowTag(HtmlTag.HEADER)) {
381            bodyTree.addContent(htmlTree);
382        }
383        return bodyTree;
384    }
385
386    /**
387     * Get the deprecated label.
388     *
389     * @return a content tree for the deprecated label
390     */
391    @Override
392    protected Content getNavLinkDeprecated() {
393        Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.deprecatedLabel);
394        return li;
395    }
396
397    /**
398     * Add module deprecation information to the documentation tree
399     *
400     * @param deprMdles list of deprecated modules
401     * @param headingKey the caption for the deprecated module table
402     * @param tableSummary the summary for the deprecated module table
403     * @param tableHeader table headers for the deprecated module table
404     * @param contentTree the content tree to which the deprecated module table will be added
405     */
406    protected void addModuleDeprecatedAPI(SortedSet<Element> deprMdles, String headingKey,
407            String tableSummary, List<String> tableHeader, Content contentTree) {
408        if (deprMdles.size() > 0) {
409            Content caption = getTableCaption(configuration.getContent(headingKey));
410            Content table = (configuration.isOutputHtml5())
411                    ? HtmlTree.TABLE(HtmlStyle.deprecatedSummary, caption)
412                    : HtmlTree.TABLE(HtmlStyle.deprecatedSummary, tableSummary, caption);
413            table.addContent(getSummaryTableHeader(tableHeader, "col"));
414            Content tbody = new HtmlTree(HtmlTag.TBODY);
415            boolean altColor = true;
416            for (Element e : deprMdles) {
417                ModuleElement mdle = (ModuleElement) e;
418                HtmlTree thRow = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst,
419                        getModuleLink(mdle, new StringContent(mdle.getQualifiedName())));
420                HtmlTree tr = HtmlTree.TR(thRow);
421                HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
422                tdDesc.addStyle(HtmlStyle.colLast);
423                List<? extends DocTree> tags = utils.getDeprecatedTrees(mdle);
424                if (!tags.isEmpty()) {
425                    addInlineDeprecatedComment(mdle, tags.get(0), tdDesc);
426                }
427                tr.addContent(tdDesc);
428                tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
429                altColor = !altColor;
430                tbody.addContent(tr);
431            }
432            table.addContent(tbody);
433            Content li = HtmlTree.LI(HtmlStyle.blockList, table);
434            Content ul = HtmlTree.UL(HtmlStyle.blockList, li);
435            contentTree.addContent(ul);
436        }
437    }
438
439    /**
440     * Add package deprecation information to the documentation tree
441     *
442     * @param deprPkgs list of deprecated packages
443     * @param headingKey the caption for the deprecated package table
444     * @param tableSummary the summary for the deprecated package table
445     * @param tableHeader table headers for the deprecated package table
446     * @param contentTree the content tree to which the deprecated package table will be added
447     */
448    protected void addPackageDeprecatedAPI(SortedSet<Element> deprPkgs, String headingKey,
449            String tableSummary, List<String> tableHeader, Content contentTree) {
450        if (deprPkgs.size() > 0) {
451            Content caption = getTableCaption(configuration.getContent(headingKey));
452            Content table = (configuration.isOutputHtml5())
453                    ? HtmlTree.TABLE(HtmlStyle.deprecatedSummary, caption)
454                    : HtmlTree.TABLE(HtmlStyle.deprecatedSummary, tableSummary, caption);
455            table.addContent(getSummaryTableHeader(tableHeader, "col"));
456            Content tbody = new HtmlTree(HtmlTag.TBODY);
457            boolean altColor = true;
458            for (Element e : deprPkgs) {
459                PackageElement pkg = (PackageElement) e;
460                HtmlTree thRow = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst,
461                        getPackageLink(pkg, getPackageName(pkg)));
462                HtmlTree tr = HtmlTree.TR(thRow);
463                HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
464                tdDesc.addStyle(HtmlStyle.colLast);
465                List<? extends DocTree> tags = utils.getDeprecatedTrees(pkg);
466                if (!tags.isEmpty()) {
467                    addInlineDeprecatedComment(pkg, tags.get(0), tdDesc);
468                }
469                tr.addContent(tdDesc);
470                tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
471                altColor = !altColor;
472                tbody.addContent(tr);
473            }
474            table.addContent(tbody);
475            Content li = HtmlTree.LI(HtmlStyle.blockList, table);
476            Content ul = HtmlTree.UL(HtmlStyle.blockList, li);
477            contentTree.addContent(ul);
478        }
479    }
480}
481