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.toolkit.util;
  27 
  28 import java.util.*;
  29 
  30 import javax.lang.model.element.Element;
  31 import javax.lang.model.element.ModuleElement;
  32 import javax.lang.model.element.PackageElement;
  33 import javax.lang.model.element.TypeElement;
  34 
  35 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
  36 
  37 /**
  38  * Build list of all the deprecated packages, classes, constructors, fields and methods.
  39  *
  40  *  <p><b>This is NOT part of any supported API.
  41  *  If you write code that depends on this, you do so at your own risk.
  42  *  This code and its internal interfaces are subject to change or
  43  *  deletion without notice.</b>
  44  */
  45 public class DeprecatedAPIListBuilder {
  46     /**
  47      * List of deprecated type Lists.
  48      */
  49     private final Map<DeprElementKind, SortedSet<Element>> deprecatedMap;
  50     private final BaseConfiguration configuration;
  51     private final Utils utils;
  52     public enum DeprElementKind {
  53         REMOVAL,
  54         MODULE,
  55         PACKAGE,
  56         INTERFACE,
  57         CLASS,
  58         ENUM,
  59         EXCEPTION,              // no ElementKind mapping
  60         ERROR,                  // no ElementKind mapping
  61         ANNOTATION_TYPE,
  62         FIELD,
  63         METHOD,
  64         CONSTRUCTOR,
  65         ENUM_CONSTANT,
  66         ANNOTATION_TYPE_MEMBER // no ElementKind mapping
  67     };
  68     /**
  69      * Constructor.
  70      *
  71      * @param configuration the current configuration of the doclet
  72      */
  73     public DeprecatedAPIListBuilder(BaseConfiguration configuration) {
  74         this.configuration = configuration;
  75         this.utils = configuration.utils;
  76         deprecatedMap = new EnumMap<>(DeprElementKind.class);
  77         for (DeprElementKind kind : DeprElementKind.values()) {
  78             deprecatedMap.put(kind,
  79                     new TreeSet<>(utils.makeDeprecatedComparator()));
  80         }
  81         buildDeprecatedAPIInfo();
  82     }
  83 
  84     /**
  85      * Build the sorted list of all the deprecated APIs in this run.
  86      * Build separate lists for deprecated modules, packages, classes, constructors,
  87      * methods and fields.
  88      *
  89      * @param configuration the current configuration of the doclet.
  90      */
  91     private void buildDeprecatedAPIInfo() {
  92         SortedSet<Element> rset = deprecatedMap.get(DeprElementKind.REMOVAL);
  93         SortedSet<ModuleElement> modules = configuration.modules;
  94         SortedSet<Element> mset = deprecatedMap.get(DeprElementKind.MODULE);
  95         for (Element me : modules) {
  96             if (utils.isDeprecatedForRemoval(me)) {
  97                 rset.add(me);
  98             }
  99             if (utils.isDeprecated(me)) {
 100                 mset.add(me);
 101             }
 102         }
 103         SortedSet<PackageElement> packages = configuration.packages;
 104         SortedSet<Element> pset = deprecatedMap.get(DeprElementKind.PACKAGE);
 105         for (Element pe : packages) {
 106             if (utils.isDeprecatedForRemoval(pe)) {
 107                 rset.add(pe);
 108             }
 109             if (utils.isDeprecated(pe)) {
 110                 pset.add(pe);
 111             }
 112         }
 113         for (Element e : configuration.getIncludedTypeElements()) {
 114             TypeElement te = (TypeElement)e;
 115             SortedSet<Element> eset;
 116             if (utils.isDeprecatedForRemoval(e)) {
 117                 rset.add(e);
 118             }
 119             if (utils.isDeprecated(e)) {
 120                 switch (e.getKind()) {
 121                     case ANNOTATION_TYPE:
 122                         eset = deprecatedMap.get(DeprElementKind.ANNOTATION_TYPE);
 123                         eset.add(e);
 124                         break;
 125                     case CLASS:
 126                         if (utils.isError(te)) {
 127                             eset = deprecatedMap.get(DeprElementKind.ERROR);
 128                         } else if (utils.isException(te)) {
 129                             eset = deprecatedMap.get(DeprElementKind.EXCEPTION);
 130                         } else {
 131                             eset = deprecatedMap.get(DeprElementKind.CLASS);
 132                         }
 133                         eset.add(e);
 134                         break;
 135                     case INTERFACE:
 136                         eset = deprecatedMap.get(DeprElementKind.INTERFACE);
 137                         eset.add(e);
 138                         break;
 139                     case ENUM:
 140                         eset = deprecatedMap.get(DeprElementKind.ENUM);
 141                         eset.add(e);
 142                         break;
 143                 }
 144             }
 145             composeDeprecatedList(rset, deprecatedMap.get(DeprElementKind.FIELD),
 146                     utils.getFields(te));
 147             composeDeprecatedList(rset, deprecatedMap.get(DeprElementKind.METHOD),
 148                     utils.getMethods(te));
 149             composeDeprecatedList(rset, deprecatedMap.get(DeprElementKind.CONSTRUCTOR),
 150                     utils.getConstructors(te));
 151             if (utils.isEnum(e)) {
 152                 composeDeprecatedList(rset, deprecatedMap.get(DeprElementKind.ENUM_CONSTANT),
 153                         utils.getEnumConstants(te));
 154             }
 155             if (utils.isAnnotationType(e)) {
 156                 composeDeprecatedList(rset, deprecatedMap.get(DeprElementKind.ANNOTATION_TYPE_MEMBER),
 157                         utils.getAnnotationMembers(te));
 158 
 159             }
 160         }
 161     }
 162 
 163     /**
 164      * Add the members into a single list of deprecated members.
 165      *
 166      * @param rset set of elements deprecated for removal.
 167      * @param sset set of deprecated elements.
 168      * @param list List of all the particular deprecated members, e.g. methods.
 169      * @param members members to be added in the list.
 170      */
 171     private void composeDeprecatedList(SortedSet<Element> rset, SortedSet<Element> sset, List<? extends Element> members) {
 172         for (Element member : members) {
 173             if (utils.isDeprecatedForRemoval(member)) {
 174                 rset.add(member);
 175             }
 176             if (utils.isDeprecated(member)) {
 177                 sset.add(member);
 178             }
 179         }
 180     }
 181 
 182     /**
 183      * Return the list of deprecated elements of a given type.
 184      *
 185      * @param kind the DeprElementKind
 186      * @return
 187      */
 188     public SortedSet<Element> getSet(DeprElementKind kind) {
 189         return deprecatedMap.get(kind);
 190     }
 191 
 192     /**
 193      * Return true if the list of a given type has size greater than 0.
 194      *
 195      * @param kind the type of list being checked.
 196      */
 197     public boolean hasDocumentation(DeprElementKind kind) {
 198         return !deprecatedMap.get(kind).isEmpty();
 199     }
 200 }