001/*
002 * Copyright (c) 2018, 2023, 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.ArrayList;
029import java.util.List;
030import java.util.Set;
031
032import javax.lang.model.element.TypeElement;
033
034import org.jdrupes.mdoclet.internal.doclets.formats.html.Navigation.PageMode;
035import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.BodyContents;
036import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.ContentBuilder;
037import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlStyle;
038import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlTree;
039import org.jdrupes.mdoclet.internal.doclets.toolkit.Content;
040import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocFileIOException;
041import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocPath;
042import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocPaths;
043import org.jdrupes.mdoclet.internal.doclets.toolkit.util.IndexBuilder;
044import org.jdrupes.mdoclet.internal.doclets.toolkit.util.IndexItem;
045import org.jdrupes.mdoclet.internal.doclets.toolkit.util.Utils.ElementFlag;
046
047import com.sun.source.doctree.DeprecatedTree;
048
049/**
050 * Generate the file with list of all the classes in this run.
051 */
052public class AllClassesIndexWriter extends HtmlDocletWriter {
053
054    /**
055     * Index of all the classes.
056     */
057    protected IndexBuilder indexBuilder;
058
059    /**
060     * Construct AllClassesIndexWriter object. Also initializes the indexBuilder variable in this
061     * class.
062     *
063     * @param configuration The current configuration
064     * @param filename Path to the file which is getting generated.
065     * @param indexBuilder Unicode based Index from {@link IndexBuilder}
066     */
067    public AllClassesIndexWriter(HtmlConfiguration configuration,
068            DocPath filename, IndexBuilder indexBuilder) {
069        super(configuration, filename);
070        this.indexBuilder = indexBuilder;
071    }
072
073    /**
074     * Create AllClassesIndexWriter object.
075     *
076     * @param configuration The current configuration
077     * @param indexBuilder IndexBuilder object for all classes index.
078     * @throws DocFileIOException
079     */
080    public static void generate(HtmlConfiguration configuration,
081            IndexBuilder indexBuilder) throws DocFileIOException {
082        generate(configuration, indexBuilder, DocPaths.ALLCLASSES_INDEX);
083    }
084
085    private static void generate(HtmlConfiguration configuration,
086            IndexBuilder indexBuilder,
087            DocPath fileName) throws DocFileIOException {
088        AllClassesIndexWriter allClassGen
089            = new AllClassesIndexWriter(configuration,
090                fileName, indexBuilder);
091        allClassGen.buildAllClassesFile();
092    }
093
094    /**
095     * Print all the classes in the file.
096     */
097    protected void buildAllClassesFile() throws DocFileIOException {
098        String label = resources.getText("doclet.All_Classes_And_Interfaces");
099        Content allClassesContent = new ContentBuilder();
100        addContents(allClassesContent);
101        Content mainContent = new ContentBuilder();
102        mainContent.add(allClassesContent);
103        HtmlTree body = getBody(getWindowTitle(label));
104        body.add(new BodyContents()
105            .setHeader(getHeader(PageMode.ALL_CLASSES))
106            .addMainContent(mainContent)
107            .setFooter(getFooter()));
108        printHtmlDocument(null, "class index", body);
109    }
110
111    /**
112     * Add all types to the content.
113     *
114     * @param target the content to which the links will be added
115     */
116    protected void addContents(Content target) {
117        var table = new Table<TypeElement>(HtmlStyle.summaryTable)
118            .setHeader(
119                new TableHeader(contents.classLabel, contents.descriptionLabel))
120            .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast)
121            .setId(HtmlIds.ALL_CLASSES_TABLE)
122            .setDefaultTab(contents.allClassesAndInterfacesLabel)
123            .addTab(contents.interfaces, utils::isPlainInterface)
124            .addTab(contents.classes, e -> utils.isNonThrowableClass(e))
125            .addTab(contents.enums, utils::isEnum)
126            .addTab(contents.records, e -> utils.isRecord(e))
127            .addTab(contents.exceptionClasses, e -> utils.isThrowable(e))
128            .addTab(contents.annotationTypes, utils::isAnnotationInterface);
129        for (Character unicode : indexBuilder.getFirstCharacters()) {
130            for (IndexItem indexItem : indexBuilder.getItems(unicode)) {
131                TypeElement typeElement = (TypeElement) indexItem.getElement();
132                if (typeElement != null && utils.isCoreClass(typeElement)) {
133                    addTableRow(table, typeElement);
134                }
135            }
136        }
137        Content titleContent = contents.allClassesAndInterfacesLabel;
138        var pHeading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING,
139            HtmlStyle.title, titleContent);
140        var headerDiv = HtmlTree.DIV(HtmlStyle.header, pHeading);
141        target.add(headerDiv);
142        if (!table.isEmpty()) {
143            target.add(table);
144        }
145    }
146
147    /**
148     * Add table row.
149     *
150     * @param table the table to which the row will be added
151     * @param klass the type to be added to the table
152     */
153    protected void addTableRow(Table<TypeElement> table, TypeElement klass) {
154        List<Content> rowContents = new ArrayList<>();
155        Content classLink = getLink(new HtmlLinkInfo(
156            configuration, HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_IN_LABEL, klass));
157        ContentBuilder description = new ContentBuilder();
158        Set<ElementFlag> flags = utils.elementFlags(klass);
159        if (flags.contains(ElementFlag.PREVIEW)) {
160            description.add(contents.previewPhrase);
161            addSummaryComment(klass, description);
162        } else if (flags.contains(ElementFlag.DEPRECATED)) {
163            description.add(getDeprecatedPhrase(klass));
164            List<? extends DeprecatedTree> tags
165                = utils.getDeprecatedTrees(klass);
166            if (!tags.isEmpty()) {
167                addSummaryDeprecatedComment(klass, tags.get(0), description);
168            }
169        } else {
170            addSummaryComment(klass, description);
171        }
172        rowContents.add(classLink);
173        rowContents.add(description);
174        table.addRow(klass, rowContents);
175    }
176}