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

Sun, 24 Feb 2013 11:36:58 -0800

author
jjg
date
Sun, 24 Feb 2013 11:36:58 -0800
changeset 1606
ccbe7ffdd867
parent 1413
bdcef2ef52d2
child 1742
7af0fa419a2b
permissions
-rw-r--r--

7112427: The doclet needs to be able to generate JavaFX documentation.
Reviewed-by: jjg
Contributed-by: jan.valenta@oracle.com

     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      * @expert).
   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         initStandardTags();
   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     /**
   210      * Add a new <code>Taglet</code>.  Print a message to indicate whether or not
   211      * the Taglet was registered properly.
   212      * @param classname  the name of the class representing the custom tag.
   213      * @param tagletPath  the path to the class representing the custom tag.
   214      */
   215     public void addCustomTag(String classname, JavaFileManager fileManager, String tagletPath) {
   216         try {
   217             Class<?> customTagClass = null;
   218             // construct class loader
   219             String cpString = null;   // make sure env.class.path defaults to dot
   221             ClassLoader tagClassLoader;
   222             if (fileManager != null && fileManager.hasLocation(DocumentationTool.Location.TAGLET_PATH)) {
   223                 tagClassLoader = fileManager.getClassLoader(DocumentationTool.Location.TAGLET_PATH);
   224             } else {
   225                 // do prepends to get correct ordering
   226                 cpString = appendPath(System.getProperty("env.class.path"), cpString);
   227                 cpString = appendPath(System.getProperty("java.class.path"), cpString);
   228                 cpString = appendPath(tagletPath, cpString);
   229                 tagClassLoader = new URLClassLoader(pathToURLs(cpString));
   230             }
   232             customTagClass = tagClassLoader.loadClass(classname);
   233             Method meth = customTagClass.getMethod("register",
   234                                                    new Class<?>[] {java.util.Map.class});
   235             Object[] list = customTags.values().toArray();
   236             Taglet lastTag = (list != null && list.length > 0)
   237                 ? (Taglet) list[list.length-1] : null;
   238             meth.invoke(null, new Object[] {customTags});
   239             list = customTags.values().toArray();
   240             Object newLastTag = (list != null&& list.length > 0)
   241                 ? list[list.length-1] : null;
   242             if (lastTag != newLastTag) {
   243                 //New taglets must always be added to the end of the LinkedHashMap.
   244                 //If the current and previous last taglet are not equal, that
   245                 //means a new Taglet has been added.
   246                 message.notice("doclet.Notice_taglet_registered", classname);
   247                 if (newLastTag != null) {
   248                     checkTaglet(newLastTag);
   249                 }
   250             }
   251         } catch (Exception exc) {
   252             message.error("doclet.Error_taglet_not_registered", exc.getClass().getName(), classname);
   253         }
   255     }
   257     private String appendPath(String path1, String path2) {
   258         if (path1 == null || path1.length() == 0) {
   259             return path2 == null ? "." : path2;
   260         } else if (path2 == null || path2.length() == 0) {
   261             return path1;
   262         } else {
   263             return path1  + File.pathSeparator + path2;
   264         }
   265     }
   267     /**
   268      * Utility method for converting a search path string to an array
   269      * of directory and JAR file URLs.
   270      *
   271      * @param path the search path string
   272      * @return the resulting array of directory and JAR file URLs
   273      */
   274     private URL[] pathToURLs(String path) {
   275         Set<URL> urls = new LinkedHashSet<URL>();
   276         for (String s: path.split(File.pathSeparator)) {
   277             if (s.isEmpty()) continue;
   278             try {
   279                 urls.add(new File(s).getAbsoluteFile().toURI().toURL());
   280             } catch (MalformedURLException e) {
   281                 message.error("doclet.MalformedURL", s);
   282             }
   283         }
   284         return urls.toArray(new URL[urls.size()]);
   285     }
   288     /**
   289      * Add a new <code>SimpleTaglet</code>.  If this tag already exists
   290      * and the header passed as an argument is null, move tag to the back of the
   291      * list. If this tag already exists and the header passed as an argument is
   292      * not null, overwrite previous tag with new one.  Otherwise, add new
   293      * SimpleTaglet to list.
   294      * @param tagName the name of this tag
   295      * @param header the header to output.
   296      * @param locations the possible locations that this tag
   297      * can appear in.
   298      */
   299     public void addNewSimpleCustomTag(String tagName, String header, String locations) {
   300         if (tagName == null || locations == null) {
   301             return;
   302         }
   303         Taglet tag = customTags.get(tagName);
   304         locations = locations.toLowerCase();
   305         if (tag == null || header != null) {
   306             customTags.remove(tagName);
   307             customTags.put(tagName, new SimpleTaglet(tagName, header, locations));
   308             if (locations != null && locations.indexOf('x') == -1) {
   309                 checkTagName(tagName);
   310             }
   311         } else {
   312             //Move to back
   313             customTags.remove(tagName);
   314             customTags.put(tagName, tag);
   315         }
   316     }
   318     /**
   319      * Given a tag name, add it to the set of tags it belongs to.
   320      */
   321     private void checkTagName(String name) {
   322         if (standardTags.contains(name)) {
   323             overridenStandardTags.add(name);
   324         } else {
   325             if (name.indexOf('.') == -1) {
   326                 potentiallyConflictingTags.add(name);
   327             }
   328             unseenCustomTags.add(name);
   329         }
   330     }
   332     /**
   333      * Check the taglet to see if it is a legacy taglet.  Also
   334      * check its name for errors.
   335      */
   336     private void checkTaglet(Object taglet) {
   337         if (taglet instanceof Taglet) {
   338             checkTagName(((Taglet) taglet).getName());
   339         } else if (taglet instanceof com.sun.tools.doclets.Taglet) {
   340             com.sun.tools.doclets.Taglet legacyTaglet = (com.sun.tools.doclets.Taglet) taglet;
   341             customTags.remove(legacyTaglet.getName());
   342             customTags.put(legacyTaglet.getName(), new LegacyTaglet(legacyTaglet));
   343             checkTagName(legacyTaglet.getName());
   344         } else {
   345             throw new IllegalArgumentException("Given object is not a taglet.");
   346         }
   347     }
   349     /**
   350      * Given a name of a seen custom tag, remove it from the set of unseen
   351      * custom tags.
   352      * @param name the name of the seen custom tag.
   353      */
   354     public void seenCustomTag(String name) {
   355         unseenCustomTags.remove(name);
   356     }
   358     /**
   359      * Given an array of <code>Tag</code>s, check for spelling mistakes.
   360      * @param doc the Doc object that holds the tags.
   361      * @param tags the list of <code>Tag</code>s to check.
   362      * @param areInlineTags true if the array of tags are inline and false otherwise.
   363      */
   364     public void checkTags(Doc doc, Tag[] tags, boolean areInlineTags) {
   365         if (tags == null) {
   366             return;
   367         }
   368         Taglet taglet;
   369         for (int i = 0; i < tags.length; i++) {
   370             String name = tags[i].name();
   371             if (name.length() > 0 && name.charAt(0) == '@') {
   372                 name = name.substring(1, name.length());
   373             }
   374             if (! (standardTags.contains(name) || customTags.containsKey(name))) {
   375                 if (standardTagsLowercase.contains(name.toLowerCase())) {
   376                     message.warning(tags[i].position(), "doclet.UnknownTagLowercase", tags[i].name());
   377                     continue;
   378                 } else {
   379                     message.warning(tags[i].position(), "doclet.UnknownTag", tags[i].name());
   380                     continue;
   381                 }
   382             }
   383             //Check if this tag is being used in the wrong location.
   384             if ((taglet = customTags.get(name)) != null) {
   385                 if (areInlineTags && ! taglet.isInlineTag()) {
   386                     printTagMisuseWarn(taglet, tags[i], "inline");
   387                 }
   388                 if ((doc instanceof RootDoc) && ! taglet.inOverview()) {
   389                     printTagMisuseWarn(taglet, tags[i], "overview");
   390                 } else if ((doc instanceof PackageDoc) && ! taglet.inPackage()) {
   391                     printTagMisuseWarn(taglet, tags[i], "package");
   392                 } else if ((doc instanceof ClassDoc) && ! taglet.inType()) {
   393                     printTagMisuseWarn(taglet, tags[i], "class");
   394                 } else if ((doc instanceof ConstructorDoc) && ! taglet.inConstructor()) {
   395                     printTagMisuseWarn(taglet, tags[i], "constructor");
   396                 } else if ((doc instanceof FieldDoc) && ! taglet.inField()) {
   397                     printTagMisuseWarn(taglet, tags[i], "field");
   398                 } else if ((doc instanceof MethodDoc) && ! taglet.inMethod()) {
   399                     printTagMisuseWarn(taglet, tags[i], "method");
   400                 }
   401             }
   402         }
   403     }
   405     /**
   406      * Given the taglet, the tag and the type of documentation that the tag
   407      * was found in, print a tag misuse warning.
   408      * @param taglet the taglet representing the misused tag.
   409      * @param tag the misused tag.
   410      * @param holderType the type of documentation that the misused tag was found in.
   411      */
   412     private void printTagMisuseWarn(Taglet taglet, Tag tag, String holderType) {
   413         Set<String> locationsSet = new LinkedHashSet<String>();
   414         if (taglet.inOverview()) {
   415             locationsSet.add("overview");
   416         }
   417         if (taglet.inPackage()) {
   418             locationsSet.add("package");
   419         }
   420         if (taglet.inType()) {
   421             locationsSet.add("class/interface");
   422         }
   423         if (taglet.inConstructor())  {
   424             locationsSet.add("constructor");
   425         }
   426         if (taglet.inField()) {
   427             locationsSet.add("field");
   428         }
   429         if (taglet.inMethod()) {
   430             locationsSet.add("method");
   431         }
   432         if (taglet.isInlineTag()) {
   433             locationsSet.add("inline text");
   434         }
   435         String[] locations = locationsSet.toArray(new String[]{});
   436         if (locations == null || locations.length == 0) {
   437             //This known tag is excluded.
   438             return;
   439         }
   440         StringBuilder combined_locations = new StringBuilder();
   441         for (int i = 0; i < locations.length; i++) {
   442             if (i > 0) {
   443                 combined_locations.append(", ");
   444             }
   445             combined_locations.append(locations[i]);
   446         }
   447         message.warning(tag.position(), "doclet.tag_misuse",
   448             "@" + taglet.getName(), holderType, combined_locations.toString());
   449     }
   451     /**
   452      * Return the array of <code>Taglet</code>s that can
   453      * appear in packages.
   454      * @return the array of <code>Taglet</code>s that can
   455      * appear in packages.
   456      */
   457     public Taglet[] getPackageCustomTags() {
   458         if (packageTags == null) {
   459             initCustomTagArrays();
   460         }
   461         return packageTags;
   462     }
   464     /**
   465      * Return the array of <code>Taglet</code>s that can
   466      * appear in classes or interfaces.
   467      * @return the array of <code>Taglet</code>s that can
   468      * appear in classes or interfaces.
   469      */
   470     public Taglet[] getTypeCustomTags() {
   471         if (typeTags == null) {
   472             initCustomTagArrays();
   473         }
   474         return typeTags;
   475     }
   477     /**
   478      * Return the array of inline <code>Taglet</code>s that can
   479      * appear in comments.
   480      * @return the array of <code>Taglet</code>s that can
   481      * appear in comments.
   482      */
   483     public Taglet[] getInlineCustomTags() {
   484         if (inlineTags == null) {
   485             initCustomTagArrays();
   486         }
   487         return inlineTags;
   488     }
   490     /**
   491      * Return the array of <code>Taglet</code>s that can
   492      * appear in fields.
   493      * @return the array of <code>Taglet</code>s that can
   494      * appear in field.
   495      */
   496     public Taglet[] getFieldCustomTags() {
   497         if (fieldTags == null) {
   498             initCustomTagArrays();
   499         }
   500         return fieldTags;
   501     }
   503     /**
   504      * Return the array of <code>Taglet</code>s that can
   505      * appear in the serialized form.
   506      * @return the array of <code>Taglet</code>s that can
   507      * appear in the serialized form.
   508      */
   509     public Taglet[] getSerializedFormTags() {
   510         if (serializedFormTags == null) {
   511             initCustomTagArrays();
   512         }
   513         return serializedFormTags;
   514     }
   516     /**
   517      * @return the array of <code>Taglet</code>s that can
   518      * appear in the given Doc.
   519      */
   520     public Taglet[] getCustomTags(Doc doc) {
   521         if (doc instanceof ConstructorDoc) {
   522             return getConstructorCustomTags();
   523         } else if (doc instanceof MethodDoc) {
   524             return getMethodCustomTags();
   525         } else if (doc instanceof FieldDoc) {
   526             return getFieldCustomTags();
   527         } else if (doc instanceof ClassDoc) {
   528             return getTypeCustomTags();
   529         } else if (doc instanceof PackageDoc) {
   530             return getPackageCustomTags();
   531         } else if (doc instanceof RootDoc) {
   532             return getOverviewCustomTags();
   533         }
   534         return null;
   535     }
   537     /**
   538      * Return the array of <code>Taglet</code>s that can
   539      * appear in constructors.
   540      * @return the array of <code>Taglet</code>s that can
   541      * appear in constructors.
   542      */
   543     public Taglet[] getConstructorCustomTags() {
   544         if (constructorTags == null) {
   545             initCustomTagArrays();
   546         }
   547         return constructorTags;
   548     }
   550     /**
   551      * Return the array of <code>Taglet</code>s that can
   552      * appear in methods.
   553      * @return the array of <code>Taglet</code>s that can
   554      * appear in methods.
   555      */
   556     public Taglet[] getMethodCustomTags() {
   557         if (methodTags == null) {
   558             initCustomTagArrays();
   559         }
   560         return methodTags;
   561     }
   563     /**
   564      * Return the array of <code>Taglet</code>s that can
   565      * appear in an overview.
   566      * @return the array of <code>Taglet</code>s that can
   567      * appear in overview.
   568      */
   569     public Taglet[] getOverviewCustomTags() {
   570         if (overviewTags == null) {
   571             initCustomTagArrays();
   572         }
   573         return overviewTags;
   574     }
   576     /**
   577      * Initialize the custom tag arrays.
   578      */
   579     private void initCustomTagArrays() {
   580         Iterator<Taglet> it = customTags.values().iterator();
   581         ArrayList<Taglet> pTags = new ArrayList<Taglet>(customTags.size());
   582         ArrayList<Taglet> tTags = new ArrayList<Taglet>(customTags.size());
   583         ArrayList<Taglet> fTags = new ArrayList<Taglet>(customTags.size());
   584         ArrayList<Taglet> cTags = new ArrayList<Taglet>(customTags.size());
   585         ArrayList<Taglet> mTags = new ArrayList<Taglet>(customTags.size());
   586         ArrayList<Taglet> iTags = new ArrayList<Taglet>(customTags.size());
   587         ArrayList<Taglet> oTags = new ArrayList<Taglet>(customTags.size());
   588         ArrayList<Taglet> sTags = new ArrayList<Taglet>();
   589         Taglet current;
   590         while (it.hasNext()) {
   591             current = it.next();
   592             if (current.inPackage() && !current.isInlineTag()) {
   593                 pTags.add(current);
   594             }
   595             if (current.inType() && !current.isInlineTag()) {
   596                 tTags.add(current);
   597             }
   598             if (current.inField() && !current.isInlineTag()) {
   599                 fTags.add(current);
   600             }
   601             if (current.inConstructor() && !current.isInlineTag()) {
   602                 cTags.add(current);
   603             }
   604             if (current.inMethod() && !current.isInlineTag()) {
   605                 mTags.add(current);
   606             }
   607             if (current.isInlineTag()) {
   608                 iTags.add(current);
   609             }
   610             if (current.inOverview() && !current.isInlineTag()) {
   611                 oTags.add(current);
   612             }
   613         }
   614         packageTags = pTags.toArray(new Taglet[] {});
   615         typeTags = tTags.toArray(new Taglet[] {});
   616         fieldTags = fTags.toArray(new Taglet[] {});
   617         constructorTags = cTags.toArray(new Taglet[] {});
   618         methodTags = mTags.toArray(new Taglet[] {});
   619         overviewTags = oTags.toArray(new Taglet[] {});
   620         inlineTags = iTags.toArray(new Taglet[] {});
   622         //Init the serialized form tags
   623         sTags.add(customTags.get("serialData"));
   624         sTags.add(customTags.get("throws"));
   625         if (!nosince)
   626             sTags.add(customTags.get("since"));
   627         sTags.add(customTags.get("see"));
   628         serializedFormTags = sTags.toArray(new Taglet[] {});
   629     }
   631     /**
   632      * Initialize standard Javadoc tags for ordering purposes.
   633      */
   634     private void initStandardTags() {
   635         Taglet temp;
   636         customTags.put((temp = new ParamTaglet()).getName(), temp);
   637         customTags.put((temp = new ReturnTaglet()).getName(), temp);
   638         customTags.put((temp = new ThrowsTaglet()).getName(), temp);
   639         customTags.put((temp = new SimpleTaglet("exception",
   640             null, SimpleTaglet.METHOD + SimpleTaglet.CONSTRUCTOR)).getName(), temp);
   641         if (!nosince) {
   642             customTags.put((temp = new SimpleTaglet("since", message.getText("doclet.Since"),
   643                SimpleTaglet.ALL)).getName(), temp);
   644         }
   645         if (showversion) {
   646             customTags.put((temp = new SimpleTaglet("version", message.getText("doclet.Version"),
   647                 SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
   648         }
   649         if (showauthor) {
   650             customTags.put((temp = new SimpleTaglet("author", message.getText("doclet.Author"),
   651                 SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
   652         }
   653         customTags.put((temp = new SimpleTaglet("serialData", message.getText("doclet.SerialData"),
   654             SimpleTaglet.EXCLUDED)).getName(), temp);
   655         customTags.put((temp = new SimpleTaglet("factory", message.getText("doclet.Factory"),
   656             SimpleTaglet.METHOD)).getName(), temp);
   657         customTags.put((temp = new SeeTaglet()).getName(), temp);
   658         //Standard inline tags
   659         customTags.put((temp = new DocRootTaglet()).getName(), temp);
   660         customTags.put((temp = new InheritDocTaglet()).getName(), temp);
   661         customTags.put((temp = new ValueTaglet()).getName(), temp);
   662         customTags.put((temp = new LegacyTaglet(new LiteralTaglet())).getName(),
   663             temp);
   664         customTags.put((temp = new LegacyTaglet(new CodeTaglet())).getName(),
   665             temp);
   667         //Keep track of the names of standard tags for error
   668         //checking purposes.
   669         standardTags.add("param");
   670         standardTags.add("return");
   671         standardTags.add("throws");
   672         standardTags.add("exception");
   673         standardTags.add("since");
   674         standardTags.add("version");
   675         standardTags.add("author");
   676         standardTags.add("see");
   677         standardTags.add("deprecated");
   678         standardTags.add("link");
   679         standardTags.add("linkplain");
   680         standardTags.add("inheritDoc");
   681         standardTags.add("docRoot");
   682         standardTags.add("value");
   683         standardTags.add("serial");
   684         standardTags.add("serialData");
   685         standardTags.add("serialField");
   686         standardTags.add("Text");
   687         standardTags.add("literal");
   688         standardTags.add("code");
   690         if (javafx) {
   691             initJavaFXTags();
   692         }
   693     }
   695     /**
   696      * Initialize JavaFX-related tags.
   697      */
   698     private void initJavaFXTags() {
   699         Taglet temp;
   700         customTags.put((temp = new PropertyGetterTaglet()).getName(), temp);
   701         customTags.put((temp = new PropertySetterTaglet()).getName(), temp);
   702         customTags.put((temp = new SimpleTaglet("propertyDescription", message.getText("doclet.PropertyDescription"),
   703             SimpleTaglet.FIELD + SimpleTaglet.METHOD)).getName(), temp);
   704         customTags.put((temp = new SimpleTaglet("defaultValue", message.getText("doclet.DefaultValue"),
   705             SimpleTaglet.FIELD + SimpleTaglet.METHOD)).getName(), temp);
   706         customTags.put((temp = new SimpleTaglet("treatAsPrivate", null,
   707                 SimpleTaglet.FIELD + SimpleTaglet.METHOD + SimpleTaglet.TYPE)).getName(), temp);
   708         customTags.put((temp = new LegacyTaglet(new ExpertTaglet())).getName(), temp);
   710         standardTags.add("propertyGetter");
   711         standardTags.add("propertySetter");
   712         standardTags.add("propertyDescription");
   713         standardTags.add("defaultValue");
   714         standardTags.add("treatAsPrivate");
   715         standardTags.add("expert");
   716     }
   718     /**
   719      * Initialize lowercase version of standard Javadoc tags.
   720      */
   721     private void initStandardTagsLowercase() {
   722         Iterator<String> it = standardTags.iterator();
   723         while (it.hasNext()) {
   724             standardTagsLowercase.add(it.next().toLowerCase());
   725         }
   726     }
   728     public boolean isKnownCustomTag(String tagName) {
   729         return customTags.containsKey(tagName);
   730     }
   732     /**
   733      * Print a list of {@link Taglet}s that might conflict with
   734      * standard tags in the future and a list of standard tags
   735      * that have been overriden.
   736      */
   737     public void printReport() {
   738         printReportHelper("doclet.Notice_taglet_conflict_warn", potentiallyConflictingTags);
   739         printReportHelper("doclet.Notice_taglet_overriden", overridenStandardTags);
   740         printReportHelper("doclet.Notice_taglet_unseen", unseenCustomTags);
   741     }
   743     private void printReportHelper(String noticeKey, Set<String> names) {
   744         if (names.size() > 0) {
   745             String[] namesArray = names.toArray(new String[] {});
   746             String result = " ";
   747             for (int i = 0; i < namesArray.length; i++) {
   748                 result += "@" + namesArray[i];
   749                 if (i + 1 < namesArray.length) {
   750                     result += ", ";
   751                 }
   752             }
   753             message.notice(noticeKey, result);
   754         }
   755     }
   757     /**
   758      * Given the name of a tag, return the corresponding taglet.
   759      * Return null if the tag is unknown.
   760      *
   761      * @param name the name of the taglet to retrieve.
   762      * @return return the corresponding taglet. Return null if the tag is
   763      *         unknown.
   764      */
   765     public Taglet getTaglet(String name) {
   766         if (name.indexOf("@") == 0) {
   767             return customTags.get(name.substring(1));
   768         } else {
   769             return customTags.get(name);
   770         }
   772     }
   773 }

mercurial