1 /*
   2  * Copyright (c) 2003, 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.toolkit.builders;
  27 
  28 import java.util.Set;
  29 import java.util.SortedSet;
  30 
  31 import javax.lang.model.element.PackageElement;
  32 import javax.lang.model.element.TypeElement;
  33 
  34 import jdk.javadoc.internal.doclets.toolkit.Content;
  35 import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler;
  36 import jdk.javadoc.internal.doclets.toolkit.DocletException;
  37 import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
  38 
  39 
  40 /**
  41  * Builds the summary for a given package.
  42  *
  43  *  <p><b>This is NOT part of any supported API.
  44  *  If you write code that depends on this, you do so at your own risk.
  45  *  This code and its internal interfaces are subject to change or
  46  *  deletion without notice.</b>
  47  */
  48 public class PackageSummaryBuilder extends AbstractBuilder {
  49 
  50     /**
  51      * The package being documented.
  52      */
  53     private final PackageElement packageElement;
  54 
  55     /**
  56      * The doclet specific writer that will output the result.
  57      */
  58     private final PackageSummaryWriter packageWriter;
  59 
  60     /**
  61      * Construct a new PackageSummaryBuilder.
  62      *
  63      * @param context  the build context.
  64      * @param pkg the package being documented.
  65      * @param packageWriter the doclet specific writer that will output the
  66      *        result.
  67      */
  68     private PackageSummaryBuilder(Context context,
  69             PackageElement pkg,
  70             PackageSummaryWriter packageWriter) {
  71         super(context);
  72         this.packageElement = pkg;
  73         this.packageWriter = packageWriter;
  74     }
  75 
  76     /**
  77      * Construct a new PackageSummaryBuilder.
  78      *
  79      * @param context  the build context.
  80      * @param pkg the package being documented.
  81      * @param packageWriter the doclet specific writer that will output the
  82      *        result.
  83      *
  84      * @return an instance of a PackageSummaryBuilder.
  85      */
  86     public static PackageSummaryBuilder getInstance(Context context,
  87             PackageElement pkg, PackageSummaryWriter packageWriter) {
  88         return new PackageSummaryBuilder(context, pkg, packageWriter);
  89     }
  90 
  91     /**
  92      * Build the package summary.
  93      *
  94      * @throws DocletException if there is a problem while building the documentation
  95      */
  96     @Override
  97     public void build() throws DocletException {
  98         if (packageWriter == null) {
  99             //Doclet does not support this output.
 100             return;
 101         }
 102         buildPackageDoc();
 103     }
 104 
 105     /**
 106      * Build the package documentation.
 107      *
 108      * @throws DocletException if there is a problem while building the documentation
 109      */
 110     protected void buildPackageDoc() throws DocletException {
 111         Content contentTree = packageWriter.getPackageHeader(utils.getPackageName(packageElement));
 112 
 113         buildContent();
 114 
 115         packageWriter.addPackageFooter();
 116         packageWriter.printDocument(contentTree);
 117         DocFilesHandler docFilesHandler = configuration
 118                 .getWriterFactory()
 119                 .getDocFilesHandler(packageElement);
 120         docFilesHandler.copyDocFiles();
 121     }
 122 
 123     /**
 124      * Build the content for the package.
 125      *
 126      * @throws DocletException if there is a problem while building the documentation
 127      */
 128     protected void buildContent() throws DocletException {
 129         Content packageContentTree = packageWriter.getContentHeader();
 130 
 131         buildPackageDescription(packageContentTree);
 132         buildPackageTags(packageContentTree);
 133         buildSummary(packageContentTree);
 134 
 135         packageWriter.addPackageContent(packageContentTree);
 136     }
 137 
 138     /**
 139      * Build the package summary.
 140      *
 141      * @param packageContentTree the package content tree to which the summaries will
 142      *                           be added
 143      * @throws DocletException if there is a problem while building the documentation
 144      */
 145     protected void buildSummary(Content packageContentTree) throws DocletException {
 146         Content summaryContentTree = packageWriter.getSummaryHeader();
 147 
 148         buildInterfaceSummary(summaryContentTree);
 149         buildClassSummary(summaryContentTree);
 150         buildEnumSummary(summaryContentTree);
 151         buildRecordSummary(summaryContentTree);
 152         buildExceptionSummary(summaryContentTree);
 153         buildErrorSummary(summaryContentTree);
 154         buildAnnotationTypeSummary(summaryContentTree);
 155 
 156         packageContentTree.add(packageWriter.getPackageSummary(summaryContentTree));
 157     }
 158 
 159     /**
 160      * Build the summary for the interfaces in this package.
 161      *
 162      * @param summaryContentTree the summary tree to which the interface summary
 163      *                           will be added
 164      */
 165     protected void buildInterfaceSummary(Content summaryContentTree) {
 166         SortedSet<TypeElement> ilist = utils.isSpecified(packageElement)
 167                         ? utils.getTypeElementsAsSortedSet(utils.getInterfaces(packageElement))
 168                         : configuration.typeElementCatalog.interfaces(packageElement);
 169         SortedSet<TypeElement> interfaces = utils.filterOutPrivateClasses(ilist, configuration.javafx);
 170         if (!interfaces.isEmpty()) {
 171             packageWriter.addInterfaceSummary(interfaces, summaryContentTree);
 172         }
 173     }
 174 
 175     /**
 176      * Build the summary for the classes in this package.
 177      *
 178      * @param summaryContentTree the summary tree to which the class summary will
 179      *                           be added
 180      */
 181     protected void buildClassSummary(Content summaryContentTree) {
 182         SortedSet<TypeElement> clist = utils.isSpecified(packageElement)
 183             ? utils.getTypeElementsAsSortedSet(utils.getOrdinaryClasses(packageElement))
 184             : configuration.typeElementCatalog.ordinaryClasses(packageElement);
 185         SortedSet<TypeElement> classes = utils.filterOutPrivateClasses(clist, configuration.javafx);
 186         if (!classes.isEmpty()) {
 187             packageWriter.addClassSummary(classes, summaryContentTree);
 188         }
 189     }
 190 
 191     /**
 192      * Build the summary for the enums in this package.
 193      *
 194      * @param summaryContentTree the summary tree to which the enum summary will
 195      *                           be added
 196      */
 197     protected void buildEnumSummary(Content summaryContentTree) {
 198         SortedSet<TypeElement> elist = utils.isSpecified(packageElement)
 199             ? utils.getTypeElementsAsSortedSet(utils.getEnums(packageElement))
 200             : configuration.typeElementCatalog.enums(packageElement);
 201         SortedSet<TypeElement> enums = utils.filterOutPrivateClasses(elist, configuration.javafx);
 202         if (!enums.isEmpty()) {
 203             packageWriter.addEnumSummary(enums, summaryContentTree);
 204         }
 205     }
 206 
 207     /**
 208      * Build the summary for the records in this package.
 209      *
 210      * @param summaryContentTree the summary tree to which the record summary will
 211      *                           be added
 212      */
 213     protected void buildRecordSummary(Content summaryContentTree) {
 214         SortedSet<TypeElement> rlist = utils.isSpecified(packageElement)
 215                 ? utils.getTypeElementsAsSortedSet(utils.getRecords(packageElement))
 216                 : configuration.typeElementCatalog.records(packageElement);
 217         SortedSet<TypeElement> records = utils.filterOutPrivateClasses(rlist, configuration.javafx);
 218         if (!records.isEmpty()) {
 219             packageWriter.addRecordSummary(records, summaryContentTree);
 220         }
 221     }
 222 
 223     /**
 224      * Build the summary for the exceptions in this package.
 225      *
 226      * @param summaryContentTree the summary tree to which the exception summary will
 227      *                           be added
 228      */
 229     protected void buildExceptionSummary(Content summaryContentTree) {
 230         Set<TypeElement> iexceptions =
 231             utils.isSpecified(packageElement)
 232                 ? utils.getTypeElementsAsSortedSet(utils.getExceptions(packageElement))
 233                 : configuration.typeElementCatalog.exceptions(packageElement);
 234         SortedSet<TypeElement> exceptions = utils.filterOutPrivateClasses(iexceptions,
 235                 configuration.javafx);
 236         if (!exceptions.isEmpty()) {
 237             packageWriter.addExceptionSummary(exceptions, summaryContentTree);
 238         }
 239     }
 240 
 241     /**
 242      * Build the summary for the errors in this package.
 243      *
 244      * @param summaryContentTree the summary tree to which the error summary will
 245      *                           be added
 246      */
 247     protected void buildErrorSummary(Content summaryContentTree) {
 248         Set<TypeElement> ierrors =
 249             utils.isSpecified(packageElement)
 250                 ? utils.getTypeElementsAsSortedSet(utils.getErrors(packageElement))
 251                 : configuration.typeElementCatalog.errors(packageElement);
 252         SortedSet<TypeElement> errors = utils.filterOutPrivateClasses(ierrors, configuration.javafx);
 253         if (!errors.isEmpty()) {
 254             packageWriter.addErrorSummary(errors, summaryContentTree);
 255         }
 256     }
 257 
 258     /**
 259      * Build the summary for the annotation type in this package.
 260      *
 261      * @param summaryContentTree the summary tree to which the annotation type
 262      *                           summary will be added
 263      */
 264     protected void buildAnnotationTypeSummary(Content summaryContentTree) {
 265         SortedSet<TypeElement> iannotationTypes =
 266             utils.isSpecified(packageElement)
 267                 ? utils.getTypeElementsAsSortedSet(utils.getAnnotationTypes(packageElement))
 268                 : configuration.typeElementCatalog.annotationTypes(packageElement);
 269         SortedSet<TypeElement> annotationTypes = utils.filterOutPrivateClasses(iannotationTypes,
 270                 configuration.javafx);
 271         if (!annotationTypes.isEmpty()) {
 272             packageWriter.addAnnotationTypeSummary(annotationTypes, summaryContentTree);
 273         }
 274     }
 275 
 276     /**
 277      * Build the description of the summary.
 278      *
 279      * @param packageContentTree the tree to which the package description will
 280      *                           be added
 281      */
 282     protected void buildPackageDescription(Content packageContentTree) {
 283         if (configuration.nocomment) {
 284             return;
 285         }
 286         packageWriter.addPackageDescription(packageContentTree);
 287     }
 288 
 289     /**
 290      * Build the tags of the summary.
 291      *
 292      * @param packageContentTree the tree to which the package tags will be added
 293      */
 294     protected void buildPackageTags(Content packageContentTree) {
 295         if (configuration.nocomment) {
 296             return;
 297         }
 298         packageWriter.addPackageTags(packageContentTree);
 299     }
 300 }