duke@1: /* jjg@1735: * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as ohair@554: * published by the Free Software Foundation. Oracle designates this duke@1: * particular file as subject to the "Classpath" exception as provided ohair@554: * by Oracle in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@554: * or visit www.oracle.com if you need additional information or have any ohair@554: * questions. duke@1: */ duke@1: duke@1: package com.sun.tools.doclets.formats.html; duke@1: bpatel@233: import com.sun.javadoc.*; jjg@1743: import com.sun.tools.doclets.formats.html.markup.ContentBuilder; jjg@1743: import com.sun.tools.doclets.formats.html.markup.HtmlStyle; jjg@1742: import com.sun.tools.doclets.formats.html.markup.HtmlTree; jjg@1743: import com.sun.tools.doclets.formats.html.markup.RawHtml; jjg@1742: import com.sun.tools.doclets.formats.html.markup.StringContent; duke@1: import com.sun.tools.doclets.internal.toolkit.*; duke@1: import com.sun.tools.doclets.internal.toolkit.builders.SerializedFormBuilder; duke@1: import com.sun.tools.doclets.internal.toolkit.taglets.*; duke@1: import com.sun.tools.doclets.internal.toolkit.util.*; duke@1: duke@1: /** duke@1: * The taglet writer that writes HTML. duke@1: * jjg@1359: *

This is NOT part of any supported API. jjg@1359: * If you write code that depends on this, you do so at your own risk. jjg@1359: * This code and its internal interfaces are subject to change or jjg@1359: * deletion without notice. jjg@1359: * duke@1: * @since 1.5 duke@1: * @author Jamie Ho bpatel@233: * @author Bhavesh Patel (Modified) duke@1: */ duke@1: duke@1: public class TagletWriterImpl extends TagletWriter { duke@1: jjg@1410: private final HtmlDocletWriter htmlWriter; jjg@1410: private final ConfigurationImpl configuration; duke@1: duke@1: public TagletWriterImpl(HtmlDocletWriter htmlWriter, boolean isFirstSentence) { jjg@1410: super(isFirstSentence); duke@1: this.htmlWriter = htmlWriter; jjg@1410: configuration = htmlWriter.configuration; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content getOutputInstance() { jjg@1751: return new ContentBuilder(); duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: protected Content codeTagOutput(Tag tag) { jjg@1742: Content result = HtmlTree.CODE(new StringContent(tag.text())); jjg@1751: return result; jjg@1742: } jjg@1742: jjg@1742: /** jjg@1742: * {@inheritDoc} jjg@1742: */ jjg@1751: public Content getDocRootOutput() { jjg@1751: String path; jjg@1410: if (configuration.docrootparent.length() > 0) jjg@1751: path = configuration.docrootparent; jjg@1372: else if (htmlWriter.pathToRoot.isEmpty()) jjg@1751: path = "."; bpatel@997: else jjg@1751: path = htmlWriter.pathToRoot.getPath(); jjg@1751: return new StringContent(path); duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content deprecatedTagOutput(Doc doc) { jjg@1743: ContentBuilder result = new ContentBuilder(); duke@1: Tag[] deprs = doc.tags("deprecated"); duke@1: if (doc instanceof ClassDoc) { duke@1: if (Util.isDeprecated((ProgramElementDoc) doc)) { jjg@1743: result.addContent(HtmlTree.SPAN(HtmlStyle.strong, jjg@1743: new StringContent(configuration.getText("doclet.Deprecated")))); jjg@1743: result.addContent(RawHtml.nbsp); duke@1: if (deprs.length > 0) { duke@1: Tag[] commentTags = deprs[0].inlineTags(); duke@1: if (commentTags.length > 0) { jjg@1743: result.addContent(commentTagsToOutput(null, doc, jjg@1751: deprs[0].inlineTags(), false) duke@1: ); duke@1: } duke@1: } duke@1: } duke@1: } else { duke@1: MemberDoc member = (MemberDoc) doc; duke@1: if (Util.isDeprecated((ProgramElementDoc) doc)) { jjg@1743: result.addContent(HtmlTree.SPAN(HtmlStyle.strong, jjg@1743: new StringContent(configuration.getText("doclet.Deprecated")))); jjg@1743: result.addContent(RawHtml.nbsp); duke@1: if (deprs.length > 0) { jjg@1751: Content body = commentTagsToOutput(null, doc, jjg@1743: deprs[0].inlineTags(), false); jjg@1751: result.addContent(HtmlTree.I(body)); duke@1: } duke@1: } else { duke@1: if (Util.isDeprecated(member.containingClass())) { jjg@1743: result.addContent(HtmlTree.SPAN(HtmlStyle.strong, jjg@1743: new StringContent(configuration.getText("doclet.Deprecated")))); jjg@1743: result.addContent(RawHtml.nbsp); duke@1: } duke@1: } duke@1: } jjg@1751: return result; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: protected Content literalTagOutput(Tag tag) { jjg@1742: Content result = new StringContent(tag.text()); jjg@1751: return result; jjg@1742: } jjg@1742: jjg@1742: /** jjg@1742: * {@inheritDoc} jjg@1742: */ duke@1: public MessageRetriever getMsgRetriever() { jjg@1410: return configuration.message; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content getParamHeader(String header) { jjg@1743: HtmlTree result = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, jjg@1743: new StringContent(header))); jjg@1751: return result; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content paramTagOutput(ParamTag paramTag, String paramName) { jjg@1743: ContentBuilder body = new ContentBuilder(); jjg@1743: body.addContent(HtmlTree.CODE(new RawHtml(paramName))); jjg@1743: body.addContent(" - "); jjg@1745: body.addContent(htmlWriter.commentTagsToContent(paramTag, null, paramTag.inlineTags(), false)); jjg@1743: HtmlTree result = HtmlTree.DD(body); jjg@1751: return result; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content propertyTagOutput(Tag tag, String prefix) { jjg@1749: Content body = new ContentBuilder(); jjg@1749: body.addContent(new RawHtml(prefix)); jjg@1749: body.addContent(" "); jjg@1749: body.addContent(HtmlTree.CODE(new RawHtml(tag.text()))); jjg@1749: body.addContent("."); jjg@1749: Content result = HtmlTree.P(body); jjg@1751: return result; jjg@1749: } jjg@1749: jjg@1749: /** jjg@1749: * {@inheritDoc} jjg@1749: */ jjg@1751: public Content returnTagOutput(Tag returnTag) { jjg@1743: ContentBuilder result = new ContentBuilder(); jjg@1743: result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, jjg@1743: new StringContent(configuration.getText("doclet.Returns"))))); jjg@1745: result.addContent(HtmlTree.DD(htmlWriter.commentTagsToContent( jjg@1745: returnTag, null, returnTag.inlineTags(), false))); jjg@1751: return result; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content seeTagOutput(Doc holder, SeeTag[] seeTags) { jjg@1743: ContentBuilder body = new ContentBuilder(); duke@1: if (seeTags.length > 0) { duke@1: for (int i = 0; i < seeTags.length; ++i) { jjg@1743: appendSeparatorIfNotEmpty(body); jjg@1745: body.addContent(htmlWriter.seeTagToContent(seeTags[i])); duke@1: } duke@1: } duke@1: if (holder.isField() && ((FieldDoc)holder).constantValue() != null && duke@1: htmlWriter instanceof ClassWriterImpl) { duke@1: //Automatically add link to constant values page for constant fields. jjg@1743: appendSeparatorIfNotEmpty(body); jjg@1373: DocPath constantsPath = jjg@1373: htmlWriter.pathToRoot.resolve(DocPaths.CONSTANT_VALUES); jjg@1373: String whichConstant = jjg@1373: ((ClassWriterImpl) htmlWriter).getClassDoc().qualifiedName() + "." + ((FieldDoc) holder).name(); jjg@1373: DocLink link = constantsPath.fragment(whichConstant); jjg@1743: body.addContent(htmlWriter.getHyperLink(link, jjg@1743: new StringContent(configuration.getText("doclet.Constants_Summary")))); duke@1: } duke@1: if (holder.isClass() && ((ClassDoc)holder).isSerializable()) { duke@1: //Automatically add link to serialized form page for serializable classes. bpatel@233: if ((SerializedFormBuilder.serialInclude(holder) && duke@1: SerializedFormBuilder.serialInclude(((ClassDoc)holder).containingPackage()))) { jjg@1743: appendSeparatorIfNotEmpty(body); jjg@1373: DocPath serialPath = htmlWriter.pathToRoot.resolve(DocPaths.SERIALIZED_FORM); jjg@1373: DocLink link = serialPath.fragment(((ClassDoc)holder).qualifiedName()); jjg@1743: body.addContent(htmlWriter.getHyperLink(link, jjg@1743: new StringContent(configuration.getText("doclet.Serialized_Form")))); duke@1: } duke@1: } jjg@1743: if (body.isEmpty()) jjg@1751: return body; jjg@1743: jjg@1743: ContentBuilder result = new ContentBuilder(); jjg@1743: result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, jjg@1743: new StringContent(configuration.getText("doclet.See_Also"))))); jjg@1743: result.addContent(HtmlTree.DD(body)); jjg@1751: return result; jjg@1743: duke@1: } duke@1: jjg@1743: private void appendSeparatorIfNotEmpty(ContentBuilder body) { jjg@1743: if (!body.isEmpty()) { jjg@1743: body.addContent(", "); jjg@1743: body.addContent(DocletConstants.NL); duke@1: } jjg@1743: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content simpleTagOutput(Tag[] simpleTags, String header) { jjg@1743: ContentBuilder result = new ContentBuilder(); jjg@1743: result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, new RawHtml(header)))); jjg@1743: ContentBuilder body = new ContentBuilder(); duke@1: for (int i = 0; i < simpleTags.length; i++) { duke@1: if (i > 0) { jjg@1743: body.addContent(", "); duke@1: } jjg@1745: body.addContent(htmlWriter.commentTagsToContent( jjg@1745: simpleTags[i], null, simpleTags[i].inlineTags(), false)); duke@1: } jjg@1743: result.addContent(HtmlTree.DD(body)); jjg@1751: return result; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content simpleTagOutput(Tag simpleTag, String header) { jjg@1743: ContentBuilder result = new ContentBuilder(); jjg@1743: result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, new RawHtml(header)))); jjg@1745: Content body = htmlWriter.commentTagsToContent( jjg@1745: simpleTag, null, simpleTag.inlineTags(), false); jjg@1743: result.addContent(HtmlTree.DD(body)); jjg@1751: return result; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content getThrowsHeader() { jjg@1743: HtmlTree result = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.strong, jjg@1743: new StringContent(configuration.getText("doclet.Throws")))); jjg@1751: return result; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content throwsTagOutput(ThrowsTag throwsTag) { jjg@1743: ContentBuilder body = new ContentBuilder(); jjg@1743: Content excName = (throwsTag.exceptionType() == null) ? jjg@1743: new RawHtml(throwsTag.exceptionName()) : jjg@1735: htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, jjg@1743: throwsTag.exceptionType())); jjg@1743: body.addContent(HtmlTree.CODE(excName)); jjg@1745: Content desc = htmlWriter.commentTagsToContent(throwsTag, null, jjg@1743: throwsTag.inlineTags(), false); jjg@1743: if (desc != null && !desc.isEmpty()) { jjg@1743: body.addContent(" - "); jjg@1745: body.addContent(desc); duke@1: } jjg@1751: HtmlTree result = HtmlTree.DD(body); jjg@1751: return result; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content throwsTagOutput(Type throwsType) { jjg@1743: HtmlTree result = HtmlTree.DD(HtmlTree.CODE(htmlWriter.getLink( jjg@1743: new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, throwsType)))); jjg@1751: return result; duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content valueTagOutput(FieldDoc field, String constantVal, duke@1: boolean includeLink) { jjg@1751: return includeLink ? jjg@1735: htmlWriter.getDocLink(LinkInfoImpl.Kind.VALUE_TAG, field, jjg@1751: constantVal, false) : new RawHtml(constantVal); duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content commentTagsToOutput(Tag holderTag, Tag[] tags) { duke@1: return commentTagsToOutput(holderTag, null, tags, false); duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content commentTagsToOutput(Doc holderDoc, Tag[] tags) { duke@1: return commentTagsToOutput(null, holderDoc, tags, false); duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ jjg@1751: public Content commentTagsToOutput(Tag holderTag, duke@1: Doc holderDoc, Tag[] tags, boolean isFirstSentence) { jjg@1751: return htmlWriter.commentTagsToContent( jjg@1751: holderTag, holderDoc, tags, isFirstSentence); duke@1: } duke@1: duke@1: /** duke@1: * {@inheritDoc} duke@1: */ duke@1: public Configuration configuration() { jjg@1410: return configuration; duke@1: } duke@1: }