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 static org.jdrupes.mdoclet.internal.doclets.toolkit.util.VisibleMemberTable.Kind.CONSTRUCTORS;
029
030import java.util.Arrays;
031import java.util.List;
032
033import javax.lang.model.element.Element;
034import javax.lang.model.element.ExecutableElement;
035import javax.lang.model.element.TypeElement;
036
037import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.ContentBuilder;
038import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.Entity;
039import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlId;
040import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlStyle;
041import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.HtmlTree;
042import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.TagName;
043import org.jdrupes.mdoclet.internal.doclets.formats.html.markup.Text;
044import org.jdrupes.mdoclet.internal.doclets.toolkit.ConstructorWriter;
045import org.jdrupes.mdoclet.internal.doclets.toolkit.Content;
046import org.jdrupes.mdoclet.internal.doclets.toolkit.MemberSummaryWriter;
047import org.jdrupes.mdoclet.internal.doclets.toolkit.util.VisibleMemberTable;
048
049/**
050 * Writes constructor documentation.
051 */
052public class ConstructorWriterImpl extends AbstractExecutableMemberWriter
053        implements ConstructorWriter, MemberSummaryWriter {
054
055    private boolean foundNonPubConstructor = false;
056
057    /**
058     * Construct a new ConstructorWriterImpl.
059     *
060     * @param writer The writer for the class that the constructors belong to.
061     * @param typeElement the class being documented.
062     */
063    public ConstructorWriterImpl(SubWriterHolderWriter writer,
064            TypeElement typeElement) {
065        super(writer, typeElement);
066
067        VisibleMemberTable vmt
068            = configuration.getVisibleMemberTable(typeElement);
069        List<? extends Element> constructors
070            = vmt.getVisibleMembers(CONSTRUCTORS);
071
072        for (Element constructor : constructors) {
073            if (utils.isProtected(constructor)
074                || utils.isPrivate(constructor)) {
075                setFoundNonPubConstructor(true);
076            }
077        }
078    }
079
080    /**
081     * Construct a new ConstructorWriterImpl.
082     *
083     * @param writer The writer for the class that the constructors belong to.
084     */
085    public ConstructorWriterImpl(SubWriterHolderWriter writer) {
086        super(writer);
087    }
088
089    @Override
090    public Content getMemberSummaryHeader(TypeElement typeElement,
091            Content content) {
092        content.add(MarkerComments.START_OF_CONSTRUCTOR_SUMMARY);
093        Content c = new ContentBuilder();
094        writer.addSummaryHeader(this, c);
095        return c;
096    }
097
098    @Override
099    public void addSummary(Content summariesList, Content content) {
100        writer.addSummary(HtmlStyle.constructorSummary,
101            HtmlIds.CONSTRUCTOR_SUMMARY, summariesList, content);
102    }
103
104    @Override
105    public Content getConstructorDetailsHeader(Content content) {
106        content.add(MarkerComments.START_OF_CONSTRUCTOR_DETAILS);
107        Content constructorDetails = new ContentBuilder();
108        var heading = HtmlTree.HEADING(Headings.TypeDeclaration.DETAILS_HEADING,
109            contents.constructorDetailsLabel);
110        constructorDetails.add(heading);
111        return constructorDetails;
112    }
113
114    @Override
115    public Content getConstructorHeaderContent(ExecutableElement constructor) {
116        Content content = new ContentBuilder();
117        var heading = HtmlTree.HEADING(Headings.TypeDeclaration.MEMBER_HEADING,
118            Text.of(name(constructor)));
119        HtmlId erasureAnchor = htmlIds.forErasure(constructor);
120        if (erasureAnchor != null) {
121            heading.setId(erasureAnchor);
122        }
123        content.add(heading);
124        return HtmlTree.SECTION(HtmlStyle.detail, content)
125            .setId(htmlIds.forMember(constructor));
126    }
127
128    @Override
129    public Content getSignature(ExecutableElement constructor) {
130        return new Signatures.MemberSignature(constructor, this)
131            .setParameters(getParameters(constructor, true))
132            .setExceptions(getExceptions(constructor))
133            .setAnnotations(writer.getAnnotationInfo(constructor, true))
134            .toContent();
135    }
136
137    @Override
138    public void addDeprecated(ExecutableElement constructor,
139            Content constructorContent) {
140        addDeprecatedInfo(constructor, constructorContent);
141    }
142
143    @Override
144    public void addPreview(ExecutableElement constructor, Content content) {
145        addPreviewInfo(constructor, content);
146    }
147
148    @Override
149    public void addComments(ExecutableElement constructor,
150            Content constructorContent) {
151        addComment(constructor, constructorContent);
152    }
153
154    @Override
155    public void addTags(ExecutableElement constructor,
156            Content constructorContent) {
157        writer.addTagsInfo(constructor, constructorContent);
158    }
159
160    @Override
161    public Content getConstructorDetails(Content memberDetailsHeader,
162            Content memberDetails) {
163        return writer.getDetailsListItem(
164            HtmlTree.SECTION(HtmlStyle.constructorDetails)
165                .setId(HtmlIds.CONSTRUCTOR_DETAIL)
166                .add(memberDetailsHeader)
167                .add(memberDetails));
168    }
169
170    @Override
171    public void setFoundNonPubConstructor(boolean foundNonPubConstructor) {
172        this.foundNonPubConstructor = foundNonPubConstructor;
173    }
174
175    @Override
176    public void addSummaryLabel(Content content) {
177        var label = HtmlTree.HEADING(Headings.TypeDeclaration.SUMMARY_HEADING,
178            contents.constructorSummaryLabel);
179        content.add(label);
180    }
181
182    @Override
183    public TableHeader getSummaryTableHeader(Element member) {
184        if (foundNonPubConstructor) {
185            return new TableHeader(contents.modifierLabel,
186                contents.constructorLabel,
187                contents.descriptionLabel);
188        } else {
189            return new TableHeader(contents.constructorLabel,
190                contents.descriptionLabel);
191        }
192    }
193
194    @Override
195    protected Table<Element> createSummaryTable() {
196        List<HtmlStyle> bodyRowStyles;
197
198        if (foundNonPubConstructor) {
199            bodyRowStyles = Arrays.asList(HtmlStyle.colFirst,
200                HtmlStyle.colConstructorName,
201                HtmlStyle.colLast);
202        } else {
203            bodyRowStyles = Arrays.asList(HtmlStyle.colConstructorName,
204                HtmlStyle.colLast);
205        }
206
207        return new Table<Element>(
208            HtmlStyle.summaryTable)
209                .setCaption(contents.constructors)
210                .setHeader(getSummaryTableHeader(typeElement))
211                .setColumnStyles(bodyRowStyles);
212    }
213
214    @Override
215    public void addInheritedSummaryLabel(TypeElement typeElement,
216            Content content) {
217    }
218
219    @Override
220    protected void addSummaryType(Element member, Content content) {
221        if (foundNonPubConstructor) {
222            var code = new HtmlTree(TagName.CODE);
223            if (utils.isProtected(member)) {
224                code.add("protected ");
225            } else if (utils.isPrivate(member)) {
226                code.add("private ");
227            } else if (utils.isPublic(member)) {
228                code.add(Entity.NO_BREAK_SPACE);
229            } else {
230                code.add(
231                    resources.getText("doclet.Package_private"));
232            }
233            content.add(code);
234        }
235    }
236
237    @Override
238    public Content getMemberHeader() {
239        return writer.getMemberHeader();
240    }
241}