001/*
002 * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package org.jdrupes.mdoclet.internal.doclets.formats.html;
027
028import java.util.SortedSet;
029
030import javax.lang.model.element.PackageElement;
031
032import org.jdrupes.mdoclet.internal.doclets.formats.html.Navigation.PageMode;
033import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.BodyContents;
034import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.ContentBuilder;
035import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlStyle;
036import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlTree;
037import org.jdrupes.mdoclet.internal.doclets.toolkit.Content;
038import org.jdrupes.mdoclet.internal.doclets.toolkit.util.ClassTree;
039import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocFileIOException;
040import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocPath;
041import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocPaths;
042
043/**
044 * Generate Class Hierarchy page for all the Classes in this run.  Use
045 * ClassTree for building the Tree. The name of
046 * the generated file is "overview-tree.html" and it is generated in the
047 * current or the destination directory.
048 */
049public class TreeWriter extends AbstractTreeWriter {
050
051    /**
052     * Packages in this run.
053     */
054    SortedSet<PackageElement> packages;
055
056    /**
057     * True if there are no packages specified on the command line,
058     * False otherwise.
059     */
060    private final boolean classesOnly;
061
062    protected BodyContents bodyContents;
063
064    /**
065     * Constructor to construct TreeWriter object.
066     *
067     * @param configuration the current configuration of the doclet.
068     * @param filename String filename
069     * @param classTree the tree being built.
070     */
071    public TreeWriter(HtmlConfiguration configuration, DocPath filename,
072            ClassTree classTree) {
073        super(configuration, filename, classTree);
074        packages = configuration.packages;
075        classesOnly = packages.isEmpty();
076        this.bodyContents = new BodyContents();
077    }
078
079    /**
080     * Create a TreeWriter object and use it to generate the
081     * "overview-tree.html" file.
082     *
083     * @param configuration the configuration for this doclet
084     * @param classTree the class tree being documented.
085     * @throws  DocFileIOException if there is a problem generating the overview tree page
086     */
087    public static void generate(HtmlConfiguration configuration,
088            ClassTree classTree) throws DocFileIOException {
089        DocPath filename = DocPaths.OVERVIEW_TREE;
090        TreeWriter treegen = new TreeWriter(configuration, filename, classTree);
091        treegen.generateTreeFile();
092    }
093
094    /**
095     * Generate the interface hierarchy and class hierarchy.
096     *
097     * @throws DocFileIOException if there is a problem generating the overview tree page
098     */
099    public void generateTreeFile() throws DocFileIOException {
100        HtmlTree body = getBody();
101        Content headContent = contents.hierarchyForAllPackages;
102        var heading = HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING,
103            HtmlStyle.title, headContent);
104        var div = HtmlTree.DIV(HtmlStyle.header, heading);
105        Content mainContent = new ContentBuilder();
106        mainContent.add(div);
107        addPackageTreeLinks(mainContent);
108        addTree(classTree.classes(), "doclet.Class_Hierarchy", mainContent);
109        addTree(classTree.interfaces(), "doclet.Interface_Hierarchy",
110            mainContent);
111        addTree(classTree.annotationInterfaces(),
112            "doclet.Annotation_Type_Hierarchy", mainContent);
113        addTree(classTree.enumClasses(), "doclet.Enum_Hierarchy", mainContent);
114        addTree(classTree.recordClasses(), "doclet.Record_Class_Hierarchy",
115            mainContent);
116        body.add(bodyContents
117            .addMainContent(mainContent)
118            .setFooter(getFooter()));
119        printHtmlDocument(null, "class tree", body);
120    }
121
122    /**
123     * Add the links to all the package tree files.
124     *
125     * @param content the content to which the links will be added
126     */
127    protected void addPackageTreeLinks(Content content) {
128        // Do nothing if only unnamed package is used
129        if (isUnnamedPackage()) {
130            return;
131        }
132        if (!classesOnly) {
133            var span = HtmlTree.SPAN(HtmlStyle.packageHierarchyLabel,
134                contents.packageHierarchies);
135            content.add(span);
136            var ul = HtmlTree.UL(HtmlStyle.horizontal)
137                .addStyle(HtmlStyle.contentsList);
138            int i = 0;
139            for (PackageElement pkg : packages) {
140                // If the package name length is 0 or if -nodeprecated option
141                // is set and the package is marked as deprecated, do not
142                // include
143                // the page in the list of package hierarchies.
144                if (pkg.isUnnamed() ||
145                    (options.noDeprecated() && utils.isDeprecated(pkg))) {
146                    i++;
147                    continue;
148                }
149                DocPath link = pathString(pkg, DocPaths.PACKAGE_TREE);
150                var li = HtmlTree.LI(links.createLink(link,
151                    getLocalizedPackageName(pkg)));
152                if (i < packages.size() - 1) {
153                    li.add(", ");
154                }
155                ul.add(li);
156                i++;
157            }
158            content.add(ul);
159        }
160    }
161
162    /**
163     * {@return a new HTML BODY element}
164     */
165    private HtmlTree getBody() {
166        String title = resources.getText("doclet.Window_Class_Hierarchy");
167        HtmlTree bodyTree = getBody(getWindowTitle(title));
168        bodyContents.setHeader(getHeader(PageMode.TREE));
169        return bodyTree;
170    }
171
172    private boolean isUnnamedPackage() {
173        return packages.size() == 1 && packages.first().isUnnamed();
174    }
175}