1 /* 2 * Copyright (c) 1997, 2016, 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 26 package jdk.javadoc.internal.doclets.formats.html; 27 28 import java.io.*; 29 import java.util.*; 30 31 import javax.lang.model.element.Element; 32 import javax.lang.model.element.TypeElement; 33 34 import com.sun.source.doctree.DocTree; 35 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 36 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; 37 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 38 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; 39 import jdk.javadoc.internal.doclets.toolkit.Content; 40 import jdk.javadoc.internal.doclets.toolkit.util.DocPath; 41 import jdk.javadoc.internal.doclets.toolkit.util.MethodTypes; 42 43 /** 44 * This abstract class exists to provide functionality needed in the 45 * the formatting of member information. Since AbstractSubWriter and its 46 * subclasses control this, they would be the logical place to put this. 47 * However, because each member type has its own subclass, subclassing 48 * can not be used effectively to change formatting. The concrete 49 * class subclass of this class can be subclassed to change formatting. 50 * 51 * <p><b>This is NOT part of any supported API. 52 * If you write code that depends on this, you do so at your own risk. 53 * This code and its internal interfaces are subject to change or 54 * deletion without notice.</b> 55 * 56 * @see AbstractMemberWriter 57 * @see ClassWriterImpl 58 * 59 * @author Robert Field 60 * @author Atul M Dambalkar 61 * @author Bhavesh Patel (Modified) 62 */ 63 public abstract class SubWriterHolderWriter extends HtmlDocletWriter { 64 65 /** 66 * The HTML tree for main tag. 67 */ 68 protected HtmlTree mainTree = HtmlTree.MAIN(); 69 70 public SubWriterHolderWriter(ConfigurationImpl configuration, DocPath filename) 71 throws IOException { 72 super(configuration, filename); 73 } 74 75 /** 76 * Add the summary header. 77 * 78 * @param mw the writer for the member being documented 79 * @param typeElement the te to be documented 80 * @param memberTree the content tree to which the summary header will be added 81 */ 82 public void addSummaryHeader(AbstractMemberWriter mw, TypeElement typeElement, 83 Content memberTree) { 84 mw.addSummaryAnchor(typeElement, memberTree); 85 mw.addSummaryLabel(memberTree); 86 } 87 88 /** 89 * Get the summary table. 90 * 91 * @param mw the writer for the member being documented 92 * @param typeElement the te to be documented 93 * @param tableContents list of summary table contents 94 * @param showTabs true if the table needs to show tabs 95 * @return the content tree for the summary table 96 */ 97 public Content getSummaryTableTree(AbstractMemberWriter mw, TypeElement typeElement, 98 List<Content> tableContents, boolean showTabs) { 99 Content caption; 100 if (showTabs) { 101 caption = getTableCaption(mw.methodTypes); 102 generateMethodTypesScript(mw.typeMap, mw.methodTypes); 103 } 104 else { 105 caption = getTableCaption(mw.getCaption()); 106 } 107 Content table = (configuration.isOutputHtml5()) 108 ? HtmlTree.TABLE(HtmlStyle.memberSummary, caption) 109 : HtmlTree.TABLE(HtmlStyle.memberSummary, mw.getTableSummary(), caption); 110 table.addContent(getSummaryTableHeader(mw.getSummaryTableHeader(typeElement), "col")); 111 for (Content tableContent : tableContents) { 112 table.addContent(tableContent); 113 } 114 return table; 115 } 116 117 /** 118 * Get the summary table caption. 119 * 120 * @param methodTypes set comprising of method types to show as table caption 121 * @return the caption for the summary table 122 */ 123 public Content getTableCaption(Set<MethodTypes> methodTypes) { 124 Content tabbedCaption = new HtmlTree(HtmlTag.CAPTION); 125 for (MethodTypes type : methodTypes) { 126 Content captionSpan; 127 Content span; 128 if (type.isDefaultTab()) { 129 captionSpan = HtmlTree.SPAN(configuration.getResource(type.resourceKey())); 130 span = HtmlTree.SPAN(type.tabId(), 131 HtmlStyle.activeTableTab, captionSpan); 132 } else { 133 captionSpan = HtmlTree.SPAN(getMethodTypeLinks(type)); 134 span = HtmlTree.SPAN(type.tabId(), 135 HtmlStyle.tableTab, captionSpan); 136 } 137 Content tabSpan = HtmlTree.SPAN(HtmlStyle.tabEnd, getSpace()); 138 span.addContent(tabSpan); 139 tabbedCaption.addContent(span); 140 } 141 return tabbedCaption; 142 } 143 144 /** 145 * Get the method type links for the table caption. 146 * 147 * @param methodType the method type to be displayed as link 148 * @return the content tree for the method type link 149 */ 150 public Content getMethodTypeLinks(MethodTypes methodType) { 151 String jsShow = "javascript:show(" + methodType.value() +");"; 152 HtmlTree link = HtmlTree.A(jsShow, configuration.getResource(methodType.resourceKey())); 153 return link; 154 } 155 156 /** 157 * Add the inherited summary header. 158 * 159 * @param mw the writer for the member being documented 160 * @param typeElement the te to be documented 161 * @param inheritedTree the content tree to which the inherited summary header will be added 162 */ 163 public void addInheritedSummaryHeader(AbstractMemberWriter mw, TypeElement typeElement, 164 Content inheritedTree) { 165 mw.addInheritedSummaryAnchor(typeElement, inheritedTree); 166 mw.addInheritedSummaryLabel(typeElement, inheritedTree); 167 } 168 169 /** 170 * Add the index comment. 171 * 172 * @param member the member being documented 173 * @param contentTree the content tree to which the comment will be added 174 */ 175 protected void addIndexComment(Element member, Content contentTree) { 176 List<? extends DocTree> tags = utils.getFirstSentenceTrees(member); 177 addIndexComment(member, tags, contentTree); 178 } 179 180 /** 181 * Add the index comment. 182 * 183 * @param member the member being documented 184 * @param firstSentenceTags the first sentence tags for the member to be documented 185 * @param tdSummary the content tree to which the comment will be added 186 */ 187 protected void addIndexComment(Element member, List<? extends DocTree> firstSentenceTags, 188 Content tdSummary) { 189 List<? extends DocTree> deprs = utils.getBlockTags(member, DocTree.Kind.DEPRECATED); 190 Content div; 191 if (utils.isDeprecated(member)) { 192 Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, deprecatedPhrase); 193 div = HtmlTree.DIV(HtmlStyle.block, deprLabel); 194 div.addContent(getSpace()); 195 if (!deprs.isEmpty()) { 196 addInlineDeprecatedComment(member, deprs.get(0), div); 197 } 198 tdSummary.addContent(div); 199 return; 200 } else { 201 Element te = member.getEnclosingElement(); 202 if (te != null && utils.isTypeElement(te) && utils.isDeprecated(te)) { 203 Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, deprecatedPhrase); 204 div = HtmlTree.DIV(HtmlStyle.block, deprLabel); 205 div.addContent(getSpace()); 206 tdSummary.addContent(div); 207 } 208 } 209 addSummaryComment(member, firstSentenceTags, tdSummary); 210 } 211 212 /** 213 * Add the summary type for the member. 214 * 215 * @param mw the writer for the member being documented 216 * @param member the member to be documented 217 * @param tdSummaryType the content tree to which the type will be added 218 */ 219 public void addSummaryType(AbstractMemberWriter mw, Element member, Content tdSummaryType) { 220 mw.addSummaryType(member, tdSummaryType); 221 } 222 223 /** 224 * Add the summary link for the member. 225 * 226 * @param mw the writer for the member being documented 227 * @param member the member to be documented 228 * @param contentTree the content tree to which the link will be added 229 */ 230 public void addSummaryLinkComment(AbstractMemberWriter mw, Element member, Content contentTree) { 231 List<? extends DocTree> tags = utils.getFirstSentenceTrees(member); 232 addSummaryLinkComment(mw, member, tags, contentTree); 233 } 234 235 /** 236 * Add the summary link comment. 237 * 238 * @param mw the writer for the member being documented 239 * @param member the member being documented 240 * @param firstSentenceTags the first sentence tags for the member to be documented 241 * @param tdSummary the content tree to which the comment will be added 242 */ 243 public void addSummaryLinkComment(AbstractMemberWriter mw, 244 Element member, List<? extends DocTree> firstSentenceTags, Content tdSummary) { 245 addIndexComment(member, firstSentenceTags, tdSummary); 246 } 247 248 /** 249 * Add the inherited member summary. 250 * 251 * @param mw the writer for the member being documented 252 * @param typeElement the class being documented 253 * @param member the member being documented 254 * @param isFirst true if its the first link being documented 255 * @param linksTree the content tree to which the summary will be added 256 */ 257 public void addInheritedMemberSummary(AbstractMemberWriter mw, TypeElement typeElement, 258 Element member, boolean isFirst, Content linksTree) { 259 if (! isFirst) { 260 linksTree.addContent(", "); 261 } 262 mw.addInheritedSummaryLink(typeElement, member, linksTree); 263 } 264 265 /** 266 * Get the document content header tree 267 * 268 * @return a content tree the document content header 269 */ 270 public Content getContentHeader() { 271 HtmlTree div = new HtmlTree(HtmlTag.DIV); 272 div.addStyle(HtmlStyle.contentContainer); 273 return div; 274 } 275 276 /** 277 * Add the class content tree. 278 * 279 * @param contentTree content tree to which the class content will be added 280 * @param classContentTree class content tree which will be added to the content tree 281 */ 282 public void addClassContentTree(Content contentTree, Content classContentTree) { 283 if (configuration.allowTag(HtmlTag.MAIN)) { 284 mainTree.addContent(classContentTree); 285 contentTree.addContent(mainTree); 286 } else { 287 contentTree.addContent(classContentTree); 288 } 289 } 290 291 /** 292 * Add the annotation content tree. 293 * 294 * @param contentTree content tree to which the annotation content will be added 295 * @param annotationContentTree annotation content tree which will be added to the content tree 296 */ 297 public void addAnnotationContentTree(Content contentTree, Content annotationContentTree) { 298 addClassContentTree(contentTree, annotationContentTree); 299 } 300 301 /** 302 * Get the member header tree 303 * 304 * @return a content tree the member header 305 */ 306 public Content getMemberTreeHeader() { 307 HtmlTree li = new HtmlTree(HtmlTag.LI); 308 li.addStyle(HtmlStyle.blockList); 309 return li; 310 } 311 312 /** 313 * Add the member tree. 314 * 315 * @param memberSummaryTree the content tree representing the member summary 316 * @param memberTree the content tree representing the member 317 */ 318 public void addMemberTree(Content memberSummaryTree, Content memberTree) { 319 if (configuration.allowTag(HtmlTag.SECTION)) { 320 HtmlTree htmlTree = HtmlTree.SECTION(getMemberTree(memberTree)); 321 memberSummaryTree.addContent(htmlTree); 322 } else { 323 memberSummaryTree.addContent(getMemberTree(memberTree)); 324 } 325 } 326 327 /** 328 * Get the member tree 329 * 330 * @param contentTree the tree used to generate the complete member tree 331 * @return a content tree for the member 332 */ 333 public Content getMemberTree(Content contentTree) { 334 Content ul = HtmlTree.UL(HtmlStyle.blockList, contentTree); 335 return ul; 336 } 337 338 /** 339 * Get the member summary tree 340 * 341 * @param contentTree the tree used to generate the member summary tree 342 * @return a content tree for the member summary 343 */ 344 public Content getMemberSummaryTree(Content contentTree) { 345 return getMemberTree(HtmlStyle.summary, contentTree); 346 } 347 348 /** 349 * Get the member details tree 350 * 351 * @param contentTree the tree used to generate the member details tree 352 * @return a content tree for the member details 353 */ 354 public Content getMemberDetailsTree(Content contentTree) { 355 return getMemberTree(HtmlStyle.details, contentTree); 356 } 357 358 /** 359 * Get the member tree 360 * 361 * @param style the style class to be added to the content tree 362 * @param contentTree the tree used to generate the complete member tree 363 */ 364 public Content getMemberTree(HtmlStyle style, Content contentTree) { 365 Content div = HtmlTree.DIV(style, getMemberTree(contentTree)); 366 return div; 367 } 368 }