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

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 3938
93012e2a5d1d
parent 2525
2eb010b6cb22
permissions
-rw-r--r--

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 }

mercurial