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 26 package com.sun.tools.doclets.internal.toolkit.util; 27 28 import java.util.*; 29 30 import com.sun.javadoc.*; 31 import 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 */ 48 public 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 }