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