duke@1: /*
ohair@554: * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1: *
duke@1: * This code is free software; you can redistribute it and/or modify it
duke@1: * under the terms of the GNU General Public License version 2 only, as
ohair@554: * published by the Free Software Foundation. Oracle designates this
duke@1: * particular file as subject to the "Classpath" exception as provided
ohair@554: * by Oracle in the LICENSE file that accompanied this code.
duke@1: *
duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1: * version 2 for more details (a copy is included in the LICENSE file that
duke@1: * accompanied this code).
duke@1: *
duke@1: * You should have received a copy of the GNU General Public License version
duke@1: * 2 along with this work; if not, write to the Free Software Foundation,
duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1: *
ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554: * or visit www.oracle.com if you need additional information or have any
ohair@554: * questions.
duke@1: */
duke@1:
duke@1: package com.sun.tools.doclets.internal.toolkit.taglets;
duke@1:
duke@1: import com.sun.javadoc.*;
duke@1: import com.sun.tools.doclets.internal.toolkit.util.*;
duke@1:
duke@1: import java.io.*;
duke@1: import java.lang.reflect.*;
duke@1: import java.net.*;
duke@1: import java.util.*;
duke@1:
duke@1: /**
duke@1: * Manages theTaglet
s used by doclets.
duke@1: *
duke@1: * This code is not part of an API.
duke@1: * It is implementation that is subject to change.
duke@1: * Do not use it as an API
duke@1: *
duke@1: * @author Jamie Ho
duke@1: * @since 1.4
duke@1: */
duke@1:
duke@1: public class TagletManager {
duke@1:
duke@1: /**
duke@1: * The default seperator for the simple tag option.
duke@1: */
duke@1: public static final char SIMPLE_TAGLET_OPT_SEPERATOR = ':';
duke@1:
duke@1: /**
duke@1: * The alternate seperator for simple tag options. Use this
duke@1: * with you want the default seperator to be in the name of the
duke@1: * custom tag.
duke@1: */
duke@1: public static final String ALT_SIMPLE_TAGLET_OPT_SEPERATOR = "-";
duke@1:
duke@1: /**
duke@1: * The map of custom tags.
duke@1: */
jjg@74: private LinkedHashMap customTags;
duke@1:
duke@1: /**
duke@1: * The array of custom tags that can appear in packages.
duke@1: */
duke@1: private Taglet[] packageTags;
duke@1:
duke@1: /**
duke@1: * The array of custom tags that can appear in classes or interfaces.
duke@1: */
duke@1: private Taglet[] typeTags;
duke@1:
duke@1: /**
duke@1: * The array of custom tags that can appear in fields.
duke@1: */
duke@1: private Taglet[] fieldTags;
duke@1:
duke@1: /**
duke@1: * The array of custom tags that can appear in constructors.
duke@1: */
duke@1: private Taglet[] constructorTags;
duke@1:
duke@1: /**
duke@1: * The array of custom tags that can appear in methods.
duke@1: */
duke@1: private Taglet[] methodTags;
duke@1:
duke@1: /**
duke@1: * The array of custom tags that can appear in the overview.
duke@1: */
duke@1: private Taglet[] overviewTags;
duke@1:
duke@1: /**
duke@1: * The array of custom tags that can appear in comments.
duke@1: */
duke@1: private Taglet[] inlineTags;
duke@1:
duke@1: /**
duke@1: * The array of custom tags that can appear in the serialized form.
duke@1: */
duke@1: private Taglet[] serializedFormTags;
duke@1:
duke@1: /**
duke@1: * The message retriever that will be used to print error messages.
duke@1: */
duke@1: private MessageRetriever message;
duke@1:
duke@1: /**
duke@1: * Keep track of standard tags.
duke@1: */
jjg@74: private Set standardTags;
duke@1:
duke@1: /**
duke@1: * Keep track of standard tags in lowercase to compare for better
duke@1: * error messages when a tag like @docRoot is mistakenly spelled
duke@1: * lowercase @docroot.
duke@1: */
jjg@74: private Set standardTagsLowercase;
duke@1:
duke@1: /**
duke@1: * Keep track of overriden standard tags.
duke@1: */
jjg@74: private Set overridenStandardTags;
duke@1:
duke@1: /**
duke@1: * Keep track of the tags that may conflict
duke@1: * with standard tags in the future (any custom tag without
duke@1: * a period in its name).
duke@1: */
jjg@74: private Set potentiallyConflictingTags;
duke@1:
duke@1: /**
duke@1: * The set of unseen custom tags.
duke@1: */
jjg@74: private Set unseenCustomTags;
duke@1:
duke@1: /**
duke@1: * True if we do not want to use @since tags.
duke@1: */
duke@1: private boolean nosince;
duke@1:
duke@1: /**
duke@1: * True if we want to use @version tags.
duke@1: */
duke@1: private boolean showversion;
duke@1:
duke@1: /**
duke@1: * True if we want to use @author tags.
duke@1: */
duke@1: private boolean showauthor;
duke@1:
duke@1: /**
duke@1: * Construct a new TagletManager
.
duke@1: * @param nosince true if we do not want to use @since tags.
duke@1: * @param showversion true if we want to use @version tags.
duke@1: * @param showauthor true if we want to use @author tags.
duke@1: * @param message the message retriever to print warnings.
duke@1: */
duke@1: public TagletManager(boolean nosince, boolean showversion,
duke@1: boolean showauthor, MessageRetriever message){
jjg@74: overridenStandardTags = new HashSet();
jjg@74: potentiallyConflictingTags = new HashSet();
jjg@74: standardTags = new HashSet();
jjg@74: standardTagsLowercase = new HashSet();
jjg@74: unseenCustomTags = new HashSet();
jjg@74: customTags = new LinkedHashMap();
duke@1: this.nosince = nosince;
duke@1: this.showversion = showversion;
duke@1: this.showauthor = showauthor;
duke@1: this.message = message;
duke@1: initStandardTags();
duke@1: initStandardTagsLowercase();
duke@1: }
duke@1:
duke@1: /**
duke@1: * Add a new CustomTag
. This is used to add a Taglet from within
duke@1: * a Doclet. No message is printed to indicate that the Taglet is properly
duke@1: * registered because these Taglets are typically added for every execution of the
duke@1: * Doclet. We don't want to see this type of error message every time.
duke@1: * @param customTag the new CustomTag
to add.
duke@1: */
duke@1: public void addCustomTag(Taglet customTag) {
duke@1: if (customTag != null) {
duke@1: String name = customTag.getName();
duke@1: if (customTags.containsKey(name)) {
duke@1: customTags.remove(name);
duke@1: }
duke@1: customTags.put(name, customTag);
duke@1: checkTagName(name);
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * Add a new Taglet
. Print a message to indicate whether or not
duke@1: * the Taglet was registered properly.
duke@1: * @param classname the name of the class representing the custom tag.
duke@1: * @param tagletPath the path to the class representing the custom tag.
duke@1: */
duke@1: public void addCustomTag(String classname, String tagletPath) {
duke@1: try {
jjg@74: Class> customTagClass = null;
duke@1: // construct class loader
duke@1: String cpString = null; // make sure env.class.path defaults to dot
duke@1:
duke@1: // do prepends to get correct ordering
duke@1: cpString = appendPath(System.getProperty("env.class.path"), cpString);
duke@1: cpString = appendPath(System.getProperty("java.class.path"), cpString);
duke@1: cpString = appendPath(tagletPath, cpString);
duke@1: URLClassLoader appClassLoader = new URLClassLoader(pathToURLs(cpString));
duke@1: customTagClass = appClassLoader.loadClass(classname);
duke@1: Method meth = customTagClass.getMethod("register",
mcimadamore@184: new Class>[] {java.util.Map.class});
duke@1: Object[] list = customTags.values().toArray();
duke@1: Taglet lastTag = (list != null && list.length > 0)
duke@1: ? (Taglet) list[list.length-1] : null;
duke@1: meth.invoke(null, new Object[] {customTags});
duke@1: list = customTags.values().toArray();
duke@1: Object newLastTag = (list != null&& list.length > 0)
jjg@74: ? list[list.length-1] : null;
duke@1: if (lastTag != newLastTag) {
duke@1: //New taglets must always be added to the end of the LinkedHashMap.
duke@1: //If the current and previous last taglet are not equal, that
duke@1: //means a new Taglet has been added.
duke@1: message.notice("doclet.Notice_taglet_registered", classname);
duke@1: if (newLastTag != null) {
duke@1: checkTaglet(newLastTag);
duke@1: }
duke@1: }
duke@1: } catch (Exception exc) {
duke@1: message.error("doclet.Error_taglet_not_registered", exc.getClass().getName(), classname);
duke@1: }
duke@1:
duke@1: }
duke@1:
duke@1: private String appendPath(String path1, String path2) {
duke@1: if (path1 == null || path1.length() == 0) {
duke@1: return path2 == null ? "." : path2;
duke@1: } else if (path2 == null || path2.length() == 0) {
duke@1: return path1;
duke@1: } else {
duke@1: return path1 + File.pathSeparator + path2;
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * Utility method for converting a search path string to an array
duke@1: * of directory and JAR file URLs.
duke@1: *
duke@1: * @param path the search path string
duke@1: * @return the resulting array of directory and JAR file URLs
duke@1: */
duke@1: private static URL[] pathToURLs(String path) {
duke@1: StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
duke@1: URL[] urls = new URL[st.countTokens()];
duke@1: int count = 0;
duke@1: while (st.hasMoreTokens()) {
duke@1: URL url = fileToURL(new File(st.nextToken()));
duke@1: if (url != null) {
duke@1: urls[count++] = url;
duke@1: }
duke@1: }
duke@1: if (urls.length != count) {
duke@1: URL[] tmp = new URL[count];
duke@1: System.arraycopy(urls, 0, tmp, 0, count);
duke@1: urls = tmp;
duke@1: }
duke@1: return urls;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Returns the directory or JAR file URL corresponding to the specified
duke@1: * local file name.
duke@1: *
duke@1: * @param file the File object
duke@1: * @return the resulting directory or JAR file URL, or null if unknown
duke@1: */
duke@1: private static URL fileToURL(File file) {
duke@1: String name;
duke@1: try {
duke@1: name = file.getCanonicalPath();
duke@1: } catch (IOException e) {
duke@1: name = file.getAbsolutePath();
duke@1: }
duke@1: name = name.replace(File.separatorChar, '/');
duke@1: if (!name.startsWith("/")) {
duke@1: name = "/" + name;
duke@1: }
duke@1: // If the file does not exist, then assume that it's a directory
duke@1: if (!file.isFile()) {
duke@1: name = name + "/";
duke@1: }
duke@1: try {
duke@1: return new URL("file", "", name);
duke@1: } catch (MalformedURLException e) {
duke@1: throw new IllegalArgumentException("file");
duke@1: }
duke@1: }
duke@1:
duke@1:
duke@1: /**
duke@1: * Add a new SimpleTaglet
. If this tag already exists
duke@1: * and the header passed as an argument is null, move tag to the back of the
duke@1: * list. If this tag already exists and the header passed as an argument is
duke@1: * not null, overwrite previous tag with new one. Otherwise, add new
duke@1: * SimpleTaglet to list.
duke@1: * @param tagName the name of this tag
duke@1: * @param header the header to output.
duke@1: * @param locations the possible locations that this tag
duke@1: * can appear in.
duke@1: */
duke@1: public void addNewSimpleCustomTag(String tagName, String header, String locations) {
duke@1: if (tagName == null || locations == null) {
duke@1: return;
duke@1: }
jjg@74: Taglet tag = customTags.get(tagName);
duke@1: locations = locations.toLowerCase();
duke@1: if (tag == null || header != null) {
duke@1: customTags.remove(tagName);
duke@1: customTags.put(tagName, new SimpleTaglet(tagName, header, locations));
duke@1: if (locations != null && locations.indexOf('x') == -1) {
duke@1: checkTagName(tagName);
duke@1: }
duke@1: } else {
duke@1: //Move to back
duke@1: customTags.remove(tagName);
duke@1: customTags.put(tagName, tag);
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * Given a tag name, add it to the set of tags it belongs to.
duke@1: */
duke@1: private void checkTagName(String name) {
duke@1: if (standardTags.contains(name)) {
duke@1: overridenStandardTags.add(name);
duke@1: } else {
duke@1: if (name.indexOf('.') == -1) {
duke@1: potentiallyConflictingTags.add(name);
duke@1: }
duke@1: unseenCustomTags.add(name);
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * Check the taglet to see if it is a legacy taglet. Also
duke@1: * check its name for errors.
duke@1: */
duke@1: private void checkTaglet(Object taglet) {
duke@1: if (taglet instanceof Taglet) {
duke@1: checkTagName(((Taglet) taglet).getName());
duke@1: } else if (taglet instanceof com.sun.tools.doclets.Taglet) {
duke@1: com.sun.tools.doclets.Taglet legacyTaglet = (com.sun.tools.doclets.Taglet) taglet;
duke@1: customTags.remove(legacyTaglet.getName());
duke@1: customTags.put(legacyTaglet.getName(), new LegacyTaglet(legacyTaglet));
duke@1: checkTagName(legacyTaglet.getName());
duke@1: } else {
duke@1: throw new IllegalArgumentException("Given object is not a taglet.");
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * Given a name of a seen custom tag, remove it from the set of unseen
duke@1: * custom tags.
duke@1: * @param name the name of the seen custom tag.
duke@1: */
duke@1: public void seenCustomTag(String name) {
duke@1: unseenCustomTags.remove(name);
duke@1: }
duke@1:
duke@1: /**
duke@1: * Given an array of Tag
s, check for spelling mistakes.
duke@1: * @param doc the Doc object that holds the tags.
duke@1: * @param tags the list of Tag
s to check.
duke@1: * @param areInlineTags true if the array of tags are inline and false otherwise.
duke@1: */
duke@1: public void checkTags(Doc doc, Tag[] tags, boolean areInlineTags) {
duke@1: if (tags == null) {
duke@1: return;
duke@1: }
duke@1: Taglet taglet;
duke@1: for (int i = 0; i < tags.length; i++) {
duke@1: String name = tags[i].name();
duke@1: if (name.length() > 0 && name.charAt(0) == '@') {
duke@1: name = name.substring(1, name.length());
duke@1: }
duke@1: if (! (standardTags.contains(name) || customTags.containsKey(name))) {
duke@1: if (standardTagsLowercase.contains(name.toLowerCase())) {
duke@1: message.warning(tags[i].position(), "doclet.UnknownTagLowercase", tags[i].name());
duke@1: continue;
duke@1: } else {
duke@1: message.warning(tags[i].position(), "doclet.UnknownTag", tags[i].name());
duke@1: continue;
duke@1: }
duke@1: }
duke@1: //Check if this tag is being used in the wrong location.
jjg@74: if ((taglet = customTags.get(name)) != null) {
duke@1: if (areInlineTags && ! taglet.isInlineTag()) {
duke@1: printTagMisuseWarn(taglet, tags[i], "inline");
duke@1: }
duke@1: if ((doc instanceof RootDoc) && ! taglet.inOverview()) {
duke@1: printTagMisuseWarn(taglet, tags[i], "overview");
duke@1: } else if ((doc instanceof PackageDoc) && ! taglet.inPackage()) {
duke@1: printTagMisuseWarn(taglet, tags[i], "package");
duke@1: } else if ((doc instanceof ClassDoc) && ! taglet.inType()) {
duke@1: printTagMisuseWarn(taglet, tags[i], "class");
duke@1: } else if ((doc instanceof ConstructorDoc) && ! taglet.inConstructor()) {
duke@1: printTagMisuseWarn(taglet, tags[i], "constructor");
duke@1: } else if ((doc instanceof FieldDoc) && ! taglet.inField()) {
duke@1: printTagMisuseWarn(taglet, tags[i], "field");
duke@1: } else if ((doc instanceof MethodDoc) && ! taglet.inMethod()) {
duke@1: printTagMisuseWarn(taglet, tags[i], "method");
duke@1: }
duke@1: }
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * Given the taglet, the tag and the type of documentation that the tag
duke@1: * was found in, print a tag misuse warning.
duke@1: * @param taglet the taglet representing the misused tag.
duke@1: * @param tag the misused tag.
duke@1: * @param holderType the type of documentation that the misused tag was found in.
duke@1: */
duke@1: private void printTagMisuseWarn(Taglet taglet, Tag tag, String holderType) {
jjg@74: Set locationsSet = new LinkedHashSet();
duke@1: if (taglet.inOverview()) {
duke@1: locationsSet.add("overview");
duke@1: }
duke@1: if (taglet.inPackage()) {
duke@1: locationsSet.add("package");
duke@1: }
duke@1: if (taglet.inType()) {
duke@1: locationsSet.add("class/interface");
duke@1: }
duke@1: if (taglet.inConstructor()) {
duke@1: locationsSet.add("constructor");
duke@1: }
duke@1: if (taglet.inField()) {
duke@1: locationsSet.add("field");
duke@1: }
duke@1: if (taglet.inMethod()) {
duke@1: locationsSet.add("method");
duke@1: }
duke@1: if (taglet.isInlineTag()) {
duke@1: locationsSet.add("inline text");
duke@1: }
jjg@74: String[] locations = locationsSet.toArray(new String[]{});
duke@1: if (locations == null || locations.length == 0) {
duke@1: //This known tag is excluded.
duke@1: return;
duke@1: }
duke@1: StringBuffer combined_locations = new StringBuffer();
duke@1: for (int i = 0; i < locations.length; i++) {
duke@1: if (i > 0) {
duke@1: combined_locations.append(", ");
duke@1: }
duke@1: combined_locations.append(locations[i]);
duke@1: }
duke@1: message.warning(tag.position(), "doclet.tag_misuse",
duke@1: "@" + taglet.getName(), holderType, combined_locations.toString());
duke@1: }
duke@1:
duke@1: /**
duke@1: * Return the array of Taglet
s that can
duke@1: * appear in packages.
duke@1: * @return the array of Taglet
s that can
duke@1: * appear in packages.
duke@1: */
duke@1: public Taglet[] getPackageCustomTags() {
duke@1: if (packageTags == null) {
duke@1: initCustomTagArrays();
duke@1: }
duke@1: return packageTags;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Return the array of Taglet
s that can
duke@1: * appear in classes or interfaces.
duke@1: * @return the array of Taglet
s that can
duke@1: * appear in classes or interfaces.
duke@1: */
duke@1: public Taglet[] getTypeCustomTags() {
duke@1: if (typeTags == null) {
duke@1: initCustomTagArrays();
duke@1: }
duke@1: return typeTags;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Return the array of inline Taglet
s that can
duke@1: * appear in comments.
duke@1: * @return the array of Taglet
s that can
duke@1: * appear in comments.
duke@1: */
duke@1: public Taglet[] getInlineCustomTags() {
duke@1: if (inlineTags == null) {
duke@1: initCustomTagArrays();
duke@1: }
duke@1: return inlineTags;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Return the array of Taglet
s that can
duke@1: * appear in fields.
duke@1: * @return the array of Taglet
s that can
duke@1: * appear in field.
duke@1: */
duke@1: public Taglet[] getFieldCustomTags() {
duke@1: if (fieldTags == null) {
duke@1: initCustomTagArrays();
duke@1: }
duke@1: return fieldTags;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Return the array of Taglet
s that can
duke@1: * appear in the serialized form.
duke@1: * @return the array of Taglet
s that can
duke@1: * appear in the serialized form.
duke@1: */
duke@1: public Taglet[] getSerializedFormTags() {
duke@1: if (serializedFormTags == null) {
duke@1: initCustomTagArrays();
duke@1: }
duke@1: return serializedFormTags;
duke@1: }
duke@1:
duke@1: /**
duke@1: * @return the array of Taglet
s that can
duke@1: * appear in the given Doc.
duke@1: */
duke@1: public Taglet[] getCustomTags(Doc doc) {
duke@1: if (doc instanceof ConstructorDoc) {
duke@1: return getConstructorCustomTags();
duke@1: } else if (doc instanceof MethodDoc) {
duke@1: return getMethodCustomTags();
duke@1: } else if (doc instanceof FieldDoc) {
duke@1: return getFieldCustomTags();
duke@1: } else if (doc instanceof ClassDoc) {
duke@1: return getTypeCustomTags();
duke@1: } else if (doc instanceof PackageDoc) {
duke@1: return getPackageCustomTags();
duke@1: } else if (doc instanceof RootDoc) {
duke@1: return getOverviewCustomTags();
duke@1: }
duke@1: return null;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Return the array of Taglet
s that can
duke@1: * appear in constructors.
duke@1: * @return the array of Taglet
s that can
duke@1: * appear in constructors.
duke@1: */
duke@1: public Taglet[] getConstructorCustomTags() {
duke@1: if (constructorTags == null) {
duke@1: initCustomTagArrays();
duke@1: }
duke@1: return constructorTags;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Return the array of Taglet
s that can
duke@1: * appear in methods.
duke@1: * @return the array of Taglet
s that can
duke@1: * appear in methods.
duke@1: */
duke@1: public Taglet[] getMethodCustomTags() {
duke@1: if (methodTags == null) {
duke@1: initCustomTagArrays();
duke@1: }
duke@1: return methodTags;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Return the array of Taglet
s that can
duke@1: * appear in an overview.
duke@1: * @return the array of Taglet
s that can
duke@1: * appear in overview.
duke@1: */
duke@1: public Taglet[] getOverviewCustomTags() {
duke@1: if (overviewTags == null) {
duke@1: initCustomTagArrays();
duke@1: }
duke@1: return overviewTags;
duke@1: }
duke@1:
duke@1: /**
duke@1: * Initialize the custom tag arrays.
duke@1: */
duke@1: private void initCustomTagArrays() {
jjg@74: Iterator it = customTags.values().iterator();
jjg@74: ArrayList pTags = new ArrayList(customTags.size());
jjg@74: ArrayList tTags = new ArrayList(customTags.size());
jjg@74: ArrayList fTags = new ArrayList(customTags.size());
jjg@74: ArrayList cTags = new ArrayList(customTags.size());
jjg@74: ArrayList mTags = new ArrayList(customTags.size());
jjg@74: ArrayList iTags = new ArrayList(customTags.size());
jjg@74: ArrayList oTags = new ArrayList(customTags.size());
duke@1: Taglet current;
duke@1: while (it.hasNext()) {
jjg@74: current = it.next();
duke@1: if (current.inPackage() && !current.isInlineTag()) {
duke@1: pTags.add(current);
duke@1: }
duke@1: if (current.inType() && !current.isInlineTag()) {
duke@1: tTags.add(current);
duke@1: }
duke@1: if (current.inField() && !current.isInlineTag()) {
duke@1: fTags.add(current);
duke@1: }
duke@1: if (current.inConstructor() && !current.isInlineTag()) {
duke@1: cTags.add(current);
duke@1: }
duke@1: if (current.inMethod() && !current.isInlineTag()) {
duke@1: mTags.add(current);
duke@1: }
duke@1: if (current.isInlineTag()) {
duke@1: iTags.add(current);
duke@1: }
duke@1: if (current.inOverview() && !current.isInlineTag()) {
duke@1: oTags.add(current);
duke@1: }
duke@1: }
jjg@74: packageTags = pTags.toArray(new Taglet[] {});
jjg@74: typeTags = tTags.toArray(new Taglet[] {});
jjg@74: fieldTags = fTags.toArray(new Taglet[] {});
jjg@74: constructorTags = cTags.toArray(new Taglet[] {});
jjg@74: methodTags = mTags.toArray(new Taglet[] {});
jjg@74: overviewTags = oTags.toArray(new Taglet[] {});
jjg@74: inlineTags = iTags.toArray(new Taglet[] {});
duke@1:
duke@1: //Init the serialized form tags
duke@1: serializedFormTags = new Taglet[4];
jjg@74: serializedFormTags[0] = customTags.get("serialData");
jjg@74: serializedFormTags[1] = customTags.get("throws");
jjg@74: serializedFormTags[2] = customTags.get("since");
jjg@74: serializedFormTags[3] = customTags.get("see");
duke@1: }
duke@1:
duke@1: /**
duke@1: * Initialize standard Javadoc tags for ordering purposes.
duke@1: */
duke@1: private void initStandardTags() {
duke@1: Taglet temp;
duke@1: customTags.put((temp = new ParamTaglet()).getName(), temp);
duke@1: customTags.put((temp = new ReturnTaglet()).getName(), temp);
duke@1: customTags.put((temp = new ThrowsTaglet()).getName(), temp);
duke@1: customTags.put((temp = new SimpleTaglet("exception",
duke@1: null, SimpleTaglet.METHOD + SimpleTaglet.CONSTRUCTOR)).getName(), temp);
duke@1: if (!nosince) {
duke@1: customTags.put((temp = new SimpleTaglet("since", message.getText("doclet.Since"),
duke@1: SimpleTaglet.ALL)).getName(), temp);
duke@1: }
duke@1: if (showversion) {
duke@1: customTags.put((temp = new SimpleTaglet("version", message.getText("doclet.Version"),
duke@1: SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
duke@1: }
duke@1: if (showauthor) {
duke@1: customTags.put((temp = new SimpleTaglet("author", message.getText("doclet.Author"),
duke@1: SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW)).getName(), temp);
duke@1: }
duke@1: customTags.put((temp = new SimpleTaglet("serialData", message.getText("doclet.SerialData"),
duke@1: SimpleTaglet.EXCLUDED)).getName(), temp);
duke@1: customTags.put((temp = new SimpleTaglet("factory", message.getText("doclet.Factory"),
duke@1: SimpleTaglet.METHOD)).getName(), temp);
duke@1: customTags.put((temp = new SeeTaglet()).getName(), temp);
duke@1: //Standard inline tags
duke@1: customTags.put((temp = new DocRootTaglet()).getName(), temp);
duke@1: customTags.put((temp = new InheritDocTaglet()).getName(), temp);
duke@1: customTags.put((temp = new ValueTaglet()).getName(), temp);
duke@1: customTags.put((temp = new LegacyTaglet(new LiteralTaglet())).getName(),
duke@1: temp);
duke@1: customTags.put((temp = new LegacyTaglet(new CodeTaglet())).getName(),
duke@1: temp);
duke@1:
duke@1: //Keep track of the names of standard tags for error
duke@1: //checking purposes.
duke@1: standardTags.add("param");
duke@1: standardTags.add("return");
duke@1: standardTags.add("throws");
duke@1: standardTags.add("exception");
duke@1: standardTags.add("since");
duke@1: standardTags.add("version");
duke@1: standardTags.add("author");
duke@1: standardTags.add("see");
duke@1: standardTags.add("deprecated");
duke@1: standardTags.add("link");
duke@1: standardTags.add("linkplain");
duke@1: standardTags.add("inheritDoc");
duke@1: standardTags.add("docRoot");
duke@1: standardTags.add("value");
duke@1: standardTags.add("serial");
duke@1: standardTags.add("serialData");
duke@1: standardTags.add("serialField");
duke@1: standardTags.add("Text");
duke@1: standardTags.add("literal");
duke@1: standardTags.add("code");
duke@1: }
duke@1:
duke@1: /**
duke@1: * Initialize lowercase version of standard Javadoc tags.
duke@1: */
duke@1: private void initStandardTagsLowercase() {
mcimadamore@184: Iterator it = standardTags.iterator();
duke@1: while (it.hasNext()) {
mcimadamore@184: standardTagsLowercase.add(it.next().toLowerCase());
duke@1: }
duke@1: }
duke@1:
duke@1: public boolean isKnownCustomTag(String tagName) {
duke@1: return customTags.containsKey(tagName);
duke@1: }
duke@1:
duke@1: /**
duke@1: * Print a list of {@link Taglet}s that might conflict with
duke@1: * standard tags in the future and a list of standard tags
duke@1: * that have been overriden.
duke@1: */
duke@1: public void printReport() {
duke@1: printReportHelper("doclet.Notice_taglet_conflict_warn", potentiallyConflictingTags);
duke@1: printReportHelper("doclet.Notice_taglet_overriden", overridenStandardTags);
duke@1: printReportHelper("doclet.Notice_taglet_unseen", unseenCustomTags);
duke@1: }
duke@1:
jjg@74: private void printReportHelper(String noticeKey, Set names) {
duke@1: if (names.size() > 0) {
jjg@74: String[] namesArray = names.toArray(new String[] {});
duke@1: String result = " ";
duke@1: for (int i = 0; i < namesArray.length; i++) {
duke@1: result += "@" + namesArray[i];
duke@1: if (i + 1 < namesArray.length) {
duke@1: result += ", ";
duke@1: }
duke@1: }
duke@1: message.notice(noticeKey, result);
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * Given the name of a tag, return the corresponding taglet.
duke@1: * Return null if the tag is unknown.
duke@1: *
duke@1: * @param name the name of the taglet to retrieve.
duke@1: * @return return the corresponding taglet. Return null if the tag is
duke@1: * unknown.
duke@1: */
duke@1: public Taglet getTaglet(String name) {
duke@1: if (name.indexOf("@") == 0) {
jjg@74: return customTags.get(name.substring(1));
duke@1: } else {
jjg@74: return customTags.get(name);
duke@1: }
duke@1:
duke@1: }
duke@1: }