001/*
002 * Copyright (c) 1998, 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.Set;
029
030import javax.lang.model.element.PackageElement;
031import javax.lang.model.element.TypeElement;
032
033import org.jdrupes.mdoclet.internal.doclets.formats.html.Navigation.PageMode;
034import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.ContentBuilder;
035import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.Entity;
036import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlStyle;
037import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlTree;
038import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.Text;
039import org.jdrupes.mdoclet.internal.doclets.toolkit.Content;
040import org.jdrupes.mdoclet.internal.doclets.toolkit.SerializedFormWriter;
041import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocFileIOException;
042import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocPaths;
043import org.jdrupes.mdoclet.internal.doclets.toolkit.util.IndexItem;
044
045/**
046 * Generates the Serialized Form Information Page, <i>serialized-form.html</i>.
047 */
048public class SerializedFormWriterImpl extends SubWriterHolderWriter
049        implements SerializedFormWriter {
050
051    Set<TypeElement> visibleClasses;
052
053    /**
054     * @param configuration the configuration data for the doclet
055     */
056    public SerializedFormWriterImpl(HtmlConfiguration configuration) {
057        super(configuration, DocPaths.SERIALIZED_FORM);
058        visibleClasses = configuration.getIncludedTypeElements();
059        configuration.conditionalPages
060            .add(HtmlConfiguration.ConditionalPage.SERIALIZED_FORM);
061    }
062
063    /**
064     * Get the given header.
065     *
066     * @param header the header to write
067     * @return the body content
068     */
069    @Override
070    public Content getHeader(String header) {
071        HtmlTree body = getBody(getWindowTitle(header));
072        Content h1Content = Text.of(header);
073        var heading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING,
074            HtmlStyle.title, h1Content);
075        var div = HtmlTree.DIV(HtmlStyle.header, heading);
076        bodyContents.setHeader(getHeader(PageMode.SERIALIZED_FORM))
077            .addMainContent(div);
078        return body;
079    }
080
081    /**
082     * Get the serialized form summaries header.
083     *
084     * @return the serialized form summaries header
085     */
086    @Override
087    public Content getSerializedSummariesHeader() {
088        return HtmlTree.UL(HtmlStyle.blockList);
089    }
090
091    /**
092     * Get the package serialized form header.
093     *
094     * @return the package serialized form header tree
095     */
096    @Override
097    public Content getPackageSerializedHeader() {
098        return HtmlTree.SECTION(HtmlStyle.serializedPackageContainer);
099    }
100
101    @Override
102    public Content getPackageHeader(PackageElement packageElement) {
103        var heading
104            = HtmlTree.HEADING_TITLE(Headings.SerializedForm.PACKAGE_HEADING,
105                contents.packageLabel);
106        heading.add(Entity.NO_BREAK_SPACE);
107        heading.add(getPackageLink(packageElement,
108            Text.of(utils.getPackageName(packageElement))));
109        return heading;
110    }
111
112    @Override
113    public Content getClassSerializedHeader() {
114        return HtmlTree.UL(HtmlStyle.blockList);
115    }
116
117    /**
118     * Checks if a class is generated and is visible.
119     *
120     * @param typeElement the class being processed.
121     * @return true if the class, that is being processed, is generated and is visible.
122     */
123    public boolean isVisibleClass(TypeElement typeElement) {
124        return visibleClasses.contains(typeElement)
125            && configuration.isGeneratedDoc(typeElement)
126            && !utils.hasHiddenTag(typeElement);
127    }
128
129    @Override
130    public Content getClassHeader(TypeElement typeElement) {
131        Content classLink = (isVisibleClass(typeElement))
132            ? getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.PLAIN,
133                typeElement)
134                    .label(configuration.getClassName(typeElement)))
135            : Text.of(utils.getFullyQualifiedName(typeElement));
136        var section = HtmlTree.SECTION(HtmlStyle.serializedClassDetails)
137            .setId(htmlIds.forClass(typeElement));
138        Content superClassLink = typeElement.getSuperclass() != null
139            ? getLink(new HtmlLinkInfo(configuration,
140                HtmlLinkInfo.Kind.LINK_TYPE_PARAMS_AND_BOUNDS,
141                typeElement.getSuperclass()))
142            : null;
143        Content interfaceLink = getLink(new HtmlLinkInfo(configuration,
144            HtmlLinkInfo.Kind.LINK_TYPE_PARAMS_AND_BOUNDS,
145            utils.isExternalizable(typeElement)
146                ? utils.getExternalizableType()
147                : utils.getSerializableType()));
148
149        // Print the heading.
150        Content className = new ContentBuilder();
151        className.add(utils.getTypeElementKindName(typeElement, false));
152        className.add(Entity.NO_BREAK_SPACE);
153        className.add(classLink);
154        section.add(
155            HtmlTree.HEADING(Headings.SerializedForm.CLASS_HEADING, className));
156        // Print a simplified signature.
157        Content signature = new ContentBuilder();
158        signature.add("class ");
159        signature.add(typeElement.getSimpleName());
160        signature.add(" extends ");
161        signature.add(superClassLink);
162        signature.add(" implements ");
163        signature.add(interfaceLink);
164        section.add(HtmlTree.DIV(HtmlStyle.typeSignature, signature));
165        return section;
166    }
167
168    @Override
169    public Content getSerialUIDInfoHeader() {
170        return HtmlTree.DL(HtmlStyle.nameValue);
171    }
172
173    /**
174     * Adds the serial UID info.
175     *
176     * @param header the header that will show up before the UID.
177     * @param serialUID the serial UID to print.
178     * @param target the serial UID content to which the serial UID
179     *               content will be added
180     */
181    @Override
182    public void addSerialUIDInfo(String header,
183            String serialUID,
184            Content target) {
185        Content headerContent = Text.of(header);
186        target.add(HtmlTree.DT(headerContent));
187        Content serialContent = Text.of(serialUID);
188        target.add(HtmlTree.DD(serialContent));
189    }
190
191    @Override
192    public Content getClassContentHeader() {
193        return HtmlTree.UL(HtmlStyle.blockList);
194    }
195
196    /**
197     * Add the serialized content section.
198     *
199     * @param source the serialized content to be added
200     */
201    @Override
202    public void addSerializedContent(Content source) {
203        bodyContents.addMainContent(source);
204    }
205
206    @Override
207    public void addPackageSerialized(Content serializedSummaries,
208            Content packageSerialized) {
209        serializedSummaries.add(HtmlTree.LI(packageSerialized));
210    }
211
212    /**
213     * Add the footer.
214     */
215    @Override
216    public void addFooter() {
217        bodyContents.setFooter(getFooter());
218    }
219
220    @Override
221    public void printDocument(Content source) throws DocFileIOException {
222        source.add(bodyContents);
223        printHtmlDocument(null, "serialized forms", source);
224
225        if (configuration.mainIndex != null) {
226            configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS,
227                resources.getText("doclet.Serialized_Form"), path));
228        }
229    }
230
231    /**
232     * Return an instance of a SerialFieldWriter.
233     *
234     * @return an instance of a SerialFieldWriter.
235     */
236    @Override
237    public SerialFieldWriter getSerialFieldWriter(TypeElement typeElement) {
238        return new HtmlSerialFieldWriter(this, typeElement);
239    }
240
241    /**
242     * Return an instance of a SerialMethodWriter.
243     *
244     * @return an instance of a SerialMethodWriter.
245     */
246    @Override
247    public SerialMethodWriter getSerialMethodWriter(TypeElement typeElement) {
248        return new HtmlSerialMethodWriter(this, typeElement);
249    }
250}