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.*;
029
030import javax.lang.model.element.Element;
031import javax.lang.model.element.TypeElement;
032
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.HtmlId;
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.toolkit.Content;
039import org.jdrupes.mdoclet.internal.doclets.toolkit.util.DocPath;
040
041import com.sun.source.doctree.DeprecatedTree;
042import com.sun.source.doctree.DocTree;
043
044/**
045 * This abstract class exists to provide functionality needed in the
046 * the formatting of member information.  Since AbstractSubWriter and its
047 * subclasses control this, they would be the logical place to put this.
048 * However, because each member type has its own subclass, subclassing
049 * can not be used effectively to change formatting.  The concrete
050 * class subclass of this class can be subclassed to change formatting.
051 *
052 * @see AbstractMemberWriter
053 * @see ClassWriterImpl
054 */
055public abstract class SubWriterHolderWriter extends HtmlDocletWriter {
056
057    /**
058     * The HTML builder for the body contents.
059     */
060    protected BodyContents bodyContents = new BodyContents();
061
062    public SubWriterHolderWriter(HtmlConfiguration configuration,
063            DocPath filename) {
064        super(configuration, filename);
065    }
066
067    /**
068     * Add the summary header.
069     *
070     * @param mw the writer for the member being documented
071     * @param memberContent the content to which the summary header will be added
072     */
073    public void addSummaryHeader(AbstractMemberWriter mw,
074            Content memberContent) {
075        mw.addSummaryLabel(memberContent);
076    }
077
078    /**
079     * Add the inherited summary header.
080     *
081     * @param mw the writer for the member being documented
082     * @param typeElement the te to be documented
083     * @param inheritedContent the content to which the inherited summary header will be added
084     */
085    public void addInheritedSummaryHeader(AbstractMemberWriter mw,
086            TypeElement typeElement,
087            Content inheritedContent) {
088        mw.addInheritedSummaryLabel(typeElement, inheritedContent);
089    }
090
091    /**
092     * Add the index comment.
093     *
094     * @param member the member being documented
095     * @param content the content to which the comment will be added
096     */
097    protected void addIndexComment(Element member, Content content) {
098        List<? extends DocTree> tags = utils.getFirstSentenceTrees(member);
099        addIndexComment(member, tags, content);
100    }
101
102    /**
103     * Add the index comment.
104     *
105     * @param member the member being documented
106     * @param firstSentenceTags the first sentence tags for the member to be documented
107     * @param tdSummaryContent the content to which the comment will be added
108     */
109    protected void addIndexComment(Element member,
110            List<? extends DocTree> firstSentenceTags,
111            Content tdSummaryContent) {
112        addPreviewSummary(member, tdSummaryContent);
113        List<? extends DeprecatedTree> deprs = utils.getDeprecatedTrees(member);
114        Content div;
115        if (utils.isDeprecated(member)) {
116            var deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
117                getDeprecatedPhrase(member));
118            div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
119            if (!deprs.isEmpty()) {
120                addSummaryDeprecatedComment(member, deprs.get(0), div);
121            }
122            tdSummaryContent.add(div);
123            return;
124        } else {
125            Element te = member.getEnclosingElement();
126            if (te != null && utils.isTypeElement(te)
127                && utils.isDeprecated(te)) {
128                var deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
129                    getDeprecatedPhrase(te));
130                div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
131                tdSummaryContent.add(div);
132            }
133        }
134        addSummaryComment(member, firstSentenceTags, tdSummaryContent);
135    }
136
137    /**
138     * Add the summary link for the member.
139     *
140     * @param member the member to be documented
141     * @param content the content to which the link will be added
142     */
143    public void addSummaryLinkComment(Element member, Content content) {
144        List<? extends DocTree> tags = utils.getFirstSentenceTrees(member);
145        addSummaryLinkComment(member, tags, content);
146    }
147
148    /**
149     * Add the summary link comment.
150     *
151     * @param member the member being documented
152     * @param firstSentenceTags the first sentence tags for the member to be documented
153     * @param tdSummaryContent the content to which the comment will be added
154     */
155    public void addSummaryLinkComment(Element member,
156            List<? extends DocTree> firstSentenceTags,
157            Content tdSummaryContent) {
158        addIndexComment(member, firstSentenceTags, tdSummaryContent);
159    }
160
161    /**
162     * Add the inherited member summary.
163     *
164     * @param mw the writer for the member being documented
165     * @param typeElement the class being documented
166     * @param member the member being documented
167     * @param isFirst true if it is the first link being documented
168     * @param linksContent the content to which the summary will be added
169     */
170    public void addInheritedMemberSummary(AbstractMemberWriter mw,
171            TypeElement typeElement,
172            Element member,
173            boolean isFirst,
174            Content linksContent) {
175        if (!isFirst) {
176            linksContent.add(", ");
177        }
178        mw.addInheritedSummaryLink(typeElement, member, linksContent);
179    }
180
181    /**
182     * {@return the document content header}
183     */
184    public Content getContentHeader() {
185        return new ContentBuilder();
186    }
187
188    /**
189     * Add the class content.
190     *
191     * @param source class content which will be added to the documentation
192     */
193    public void addClassContent(Content source) {
194        bodyContents.addMainContent(source);
195    }
196
197    /**
198     * Add the annotation content.
199     *
200     * @param source annotation content which will be added to the documentation
201     */
202    public void addAnnotationContent(Content source) {
203        addClassContent(source);
204    }
205
206    /**
207     * {@return the member header}
208     */
209    public Content getMemberHeader() {
210        return HtmlTree.UL(HtmlStyle.blockList);
211    }
212
213    /**
214     * Returns a list to be used for the list of summaries for members of a given kind.
215     *
216     * @return a list to be used for the list of summaries for members of a given kind
217     */
218    public Content getSummariesList() {
219        return HtmlTree.UL(HtmlStyle.summaryList);
220    }
221
222    /**
223     * Returns an item for the list of summaries for members of a given kind.
224     *
225     * @param content content for the item
226     * @return an item for the list of summaries for members of a given kind
227     */
228    public Content getSummariesListItem(Content content) {
229        return HtmlTree.LI(content);
230    }
231
232    /**
233     * Returns a list to be used for the list of details for members of a given kind.
234     *
235     * @return a list to be used for the list of details for members of a given kind
236     */
237    public Content getDetailsList() {
238        return HtmlTree.UL(HtmlStyle.detailsList);
239    }
240
241    /**
242     * Returns an item for the list of details for members of a given kind.
243     *
244     * @param content content for the item
245     * @return an item for the list of details for members of a given kind
246     */
247    public Content getDetailsListItem(Content content) {
248        return HtmlTree.LI(content);
249    }
250
251    /**
252     * {@return a list to add member items to}
253     */
254    public Content getMemberList() {
255        return HtmlTree.UL(HtmlStyle.memberList);
256    }
257
258    /**
259     * {@return a member item}
260     *
261     * @param member the member to represent as an item
262     */
263    public Content getMemberListItem(Content member) {
264        return HtmlTree.LI(member);
265    }
266
267    public Content getMemberInherited() {
268        return HtmlTree.DIV(HtmlStyle.inheritedList);
269    }
270
271    /**
272     * Adds a section for a summary with the given CSS {@code class} and {@code id} attribute.
273     *
274     * @param style  the CSS class for the section
275     * @param htmlId the id for the section
276     * @param target the list of summary sections to which the summary will be added
277     * @param source the content representing the summary
278     */
279    public void addSummary(HtmlStyle style, HtmlId htmlId, Content target,
280            Content source) {
281        var htmlTree = HtmlTree.SECTION(style, source)
282            .setId(htmlId);
283        target.add(getSummariesListItem(htmlTree));
284    }
285
286    /**
287     * {@return the member content}
288     *
289     * @param content the content used to generate the complete member
290     */
291    public Content getMember(Content content) {
292        return HtmlTree.LI(content);
293    }
294
295    /**
296     * {@return the member summary content}
297     *
298     * @param memberContent the content used to generate the member summary
299     */
300    public Content getMemberSummary(Content memberContent) {
301        return HtmlTree.SECTION(HtmlStyle.summary, memberContent);
302    }
303
304    /**
305     * {@return the member details}
306     *
307     * @param content the content used to generate the member details
308     */
309    public Content getMemberDetailsContent(Content content) {
310        return HtmlTree.SECTION(HtmlStyle.details, content);
311    }
312
313    /**
314     * Get the member content
315     *
316     * @param id the id to be used for the content
317     * @param style the style class to be added to the content
318     * @param source the content used to generate the complete member content
319     * @return the member content
320     */
321    public Content getMember(HtmlId id, HtmlStyle style, Content source) {
322        return HtmlTree.SECTION(style, source).setId(id);
323    }
324}