1 /*
   2  * Copyright (c) 2001, 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.Collection;
  29 import java.util.Set;
  30 
  31 import javax.lang.model.element.Modifier;
  32 import javax.lang.model.element.PackageElement;
  33 import javax.lang.model.element.TypeElement;
  34 import javax.lang.model.element.VariableElement;
  35 
  36 import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents;
  37 import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
  38 import jdk.javadoc.internal.doclets.formats.html.markup.Entity;
  39 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
  40 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
  41 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
  42 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
  43 import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
  44 import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
  45 import jdk.javadoc.internal.doclets.formats.html.markup.Table;
  46 import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader;
  47 import jdk.javadoc.internal.doclets.toolkit.ConstantsSummaryWriter;
  48 import jdk.javadoc.internal.doclets.toolkit.Content;
  49 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
  50 import jdk.javadoc.internal.doclets.toolkit.util.DocLink;
  51 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
  52 
  53 
  54 /**
  55  * Write the Constants Summary Page in HTML format.
  56  *
  57  *  <p><b>This is NOT part of any supported API.
  58  *  If you write code that depends on this, you do so at your own risk.
  59  *  This code and its internal interfaces are subject to change or
  60  *  deletion without notice.</b>
  61  */
  62 public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements ConstantsSummaryWriter {
  63 
  64     /**
  65      * The configuration used in this run of the standard doclet.
  66      */
  67     HtmlConfiguration configuration;
  68 
  69     /**
  70      * The current class being documented.
  71      */
  72     private TypeElement currentTypeElement;
  73 
  74     private final TableHeader constantsTableHeader;
  75 
  76     /**
  77      * The HTML tree for constant values summary.
  78      */
  79     private HtmlTree summaryTree;
  80 
  81     private final Navigation navBar;
  82 
  83     private final BodyContents bodyContents = new BodyContents();
  84 
  85     /**
  86      * Construct a ConstantsSummaryWriter.
  87      * @param configuration the configuration used in this run
  88      *        of the standard doclet.
  89      */
  90     public ConstantsSummaryWriterImpl(HtmlConfiguration configuration) {
  91         super(configuration, DocPaths.CONSTANT_VALUES);
  92         this.configuration = configuration;
  93         constantsTableHeader = new TableHeader(
  94                 contents.modifierAndTypeLabel, contents.constantFieldLabel, contents.valueLabel);
  95         this.navBar = new Navigation(null, configuration, PageMode.CONSTANTVALUES, path);
  96     }
  97 
  98     /**
  99      * {@inheritDoc}
 100      */
 101     @Override
 102     public Content getHeader() {
 103         String label = resources.getText("doclet.Constants_Summary");
 104         HtmlTree bodyTree = getBody(getWindowTitle(label));
 105         Content headerContent = new ContentBuilder();
 106         addTop(headerContent);
 107         navBar.setUserHeader(getUserHeaderFooter(true));
 108         headerContent.add(navBar.getContent(true));
 109         bodyContents.setHeader(headerContent);
 110         return bodyTree;
 111     }
 112 
 113     /**
 114      * {@inheritDoc}
 115      */
 116     @Override
 117     public Content getContentsHeader() {
 118         return new HtmlTree(HtmlTag.UL);
 119     }
 120 
 121     /**
 122      * {@inheritDoc}
 123      */
 124     @Override
 125     public void addLinkToPackageContent(PackageElement pkg,
 126             Set<PackageElement> printedPackageHeaders, Content contentListTree) {
 127         //add link to summary
 128         Content link;
 129         if (pkg.isUnnamed()) {
 130             link = links.createLink(SectionName.UNNAMED_PACKAGE_ANCHOR,
 131                     contents.defaultPackageLabel, "", "");
 132         } else {
 133             String parsedPackageName = utils.parsePackageName(pkg);
 134             Content packageNameContent = getPackageLabel(parsedPackageName);
 135             packageNameContent.add(".*");
 136             link = links.createLink(DocLink.fragment(parsedPackageName),
 137                     packageNameContent, "", "");
 138             PackageElement abbrevPkg = configuration.workArounds.getAbbreviatedPackageElement(pkg);
 139             printedPackageHeaders.add(abbrevPkg);
 140         }
 141         contentListTree.add(HtmlTree.LI(link));
 142     }
 143 
 144     /**
 145      * {@inheritDoc}
 146      */
 147     @Override
 148     public void addContentsList(Content contentListTree) {
 149         Content titleContent = contents.constantsSummaryTitle;
 150         Content pHeading = HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, true,
 151                 HtmlStyle.title, titleContent);
 152         Content div = HtmlTree.DIV(HtmlStyle.header, pHeading);
 153         Content headingContent = contents.contentsHeading;
 154         Content heading = HtmlTree.HEADING(Headings.CONTENT_HEADING, true,
 155                 headingContent);
 156         HtmlTree section = HtmlTree.SECTION(HtmlStyle.packages, heading);
 157         section.add(contentListTree);
 158         div.add(section);
 159         bodyContents.addMainContent(div);
 160     }
 161 
 162     /**
 163      * {@inheritDoc}
 164      */
 165     @Override
 166     public Content getConstantSummaries() {
 167         HtmlTree summariesDiv = new HtmlTree(HtmlTag.DIV);
 168         summariesDiv.setStyle(HtmlStyle.constantValuesContainer);
 169         return summariesDiv;
 170     }
 171 
 172     /**
 173      * {@inheritDoc}
 174      */
 175     @Override
 176     public void addPackageName(PackageElement pkg, Content summariesTree, boolean first) {
 177         Content pkgNameContent;
 178         if (!first) {
 179             summariesTree.add(summaryTree);
 180         }
 181         if (pkg.isUnnamed()) {
 182             summariesTree.add(links.createAnchor(SectionName.UNNAMED_PACKAGE_ANCHOR));
 183             pkgNameContent = contents.defaultPackageLabel;
 184         } else {
 185             String parsedPackageName = utils.parsePackageName(pkg);
 186             summariesTree.add(links.createAnchor(parsedPackageName));
 187             pkgNameContent = getPackageLabel(parsedPackageName);
 188         }
 189         Content headingContent = new StringContent(".*");
 190         Content heading = HtmlTree.HEADING(Headings.ConstantsSummary.PACKAGE_HEADING, true,
 191                 pkgNameContent);
 192         heading.add(headingContent);
 193         summaryTree = HtmlTree.SECTION(HtmlStyle.constantsSummary, heading);
 194     }
 195 
 196     /**
 197      * {@inheritDoc}
 198      */
 199     @Override
 200     public Content getClassConstantHeader() {
 201         HtmlTree ul = new HtmlTree(HtmlTag.UL);
 202         ul.setStyle(HtmlStyle.blockList);
 203         return ul;
 204     }
 205 
 206     /**
 207      * {@inheritDoc}
 208      */
 209     @Override
 210     public void addClassConstant(Content summariesTree, Content classConstantTree) {
 211         summaryTree.add(classConstantTree);
 212     }
 213 
 214     /**
 215      * {@inheritDoc}
 216      */
 217     @Override
 218     public void addConstantMembers(TypeElement typeElement, Collection<VariableElement> fields,
 219             Content classConstantTree) {
 220         currentTypeElement = typeElement;
 221 
 222         //generate links backward only to public classes.
 223         Content classlink = (utils.isPublic(typeElement) || utils.isProtected(typeElement)) ?
 224             getLink(new LinkInfoImpl(configuration,
 225                     LinkInfoImpl.Kind.CONSTANT_SUMMARY, typeElement)) :
 226             new StringContent(utils.getFullyQualifiedName(typeElement));
 227 
 228         PackageElement enclosingPackage  = utils.containingPackage(typeElement);
 229         Content caption = new ContentBuilder();
 230         if (!enclosingPackage.isUnnamed()) {
 231             caption.add(enclosingPackage.getQualifiedName());
 232             caption.add(".");
 233         }
 234         caption.add(classlink);
 235 
 236         Table table = new Table(HtmlStyle.constantsSummary)
 237                 .setCaption(caption)
 238                 .setHeader(constantsTableHeader)
 239                 .setRowScopeColumn(1)
 240                 .setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colSecond, HtmlStyle.colLast);
 241 
 242         for (VariableElement field : fields) {
 243             table.addRow(getTypeColumn(field), getNameColumn(field), getValue(field));
 244         }
 245         Content li = HtmlTree.LI(HtmlStyle.blockList, table.toContent());
 246         classConstantTree.add(li);
 247     }
 248 
 249     /**
 250      * Get the type column for the constant summary table row.
 251      *
 252      * @param member the field to be documented.
 253      * @return the type column of the constant table row
 254      */
 255     private Content getTypeColumn(VariableElement member) {
 256         Content anchor = links.createAnchor(
 257                 currentTypeElement.getQualifiedName() + "." + member.getSimpleName());
 258         Content typeContent = new ContentBuilder();
 259         typeContent.add(anchor);
 260         Content code = new HtmlTree(HtmlTag.CODE);
 261         for (Modifier mod : member.getModifiers()) {
 262             Content modifier = new StringContent(mod.toString());
 263             code.add(modifier);
 264             code.add(Entity.NO_BREAK_SPACE);
 265         }
 266         Content type = getLink(new LinkInfoImpl(configuration,
 267                 LinkInfoImpl.Kind.CONSTANT_SUMMARY, member.asType()));
 268         code.add(type);
 269         typeContent.add(code);
 270         return typeContent;
 271     }
 272 
 273     /**
 274      * Get the name column for the constant summary table row.
 275      *
 276      * @param member the field to be documented.
 277      * @return the name column of the constant table row
 278      */
 279     private Content getNameColumn(VariableElement member) {
 280         Content nameContent = getDocLink(LinkInfoImpl.Kind.CONSTANT_SUMMARY,
 281                 member, member.getSimpleName(), false);
 282         return HtmlTree.CODE(nameContent);
 283     }
 284 
 285     /**
 286      * Get the value column for the constant summary table row.
 287      *
 288      * @param member the field to be documented.
 289      * @return the value column of the constant table row
 290      */
 291     private Content getValue(VariableElement member) {
 292         String value = utils.constantValueExpresion(member);
 293         Content valueContent = new StringContent(value);
 294         return HtmlTree.CODE(valueContent);
 295     }
 296 
 297     /**
 298      * {@inheritDoc}
 299      */
 300     @Override
 301     public void addConstantSummaries(Content summariesTree) {
 302         if (summaryTree != null) {
 303             summariesTree.add(summaryTree);
 304         }
 305         bodyContents.addMainContent(summariesTree);
 306     }
 307 
 308     /**
 309      * {@inheritDoc}
 310      */
 311     @Override
 312     public void addFooter() {
 313         Content htmlTree = HtmlTree.FOOTER();
 314         navBar.setUserFooter(getUserHeaderFooter(false));
 315         htmlTree.add(navBar.getContent(false));
 316         addBottom(htmlTree);
 317         bodyContents.setFooter(htmlTree);
 318     }
 319 
 320     /**
 321      * {@inheritDoc}
 322      */
 323     @Override
 324     public void printDocument(Content contentTree) throws DocFileIOException {
 325         contentTree.add(bodyContents.toContent());
 326         printHtmlDocument(null, "summary of constants", contentTree);
 327     }
 328 }