TypeElementCatalog.java revision 3233:b5d08bc0d224
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            addClassDoc(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 addClassDoc(TypeElement typeElement) {
131        if (typeElement == null) {
132            return;
133        }
134        addClass(typeElement, allClasses);
135        if (utils.isOrdinaryClass(typeElement)) {
136            addClass(typeElement, ordinaryClasses);
137        } else if (utils.isException(typeElement)) {
138            addClass(typeElement, exceptions);
139        } else if (utils.isEnum(typeElement)) {
140            addClass(typeElement, enums);
141        } else if (utils.isAnnotationType(typeElement)) {
142            addClass(typeElement, annotationTypes);
143        } else if (utils.isError(typeElement)) {
144            addClass(typeElement, errors);
145        } else if (utils.isInterface(typeElement)) {
146            addClass(typeElement, interfaces);
147        }
148    }
149
150    /**
151     * Add the given class to the given map.
152     *
153     * @param typeElement the ClassDoc to add to the catalog.
154     * @param map the Map to add the TypeElement to.
155     */
156    private void addClass(TypeElement typeElement, Map<PackageElement, SortedSet<TypeElement>> map) {
157
158        PackageElement pkg = utils.containingPackage(typeElement);
159        if (utils.isIncluded(pkg) || (configuration.nodeprecated && utils.isDeprecated(pkg))) {
160            // No need to catalog this class if it's package is
161            // included on the command line or if -nodeprecated option is set
162            // and the containing package is marked as deprecated.
163            return;
164        }
165
166        SortedSet<TypeElement> s = map.get(pkg);
167        if (s == null) {
168            packageSet.add(pkg);
169            s = new TreeSet<>(comparator);
170        }
171        s.add(typeElement);
172        map.put(pkg, s);
173
174    }
175
176    private SortedSet<TypeElement> getSet(Map<PackageElement, SortedSet<TypeElement>> m, PackageElement key) {
177        SortedSet<TypeElement> s = m.get(key);
178        if (s != null) {
179            return s;
180        }
181        return new TreeSet<>(comparator);
182    }
183    /**
184     * Return all of the classes specified on the command-line that belong to the given package.
185     *
186     * @param packageElement the package to return the classes for.
187     */
188    public SortedSet<TypeElement> allClasses(PackageElement packageElement) {
189        return utils.isIncluded(packageElement)
190                ? utils.getTypeElementsAsSortedSet(utils.getEnclosedTypeElements(packageElement))
191                : getSet(allClasses, packageElement);
192    }
193
194    /**
195     * Return all of the classes specified on the command-line that belong to the given package.
196     *
197     * @param packageName the name of the package specified on the command-line.
198     */
199    public SortedSet<TypeElement> allUnnamedClasses() {
200        for (PackageElement pkg : allClasses.keySet()) {
201            if (pkg.isUnnamed()) {
202                return allClasses.get(pkg);
203            }
204        }
205        return new TreeSet<>(comparator);
206    }
207
208    /**
209     * Return a SortedSet of packages that this catalog stores.
210     */
211    public SortedSet<PackageElement> packages() {
212         return packageSet;
213    }
214
215    /**
216     * Return all of the errors specified on the command-line that belong to the given package.
217     *
218     * @param packageName the name of the package specified on the command-line.
219     */
220    public SortedSet<TypeElement> errors(PackageElement pkg) {
221        return getSet(errors, pkg);
222    }
223
224    /**
225     * Return all of the exceptions specified on the command-line that belong to the given package.
226     *
227     * @param packageName the name of the package specified on the command-line.
228     */
229    public SortedSet<TypeElement> exceptions(PackageElement pkg) {
230        return getSet(exceptions, pkg);
231    }
232
233    /**
234     * Return all of the enums specified on the command-line that belong to the given package.
235     *
236     * @param packageName the name of the package specified on the command-line.
237     */
238    public SortedSet<TypeElement> enums(PackageElement pkg) {
239        return getSet(enums, pkg);
240    }
241
242    /**
243     * Return all of the annotation types specified on the command-line that belong to the given
244     * package.
245     *
246     * @param packageName the name of the package specified on the command-line.
247     */
248    public SortedSet<TypeElement> annotationTypes(PackageElement pkg) {
249        return getSet(annotationTypes, pkg);
250    }
251
252    /**
253     * Return all of the interfaces specified on the command-line that belong to the given package.
254     *
255     * @param packageName the name of the package specified on the command-line.
256     */
257    public SortedSet<TypeElement> interfaces(PackageElement pkg) {
258        return getSet(interfaces, pkg);
259    }
260
261    /**
262     * Return all of the ordinary classes specified on the command-line that belong to the given
263     * package.
264     *
265     * @param packageName the name of the package specified on the command-line.
266     */
267    public SortedSet<TypeElement> ordinaryClasses(PackageElement pkg) {
268        return getSet(ordinaryClasses, pkg);
269    }
270}
271