1 /*
   2  * Copyright (c) 1997, 2019, 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.BodyContents;
  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.toolkit.Content;
  39 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
  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 public abstract class SubWriterHolderWriter extends HtmlDocletWriter {
  58 
  59     /**
  60      * The HTML builder for the body contents.
  61      */
  62     protected BodyContents bodyContents = new BodyContents();
  63 
  64     public SubWriterHolderWriter(HtmlConfiguration configuration, DocPath filename) {
  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 typeElement the type element to be documented
  73      * @param memberTree the content tree to which the summary header will be added
  74      */
  75     public void addSummaryHeader(AbstractMemberWriter mw, TypeElement typeElement,
  76             Content memberTree) {
  77         mw.addSummaryAnchor(typeElement, memberTree);
  78         mw.addSummaryLabel(memberTree);
  79     }
  80 
  81     /**
  82      * Add the inherited summary header.
  83      *
  84      * @param mw the writer for the member being documented
  85      * @param typeElement the te to be documented
  86      * @param inheritedTree the content tree to which the inherited summary header will be added
  87      */
  88     public void addInheritedSummaryHeader(AbstractMemberWriter mw, TypeElement typeElement,
  89             Content inheritedTree) {
  90         mw.addInheritedSummaryLabel(typeElement, inheritedTree);
  91         mw.addInheritedSummaryAnchor(typeElement, inheritedTree);
  92     }
  93 
  94     /**
  95      * Add the index comment.
  96      *
  97      * @param member the member being documented
  98      * @param contentTree the content tree to which the comment will be added
  99      */
 100     protected void addIndexComment(Element member, Content contentTree) {
 101         List<? extends DocTree> tags = utils.getFirstSentenceTrees(member);
 102         addIndexComment(member, tags, contentTree);
 103     }
 104 
 105     /**
 106      * Add the index comment.
 107      *
 108      * @param member the member being documented
 109      * @param firstSentenceTags the first sentence tags for the member to be documented
 110      * @param tdSummary the content tree to which the comment will be added
 111      */
 112     protected void addIndexComment(Element member, List<? extends DocTree> firstSentenceTags,
 113             Content tdSummary) {
 114         List<? extends DocTree> deprs = utils.getBlockTags(member, DocTree.Kind.DEPRECATED);
 115         Content div;
 116         if (utils.isDeprecated(member)) {
 117             Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(member));
 118             div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
 119             if (!deprs.isEmpty()) {
 120                 addSummaryDeprecatedComment(member, deprs.get(0), div);
 121             }
 122             tdSummary.add(div);
 123             return;
 124         } else {
 125             Element te = member.getEnclosingElement();
 126             if (te != null &&  utils.isTypeElement(te) && utils.isDeprecated(te)) {
 127                 Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(te));
 128                 div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
 129                 tdSummary.add(div);
 130             }
 131         }
 132         addSummaryComment(member, firstSentenceTags, tdSummary);
 133     }
 134 
 135     /**
 136      * Add the summary link for the member.
 137      *
 138      * @param mw the writer for the member being documented
 139      * @param member the member to be documented
 140      * @param contentTree the content tree to which the link will be added
 141      */
 142     public void addSummaryLinkComment(AbstractMemberWriter mw, Element member, Content contentTree) {
 143         List<? extends DocTree> tags = utils.getFirstSentenceTrees(member);
 144         addSummaryLinkComment(mw, member, tags, contentTree);
 145     }
 146 
 147     /**
 148      * Add the summary link comment.
 149      *
 150      * @param mw the writer for the member being documented
 151      * @param member the member being documented
 152      * @param firstSentenceTags the first sentence tags for the member to be documented
 153      * @param tdSummary the content tree to which the comment will be added
 154      */
 155     public void addSummaryLinkComment(AbstractMemberWriter mw,
 156             Element member, List<? extends DocTree> firstSentenceTags, Content tdSummary) {
 157         addIndexComment(member, firstSentenceTags, tdSummary);
 158     }
 159 
 160     /**
 161      * Add the inherited member summary.
 162      *
 163      * @param mw the writer for the member being documented
 164      * @param typeElement the class being documented
 165      * @param member the member being documented
 166      * @param isFirst true if its the first link being documented
 167      * @param linksTree the content tree to which the summary will be added
 168      */
 169     public void addInheritedMemberSummary(AbstractMemberWriter mw, TypeElement typeElement,
 170             Element member, boolean isFirst, Content linksTree) {
 171         if (! isFirst) {
 172             linksTree.add(", ");
 173         }
 174         mw.addInheritedSummaryLink(typeElement, member, linksTree);
 175     }
 176 
 177     /**
 178      * Get the document content header tree
 179      *
 180      * @return a content tree the document content header
 181      */
 182     public Content getContentHeader() {
 183         HtmlTree div = new HtmlTree(HtmlTag.DIV);
 184         div.setStyle(HtmlStyle.contentContainer);
 185         return div;
 186     }
 187 
 188     /**
 189      * Add the class content tree.
 190      *
 191      * @param classContentTree class content tree which will be added to the content tree
 192      */
 193     public void addClassContentTree(Content classContentTree) {
 194         bodyContents.addMainContent(classContentTree);
 195     }
 196 
 197     /**
 198      * Add the annotation content tree.
 199      *
 200      * @param annotationContentTree annotation content tree which will be added to the content tree
 201      */
 202     public void addAnnotationContentTree(Content annotationContentTree) {
 203         addClassContentTree(annotationContentTree);
 204     }
 205 
 206     /**
 207      * Get the member header tree
 208      *
 209      * @return a content tree for the member header
 210      */
 211     public Content getMemberTreeHeader() {
 212         HtmlTree ul = new HtmlTree(HtmlTag.UL);
 213         ul.setStyle(HtmlStyle.blockList);
 214         return ul;
 215     }
 216 
 217     public Content getMemberInheritedTree() {
 218         HtmlTree div = new HtmlTree(HtmlTag.DIV);
 219         div.setStyle(HtmlStyle.inheritedList);
 220         return div;
 221     }
 222 
 223     /**
 224      * Adds the member tree with css style.
 225      * @param style the css style to be applied to member tree
 226      * @param memberSummaryTree the content tree representing the member summary
 227      * @param memberTree the content tree representing the member
 228      */
 229     public void addMemberTree(HtmlStyle style, Content memberSummaryTree, Content memberTree) {
 230         HtmlTree htmlTree = HtmlTree.SECTION(style, memberTree);
 231         memberSummaryTree.add(getMemberTree(htmlTree));
 232     }
 233 
 234     /**
 235      * Get the member tree
 236      *
 237      * @param contentTree the tree used to generate the complete member tree
 238      * @return a content tree for the member
 239      */
 240     public Content getMemberTree(Content contentTree) {
 241         return HtmlTree.LI(HtmlStyle.blockList, contentTree);
 242     }
 243 
 244     /**
 245      * Get the member summary tree
 246      *
 247      * @param contentTree the tree used to generate the member summary tree
 248      * @return a content tree for the member summary
 249      */
 250     public Content getMemberSummaryTree(Content contentTree) {
 251         return HtmlTree.SECTION(HtmlStyle.summary, contentTree);
 252     }
 253 
 254     /**
 255      * Get the member details tree
 256      *
 257      * @param contentTree the tree used to generate the member details tree
 258      * @return a content tree for the member details
 259      */
 260     public Content getMemberDetailsTree(Content contentTree) {
 261         return HtmlTree.SECTION(HtmlStyle.details, contentTree);
 262     }
 263 
 264     /**
 265      * Get the member tree
 266      *
 267      * @param style the style class to be added to the content tree
 268      * @param contentTree the tree used to generate the complete member tree
 269      * @return the member tree
 270      */
 271     public Content getMemberTree(HtmlStyle style, Content contentTree) {
 272         return HtmlTree.SECTION(style, contentTree);
 273     }
 274 }