1 /*
   2  * Copyright (c) 1998, 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.TypeElement;
  31 import javax.lang.model.element.VariableElement;
  32 import javax.lang.model.type.TypeMirror;
  33 
  34 import com.sun.source.doctree.DocTree;
  35 
  36 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
  37 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
  38 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
  39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
  40 import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
  41 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
  42 import jdk.javadoc.internal.doclets.toolkit.Content;
  43 import jdk.javadoc.internal.doclets.toolkit.SerializedFormWriter;
  44 import jdk.javadoc.internal.doclets.toolkit.taglets.TagletWriter;
  45 import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
  46 
  47 /**
  48  * Generate serialized form for serializable fields.
  49  * Documentation denoted by the tags <code>serial</code> and
  50  * <code>serialField</code> is processed.
  51  *
  52  *  <p><b>This is NOT part of any supported API.
  53  *  If you write code that depends on this, you do so at your own risk.
  54  *  This code and its internal interfaces are subject to change or
  55  *  deletion without notice.</b>
  56  *
  57  * @author Joe Fialli
  58  * @author Bhavesh Patel (Modified)
  59  */
  60 public class HtmlSerialFieldWriter extends FieldWriterImpl
  61         implements SerializedFormWriter.SerialFieldWriter {
  62 
  63     public HtmlSerialFieldWriter(SubWriterHolderWriter writer, TypeElement typeElement) {
  64         super(writer, typeElement);
  65     }
  66 
  67     public SortedSet<VariableElement> members(TypeElement te) {
  68         return utils.serializableFields(te);
  69     }
  70 
  71     /**
  72      * Return the header for serializable fields section.
  73      *
  74      * @return a content tree for the header
  75      */
  76     public Content getSerializableFieldsHeader() {
  77         HtmlTree ul = new HtmlTree(HtmlTag.UL);
  78         ul.setStyle(HtmlStyle.blockList);
  79         return ul;
  80     }
  81 
  82     /**
  83      * Return the header for serializable fields content section.
  84      *
  85      * @param isLastContent true if the cotent being documented is the last content.
  86      * @return a content tree for the header
  87      */
  88     public Content getFieldsContentHeader(boolean isLastContent) {
  89         HtmlTree li = new HtmlTree(HtmlTag.LI);
  90         if (isLastContent)
  91             li.setStyle(HtmlStyle.blockListLast);
  92         else
  93             li.setStyle(HtmlStyle.blockList);
  94         return li;
  95     }
  96 
  97     /**
  98      * Add serializable fields.
  99      *
 100      * @param heading the heading for the section
 101      * @param serializableFieldsTree the tree to be added to the serializable fileds
 102      *        content tree
 103      * @return a content tree for the serializable fields content
 104      */
 105     public Content getSerializableFields(String heading, Content serializableFieldsTree) {
 106         HtmlTree section = HtmlTree.SECTION(HtmlStyle.detail);
 107         if (serializableFieldsTree.isValid()) {
 108             Content headingContent = new StringContent(heading);
 109             Content serialHeading = HtmlTree.HEADING(Headings.SerializedForm.CLASS_SUBHEADING, headingContent);
 110             section.add(serialHeading);
 111             section.add(serializableFieldsTree);
 112         }
 113         return HtmlTree.LI(HtmlStyle.blockList, section);
 114     }
 115 
 116     @Override
 117     public void addMemberHeader(TypeElement fieldType, String fieldTypeStr,
 118             String fieldDimensions, String fieldName, Content contentTree) {
 119         Content nameContent = new StringContent(fieldName);
 120         Content heading = HtmlTree.HEADING(Headings.SerializedForm.MEMBER_HEADING, nameContent);
 121         contentTree.add(heading);
 122         Content pre = new HtmlTree(HtmlTag.PRE);
 123         if (fieldType == null) {
 124             pre.add(fieldTypeStr);
 125         } else {
 126             Content fieldContent = writer.getLink(new LinkInfoImpl(
 127                     configuration, LinkInfoImpl.Kind.SERIAL_MEMBER, fieldType));
 128             pre.add(fieldContent);
 129         }
 130         pre.add(fieldDimensions + " ");
 131         pre.add(fieldName);
 132         contentTree.add(pre);
 133     }
 134 
 135     @Override
 136     public void addMemberHeader(TypeMirror fieldType, String fieldName, Content contentTree) {
 137         Content nameContent = new StringContent(fieldName);
 138         Content heading = HtmlTree.HEADING(HtmlTag.H5, nameContent);
 139         contentTree.add(heading);
 140         Content pre = new HtmlTree(HtmlTag.PRE);
 141         Content fieldContent = writer.getLink(new LinkInfoImpl(
 142                 configuration, LinkInfoImpl.Kind.SERIAL_MEMBER, fieldType));
 143         pre.add(fieldContent);
 144         pre.add(" ");
 145         pre.add(fieldName);
 146         contentTree.add(pre);
 147     }
 148 
 149     /**
 150      * Add the deprecated information for this member.
 151      *
 152      * @param field the field to document.
 153      * @param contentTree the tree to which the deprecated info will be added
 154      */
 155     public void addMemberDeprecatedInfo(VariableElement field, Content contentTree) {
 156         addDeprecatedInfo(field, contentTree);
 157     }
 158 
 159     /**
 160      * Add the description text for this member.
 161      *
 162      * @param field the field to document.
 163      * @param contentTree the tree to which the deprecated info will be added
 164      */
 165     public void addMemberDescription(VariableElement field, Content contentTree) {
 166         if (!utils.getFullBody(field).isEmpty()) {
 167             writer.addInlineComment(field, contentTree);
 168         }
 169         List<? extends DocTree> tags = utils.getBlockTags(field, DocTree.Kind.SERIAL);
 170         if (!tags.isEmpty()) {
 171             writer.addInlineComment(field, tags.get(0), contentTree);
 172         }
 173     }
 174 
 175     /**
 176      * Add the description text for this member represented by the tag.
 177      *
 178      * @param serialFieldTag the field to document (represented by tag)
 179      * @param contentTree the tree to which the deprecated info will be added
 180      */
 181     public void addMemberDescription(VariableElement field, DocTree serialFieldTag, Content contentTree) {
 182         CommentHelper ch = utils.getCommentHelper(field);
 183         List<? extends DocTree> description = ch.getDescription(configuration, serialFieldTag);
 184         if (!description.isEmpty()) {
 185             Content serialFieldContent = new RawHtml(ch.getText(description));
 186             Content div = HtmlTree.DIV(HtmlStyle.block, serialFieldContent);
 187             contentTree.add(div);
 188         }
 189     }
 190 
 191     /**
 192      * Add the tag information for this member.
 193      *
 194      * @param field the field to document.
 195      * @param contentTree the tree to which the member tags info will be added
 196      */
 197     public void addMemberTags(VariableElement field, Content contentTree) {
 198         Content tagContent = new ContentBuilder();
 199         TagletWriter.genTagOutput(configuration.tagletManager, field,
 200                 configuration.tagletManager.getBlockTaglets(field),
 201                 writer.getTagletWriterInstance(false), tagContent);
 202         Content dlTags = new HtmlTree(HtmlTag.DL);
 203         dlTags.add(tagContent);
 204         contentTree.add(dlTags);  // TODO: what if empty?
 205     }
 206 
 207     /**
 208      * Check to see if overview details should be printed. If
 209      * nocomment option set or if there is no text to be printed
 210      * for deprecation info, comment or tags, do not print overview details.
 211      *
 212      * @param field the field to check overview details for.
 213      * @return true if overview details need to be printed
 214      */
 215     public boolean shouldPrintOverview(VariableElement field) {
 216         if (!configuration.nocomment) {
 217             if(!utils.getFullBody(field).isEmpty() ||
 218                     writer.hasSerializationOverviewTags(field))
 219                 return true;
 220         }
 221         if (utils.isDeprecated(field))
 222             return true;
 223         return false;
 224     }
 225 }