IndexBuilder.java revision 2571:10fc81ac75b4
1/*
2 * Copyright (c) 1998, 2014, 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
26package com.sun.tools.doclets.internal.toolkit.util;
27
28import java.util.*;
29
30import com.sun.javadoc.*;
31import com.sun.tools.doclets.internal.toolkit.*;
32
33/**
34 * Build the mapping of each Unicode character with it's member lists
35 * containing members names starting with it. Also build a list for all the
36 * Unicode characters which start a member name. Member name is
37 * classkind or field or method or constructor name.
38 *
39 *  <p><b>This is NOT part of any supported API.
40 *  If you write code that depends on this, you do so at your own risk.
41 *  This code and its internal interfaces are subject to change or
42 *  deletion without notice.</b>
43 *
44 * @since 1.2
45 * @see java.lang.Character
46 * @author Atul M Dambalkar
47 */
48public class IndexBuilder {
49
50    /**
51     * Mapping of each Unicode Character with the member list containing
52     * members with names starting with it.
53     */
54    private Map<Character,List<Doc>> indexmap = new HashMap<>();
55
56    /**
57     * Don't generate deprecated information if true.
58     */
59    private boolean noDeprecated;
60
61    /**
62     * Build this Index only for classes?
63     */
64    private boolean classesOnly;
65
66    /**
67     * Indicates javafx mode.
68     */
69    private boolean javafx;
70
71    // make ProgramElementDoc[] when new toArray is available
72    protected final Object[] elements;
73
74    private final Configuration configuration;
75    /**
76     * Constructor. Build the index map.
77     *
78     * @param configuration the current configuration of the doclet.
79     * @param noDeprecated  true if -nodeprecated option is used,
80     *                      false otherwise.
81     */
82    public IndexBuilder(Configuration configuration, boolean noDeprecated) {
83        this(configuration, noDeprecated, false);
84    }
85
86    /**
87     * Constructor. Build the index map.
88     *
89     * @param configuration the current configuration of the doclet.
90     * @param noDeprecated  true if -nodeprecated option is used,
91     *                      false otherwise.
92     * @param classesOnly   Include only classes in index.
93     */
94    public IndexBuilder(Configuration configuration, boolean noDeprecated,
95                        boolean classesOnly) {
96        this.configuration  = configuration;
97        if (classesOnly) {
98            configuration.message.notice("doclet.Building_Index_For_All_Classes");
99        } else {
100            configuration.message.notice("doclet.Building_Index");
101        }
102        this.noDeprecated = noDeprecated;
103        this.classesOnly = classesOnly;
104        this.javafx = configuration.javafx;
105        buildIndexMap(configuration.root);
106        Set<Character> set = indexmap.keySet();
107        elements =  set.toArray();
108        Arrays.sort(elements);
109    }
110
111    /**
112     * Sort the index map. Traverse the index map for all it's elements and
113     * sort each element which is a list.
114     */
115    protected void sortIndexMap() {
116        for (List<Doc> docs : indexmap.values()) {
117            Collections.sort(docs, configuration.utils.makeComparatorForIndexUse());
118        }
119    }
120
121    /**
122     * Get all the members in all the Packages and all the Classes
123     * given on the command line. Form separate list of those members depending
124     * upon their names.
125     *
126     * @param root Root of the documemt.
127     */
128    protected void buildIndexMap(RootDoc root)  {
129        PackageDoc[] packages = root.specifiedPackages();
130        ClassDoc[] classes = root.classes();
131        if (!classesOnly) {
132            if (packages.length == 0) {
133                Set<PackageDoc> set = new HashSet<>();
134                for (ClassDoc aClass : classes) {
135                    PackageDoc pd = aClass.containingPackage();
136                    if (pd != null && pd.name().length() > 0) {
137                        set.add(pd);
138                    }
139                }
140                adjustIndexMap(set.toArray(packages));
141            } else {
142                adjustIndexMap(packages);
143            }
144        }
145        adjustIndexMap(classes);
146        if (!classesOnly) {
147            for (ClassDoc aClass : classes) {
148                if (shouldAddToIndexMap(aClass)) {
149                    putMembersInIndexMap(aClass);
150                }
151            }
152        }
153        sortIndexMap();
154    }
155
156    /**
157     * Put all the members(fields, methods and constructors) in the classdoc
158     * to the indexmap.
159     *
160     * @param classdoc ClassDoc whose members will be added to the indexmap.
161     */
162    protected void putMembersInIndexMap(ClassDoc classdoc) {
163        adjustIndexMap(classdoc.fields());
164        adjustIndexMap(classdoc.methods());
165        adjustIndexMap(classdoc.constructors());
166    }
167
168
169    /**
170     * Adjust list of members according to their names. Check the first
171     * character in a member name, and then add the member to a list of members
172     * for that particular unicode character.
173     *
174     * @param elements Array of members.
175     */
176    protected void adjustIndexMap(Doc[] elements) {
177        for (Doc element : elements) {
178            if (shouldAddToIndexMap(element)) {
179                String name = element.name();
180                char ch = (name.length() == 0) ?
181                          '*' :
182                          Character.toUpperCase(name.charAt(0));
183                Character unicode = ch;
184                List<Doc> list = indexmap.get(unicode);
185                if (list == null) {
186                    list = new ArrayList<>();
187                    indexmap.put(unicode, list);
188                }
189                list.add(element);
190            }
191        }
192    }
193
194    /**
195     * Should this doc element be added to the index map?
196     */
197    protected boolean shouldAddToIndexMap(Doc element) {
198        if (javafx) {
199            if (element.tags("treatAsPrivate").length > 0) {
200                return false;
201            }
202        }
203
204        if (element instanceof PackageDoc)
205            // Do not add to index map if -nodeprecated option is set and the
206            // package is marked as deprecated.
207            return !(noDeprecated && configuration.utils.isDeprecated(element));
208        else
209            // Do not add to index map if -nodeprecated option is set and if the
210            // Doc is marked as deprecated or the containing package is marked as
211            // deprecated.
212            return !(noDeprecated &&
213                    (configuration.utils.isDeprecated(element) ||
214                    configuration.utils.isDeprecated(((ProgramElementDoc)element).containingPackage())));
215    }
216
217    /**
218     * Return a map of all the individual member lists with Unicode character.
219     *
220     * @return Map index map.
221     */
222    public Map<Character,List<Doc>> getIndexMap() {
223        return indexmap;
224    }
225
226    /**
227     * Return the sorted list of members, for passed Unicode Character.
228     *
229     * @param index index Unicode character.
230     * @return List member list for specific Unicode character.
231     */
232    public List<Doc> getMemberList(Character index) {
233        return indexmap.get(index);
234    }
235
236    /**
237     * Array of IndexMap keys, Unicode characters.
238     */
239    public Object[] elements() {
240        return elements;
241    }
242}
243