ModuleWriterImpl.java revision 3692:87b48a8fb3cf
1/*
2 * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.javadoc.internal.doclets.formats.html;
27
28import java.util.ArrayList;
29import java.util.EnumMap;
30import java.util.List;
31import java.util.Map;
32
33import javax.lang.model.element.ModuleElement;
34import javax.lang.model.element.ModuleElement.DirectiveKind;
35import javax.lang.model.element.PackageElement;
36import javax.lang.model.element.TypeElement;
37
38import com.sun.source.doctree.DocTree;
39import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
40import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
41import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
42import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
43import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
44import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
45import jdk.javadoc.internal.doclets.toolkit.Content;
46import jdk.javadoc.internal.doclets.toolkit.ModuleSummaryWriter;
47import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
48import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
49import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
50
51/**
52 * Class to generate file for each module contents in the right-hand
53 * frame. This will list all the packages and Class Kinds in the module. A click on any
54 * class-kind will update the frame with the clicked class-kind page. A click on any
55 * package will update the frame with the clicked module package page.
56 *
57 *  <p><b>This is NOT part of any supported API.
58 *  If you write code that depends on this, you do so at your own risk.
59 *  This code and its internal interfaces are subject to change or
60 *  deletion without notice.</b>
61 *
62 * @author Bhavesh Patel
63 */
64public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryWriter {
65
66    /**
67     * The prev module name in the alpha-order list.
68     */
69    protected ModuleElement prevModule;
70
71    /**
72     * The next module name in the alpha-order list.
73     */
74    protected ModuleElement nextModule;
75
76    /**
77     * The module being documented.
78     */
79    protected ModuleElement mdle;
80
81    private final Map<ModuleElement.DirectiveKind, List<ModuleElement.Directive>> directiveMap
82            = new EnumMap<>(ModuleElement.DirectiveKind.class);
83
84    /**
85     * The HTML tree for main tag.
86     */
87    protected HtmlTree mainTree = HtmlTree.MAIN();
88
89    /**
90     * The HTML tree for section tag.
91     */
92    protected HtmlTree sectionTree = HtmlTree.SECTION();
93
94    /**
95     * Constructor to construct ModuleWriter object and to generate
96     * "moduleName-summary.html" file.
97     *
98     * @param configuration the configuration of the doclet.
99     * @param mdle        Module under consideration.
100     * @param prevModule   Previous module in the sorted array.
101     * @param nextModule   Next module in the sorted array.
102     */
103    public ModuleWriterImpl(ConfigurationImpl configuration,
104            ModuleElement mdle, ModuleElement prevModule, ModuleElement nextModule) {
105        super(configuration, DocPaths.moduleSummary(mdle));
106        this.prevModule = prevModule;
107        this.nextModule = nextModule;
108        this.mdle = mdle;
109        generateDirectiveMap();
110    }
111
112    /**
113     * Get the module header.
114     *
115     * @param heading the heading for the section
116     */
117    public Content getModuleHeader(String heading) {
118        HtmlTree bodyTree = getBody(true, getWindowTitle(mdle.getQualifiedName().toString()));
119        HtmlTree htmlTree = (configuration.allowTag(HtmlTag.HEADER))
120                ? HtmlTree.HEADER()
121                : bodyTree;
122        addTop(htmlTree);
123        addNavLinks(true, htmlTree);
124        if (configuration.allowTag(HtmlTag.HEADER)) {
125            bodyTree.addContent(htmlTree);
126        }
127        HtmlTree div = new HtmlTree(HtmlTag.DIV);
128        div.addStyle(HtmlStyle.header);
129        Content tHeading = HtmlTree.HEADING(HtmlConstants.TITLE_HEADING, true,
130                HtmlStyle.title, contents.moduleLabel);
131        tHeading.addContent(Contents.SPACE);
132        Content moduleHead = new RawHtml(heading);
133        tHeading.addContent(moduleHead);
134        div.addContent(tHeading);
135        if (configuration.allowTag(HtmlTag.MAIN)) {
136            mainTree.addContent(div);
137        } else {
138            bodyTree.addContent(div);
139        }
140        return bodyTree;
141    }
142
143    /**
144     * Get the content header.
145     */
146    public Content getContentHeader() {
147        HtmlTree div = new HtmlTree(HtmlTag.DIV);
148        div.addStyle(HtmlStyle.contentContainer);
149        return div;
150    }
151
152    /**
153     * Get the summary section header.
154     */
155    public Content getSummaryHeader() {
156        HtmlTree li = new HtmlTree(HtmlTag.LI);
157        li.addStyle(HtmlStyle.blockList);
158        return li;
159    }
160
161    /**
162     * Get the summary tree.
163     *
164     * @param summaryContentTree the content tree to be added to the summary tree.
165     */
166    public Content getSummaryTree(Content summaryContentTree) {
167        HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, summaryContentTree);
168        return ul;
169    }
170
171    /**
172     * Generate the directive map for the directives on the module.
173     */
174    public void generateDirectiveMap() {
175        for (ModuleElement.Directive d : mdle.getDirectives()) {
176            if (directiveMap.containsKey(d.getKind())) {
177                List<ModuleElement.Directive> dir = directiveMap.get(d.getKind());
178                dir.add(d);
179                directiveMap.put(d.getKind(), dir);
180            } else {
181                List<ModuleElement.Directive> dir = new ArrayList<>();
182                dir.add(d);
183                directiveMap.put(d.getKind(), dir);
184            }
185        }
186    }
187
188    /**
189     * Add the summary header.
190     *
191     * @param startMarker the marker comment
192     * @param markerAnchor the marker anchor for the section
193     * @param heading the heading for the section
194     * @param htmltree the content tree to which the information is added
195     */
196    public void addSummaryHeader(Content startMarker, SectionName markerAnchor, Content heading, Content htmltree) {
197        htmltree.addContent(startMarker);
198        htmltree.addContent(getMarkerAnchor(markerAnchor));
199        htmltree.addContent(HtmlTree.HEADING(HtmlTag.H3, heading));
200    }
201
202    /**
203     * Add the summary for the module.
204     *
205     * @param text the table caption
206     * @param tableSummary the summary for the table
207     * @param htmltree the content tree to which the table will be added
208     * @param tableStyle the table style
209     * @param tableHeader the table header
210     * @param dirs the list of module directives
211     */
212    public void addSummary(String text, String tableSummary, Content htmltree, HtmlStyle tableStyle,
213            List<String> tableHeader, List<ModuleElement.Directive> dirs) {
214        Content table = (configuration.isOutputHtml5())
215                ? HtmlTree.TABLE(tableStyle, getTableCaption(new RawHtml(text)))
216                : HtmlTree.TABLE(tableStyle, tableSummary, getTableCaption(new RawHtml(text)));
217        table.addContent(getSummaryTableHeader(tableHeader, "col"));
218        Content tbody = new HtmlTree(HtmlTag.TBODY);
219        addList(dirs, tbody);
220        table.addContent(tbody);
221        htmltree.addContent(table);
222    }
223
224    /**
225     * Add the list of directives for the module.
226     *
227     * @param dirs the list of module directives
228     * @params tbody the content tree to which the list is added
229     */
230    public void addList(List<ModuleElement.Directive> dirs, Content tbody) {
231        boolean altColor = true;
232        for (ModuleElement.Directive direct : dirs) {
233            DirectiveKind kind = direct.getKind();
234            switch (kind) {
235                case REQUIRES:
236                    addRequiresList((ModuleElement.RequiresDirective) direct, tbody, altColor);
237                    break;
238                case EXPORTS:
239                    addExportedPackagesList((ModuleElement.ExportsDirective) direct, tbody, altColor);
240                    break;
241                case USES:
242                    addUsesList((ModuleElement.UsesDirective) direct, tbody, altColor);
243                    break;
244                case PROVIDES:
245                    addProvidesList((ModuleElement.ProvidesDirective) direct, tbody, altColor);
246                    break;
247                default:
248                    throw new AssertionError("unknown directive kind: " + kind);
249            }
250            altColor = !altColor;
251        }
252    }
253
254    /**
255     * {@inheritDoc}
256     */
257    public void addModulesSummary(Content summaryContentTree) {
258        List<ModuleElement.Directive> dirs = directiveMap.get(DirectiveKind.REQUIRES);
259        if (dirs != null && !dirs.isEmpty()) {
260            HtmlTree li = new HtmlTree(HtmlTag.LI);
261            li.addStyle(HtmlStyle.blockList);
262            addSummaryHeader(HtmlConstants.START_OF_MODULES_SUMMARY, SectionName.MODULES,
263                    contents.navModules, li);
264            String text = configuration.getText("doclet.Requires_Summary");
265            String tableSummary = configuration.getText("doclet.Member_Table_Summary",
266                    configuration.getText("doclet.Requires_Summary"),
267                    configuration.getText("doclet.modules"));
268            addRequiresSummary(text, tableSummary, dirs, li);
269            HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
270            summaryContentTree.addContent(ul);
271        }
272    }
273
274    /**
275     * Add the requires summary for the module.
276     *
277     * @param text the table caption
278     * @param tableSummary the summary for the table
279     * @param dirs the list of module directives
280     * @param htmltree the content tree to which the table will be added
281     */
282    public void addRequiresSummary(String text, String tableSummary, List<ModuleElement.Directive> dirs,
283            Content htmltree) {
284        addSummary(text, tableSummary, htmltree, HtmlStyle.requiresSummary, requiresTableHeader, dirs);
285    }
286
287    /**
288     * Add the requires directive list for the module.
289     *
290     * @param direct the requires directive
291     * @param tbody the content tree to which the directive will be added
292     * @param altColor true if altColor style should be used or false if rowColor style should be used
293     */
294    public void addRequiresList(ModuleElement.RequiresDirective direct, Content tbody, boolean altColor) {
295        ModuleElement m = direct.getDependency();
296        Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName().toString()));
297        Content thPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, moduleLinkContent);
298        HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
299        tdSummary.addStyle(HtmlStyle.colLast);
300        addSummaryComment(m, tdSummary);
301        HtmlTree tr = HtmlTree.TR(thPackage);
302        tr.addContent(tdSummary);
303        tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
304        tbody.addContent(tr);
305    }
306
307    /**
308     * {@inheritDoc}
309     */
310    public void addPackagesSummary(Content summaryContentTree) {
311        List<ModuleElement.Directive> dirs = directiveMap.get(DirectiveKind.EXPORTS);
312        if (dirs != null && !dirs.isEmpty()) {
313            HtmlTree li = new HtmlTree(HtmlTag.LI);
314            li.addStyle(HtmlStyle.blockList);
315            addSummaryHeader(HtmlConstants.START_OF_PACKAGES_SUMMARY, SectionName.PACKAGES,
316                    contents.navPackages, li);
317            String text = configuration.getText("doclet.Exported_Packages_Summary");
318            String tableSummary = configuration.getText("doclet.Member_Table_Summary",
319                    configuration.getText("doclet.Exported_Packages_Summary"),
320                    configuration.getText("doclet.packages"));
321            addExportedPackagesSummary(text, tableSummary, dirs, li);
322            HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
323            summaryContentTree.addContent(ul);
324        }
325    }
326
327    /**
328     * Add the exported packages summary for the module.
329     *
330     * @param text the table caption
331     * @param tableSummary the summary for the table
332     * @param dirs the list of module directives
333     * @param htmltree the content tree to which the table will be added
334     */
335    public void addExportedPackagesSummary(String text, String tableSummary, List<ModuleElement.Directive> dirs,
336            Content htmltree) {
337        addSummary(text, tableSummary, htmltree, HtmlStyle.packagesSummary, exportedPackagesTableHeader, dirs);
338    }
339
340    /**
341     * Add the exported packages list for the module.
342     *
343     * @param direct the requires directive
344     * @param tbody the content tree to which the directive will be added
345     * @param altColor true if altColor style should be used or false if rowColor style should be used
346     */
347    public void addExportedPackagesList(ModuleElement.ExportsDirective direct, Content tbody, boolean altColor) {
348        PackageElement pkg = direct.getPackage();
349        Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
350        Content tdPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, pkgLinkContent);
351        HtmlTree thModules = new HtmlTree(HtmlTag.TD);
352        thModules.addStyle(HtmlStyle.colSecond);
353        List<? extends ModuleElement> targetModules = direct.getTargetModules();
354        if (targetModules != null) {
355            List<? extends ModuleElement> mElements = direct.getTargetModules();
356            for (int i = 0; i < mElements.size(); i++) {
357                if (i > 0) {
358                    thModules.addContent(new HtmlTree(HtmlTag.BR));
359                }
360                ModuleElement m = mElements.get(i);
361                thModules.addContent(new StringContent(m.getQualifiedName().toString()));
362            }
363        } else {
364            thModules.addContent(configuration.getText("doclet.All_Modules"));
365        }
366        HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
367        tdSummary.addStyle(HtmlStyle.colLast);
368        addSummaryComment(pkg, tdSummary);
369        HtmlTree tr = HtmlTree.TR(tdPackage);
370        tr.addContent(thModules);
371        tr.addContent(tdSummary);
372        tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
373        tbody.addContent(tr);
374    }
375
376    /**
377     * {@inheritDoc}
378     */
379    public void addServicesSummary(Content summaryContentTree) {
380        List<ModuleElement.Directive> usesDirs = directiveMap.get(DirectiveKind.USES);
381        List<ModuleElement.Directive> providesDirs = directiveMap.get(DirectiveKind.PROVIDES);
382        if ((usesDirs != null && !usesDirs.isEmpty()) || (providesDirs != null && !providesDirs.isEmpty())) {
383            HtmlTree li = new HtmlTree(HtmlTag.LI);
384            li.addStyle(HtmlStyle.blockList);
385            addSummaryHeader(HtmlConstants.START_OF_SERVICES_SUMMARY, SectionName.SERVICES,
386                    contents.navServices, li);
387            String text;
388            String tableSummary;
389            if (usesDirs != null && !usesDirs.isEmpty()) {
390                text = configuration.getText("doclet.Uses_Summary");
391                tableSummary = configuration.getText("doclet.Member_Table_Summary",
392                        configuration.getText("doclet.Uses_Summary"),
393                        configuration.getText("doclet.types"));
394                addUsesSummary(text, tableSummary, usesDirs, li);
395            }
396            if (providesDirs != null && !providesDirs.isEmpty()) {
397                text = configuration.getText("doclet.Provides_Summary");
398                tableSummary = configuration.getText("doclet.Member_Table_Summary",
399                        configuration.getText("doclet.Provides_Summary"),
400                        configuration.getText("doclet.types"));
401                addProvidesSummary(text, tableSummary, providesDirs, li);
402            }
403            HtmlTree ul = HtmlTree.UL(HtmlStyle.blockList, li);
404            summaryContentTree.addContent(ul);
405        }
406    }
407
408    /**
409     * Add the uses summary for the module.
410     *
411     * @param text the table caption
412     * @param tableSummary the summary for the table
413     * @param dirs the list of module directives
414     * @param htmltree the content tree to which the table will be added
415     */
416    public void addUsesSummary(String text, String tableSummary, List<ModuleElement.Directive> dirs,
417            Content htmltree) {
418        addSummary(text, tableSummary, htmltree, HtmlStyle.usesSummary, usesTableHeader, dirs);
419    }
420
421    /**
422     * Add the uses list for the module.
423     *
424     * @param direct the requires directive
425     * @param tbody the content tree to which the directive will be added
426     * @param altColor true if altColor style should be used or false if rowColor style should be used
427     */
428    public void addUsesList(ModuleElement.UsesDirective direct, Content tbody, boolean altColor) {
429        TypeElement type = direct.getService();
430        Content typeLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, type));
431        Content thPackage = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, typeLinkContent);
432        HtmlTree tdSummary = new HtmlTree(HtmlTag.TD);
433        tdSummary.addStyle(HtmlStyle.colLast);
434        addSummaryComment(type, tdSummary);
435        HtmlTree tr = HtmlTree.TR(thPackage);
436        tr.addContent(tdSummary);
437        tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
438        tbody.addContent(tr);
439    }
440
441    /**
442     * Add the provides summary for the module.
443     *
444     * @param text the table caption
445     * @param tableSummary the summary for the table
446     * @param dirs the list of module directives
447     * @param htmltree the content tree to which the table will be added
448     */
449    public void addProvidesSummary(String text, String tableSummary, List<ModuleElement.Directive> dirs,
450            Content htmltree) {
451        addSummary(text, tableSummary, htmltree, HtmlStyle.providesSummary, providesTableHeader, dirs);
452    }
453
454    /**
455     * Add the exported packages list for the module.
456     *
457     * @param direct the requires directive
458     * @param tbody the content tree to which the directive will be added
459     * @param altColor true if altColor style should be used or false if rowColor style should be used
460     */
461    public void addProvidesList(ModuleElement.ProvidesDirective direct, Content tbody, boolean altColor) {
462        TypeElement impl = direct.getImplementation();
463        TypeElement srv = direct.getService();
464        Content implLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, impl));
465        Content srvLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, srv));
466        HtmlTree thType = HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, srvLinkContent);
467        thType.addContent(new HtmlTree(HtmlTag.BR));
468        thType.addContent("(");
469        HtmlTree implSpan = HtmlTree.SPAN(HtmlStyle.implementationLabel, contents.implementation);
470        thType.addContent(implSpan);
471        thType.addContent(Contents.SPACE);
472        thType.addContent(implLinkContent);
473        thType.addContent(")");
474        HtmlTree tdDesc = new HtmlTree(HtmlTag.TD);
475        tdDesc.addStyle(HtmlStyle.colLast);
476        addSummaryComment(srv, tdDesc);
477        HtmlTree tr = HtmlTree.TR(thType);
478        tr.addContent(tdDesc);
479        tr.addStyle(altColor ? HtmlStyle.altColor : HtmlStyle.rowColor);
480        tbody.addContent(tr);
481    }
482
483    /**
484     * {@inheritDoc}
485     */
486    public void addModuleDescription(Content moduleContentTree) {
487        if (!utils.getFullBody(mdle).isEmpty()) {
488            Content tree = configuration.allowTag(HtmlTag.SECTION) ? HtmlTree.SECTION() : moduleContentTree;
489            tree.addContent(HtmlConstants.START_OF_MODULE_DESCRIPTION);
490            tree.addContent(getMarkerAnchor(SectionName.MODULE_DESCRIPTION));
491            addInlineComment(mdle, tree);
492            if (configuration.allowTag(HtmlTag.SECTION)) {
493                moduleContentTree.addContent(tree);
494            }
495        }
496    }
497
498    /**
499     * {@inheritDoc}
500     */
501    public void addModuleTags(Content moduleContentTree) {
502        Content tree = (configuration.allowTag(HtmlTag.SECTION))
503                ? HtmlTree.SECTION()
504                : moduleContentTree;
505        addTagsInfo(mdle, tree);
506        if (configuration.allowTag(HtmlTag.SECTION)) {
507            moduleContentTree.addContent(tree);
508        }
509    }
510
511    /**
512     * Add summary details to the navigation bar.
513     *
514     * @param subDiv the content tree to which the summary detail links will be added
515     */
516    protected void addSummaryDetailLinks(Content subDiv) {
517        Content div = HtmlTree.DIV(getNavSummaryLinks());
518        subDiv.addContent(div);
519    }
520
521    /**
522     * Get summary links for navigation bar.
523     *
524     * @return the content tree for the navigation summary links
525     */
526    protected Content getNavSummaryLinks() {
527        Content li = HtmlTree.LI(contents.moduleSubNavLabel);
528        li.addContent(Contents.SPACE);
529        Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
530        Content liNav = new HtmlTree(HtmlTag.LI);
531        liNav.addContent(!utils.getFullBody(mdle).isEmpty() && !configuration.nocomment
532                ? getHyperLink(SectionName.MODULE_DESCRIPTION, contents.navModuleDescription)
533                : contents.navModuleDescription);
534        addNavGap(liNav);
535        liNav.addContent(showDirectives(DirectiveKind.REQUIRES)
536                ? getHyperLink(SectionName.MODULES, contents.navModules)
537                : contents.navModules);
538        addNavGap(liNav);
539        liNav.addContent(showDirectives(DirectiveKind.EXPORTS)
540                ? getHyperLink(SectionName.PACKAGES, contents.navPackages)
541                : contents.navPackages);
542        addNavGap(liNav);
543        liNav.addContent((showDirectives(DirectiveKind.USES) || showDirectives(DirectiveKind.PROVIDES))
544                ? getHyperLink(SectionName.SERVICES, contents.navServices)
545                : contents.navServices);
546        ulNav.addContent(liNav);
547        return ulNav;
548    }
549
550    /**
551     * Return true if the directive should be displayed.
552     *
553     * @param dirKind the kind of directive for the module
554     * @return true if the directive should be displayed
555     */
556    private boolean showDirectives(DirectiveKind dirKind) {
557        return directiveMap.get(dirKind) != null && !directiveMap.get(dirKind).isEmpty();
558    }
559
560    /**
561     * {@inheritDoc}
562     */
563    public void addModuleContent(Content contentTree, Content moduleContentTree) {
564        if (configuration.allowTag(HtmlTag.MAIN)) {
565            mainTree.addContent(moduleContentTree);
566            contentTree.addContent(mainTree);
567        } else {
568            contentTree.addContent(moduleContentTree);
569        }
570    }
571
572    /**
573     * {@inheritDoc}
574     */
575    public void addModuleFooter(Content contentTree) {
576        Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
577                ? HtmlTree.FOOTER()
578                : contentTree;
579        addNavLinks(false, htmlTree);
580        addBottom(htmlTree);
581        if (configuration.allowTag(HtmlTag.FOOTER)) {
582            contentTree.addContent(htmlTree);
583        }
584    }
585
586    /**
587     * {@inheritDoc}
588     */
589    @Override
590    public void printDocument(Content contentTree) throws DocFileIOException {
591        printHtmlDocument(configuration.metakeywords.getMetaKeywordsForModule(mdle),
592                true, contentTree);
593    }
594
595    /**
596     * Add the module package deprecation information to the documentation tree.
597     *
598     * @param li the content tree to which the deprecation information will be added
599     * @param pkg the PackageDoc that is added
600     */
601    public void addPackageDeprecationInfo(Content li, PackageElement pkg) {
602        List<? extends DocTree> deprs;
603        if (utils.isDeprecated(pkg)) {
604            deprs = utils.getDeprecatedTrees(pkg);
605            HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
606            deprDiv.addStyle(HtmlStyle.deprecatedContent);
607            Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, contents.deprecatedPhrase);
608            deprDiv.addContent(deprPhrase);
609            if (!deprs.isEmpty()) {
610                CommentHelper ch = utils.getCommentHelper(pkg);
611                List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
612                if (!commentTags.isEmpty()) {
613                    addInlineDeprecatedComment(pkg, deprs.get(0), deprDiv);
614                }
615            }
616            li.addContent(deprDiv);
617        }
618    }
619
620    /**
621     * Get this module link.
622     *
623     * @return a content tree for the module link
624     */
625    @Override
626    protected Content getNavLinkModule() {
627        Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.moduleLabel);
628        return li;
629    }
630
631    /**
632     * Get "PREV MODULE" link in the navigation bar.
633     *
634     * @return a content tree for the previous link
635     */
636    public Content getNavLinkPrevious() {
637        Content li;
638        if (prevModule == null) {
639            li = HtmlTree.LI(contents.prevModuleLabel);
640        } else {
641            li = HtmlTree.LI(getHyperLink(pathToRoot.resolve(DocPaths.moduleSummary(
642                    prevModule)), contents.prevModuleLabel, "", ""));
643        }
644        return li;
645    }
646
647    /**
648     * Get "NEXT MODULE" link in the navigation bar.
649     *
650     * @return a content tree for the next link
651     */
652    public Content getNavLinkNext() {
653        Content li;
654        if (nextModule == null) {
655            li = HtmlTree.LI(contents.nextModuleLabel);
656        } else {
657            li = HtmlTree.LI(getHyperLink(pathToRoot.resolve(DocPaths.moduleSummary(
658                    nextModule)), contents.nextModuleLabel, "", ""));
659        }
660        return li;
661    }
662}
663