TypeElementCatalog.java revision 3595:81692f730015
1/*
2 * Copyright (c) 2001, 2016, 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 */
25package jdk.javadoc.internal.doclets.toolkit.util;
26
27import java.util.*;
28
29import javax.lang.model.element.Element;
30import javax.lang.model.element.PackageElement;
31import javax.lang.model.element.TypeElement;
32
33import jdk.javadoc.internal.doclets.toolkit.Configuration;
34
35/**
36 * This class acts as an artificial container for classes specified on the command line when
37 * running Javadoc. For example, if you specify several classes from package java.lang, this class
38 * will catalog those classes so that we can retrieve all of the classes from a particular package
39 * later.
40 *
41 * <p>
42 * <b>This is NOT part of any supported API. If you write code that depends on this, you do so at
43 * your own risk. This code and its internal interfaces are subject to change or deletion without
44 * notice.</b>
45 *
46 * @author Jamie Ho
47 */
48public class TypeElementCatalog {
49
50    /**
51     * Stores the set of packages that the classes specified on the command line belong to. Note
52     * that the default package is "".
53     */
54    private final SortedSet<PackageElement> packageSet;
55
56    /**
57     * Stores all classes for each package
58     */
59    private final Map<PackageElement, SortedSet<TypeElement>> allClasses;
60
61    /**
62     * Stores ordinary classes (excluding Exceptions and Errors) for each package
63     */
64    private final Map<PackageElement, SortedSet<TypeElement>> ordinaryClasses;
65
66    /**
67     * Stores exceptions for each package
68     */
69    private final Map<PackageElement, SortedSet<TypeElement>> exceptions;
70
71    /**
72     * Stores enums for each package.
73     */
74    private final Map<PackageElement, SortedSet<TypeElement>> enums;
75
76    /**
77     * Stores annotation types for each package.
78     */
79    private final Map<PackageElement, SortedSet<TypeElement>> annotationTypes;
80
81    /**
82     * Stores errors for each package
83     */
84    private final Map<PackageElement, SortedSet<TypeElement>> errors;
85
86    /**
87     * Stores interfaces for each package
88     */
89    private final Map<PackageElement, SortedSet<TypeElement>> interfaces;
90
91    private final Configuration configuration;
92    private final Utils utils;
93    private final Comparator<Element> comparator;
94
95    /**
96     * Construct a new TypeElementCatalog.
97     *
98     * @param typeElements the array of TypeElements to catalog
99     */
100    public TypeElementCatalog(Iterable<TypeElement> typeElements, Configuration config) {
101        this(config);
102        for (TypeElement typeElement : typeElements) {
103            addTypeElement(typeElement);
104        }
105    }
106
107    /**
108     * Construct a new TypeElementCatalog.
109     *
110     */
111    public TypeElementCatalog(Configuration config) {
112        this.configuration = config;
113        this.utils = config.utils;
114        comparator = utils.makeGeneralPurposeComparator();
115        allClasses = new HashMap<>();
116        ordinaryClasses = new HashMap<>();
117        exceptions = new HashMap<>();
118        enums = new HashMap<>();
119        annotationTypes = new HashMap<>();
120        errors = new HashMap<>();
121        interfaces = new HashMap<>();
122        packageSet = new TreeSet<>(comparator);
123    }
124
125    /**
126     * Add the given class to the catalog.
127     *
128     * @param typeElement the TypeElement to add to the catalog.
129     */
130    public final void addTypeElement(TypeElement typeElement) {
131        if (typeElement == null) {
132            return;
133        }
134        addTypeElement(typeElement, allClasses);
135        if (utils.isOrdinaryClass(typeElement)) {
136            addTypeElement(typeElement, ordinaryClasses);
137        } else if (utils.isException(typeElement)) {
138            addTypeElement(typeElement, exceptions);
139        } else if (utils.isEnum(typeElement)) {
140            addTypeElement(typeElement, enums);
141        } else if (utils.isAnnotationType(typeElement)) {
142            addTypeElement(typeElement, annotationTypes);
143        } else if (utils.isError(typeElement)) {
144            addTypeElement(typeElement, errors);
145        } else if (utils.isInterface(typeElement)) {
146            addTypeElement(typeElement, interfaces);
147        }
148    }
149
150    /**
151     * Add the given class to the given map.
152     *
153     * @param typeElement the class to add to the catalog.
154     * @param map the Map to add the TypeElement to.
155     */
156    private void addTypeElement(TypeElement typeElement, Map<PackageElement, SortedSet<TypeElement>> map) {
157
158        PackageElement pkg = utils.containingPackage(typeElement);
159        if (utils.isSpecified(pkg) || configuration.nodeprecated && utils.isDeprecated(pkg)) {
160            // No need to catalog this class if it's package is
161            // specified on the command line or if -nodeprecated option is set
162            return;
163        }
164
165        SortedSet<TypeElement> s = map.get(pkg);
166        if (s == null) {
167            packageSet.add(pkg);
168            s = new TreeSet<>(comparator);
169        }
170        s.add(typeElement);
171        map.put(pkg, s);
172
173    }
174
175    private SortedSet<TypeElement> getSet(Map<PackageElement, SortedSet<TypeElement>> m, PackageElement key) {
176        SortedSet<TypeElement> s = m.get(key);
177        if (s != null) {
178            return s;
179        }
180        return new TreeSet<>(comparator);
181    }
182    /**
183     * Return all of the classes specified on the command-line that belong to the given package.
184     *
185     * @param packageElement the package to return the classes for.
186     */
187    public SortedSet<TypeElement> allClasses(PackageElement packageElement) {
188        return utils.isSpecified(packageElement)
189                ? utils.getTypeElementsAsSortedSet(utils.getEnclosedTypeElements(packageElement))
190                : getSet(allClasses, packageElement);
191    }
192
193    /**
194     * Return all of the classes specified on the command-line that belong to the given package.
195     *
196     * @param packageName the name of the package specified on the command-line.
197     */
198    public SortedSet<TypeElement> allUnnamedClasses() {
199        for (PackageElement pkg : allClasses.keySet()) {
200            if (pkg.isUnnamed()) {
201                return allClasses.get(pkg);
202            }
203        }
204        return new TreeSet<>(comparator);
205    }
206
207    /**
208     * Return a SortedSet of packages that this catalog stores.
209     */
210    public SortedSet<PackageElement> packages() {
211         return packageSet;
212    }
213
214    /**
215     * Return all of the errors specified on the command-line that belong to the given package.
216     *
217     * @param packageName the name of the package specified on the command-line.
218     */
219    public SortedSet<TypeElement> errors(PackageElement pkg) {
220        return getSet(errors, pkg);
221    }
222
223    /**
224     * Return all of the exceptions specified on the command-line that belong to the given package.
225     *
226     * @param packageName the name of the package specified on the command-line.
227     */
228    public SortedSet<TypeElement> exceptions(PackageElement pkg) {
229        return getSet(exceptions, pkg);
230    }
231
232    /**
233     * Return all of the enums specified on the command-line that belong to the given package.
234     *
235     * @param packageName the name of the package specified on the command-line.
236     */
237    public SortedSet<TypeElement> enums(PackageElement pkg) {
238        return getSet(enums, pkg);
239    }
240
241    /**
242     * Return all of the annotation types specified on the command-line that belong to the given
243     * package.
244     *
245     * @param packageName the name of the package specified on the command-line.
246     */
247    public SortedSet<TypeElement> annotationTypes(PackageElement pkg) {
248        return getSet(annotationTypes, pkg);
249    }
250
251    /**
252     * Return all of the interfaces specified on the command-line that belong to the given package.
253     *
254     * @param packageName the name of the package specified on the command-line.
255     */
256    public SortedSet<TypeElement> interfaces(PackageElement pkg) {
257        return getSet(interfaces, pkg);
258    }
259
260    /**
261     * Return all of the ordinary classes specified on the command-line that belong to the given
262     * package.
263     *
264     * @param packageName the name of the package specified on the command-line.
265     */
266    public SortedSet<TypeElement> ordinaryClasses(PackageElement pkg) {
267        return getSet(ordinaryClasses, pkg);
268    }
269}
270