IndexBuilder.java revision 3233:b5d08bc0d224
1/* 2 * Copyright (c) 1998, 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 */ 25 26package jdk.javadoc.internal.doclets.toolkit.util; 27 28import java.util.*; 29 30import javax.lang.model.element.Element; 31import javax.lang.model.element.PackageElement; 32import javax.lang.model.element.TypeElement; 33 34import jdk.javadoc.doclet.DocletEnvironment; 35import jdk.javadoc.internal.doclets.toolkit.Configuration; 36 37/** 38 * Build the mapping of each Unicode character with it's member lists 39 * containing members names starting with it. Also build a list for all the 40 * Unicode characters which start a member name. Member name is 41 * classkind or field or method or constructor name. 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 * @see java.lang.Character 49 * @author Atul M Dambalkar 50 */ 51public class IndexBuilder { 52 53 /** 54 * Mapping of each Unicode Character with the member list containing 55 * members with names starting with it. 56 */ 57 private final Map<Character, SortedSet<Element>> indexmap; 58 59 /** 60 * Don't generate deprecated information if true. 61 */ 62 private boolean noDeprecated; 63 64 /** 65 * Build this Index only for classes? 66 */ 67 private boolean classesOnly; 68 69 /** 70 * Indicates javafx mode. 71 */ 72 private boolean javafx; 73 74 private final Configuration configuration; 75 private final Utils utils; 76 77 /** 78 * Constructor. Build the index map. 79 * 80 * @param configuration the current configuration of the doclet. 81 * @param noDeprecated true if -nodeprecated option is used, 82 * false otherwise. 83 */ 84 public IndexBuilder(Configuration configuration, boolean noDeprecated) { 85 this(configuration, noDeprecated, false); 86 } 87 88 /** 89 * Constructor. Build the index map. 90 * 91 * @param configuration the current configuration of the doclet. 92 * @param noDeprecated true if -nodeprecated option is used, 93 * false otherwise. 94 * @param classesOnly Include only classes in index. 95 */ 96 public IndexBuilder(Configuration configuration, boolean noDeprecated, 97 boolean classesOnly) { 98 this.configuration = configuration; 99 this.utils = configuration.utils; 100 if (classesOnly) { 101 configuration.message.notice("doclet.Building_Index_For_All_Classes"); 102 } else { 103 configuration.message.notice("doclet.Building_Index"); 104 } 105 this.noDeprecated = noDeprecated; 106 this.classesOnly = classesOnly; 107 this.javafx = configuration.javafx; 108 this.indexmap = new TreeMap<>(); 109 buildIndexMap(configuration.root); 110 } 111 112 /** 113 * Get all the members in all the Packages and all the Classes 114 * given on the command line. Form separate list of those members depending 115 * upon their names. 116 * 117 * @param root Root of the documemt. 118 */ 119 protected void buildIndexMap(DocletEnvironment root) { 120 Set<PackageElement> packages = utils.getSpecifiedPackages(); 121 Set<TypeElement> classes = root.getIncludedClasses(); 122 if (!classesOnly) { 123 if (packages.isEmpty()) { 124 Set<PackageElement> set = new HashSet<>(); 125 for (TypeElement aClass : classes) { 126 PackageElement pkg = utils.containingPackage(aClass); 127 if (pkg != null && !pkg.isUnnamed()) { 128 set.add(pkg); 129 } 130 } 131 adjustIndexMap(set); 132 } else { 133 adjustIndexMap(packages); 134 } 135 } 136 adjustIndexMap(classes); 137 if (!classesOnly) { 138 for (TypeElement aClass : classes) { 139 if (shouldAddToIndexMap(aClass)) { 140 putMembersInIndexMap(aClass); 141 } 142 } 143 } 144 } 145 146 /** 147 * Put all the members(fields, methods and constructors) in the te 148 * to the indexmap. 149 * 150 * @param te TypeElement whose members will be added to the indexmap. 151 */ 152 protected void putMembersInIndexMap(TypeElement te) { 153 adjustIndexMap(utils.getAnnotationFields(te)); 154 adjustIndexMap(utils.getFields(te)); 155 adjustIndexMap(utils.getMethods(te)); 156 adjustIndexMap(utils.getConstructors(te)); 157 } 158 159 160 /** 161 * Adjust list of members according to their names. Check the first 162 * character in a member name, and then add the member to a list of members 163 * for that particular unicode character. 164 * 165 * @param elements Array of members. 166 */ 167 protected void adjustIndexMap(Iterable<? extends Element> elements) { 168 for (Element element : elements) { 169 if (shouldAddToIndexMap(element)) { 170 String name = utils.isPackage(element) 171 ? utils.getPackageName((PackageElement)element) 172 : utils.getSimpleName(element); 173 char ch = (name.length() == 0) ? 174 '*' : 175 Character.toUpperCase(name.charAt(0)); 176 Character unicode = ch; 177 SortedSet<Element> list = indexmap.computeIfAbsent(unicode, 178 c -> new TreeSet<>(utils.makeIndexUseComparator())); 179 list.add(element); 180 } 181 } 182 } 183 184 /** 185 * Should this element be added to the index map? 186 */ 187 protected boolean shouldAddToIndexMap(Element element) { 188 if (javafx) { 189 if (!utils.getBlockTags(element, "treatAsPrivate").isEmpty()) { 190 return false; 191 } 192 } 193 194 if (utils.isPackage(element)) 195 // Do not add to index map if -nodeprecated option is set and the 196 // package is marked as deprecated. 197 return !(noDeprecated && configuration.utils.isDeprecated(element)); 198 else 199 // Do not add to index map if -nodeprecated option is set and if the 200 // element is marked as deprecated or the containing package is marked as 201 // deprecated. 202 return !(noDeprecated && 203 (configuration.utils.isDeprecated(element) || 204 configuration.utils.isDeprecated(utils.containingPackage(element)))); 205 } 206 207 /** 208 * Return a map of all the individual member lists with Unicode character. 209 * 210 * @return Map index map. 211 */ 212 public Map<Character, SortedSet<Element>> getIndexMap() { 213 return indexmap; 214 } 215 216 /** 217 * Return the sorted list of members, for passed Unicode Character. 218 * 219 * @param index index Unicode character. 220 * @return List member list for specific Unicode character. 221 */ 222 public List<? extends Element> getMemberList(Character index) { 223 SortedSet<Element> set = indexmap.get(index); 224 if (set == null) 225 return null; 226 List<Element> out = new ArrayList<>(); 227 out.addAll(set); 228 return out; 229 } 230 231 /** 232 * Array of IndexMap keys, Unicode characters. 233 */ 234 public List<Character> index() { 235 return new ArrayList<>(indexmap.keySet()); 236 } 237} 238