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