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