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