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 }