TagletWriterImpl.java revision 2571:10fc81ac75b4
1/*
2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.doclets.formats.html;
27
28import com.sun.javadoc.*;
29import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
30import com.sun.tools.doclets.formats.html.markup.HtmlStyle;
31import com.sun.tools.doclets.formats.html.markup.HtmlTree;
32import com.sun.tools.doclets.formats.html.markup.RawHtml;
33import com.sun.tools.doclets.formats.html.markup.StringContent;
34import com.sun.tools.doclets.internal.toolkit.*;
35import com.sun.tools.doclets.internal.toolkit.builders.SerializedFormBuilder;
36import com.sun.tools.doclets.internal.toolkit.taglets.*;
37import com.sun.tools.doclets.internal.toolkit.util.*;
38
39/**
40 * The taglet writer that writes HTML.
41 *
42 *  <p><b>This is NOT part of any supported API.
43 *  If you write code that depends on this, you do so at your own risk.
44 *  This code and its internal interfaces are subject to change or
45 *  deletion without notice.</b>
46 *
47 * @since 1.5
48 * @author Jamie Ho
49 * @author Bhavesh Patel (Modified)
50 */
51
52public class TagletWriterImpl extends TagletWriter {
53
54    private final HtmlDocletWriter htmlWriter;
55    private final ConfigurationImpl configuration;
56    private final Utils utils;
57
58    public TagletWriterImpl(HtmlDocletWriter htmlWriter, boolean isFirstSentence) {
59        super(isFirstSentence);
60        this.htmlWriter = htmlWriter;
61        configuration = htmlWriter.configuration;
62        this.utils = configuration.utils;
63    }
64
65    /**
66     * {@inheritDoc}
67     */
68    public Content getOutputInstance() {
69        return new ContentBuilder();
70    }
71
72    /**
73     * {@inheritDoc}
74     */
75    protected Content codeTagOutput(Tag tag) {
76        Content result = HtmlTree.CODE(new StringContent(utils.normalizeNewlines(tag.text())));
77        return result;
78    }
79
80    /**
81     * {@inheritDoc}
82     */
83    public Content getDocRootOutput() {
84        String path;
85        if (htmlWriter.pathToRoot.isEmpty())
86            path = ".";
87        else
88            path = htmlWriter.pathToRoot.getPath();
89        return new StringContent(path);
90    }
91
92    /**
93     * {@inheritDoc}
94     */
95    public Content deprecatedTagOutput(Doc doc) {
96        ContentBuilder result = new ContentBuilder();
97        Tag[] deprs = doc.tags("deprecated");
98        if (doc instanceof ClassDoc) {
99            if (utils.isDeprecated((ProgramElementDoc) doc)) {
100                result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
101                        new StringContent(configuration.getText("doclet.Deprecated"))));
102                result.addContent(RawHtml.nbsp);
103                if (deprs.length > 0) {
104                    Tag[] commentTags = deprs[0].inlineTags();
105                    if (commentTags.length > 0) {
106                        result.addContent(commentTagsToOutput(null, doc,
107                            deprs[0].inlineTags(), false)
108                        );
109                    }
110                }
111            }
112        } else {
113            MemberDoc member = (MemberDoc) doc;
114            if (utils.isDeprecated((ProgramElementDoc) doc)) {
115                result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
116                        new StringContent(configuration.getText("doclet.Deprecated"))));
117                result.addContent(RawHtml.nbsp);
118                if (deprs.length > 0) {
119                    Content body = commentTagsToOutput(null, doc,
120                        deprs[0].inlineTags(), false);
121                    if (!body.isEmpty())
122                        result.addContent(HtmlTree.SPAN(HtmlStyle.deprecationComment, body));
123                }
124            } else {
125                if (utils.isDeprecated(member.containingClass())) {
126                    result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
127                            new StringContent(configuration.getText("doclet.Deprecated"))));
128                    result.addContent(RawHtml.nbsp);
129                }
130            }
131        }
132        return result;
133    }
134
135    /**
136     * {@inheritDoc}
137     */
138    protected Content literalTagOutput(Tag tag) {
139        Content result = new StringContent(utils.normalizeNewlines(tag.text()));
140        return result;
141    }
142
143    /**
144     * {@inheritDoc}
145     */
146    public MessageRetriever getMsgRetriever() {
147        return configuration.message;
148    }
149
150    /**
151     * {@inheritDoc}
152     */
153    public Content getParamHeader(String header) {
154        HtmlTree result = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.paramLabel,
155                new StringContent(header)));
156        return result;
157    }
158
159    /**
160     * {@inheritDoc}
161     */
162    public Content paramTagOutput(ParamTag paramTag, String paramName) {
163        ContentBuilder body = new ContentBuilder();
164        body.addContent(HtmlTree.CODE(new RawHtml(paramName)));
165        body.addContent(" - ");
166        body.addContent(htmlWriter.commentTagsToContent(paramTag, null, paramTag.inlineTags(), false));
167        HtmlTree result = HtmlTree.DD(body);
168        return result;
169    }
170
171    /**
172     * {@inheritDoc}
173     */
174    public Content propertyTagOutput(Tag tag, String prefix) {
175        Content body = new ContentBuilder();
176        body.addContent(new RawHtml(prefix));
177        body.addContent(" ");
178        body.addContent(HtmlTree.CODE(new RawHtml(tag.text())));
179        body.addContent(".");
180        Content result = HtmlTree.P(body);
181        return result;
182    }
183
184    /**
185     * {@inheritDoc}
186     */
187    public Content returnTagOutput(Tag returnTag) {
188        ContentBuilder result = new ContentBuilder();
189        result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.returnLabel,
190                new StringContent(configuration.getText("doclet.Returns")))));
191        result.addContent(HtmlTree.DD(htmlWriter.commentTagsToContent(
192                returnTag, null, returnTag.inlineTags(), false)));
193        return result;
194    }
195
196    /**
197     * {@inheritDoc}
198     */
199    public Content seeTagOutput(Doc holder, SeeTag[] seeTags) {
200        ContentBuilder body = new ContentBuilder();
201        if (seeTags.length > 0) {
202            for (SeeTag seeTag : seeTags) {
203                appendSeparatorIfNotEmpty(body);
204                body.addContent(htmlWriter.seeTagToContent(seeTag));
205            }
206        }
207        if (holder.isField() && ((FieldDoc)holder).constantValue() != null &&
208                htmlWriter instanceof ClassWriterImpl) {
209            //Automatically add link to constant values page for constant fields.
210            appendSeparatorIfNotEmpty(body);
211            DocPath constantsPath =
212                    htmlWriter.pathToRoot.resolve(DocPaths.CONSTANT_VALUES);
213            String whichConstant =
214                    ((ClassWriterImpl) htmlWriter).getClassDoc().qualifiedName() + "." + ((FieldDoc) holder).name();
215            DocLink link = constantsPath.fragment(whichConstant);
216            body.addContent(htmlWriter.getHyperLink(link,
217                    new StringContent(configuration.getText("doclet.Constants_Summary"))));
218        }
219        if (holder.isClass() && ((ClassDoc)holder).isSerializable()) {
220            //Automatically add link to serialized form page for serializable classes.
221            if ((SerializedFormBuilder.serialInclude(holder) &&
222                      SerializedFormBuilder.serialInclude(((ClassDoc)holder).containingPackage()))) {
223                appendSeparatorIfNotEmpty(body);
224                DocPath serialPath = htmlWriter.pathToRoot.resolve(DocPaths.SERIALIZED_FORM);
225                DocLink link = serialPath.fragment(((ClassDoc)holder).qualifiedName());
226                body.addContent(htmlWriter.getHyperLink(link,
227                        new StringContent(configuration.getText("doclet.Serialized_Form"))));
228            }
229        }
230        if (body.isEmpty())
231            return body;
232
233        ContentBuilder result = new ContentBuilder();
234        result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.seeLabel,
235                new StringContent(configuration.getText("doclet.See_Also")))));
236        result.addContent(HtmlTree.DD(body));
237        return result;
238
239    }
240
241    private void appendSeparatorIfNotEmpty(ContentBuilder body) {
242        if (!body.isEmpty()) {
243            body.addContent(", ");
244            body.addContent(DocletConstants.NL);
245        }
246    }
247
248    /**
249     * {@inheritDoc}
250     */
251    public Content simpleTagOutput(Tag[] simpleTags, String header) {
252        ContentBuilder result = new ContentBuilder();
253        result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.simpleTagLabel, new RawHtml(header))));
254        ContentBuilder body = new ContentBuilder();
255        for (int i = 0; i < simpleTags.length; i++) {
256            if (i > 0) {
257                body.addContent(", ");
258            }
259            body.addContent(htmlWriter.commentTagsToContent(
260                    simpleTags[i], null, simpleTags[i].inlineTags(), false));
261        }
262        result.addContent(HtmlTree.DD(body));
263        return result;
264    }
265
266    /**
267     * {@inheritDoc}
268     */
269    public Content simpleTagOutput(Tag simpleTag, String header) {
270        ContentBuilder result = new ContentBuilder();
271        result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.simpleTagLabel, new RawHtml(header))));
272        Content body = htmlWriter.commentTagsToContent(
273                simpleTag, null, simpleTag.inlineTags(), false);
274        result.addContent(HtmlTree.DD(body));
275        return result;
276    }
277
278    /**
279     * {@inheritDoc}
280     */
281    public Content getThrowsHeader() {
282        HtmlTree result = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.throwsLabel,
283                new StringContent(configuration.getText("doclet.Throws"))));
284        return result;
285    }
286
287    /**
288     * {@inheritDoc}
289     */
290    public Content throwsTagOutput(ThrowsTag throwsTag) {
291        ContentBuilder body = new ContentBuilder();
292        Content excName = (throwsTag.exceptionType() == null) ?
293                new RawHtml(throwsTag.exceptionName()) :
294                htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER,
295                throwsTag.exceptionType()));
296        body.addContent(HtmlTree.CODE(excName));
297        Content desc = htmlWriter.commentTagsToContent(throwsTag, null,
298            throwsTag.inlineTags(), false);
299        if (desc != null && !desc.isEmpty()) {
300            body.addContent(" - ");
301            body.addContent(desc);
302        }
303        HtmlTree result = HtmlTree.DD(body);
304        return result;
305    }
306
307    /**
308     * {@inheritDoc}
309     */
310    public Content throwsTagOutput(Type throwsType) {
311        HtmlTree result = HtmlTree.DD(HtmlTree.CODE(htmlWriter.getLink(
312                new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, throwsType))));
313        return result;
314    }
315
316    /**
317     * {@inheritDoc}
318     */
319    public Content valueTagOutput(FieldDoc field, String constantVal,
320            boolean includeLink) {
321        return includeLink ?
322            htmlWriter.getDocLink(LinkInfoImpl.Kind.VALUE_TAG, field,
323                constantVal, false) : new RawHtml(constantVal);
324    }
325
326    /**
327     * {@inheritDoc}
328     */
329    public Content commentTagsToOutput(Tag holderTag, Tag[] tags) {
330        return commentTagsToOutput(holderTag, null, tags, false);
331    }
332
333    /**
334     * {@inheritDoc}
335     */
336    public Content commentTagsToOutput(Doc holderDoc, Tag[] tags) {
337        return commentTagsToOutput(null, holderDoc, tags, false);
338    }
339
340    /**
341     * {@inheritDoc}
342     */
343    public Content commentTagsToOutput(Tag holderTag,
344        Doc holderDoc, Tag[] tags, boolean isFirstSentence) {
345        return htmlWriter.commentTagsToContent(
346            holderTag, holderDoc, tags, isFirstSentence);
347    }
348
349    /**
350     * {@inheritDoc}
351     */
352    public Configuration configuration() {
353        return configuration;
354    }
355}
356