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