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

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