src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java

Tue, 09 Oct 2012 19:10:00 -0700

author
jjg
date
Tue, 09 Oct 2012 19:10:00 -0700
changeset 1357
c75be5bc5283
parent 1339
0e5899f09dab
child 1359
25e14ad23cef
permissions
-rw-r--r--

8000663: clean up langtools imports
Reviewed-by: darcy

duke@1 1 /*
bpatel@1324 2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
duke@1 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1 4 *
duke@1 5 * This code is free software; you can redistribute it and/or modify it
duke@1 6 * under the terms of the GNU General Public License version 2 only, as
ohair@554 7 * published by the Free Software Foundation. Oracle designates this
duke@1 8 * particular file as subject to the "Classpath" exception as provided
ohair@554 9 * by Oracle in the LICENSE file that accompanied this code.
duke@1 10 *
duke@1 11 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1 14 * version 2 for more details (a copy is included in the LICENSE file that
duke@1 15 * accompanied this code).
duke@1 16 *
duke@1 17 * You should have received a copy of the GNU General Public License version
duke@1 18 * 2 along with this work; if not, write to the Free Software Foundation,
duke@1 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1 20 *
ohair@554 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554 22 * or visit www.oracle.com if you need additional information or have any
ohair@554 23 * questions.
duke@1 24 */
duke@1 25
duke@1 26 package com.sun.tools.doclets.internal.toolkit.taglets;
duke@1 27
duke@1 28 import java.io.*;
duke@1 29 import java.lang.reflect.*;
duke@1 30 import java.net.*;
duke@1 31 import java.util.*;
duke@1 32
jjg@1357 33 import com.sun.javadoc.*;
jjg@1357 34 import com.sun.tools.doclets.internal.toolkit.util.*;
jjg@1357 35
duke@1 36 /**
duke@1 37 * Manages the<code>Taglet</code>s used by doclets.
duke@1 38 *
duke@1 39 * This code is not part of an API.
duke@1 40 * It is implementation that is subject to change.
duke@1 41 * Do not use it as an API
duke@1 42 *
duke@1 43 * @author Jamie Ho
duke@1 44 * @since 1.4
duke@1 45 */
duke@1 46
duke@1 47 public class TagletManager {
duke@1 48
duke@1 49 /**
duke@1 50 * The default seperator for the simple tag option.
duke@1 51 */
duke@1 52 public static final char SIMPLE_TAGLET_OPT_SEPERATOR = ':';
duke@1 53
duke@1 54 /**
duke@1 55 * The alternate seperator for simple tag options. Use this
duke@1 56 * with you want the default seperator to be in the name of the
duke@1 57 * custom tag.
duke@1 58 */
duke@1 59 public static final String ALT_SIMPLE_TAGLET_OPT_SEPERATOR = "-";
duke@1 60
duke@1 61 /**
duke@1 62 * The map of custom tags.
duke@1 63 */
jjg@74 64 private LinkedHashMap<String,Taglet> customTags;
duke@1 65
duke@1 66 /**
duke@1 67 * The array of custom tags that can appear in packages.
duke@1 68 */
duke@1 69 private Taglet[] packageTags;
duke@1 70
duke@1 71 /**
duke@1 72 * The array of custom tags that can appear in classes or interfaces.
duke@1 73 */
duke@1 74 private Taglet[] typeTags;
duke@1 75
duke@1 76 /**
duke@1 77 * The array of custom tags that can appear in fields.
duke@1 78 */
duke@1 79 private Taglet[] fieldTags;
duke@1 80
duke@1 81 /**
duke@1 82 * The array of custom tags that can appear in constructors.
duke@1 83 */
duke@1 84 private Taglet[] constructorTags;
duke@1 85
duke@1 86 /**
duke@1 87 * The array of custom tags that can appear in methods.
duke@1 88 */
duke@1 89 private Taglet[] methodTags;
duke@1 90
duke@1 91 /**
duke@1 92 * The array of custom tags that can appear in the overview.
duke@1 93 */
duke@1 94 private Taglet[] overviewTags;
duke@1 95
duke@1 96 /**
duke@1 97 * The array of custom tags that can appear in comments.
duke@1 98 */
duke@1 99 private Taglet[] inlineTags;
duke@1 100
duke@1 101 /**
duke@1 102 * The array of custom tags that can appear in the serialized form.
duke@1 103 */
duke@1 104 private Taglet[] serializedFormTags;
duke@1 105
duke@1 106 /**
duke@1 107 * The message retriever that will be used to print error messages.
duke@1 108 */
duke@1 109 private MessageRetriever message;
duke@1 110
duke@1 111 /**
duke@1 112 * Keep track of standard tags.
duke@1 113 */
jjg@74 114 private Set<String> standardTags;
duke@1 115
duke@1 116 /**
duke@1 117 * Keep track of standard tags in lowercase to compare for better
duke@1 118 * error messages when a tag like @docRoot is mistakenly spelled
duke@1 119 * lowercase @docroot.
duke@1 120 */
jjg@74 121 private Set<String> standardTagsLowercase;
duke@1 122
duke@1 123 /**
duke@1 124 * Keep track of overriden standard tags.
duke@1 125 */
jjg@74 126 private Set<String> overridenStandardTags;
duke@1 127
duke@1 128 /**
duke@1 129 * Keep track of the tags that may conflict
duke@1 130 * with standard tags in the future (any custom tag without
duke@1 131 * a period in its name).
duke@1 132 */
jjg@74 133 private Set<String> potentiallyConflictingTags;
duke@1 134
duke@1 135 /**
duke@1 136 * The set of unseen custom tags.
duke@1 137 */
jjg@74 138 private Set<String> unseenCustomTags;
duke@1 139
duke@1 140 /**
duke@1 141 * True if we do not want to use @since tags.
duke@1 142 */
duke@1 143 private boolean nosince;
duke@1 144
duke@1 145 /**
duke@1 146 * True if we want to use @version tags.
duke@1 147 */
duke@1 148 private boolean showversion;
duke@1 149
duke@1 150 /**
duke@1 151 * True if we want to use @author tags.
duke@1 152 */
duke@1 153 private boolean showauthor;
duke@1 154
duke@1 155 /**
duke@1 156 * Construct a new <code>TagletManager</code>.
duke@1 157 * @param nosince true if we do not want to use @since tags.
duke@1 158 * @param showversion true if we want to use @version tags.
duke@1 159 * @param showauthor true if we want to use @author tags.
duke@1 160 * @param message the message retriever to print warnings.
duke@1 161 */
duke@1 162 public TagletManager(boolean nosince, boolean showversion,
duke@1 163 boolean showauthor, MessageRetriever message){
jjg@74 164 overridenStandardTags = new HashSet<String>();
jjg@74 165 potentiallyConflictingTags = new HashSet<String>();
jjg@74 166 standardTags = new HashSet<String>();
jjg@74 167 standardTagsLowercase = new HashSet<String>();
jjg@74 168 unseenCustomTags = new HashSet<String>();
jjg@74 169 customTags = new LinkedHashMap<String,Taglet>();
duke@1 170 this.nosince = nosince;
duke@1 171 this.showversion = showversion;
duke@1 172 this.showauthor = showauthor;
duke@1 173 this.message = message;
duke@1 174 initStandardTags();
duke@1 175 initStandardTagsLowercase();
duke@1 176 }
duke@1 177
duke@1 178 /**
duke@1 179 * Add a new <code>CustomTag</code>. This is used to add a Taglet from within
duke@1 180 * a Doclet. No message is printed to indicate that the Taglet is properly
duke@1 181 * registered because these Taglets are typically added for every execution of the
duke@1 182 * Doclet. We don't want to see this type of error message every time.
duke@1 183 * @param customTag the new <code>CustomTag</code> to add.
duke@1 184 */
duke@1 185 public void addCustomTag(Taglet customTag) {
duke@1 186 if (customTag != null) {
duke@1 187 String name = customTag.getName();
duke@1 188 if (customTags.containsKey(name)) {
duke@1 189 customTags.remove(name);
duke@1 190 }
duke@1 191 customTags.put(name, customTag);
duke@1 192 checkTagName(name);
duke@1 193 }
duke@1 194 }
duke@1 195
duke@1 196 /**
duke@1 197 * Add a new <code>Taglet</code>. Print a message to indicate whether or not
duke@1 198 * the Taglet was registered properly.
duke@1 199 * @param classname the name of the class representing the custom tag.
duke@1 200 * @param tagletPath the path to the class representing the custom tag.
duke@1 201 */
duke@1 202 public void addCustomTag(String classname, String tagletPath) {
duke@1 203 try {
jjg@74 204 Class<?> customTagClass = null;
duke@1 205 // construct class loader
duke@1 206 String cpString = null; // make sure env.class.path defaults to dot
duke@1 207
duke@1 208 // do prepends to get correct ordering
duke@1 209 cpString = appendPath(System.getProperty("env.class.path"), cpString);
duke@1 210 cpString = appendPath(System.getProperty("java.class.path"), cpString);
duke@1 211 cpString = appendPath(tagletPath, cpString);
duke@1 212 URLClassLoader appClassLoader = new URLClassLoader(pathToURLs(cpString));
duke@1 213 customTagClass = appClassLoader.loadClass(classname);
duke@1 214 Method meth = customTagClass.getMethod("register",
mcimadamore@184 215 new Class<?>[] {java.util.Map.class});
duke@1 216 Object[] list = customTags.values().toArray();
duke@1 217 Taglet lastTag = (list != null && list.length > 0)
duke@1 218 ? (Taglet) list[list.length-1] : null;
duke@1 219 meth.invoke(null, new Object[] {customTags});
duke@1 220 list = customTags.values().toArray();
duke@1 221 Object newLastTag = (list != null&& list.length > 0)
jjg@74 222 ? list[list.length-1] : null;
duke@1 223 if (lastTag != newLastTag) {
duke@1 224 //New taglets must always be added to the end of the LinkedHashMap.
duke@1 225 //If the current and previous last taglet are not equal, that
duke@1 226 //means a new Taglet has been added.
duke@1 227 message.notice("doclet.Notice_taglet_registered", classname);
duke@1 228 if (newLastTag != null) {
duke@1 229 checkTaglet(newLastTag);
duke@1 230 }
duke@1 231 }
duke@1 232 } catch (Exception exc) {
duke@1 233 message.error("doclet.Error_taglet_not_registered", exc.getClass().getName(), classname);
duke@1 234 }
duke@1 235
duke@1 236 }
duke@1 237
duke@1 238 private String appendPath(String path1, String path2) {
duke@1 239 if (path1 == null || path1.length() == 0) {
duke@1 240 return path2 == null ? "." : path2;
duke@1 241 } else if (path2 == null || path2.length() == 0) {
duke@1 242 return path1;
duke@1 243 } else {
duke@1 244 return path1 + File.pathSeparator + path2;
duke@1 245 }
duke@1 246 }
duke@1 247
duke@1 248 /**
duke@1 249 * Utility method for converting a search path string to an array
duke@1 250 * of directory and JAR file URLs.
duke@1 251 *
duke@1 252 * @param path the search path string
duke@1 253 * @return the resulting array of directory and JAR file URLs
duke@1 254 */
duke@1 255 private static URL[] pathToURLs(String path) {
duke@1 256 StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
duke@1 257 URL[] urls = new URL[st.countTokens()];
duke@1 258 int count = 0;
duke@1 259 while (st.hasMoreTokens()) {
duke@1 260 URL url = fileToURL(new File(st.nextToken()));
duke@1 261 if (url != null) {
duke@1 262 urls[count++] = url;
duke@1 263 }
duke@1 264 }
jjg@1339 265 urls = Arrays.copyOf(urls, count);
duke@1 266 return urls;
duke@1 267 }
duke@1 268
duke@1 269 /**
duke@1 270 * Returns the directory or JAR file URL corresponding to the specified
duke@1 271 * local file name.
duke@1 272 *
duke@1 273 * @param file the File object
duke@1 274 * @return the resulting directory or JAR file URL, or null if unknown
duke@1 275 */
duke@1 276 private static URL fileToURL(File file) {
duke@1 277 String name;
duke@1 278 try {
duke@1 279 name = file.getCanonicalPath();
duke@1 280 } catch (IOException e) {
duke@1 281 name = file.getAbsolutePath();
duke@1 282 }
duke@1 283 name = name.replace(File.separatorChar, '/');
duke@1 284 if (!name.startsWith("/")) {
duke@1 285 name = "/" + name;
duke@1 286 }
duke@1 287 // If the file does not exist, then assume that it's a directory
duke@1 288 if (!file.isFile()) {
duke@1 289 name = name + "/";
duke@1 290 }
duke@1 291 try {
duke@1 292 return new URL("file", "", name);
duke@1 293 } catch (MalformedURLException e) {
duke@1 294 throw new IllegalArgumentException("file");
duke@1 295 }
duke@1 296 }
duke@1 297
duke@1 298
duke@1 299 /**
duke@1 300 * Add a new <code>SimpleTaglet</code>. If this tag already exists
duke@1 301 * and the header passed as an argument is null, move tag to the back of the
duke@1 302 * list. If this tag already exists and the header passed as an argument is
duke@1 303 * not null, overwrite previous tag with new one. Otherwise, add new
duke@1 304 * SimpleTaglet to list.
duke@1 305 * @param tagName the name of this tag
duke@1 306 * @param header the header to output.
duke@1 307 * @param locations the possible locations that this tag
duke@1 308 * can appear in.
duke@1 309 */
duke@1 310 public void addNewSimpleCustomTag(String tagName, String header, String locations) {
duke@1 311 if (tagName == null || locations == null) {
duke@1 312 return;
duke@1 313 }
jjg@74 314 Taglet tag = customTags.get(tagName);
duke@1 315 locations = locations.toLowerCase();
duke@1 316 if (tag == null || header != null) {
duke@1 317 customTags.remove(tagName);
duke@1 318 customTags.put(tagName, new SimpleTaglet(tagName, header, locations));
duke@1 319 if (locations != null && locations.indexOf('x') == -1) {
duke@1 320 checkTagName(tagName);
duke@1 321 }
duke@1 322 } else {
duke@1 323 //Move to back
duke@1 324 customTags.remove(tagName);
duke@1 325 customTags.put(tagName, tag);
duke@1 326 }
duke@1 327 }
duke@1 328
duke@1 329 /**
duke@1 330 * Given a tag name, add it to the set of tags it belongs to.
duke@1 331 */
duke@1 332 private void checkTagName(String name) {
duke@1 333 if (standardTags.contains(name)) {
duke@1 334 overridenStandardTags.add(name);
duke@1 335 } else {
duke@1 336 if (name.indexOf('.') == -1) {
duke@1 337 potentiallyConflictingTags.add(name);
duke@1 338 }
duke@1 339 unseenCustomTags.add(name);
duke@1 340 }
duke@1 341 }
duke@1 342
duke@1 343 /**
duke@1 344 * Check the taglet to see if it is a legacy taglet. Also
duke@1 345 * check its name for errors.
duke@1 346 */
duke@1 347 private void checkTaglet(Object taglet) {
duke@1 348 if (taglet instanceof Taglet) {
duke@1 349 checkTagName(((Taglet) taglet).getName());
duke@1 350 } else if (taglet instanceof com.sun.tools.doclets.Taglet) {
duke@1 351 com.sun.tools.doclets.Taglet legacyTaglet = (com.sun.tools.doclets.Taglet) taglet;
duke@1 352 customTags.remove(legacyTaglet.getName());
duke@1 353 customTags.put(legacyTaglet.getName(), new LegacyTaglet(legacyTaglet));
duke@1 354 checkTagName(legacyTaglet.getName());
duke@1 355 } else {
duke@1 356 throw new IllegalArgumentException("Given object is not a taglet.");
duke@1 357 }
duke@1 358 }
duke@1 359
duke@1 360 /**
duke@1 361 * Given a name of a seen custom tag, remove it from the set of unseen
duke@1 362 * custom tags.
duke@1 363 * @param name the name of the seen custom tag.
duke@1 364 */
duke@1 365 public void seenCustomTag(String name) {
duke@1 366 unseenCustomTags.remove(name);
duke@1 367 }
duke@1 368
duke@1 369 /**
duke@1 370 * Given an array of <code>Tag</code>s, check for spelling mistakes.
duke@1 371 * @param doc the Doc object that holds the tags.
duke@1 372 * @param tags the list of <code>Tag</code>s to check.
duke@1 373 * @param areInlineTags true if the array of tags are inline and false otherwise.
duke@1 374 */
duke@1 375 public void checkTags(Doc doc, Tag[] tags, boolean areInlineTags) {
duke@1 376 if (tags == null) {
duke@1 377 return;
duke@1 378 }
duke@1 379 Taglet taglet;
duke@1 380 for (int i = 0; i < tags.length; i++) {
duke@1 381 String name = tags[i].name();
duke@1 382 if (name.length() > 0 && name.charAt(0) == '@') {
duke@1 383 name = name.substring(1, name.length());
duke@1 384 }
duke@1 385 if (! (standardTags.contains(name) || customTags.containsKey(name))) {
duke@1 386 if (standardTagsLowercase.contains(name.toLowerCase())) {
duke@1 387 message.warning(tags[i].position(), "doclet.UnknownTagLowercase", tags[i].name());
duke@1 388 continue;
duke@1 389 } else {
duke@1 390 message.warning(tags[i].position(), "doclet.UnknownTag", tags[i].name());
duke@1 391 continue;
duke@1 392 }
duke@1 393 }
duke@1 394 //Check if this tag is being used in the wrong location.
jjg@74 395 if ((taglet = customTags.get(name)) != null) {
duke@1 396 if (areInlineTags && ! taglet.isInlineTag()) {
duke@1 397 printTagMisuseWarn(taglet, tags[i], "inline");
duke@1 398 }
duke@1 399 if ((doc instanceof RootDoc) && ! taglet.inOverview()) {
duke@1 400 printTagMisuseWarn(taglet, tags[i], "overview");
duke@1 401 } else if ((doc instanceof PackageDoc) && ! taglet.inPackage()) {
duke@1 402 printTagMisuseWarn(taglet, tags[i], "package");
duke@1 403 } else if ((doc instanceof ClassDoc) && ! taglet.inType()) {
duke@1 404 printTagMisuseWarn(taglet, tags[i], "class");
duke@1 405 } else if ((doc instanceof ConstructorDoc) && ! taglet.inConstructor()) {
duke@1 406 printTagMisuseWarn(taglet, tags[i], "constructor");
duke@1 407 } else if ((doc instanceof FieldDoc) && ! taglet.inField()) {
duke@1 408 printTagMisuseWarn(taglet, tags[i], "field");
duke@1 409 } else if ((doc instanceof MethodDoc) && ! taglet.inMethod()) {
duke@1 410 printTagMisuseWarn(taglet, tags[i], "method");
duke@1 411 }
duke@1 412 }
duke@1 413 }
duke@1 414 }
duke@1 415
duke@1 416 /**
duke@1 417 * Given the taglet, the tag and the type of documentation that the tag
duke@1 418 * was found in, print a tag misuse warning.
duke@1 419 * @param taglet the taglet representing the misused tag.
duke@1 420 * @param tag the misused tag.
duke@1 421 * @param holderType the type of documentation that the misused tag was found in.
duke@1 422 */
duke@1 423 private void printTagMisuseWarn(Taglet taglet, Tag tag, String holderType) {
jjg@74 424 Set<String> locationsSet = new LinkedHashSet<String>();
duke@1 425 if (taglet.inOverview()) {
duke@1 426 locationsSet.add("overview");
duke@1 427 }
duke@1 428 if (taglet.inPackage()) {
duke@1 429 locationsSet.add("package");
duke@1 430 }
duke@1 431 if (taglet.inType()) {
duke@1 432 locationsSet.add("class/interface");
duke@1 433 }
duke@1 434 if (taglet.inConstructor()) {
duke@1 435 locationsSet.add("constructor");
duke@1 436 }
duke@1 437 if (taglet.inField()) {
duke@1 438 locationsSet.add("field");
duke@1 439 }
duke@1 440 if (taglet.inMethod()) {
duke@1 441 locationsSet.add("method");
duke@1 442 }
duke@1 443 if (taglet.isInlineTag()) {
duke@1 444 locationsSet.add("inline text");
duke@1 445 }
jjg@74 446 String[] locations = locationsSet.toArray(new String[]{});
duke@1 447 if (locations == null || locations.length == 0) {
duke@1 448 //This known tag is excluded.
duke@1 449 return;
duke@1 450 }
duke@1 451 StringBuffer combined_locations = new StringBuffer();
duke@1 452 for (int i = 0; i < locations.length; i++) {
duke@1 453 if (i > 0) {
duke@1 454 combined_locations.append(", ");
duke@1 455 }
duke@1 456 combined_locations.append(locations[i]);
duke@1 457 }
duke@1 458 message.warning(tag.position(), "doclet.tag_misuse",
duke@1 459 "@" + taglet.getName(), holderType, combined_locations.toString());
duke@1 460 }
duke@1 461
duke@1 462 /**
duke@1 463 * Return the array of <code>Taglet</code>s that can
duke@1 464 * appear in packages.
duke@1 465 * @return the array of <code>Taglet</code>s that can
duke@1 466 * appear in packages.
duke@1 467 */
duke@1 468 public Taglet[] getPackageCustomTags() {
duke@1 469 if (packageTags == null) {
duke@1 470 initCustomTagArrays();
duke@1 471 }
duke@1 472 return packageTags;
duke@1 473 }
duke@1 474
duke@1 475 /**
duke@1 476 * Return the array of <code>Taglet</code>s that can
duke@1 477 * appear in classes or interfaces.
duke@1 478 * @return the array of <code>Taglet</code>s that can
duke@1 479 * appear in classes or interfaces.
duke@1 480 */
duke@1 481 public Taglet[] getTypeCustomTags() {
duke@1 482 if (typeTags == null) {
duke@1 483 initCustomTagArrays();
duke@1 484 }
duke@1 485 return typeTags;
duke@1 486 }
duke@1 487
duke@1 488 /**
duke@1 489 * Return the array of inline <code>Taglet</code>s that can
duke@1 490 * appear in comments.
duke@1 491 * @return the array of <code>Taglet</code>s that can
duke@1 492 * appear in comments.
duke@1 493 */
duke@1 494 public Taglet[] getInlineCustomTags() {
duke@1 495 if (inlineTags == null) {
duke@1 496 initCustomTagArrays();
duke@1 497 }
duke@1 498 return inlineTags;
duke@1 499 }
duke@1 500
duke@1 501 /**
duke@1 502 * Return the array of <code>Taglet</code>s that can
duke@1 503 * appear in fields.
duke@1 504 * @return the array of <code>Taglet</code>s that can
duke@1 505 * appear in field.
duke@1 506 */
duke@1 507 public Taglet[] getFieldCustomTags() {
duke@1 508 if (fieldTags == null) {
duke@1 509 initCustomTagArrays();
duke@1 510 }
duke@1 511 return fieldTags;
duke@1 512 }
duke@1 513
duke@1 514 /**
duke@1 515 * Return the array of <code>Taglet</code>s that can
duke@1 516 * appear in the serialized form.
duke@1 517 * @return the array of <code>Taglet</code>s that can
duke@1 518 * appear in the serialized form.
duke@1 519 */
duke@1 520 public Taglet[] getSerializedFormTags() {
duke@1 521 if (serializedFormTags == null) {
duke@1 522 initCustomTagArrays();
duke@1 523 }
duke@1 524 return serializedFormTags;
duke@1 525 }
duke@1 526
duke@1 527 /**
duke@1 528 * @return the array of <code>Taglet</code>s that can
duke@1 529 * appear in the given Doc.
duke@1 530 */
duke@1 531 public Taglet[] getCustomTags(Doc doc) {
duke@1 532 if (doc instanceof ConstructorDoc) {
duke@1 533 return getConstructorCustomTags();
duke@1 534 } else if (doc instanceof MethodDoc) {
duke@1 535 return getMethodCustomTags();
duke@1 536 } else if (doc instanceof FieldDoc) {
duke@1 537 return getFieldCustomTags();
duke@1 538 } else if (doc instanceof ClassDoc) {
duke@1 539 return getTypeCustomTags();
duke@1 540 } else if (doc instanceof PackageDoc) {
duke@1 541 return getPackageCustomTags();
duke@1 542 } else if (doc instanceof RootDoc) {
duke@1 543 return getOverviewCustomTags();
duke@1 544 }
duke@1 545 return null;
duke@1 546 }
duke@1 547
duke@1 548 /**
duke@1 549 * Return the array of <code>Taglet</code>s that can
duke@1 550 * appear in constructors.
duke@1 551 * @return the array of <code>Taglet</code>s that can
duke@1 552 * appear in constructors.
duke@1 553 */
duke@1 554 public Taglet[] getConstructorCustomTags() {
duke@1 555 if (constructorTags == null) {
duke@1 556 initCustomTagArrays();
duke@1 557 }
duke@1 558 return constructorTags;
duke@1 559 }
duke@1 560
duke@1 561 /**
duke@1 562 * Return the array of <code>Taglet</code>s that can
duke@1 563 * appear in methods.
duke@1 564 * @return the array of <code>Taglet</code>s that can
duke@1 565 * appear in methods.
duke@1 566 */
duke@1 567 public Taglet[] getMethodCustomTags() {
duke@1 568 if (methodTags == null) {
duke@1 569 initCustomTagArrays();
duke@1 570 }
duke@1 571 return methodTags;
duke@1 572 }
duke@1 573
duke@1 574 /**
duke@1 575 * Return the array of <code>Taglet</code>s that can
duke@1 576 * appear in an overview.
duke@1 577 * @return the array of <code>Taglet</code>s that can
duke@1 578 * appear in overview.
duke@1 579 */
duke@1 580 public Taglet[] getOverviewCustomTags() {
duke@1 581 if (overviewTags == null) {
duke@1 582 initCustomTagArrays();
duke@1 583 }
duke@1 584 return overviewTags;
duke@1 585 }
duke@1 586
duke@1 587 /**
duke@1 588 * Initialize the custom tag arrays.
duke@1 589 */
duke@1 590 private void initCustomTagArrays() {
jjg@74 591 Iterator<Taglet> it = customTags.values().iterator();
jjg@74 592 ArrayList<Taglet> pTags = new ArrayList<Taglet>(customTags.size());
jjg@74 593 ArrayList<Taglet> tTags = new ArrayList<Taglet>(customTags.size());
jjg@74 594 ArrayList<Taglet> fTags = new ArrayList<Taglet>(customTags.size());
jjg@74 595 ArrayList<Taglet> cTags = new ArrayList<Taglet>(customTags.size());
jjg@74 596 ArrayList<Taglet> mTags = new ArrayList<Taglet>(customTags.size());
jjg@74 597 ArrayList<Taglet> iTags = new ArrayList<Taglet>(customTags.size());
jjg@74 598 ArrayList<Taglet> oTags = new ArrayList<Taglet>(customTags.size());
bpatel@1324 599 ArrayList<Taglet> sTags = new ArrayList<Taglet>();
duke@1 600 Taglet current;
duke@1 601 while (it.hasNext()) {
jjg@74 602 current = it.next();
duke@1 603 if (current.inPackage() && !current.isInlineTag()) {
duke@1 604 pTags.add(current);
duke@1 605 }
duke@1 606 if (current.inType() && !current.isInlineTag()) {
duke@1 607 tTags.add(current);
duke@1 608 }
duke@1 609 if (current.inField() && !current.isInlineTag()) {
duke@1 610 fTags.add(current);
duke@1 611 }
duke@1 612 if (current.inConstructor() && !current.isInlineTag()) {
duke@1 613 cTags.add(current);
duke@1 614 }
duke@1 615 if (current.inMethod() && !current.isInlineTag()) {
duke@1 616 mTags.add(current);
duke@1 617 }
duke@1 618 if (current.isInlineTag()) {
duke@1 619 iTags.add(current);
duke@1 620 }
duke@1 621 if (current.inOverview() && !current.isInlineTag()) {
duke@1 622 oTags.add(current);
duke@1 623 }
duke@1 624 }
jjg@74 625 packageTags = pTags.toArray(new Taglet[] {});
jjg@74 626 typeTags = tTags.toArray(new Taglet[] {});
jjg@74 627 fieldTags = fTags.toArray(new Taglet[] {});
jjg@74 628 constructorTags = cTags.toArray(new Taglet[] {});
jjg@74 629 methodTags = mTags.toArray(new Taglet[] {});
jjg@74 630 overviewTags = oTags.toArray(new Taglet[] {});
jjg@74 631 inlineTags = iTags.toArray(new Taglet[] {});
duke@1 632
duke@1 633 //Init the serialized form tags
bpatel@1324 634 sTags.add(customTags.get("serialData"));
bpatel@1324 635 sTags.add(customTags.get("throws"));
bpatel@1324 636 if (!nosince)
bpatel@1324 637 sTags.add(customTags.get("since"));
bpatel@1324 638 sTags.add(customTags.get("see"));
bpatel@1324 639 serializedFormTags = sTags.toArray(new Taglet[] {});
duke@1 640 }
duke@1 641
duke@1 642 /**
duke@1 643 * Initialize standard Javadoc tags for ordering purposes.
duke@1 644 */
duke@1 645 private void initStandardTags() {
duke@1 646 Taglet temp;
duke@1 647 customTags.put((temp = new ParamTaglet()).getName(), temp);
duke@1 648 customTags.put((temp = new ReturnTaglet()).getName(), temp);
duke@1 649 customTags.put((temp = new ThrowsTaglet()).getName(), temp);
duke@1 650 customTags.put((temp = new SimpleTaglet("exception",
duke@1 651 null, SimpleTaglet.METHOD + SimpleTaglet.CONSTRUCTOR)).getName(), temp);
duke@1 652 if (!nosince) {
duke@1 653 customTags.put((temp = new SimpleTaglet("since", message.getText("doclet.Since"),
duke@1 654 SimpleTaglet.ALL)).getName(), temp);
duke@1 655 }
duke@1 656 if (showversion) {
duke@1 657 customTags.put((temp = new SimpleTaglet("version", message.getText("doclet.Version"),
duke@1 658 SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
duke@1 659 }
duke@1 660 if (showauthor) {
duke@1 661 customTags.put((temp = new SimpleTaglet("author", message.getText("doclet.Author"),
duke@1 662 SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
duke@1 663 }
duke@1 664 customTags.put((temp = new SimpleTaglet("serialData", message.getText("doclet.SerialData"),
duke@1 665 SimpleTaglet.EXCLUDED)).getName(), temp);
duke@1 666 customTags.put((temp = new SimpleTaglet("factory", message.getText("doclet.Factory"),
duke@1 667 SimpleTaglet.METHOD)).getName(), temp);
duke@1 668 customTags.put((temp = new SeeTaglet()).getName(), temp);
duke@1 669 //Standard inline tags
duke@1 670 customTags.put((temp = new DocRootTaglet()).getName(), temp);
duke@1 671 customTags.put((temp = new InheritDocTaglet()).getName(), temp);
duke@1 672 customTags.put((temp = new ValueTaglet()).getName(), temp);
duke@1 673 customTags.put((temp = new LegacyTaglet(new LiteralTaglet())).getName(),
duke@1 674 temp);
duke@1 675 customTags.put((temp = new LegacyTaglet(new CodeTaglet())).getName(),
duke@1 676 temp);
duke@1 677
duke@1 678 //Keep track of the names of standard tags for error
duke@1 679 //checking purposes.
duke@1 680 standardTags.add("param");
duke@1 681 standardTags.add("return");
duke@1 682 standardTags.add("throws");
duke@1 683 standardTags.add("exception");
duke@1 684 standardTags.add("since");
duke@1 685 standardTags.add("version");
duke@1 686 standardTags.add("author");
duke@1 687 standardTags.add("see");
duke@1 688 standardTags.add("deprecated");
duke@1 689 standardTags.add("link");
duke@1 690 standardTags.add("linkplain");
duke@1 691 standardTags.add("inheritDoc");
duke@1 692 standardTags.add("docRoot");
duke@1 693 standardTags.add("value");
duke@1 694 standardTags.add("serial");
duke@1 695 standardTags.add("serialData");
duke@1 696 standardTags.add("serialField");
duke@1 697 standardTags.add("Text");
duke@1 698 standardTags.add("literal");
duke@1 699 standardTags.add("code");
duke@1 700 }
duke@1 701
duke@1 702 /**
duke@1 703 * Initialize lowercase version of standard Javadoc tags.
duke@1 704 */
duke@1 705 private void initStandardTagsLowercase() {
mcimadamore@184 706 Iterator<String> it = standardTags.iterator();
duke@1 707 while (it.hasNext()) {
mcimadamore@184 708 standardTagsLowercase.add(it.next().toLowerCase());
duke@1 709 }
duke@1 710 }
duke@1 711
duke@1 712 public boolean isKnownCustomTag(String tagName) {
duke@1 713 return customTags.containsKey(tagName);
duke@1 714 }
duke@1 715
duke@1 716 /**
duke@1 717 * Print a list of {@link Taglet}s that might conflict with
duke@1 718 * standard tags in the future and a list of standard tags
duke@1 719 * that have been overriden.
duke@1 720 */
duke@1 721 public void printReport() {
duke@1 722 printReportHelper("doclet.Notice_taglet_conflict_warn", potentiallyConflictingTags);
duke@1 723 printReportHelper("doclet.Notice_taglet_overriden", overridenStandardTags);
duke@1 724 printReportHelper("doclet.Notice_taglet_unseen", unseenCustomTags);
duke@1 725 }
duke@1 726
jjg@74 727 private void printReportHelper(String noticeKey, Set<String> names) {
duke@1 728 if (names.size() > 0) {
jjg@74 729 String[] namesArray = names.toArray(new String[] {});
duke@1 730 String result = " ";
duke@1 731 for (int i = 0; i < namesArray.length; i++) {
duke@1 732 result += "@" + namesArray[i];
duke@1 733 if (i + 1 < namesArray.length) {
duke@1 734 result += ", ";
duke@1 735 }
duke@1 736 }
duke@1 737 message.notice(noticeKey, result);
duke@1 738 }
duke@1 739 }
duke@1 740
duke@1 741 /**
duke@1 742 * Given the name of a tag, return the corresponding taglet.
duke@1 743 * Return null if the tag is unknown.
duke@1 744 *
duke@1 745 * @param name the name of the taglet to retrieve.
duke@1 746 * @return return the corresponding taglet. Return null if the tag is
duke@1 747 * unknown.
duke@1 748 */
duke@1 749 public Taglet getTaglet(String name) {
duke@1 750 if (name.indexOf("@") == 0) {
jjg@74 751 return customTags.get(name.substring(1));
duke@1 752 } else {
jjg@74 753 return customTags.get(name);
duke@1 754 }
duke@1 755
duke@1 756 }
duke@1 757 }

mercurial