alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (TagletManager.java)

This example Java source code file (TagletManager.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

arraylist, class, constructordoc, fielddoc, hashset, javadoc, linkedhashmap, messageretriever, net, network, object, reflection, set, simpletaglet, string, stringbuilder, taglet, tagletmanager, util

The TagletManager.java Java example source code

/*
 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.tools.doclets.internal.toolkit.taglets;

import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.util.*;

import javax.tools.DocumentationTool;
import javax.tools.JavaFileManager;

import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.util.*;

/**
 * Manages the<code>Taglets used by doclets.
 *
 *  <p>This is NOT part of any supported API.
 *  If you write code that depends on this, you do so at your own risk.
 *  This code and its internal interfaces are subject to change or
 *  deletion without notice.</b>
 *
 * @author Jamie Ho
 * @since 1.4
 */

public class TagletManager {

    /**
     * The default separator for the simple tag option.
     */
    public static final char SIMPLE_TAGLET_OPT_SEPARATOR = ':';

    /**
     * The alternate separator for simple tag options.  Use this
     * when you want the default separator to be in the name of the
     * custom tag.
     */
    public static final String ALT_SIMPLE_TAGLET_OPT_SEPARATOR = "-";

    /**
     * The map of custom tags.
     */
    private LinkedHashMap<String,Taglet> customTags;

    /**
     * The array of custom tags that can appear in packages.
     */
    private Taglet[] packageTags;

    /**
     * The array of custom tags that can appear in classes or interfaces.
     */
    private Taglet[] typeTags;

    /**
     * The array of custom tags that can appear in fields.
     */
    private Taglet[] fieldTags;

    /**
     * The array of custom tags that can appear in constructors.
     */
    private Taglet[] constructorTags;

    /**
     * The array of custom tags that can appear in methods.
     */
    private Taglet[] methodTags;

    /**
     * The array of custom tags that can appear in the overview.
     */
    private Taglet[] overviewTags;

    /**
     * The array of custom tags that can appear in comments.
     */
    private Taglet[] inlineTags;

    /**
     * The array of custom tags that can appear in the serialized form.
     */
    private Taglet[] serializedFormTags;

    /**
     * The message retriever that will be used to print error messages.
     */
    private MessageRetriever message;

    /**
     * Keep track of standard tags.
     */
    private Set<String> standardTags;

    /**
     * Keep track of standard tags in lowercase to compare for better
     * error messages when a tag like @docRoot is mistakenly spelled
     * lowercase @docroot.
     */
    private Set<String> standardTagsLowercase;

    /**
     * Keep track of overriden standard tags.
     */
    private Set<String> overridenStandardTags;

    /**
     * Keep track of the tags that may conflict
     * with standard tags in the future (any custom tag without
     * a period in its name).
     */
    private Set<String> potentiallyConflictingTags;

    /**
     * The set of unseen custom tags.
     */
    private Set<String> unseenCustomTags;

    /**
     * True if we do not want to use @since tags.
     */
    private boolean nosince;

    /**
     * True if we want to use @version tags.
     */
    private boolean showversion;

    /**
     * True if we want to use @author tags.
     */
    private boolean showauthor;

    /**
     * True if we want to use JavaFX-related tags (@propertyGetter,
     * @propertySetter, @propertyDescription, @defaultValue, @treatAsPrivate).
     */
    private boolean javafx;

    /**
     * Construct a new <code>TagletManager.
     * @param nosince true if we do not want to use @since tags.
     * @param showversion true if we want to use @version tags.
     * @param showauthor true if we want to use @author tags.
     * @param message the message retriever to print warnings.
     */
    public TagletManager(boolean nosince, boolean showversion,
                         boolean showauthor, boolean javafx,
                         MessageRetriever message) {
        overridenStandardTags = new HashSet<String>();
        potentiallyConflictingTags = new HashSet<String>();
        standardTags = new HashSet<String>();
        standardTagsLowercase = new HashSet<String>();
        unseenCustomTags = new HashSet<String>();
        customTags = new LinkedHashMap<String,Taglet>();
        this.nosince = nosince;
        this.showversion = showversion;
        this.showauthor = showauthor;
        this.javafx = javafx;
        this.message = message;
        initStandardTaglets();
        initStandardTagsLowercase();
    }

    /**
     * Add a new <code>CustomTag.  This is used to add a Taglet from within
     * a Doclet.  No message is printed to indicate that the Taglet is properly
     * registered because these Taglets are typically added for every execution of the
     * Doclet.  We don't want to see this type of error message every time.
     * @param customTag the new <code>CustomTag to add.
     */
    public void addCustomTag(Taglet customTag) {
        if (customTag != null) {
            String name = customTag.getName();
            if (customTags.containsKey(name)) {
                customTags.remove(name);
            }
            customTags.put(name, customTag);
            checkTagName(name);
        }
    }

    public Set<String> getCustomTagNames() {
        return customTags.keySet();
    }

    /**
     * Add a new <code>Taglet.  Print a message to indicate whether or not
     * the Taglet was registered properly.
     * @param classname  the name of the class representing the custom tag.
     * @param tagletPath  the path to the class representing the custom tag.
     */
    public void addCustomTag(String classname, JavaFileManager fileManager, String tagletPath) {
        try {
            Class<?> customTagClass = null;
            // construct class loader
            String cpString = null;   // make sure env.class.path defaults to dot

            ClassLoader tagClassLoader;
            if (fileManager != null && fileManager.hasLocation(DocumentationTool.Location.TAGLET_PATH)) {
                tagClassLoader = fileManager.getClassLoader(DocumentationTool.Location.TAGLET_PATH);
            } else {
                // do prepends to get correct ordering
                cpString = appendPath(System.getProperty("env.class.path"), cpString);
                cpString = appendPath(System.getProperty("java.class.path"), cpString);
                cpString = appendPath(tagletPath, cpString);
                tagClassLoader = new URLClassLoader(pathToURLs(cpString));
            }

            customTagClass = tagClassLoader.loadClass(classname);
            Method meth = customTagClass.getMethod("register",
                                                   new Class<?>[] {java.util.Map.class});
            Object[] list = customTags.values().toArray();
            Taglet lastTag = (list != null && list.length > 0)
                ? (Taglet) list[list.length-1] : null;
            meth.invoke(null, new Object[] {customTags});
            list = customTags.values().toArray();
            Object newLastTag = (list != null&& list.length > 0)
                ? list[list.length-1] : null;
            if (lastTag != newLastTag) {
                //New taglets must always be added to the end of the LinkedHashMap.
                //If the current and previous last taglet are not equal, that
                //means a new Taglet has been added.
                message.notice("doclet.Notice_taglet_registered", classname);
                if (newLastTag != null) {
                    checkTaglet(newLastTag);
                }
            }
        } catch (Exception exc) {
            message.error("doclet.Error_taglet_not_registered", exc.getClass().getName(), classname);
        }

    }

    private String appendPath(String path1, String path2) {
        if (path1 == null || path1.length() == 0) {
            return path2 == null ? "." : path2;
        } else if (path2 == null || path2.length() == 0) {
            return path1;
        } else {
            return path1  + File.pathSeparator + path2;
        }
    }

    /**
     * Utility method for converting a search path string to an array
     * of directory and JAR file URLs.
     *
     * @param path the search path string
     * @return the resulting array of directory and JAR file URLs
     */
    private URL[] pathToURLs(String path) {
        Set<URL> urls = new LinkedHashSet();
        for (String s: path.split(File.pathSeparator)) {
            if (s.isEmpty()) continue;
            try {
                urls.add(new File(s).getAbsoluteFile().toURI().toURL());
            } catch (MalformedURLException e) {
                message.error("doclet.MalformedURL", s);
            }
        }
        return urls.toArray(new URL[urls.size()]);
    }


    /**
     * Add a new <code>SimpleTaglet.  If this tag already exists
     * and the header passed as an argument is null, move tag to the back of the
     * list. If this tag already exists and the header passed as an argument is
     * not null, overwrite previous tag with new one.  Otherwise, add new
     * SimpleTaglet to list.
     * @param tagName the name of this tag
     * @param header the header to output.
     * @param locations the possible locations that this tag
     * can appear in.
     */
    public void addNewSimpleCustomTag(String tagName, String header, String locations) {
        if (tagName == null || locations == null) {
            return;
        }
        Taglet tag = customTags.get(tagName);
        locations = locations.toLowerCase();
        if (tag == null || header != null) {
            customTags.remove(tagName);
            customTags.put(tagName, new SimpleTaglet(tagName, header, locations));
            if (locations != null && locations.indexOf('x') == -1) {
                checkTagName(tagName);
            }
        } else {
            //Move to back
            customTags.remove(tagName);
            customTags.put(tagName, tag);
        }
    }

    /**
     * Given a tag name, add it to the set of tags it belongs to.
     */
    private void checkTagName(String name) {
        if (standardTags.contains(name)) {
            overridenStandardTags.add(name);
        } else {
            if (name.indexOf('.') == -1) {
                potentiallyConflictingTags.add(name);
            }
            unseenCustomTags.add(name);
        }
    }

    /**
     * Check the taglet to see if it is a legacy taglet.  Also
     * check its name for errors.
     */
    private void checkTaglet(Object taglet) {
        if (taglet instanceof Taglet) {
            checkTagName(((Taglet) taglet).getName());
        } else if (taglet instanceof com.sun.tools.doclets.Taglet) {
            com.sun.tools.doclets.Taglet legacyTaglet = (com.sun.tools.doclets.Taglet) taglet;
            customTags.remove(legacyTaglet.getName());
            customTags.put(legacyTaglet.getName(), new LegacyTaglet(legacyTaglet));
            checkTagName(legacyTaglet.getName());
        } else {
            throw new IllegalArgumentException("Given object is not a taglet.");
        }
    }

    /**
     * Given a name of a seen custom tag, remove it from the set of unseen
     * custom tags.
     * @param name the name of the seen custom tag.
     */
    public void seenCustomTag(String name) {
        unseenCustomTags.remove(name);
    }

    /**
     * Given an array of <code>Tags, check for spelling mistakes.
     * @param doc the Doc object that holds the tags.
     * @param tags the list of <code>Tags to check.
     * @param areInlineTags true if the array of tags are inline and false otherwise.
     */
    public void checkTags(Doc doc, Tag[] tags, boolean areInlineTags) {
        if (tags == null) {
            return;
        }
        Taglet taglet;
        for (int i = 0; i < tags.length; i++) {
            String name = tags[i].name();
            if (name.length() > 0 && name.charAt(0) == '@') {
                name = name.substring(1, name.length());
            }
            if (! (standardTags.contains(name) || customTags.containsKey(name))) {
                if (standardTagsLowercase.contains(name.toLowerCase())) {
                    message.warning(tags[i].position(), "doclet.UnknownTagLowercase", tags[i].name());
                    continue;
                } else {
                    message.warning(tags[i].position(), "doclet.UnknownTag", tags[i].name());
                    continue;
                }
            }
            //Check if this tag is being used in the wrong location.
            if ((taglet = customTags.get(name)) != null) {
                if (areInlineTags && ! taglet.isInlineTag()) {
                    printTagMisuseWarn(taglet, tags[i], "inline");
                }
                if ((doc instanceof RootDoc) && ! taglet.inOverview()) {
                    printTagMisuseWarn(taglet, tags[i], "overview");
                } else if ((doc instanceof PackageDoc) && ! taglet.inPackage()) {
                    printTagMisuseWarn(taglet, tags[i], "package");
                } else if ((doc instanceof ClassDoc) && ! taglet.inType()) {
                    printTagMisuseWarn(taglet, tags[i], "class");
                } else if ((doc instanceof ConstructorDoc) && ! taglet.inConstructor()) {
                    printTagMisuseWarn(taglet, tags[i], "constructor");
                } else if ((doc instanceof FieldDoc) && ! taglet.inField()) {
                    printTagMisuseWarn(taglet, tags[i], "field");
                } else if ((doc instanceof MethodDoc) && ! taglet.inMethod()) {
                    printTagMisuseWarn(taglet, tags[i], "method");
                }
            }
        }
    }

    /**
     * Given the taglet, the tag and the type of documentation that the tag
     * was found in, print a tag misuse warning.
     * @param taglet the taglet representing the misused tag.
     * @param tag the misused tag.
     * @param holderType the type of documentation that the misused tag was found in.
     */
    private void printTagMisuseWarn(Taglet taglet, Tag tag, String holderType) {
        Set<String> locationsSet = new LinkedHashSet();
        if (taglet.inOverview()) {
            locationsSet.add("overview");
        }
        if (taglet.inPackage()) {
            locationsSet.add("package");
        }
        if (taglet.inType()) {
            locationsSet.add("class/interface");
        }
        if (taglet.inConstructor())  {
            locationsSet.add("constructor");
        }
        if (taglet.inField()) {
            locationsSet.add("field");
        }
        if (taglet.inMethod()) {
            locationsSet.add("method");
        }
        if (taglet.isInlineTag()) {
            locationsSet.add("inline text");
        }
        String[] locations = locationsSet.toArray(new String[]{});
        if (locations == null || locations.length == 0) {
            //This known tag is excluded.
            return;
        }
        StringBuilder combined_locations = new StringBuilder();
        for (int i = 0; i < locations.length; i++) {
            if (i > 0) {
                combined_locations.append(", ");
            }
            combined_locations.append(locations[i]);
        }
        message.warning(tag.position(), "doclet.tag_misuse",
            "@" + taglet.getName(), holderType, combined_locations.toString());
    }

    /**
     * Return the array of <code>Taglets that can
     * appear in packages.
     * @return the array of <code>Taglets that can
     * appear in packages.
     */
    public Taglet[] getPackageCustomTaglets() {
        if (packageTags == null) {
            initCustomTagletArrays();
        }
        return packageTags;
    }

    /**
     * Return the array of <code>Taglets that can
     * appear in classes or interfaces.
     * @return the array of <code>Taglets that can
     * appear in classes or interfaces.
     */
    public Taglet[] getTypeCustomTaglets() {
        if (typeTags == null) {
            initCustomTagletArrays();
        }
        return typeTags;
    }

    /**
     * Return the array of inline <code>Taglets that can
     * appear in comments.
     * @return the array of <code>Taglets that can
     * appear in comments.
     */
    public Taglet[] getInlineCustomTaglets() {
        if (inlineTags == null) {
            initCustomTagletArrays();
        }
        return inlineTags;
    }

    /**
     * Return the array of <code>Taglets that can
     * appear in fields.
     * @return the array of <code>Taglets that can
     * appear in field.
     */
    public Taglet[] getFieldCustomTaglets() {
        if (fieldTags == null) {
            initCustomTagletArrays();
        }
        return fieldTags;
    }

    /**
     * Return the array of <code>Taglets that can
     * appear in the serialized form.
     * @return the array of <code>Taglets that can
     * appear in the serialized form.
     */
    public Taglet[] getSerializedFormTaglets() {
        if (serializedFormTags == null) {
            initCustomTagletArrays();
        }
        return serializedFormTags;
    }

    /**
     * @return the array of <code>Taglets that can
     * appear in the given Doc.
     */
    public Taglet[] getCustomTaglets(Doc doc) {
        if (doc instanceof ConstructorDoc) {
            return getConstructorCustomTaglets();
        } else if (doc instanceof MethodDoc) {
            return getMethodCustomTaglets();
        } else if (doc instanceof FieldDoc) {
            return getFieldCustomTaglets();
        } else if (doc instanceof ClassDoc) {
            return getTypeCustomTaglets();
        } else if (doc instanceof PackageDoc) {
            return getPackageCustomTaglets();
        } else if (doc instanceof RootDoc) {
            return getOverviewCustomTaglets();
        }
        return null;
    }

    /**
     * Return the array of <code>Taglets that can
     * appear in constructors.
     * @return the array of <code>Taglets that can
     * appear in constructors.
     */
    public Taglet[] getConstructorCustomTaglets() {
        if (constructorTags == null) {
            initCustomTagletArrays();
        }
        return constructorTags;
    }

    /**
     * Return the array of <code>Taglets that can
     * appear in methods.
     * @return the array of <code>Taglets that can
     * appear in methods.
     */
    public Taglet[] getMethodCustomTaglets() {
        if (methodTags == null) {
            initCustomTagletArrays();
        }
        return methodTags;
    }

    /**
     * Return the array of <code>Taglets that can
     * appear in an overview.
     * @return the array of <code>Taglets that can
     * appear in overview.
     */
    public Taglet[] getOverviewCustomTaglets() {
        if (overviewTags == null) {
            initCustomTagletArrays();
        }
        return overviewTags;
    }

    /**
     * Initialize the custom tag arrays.
     */
    private void initCustomTagletArrays() {
        Iterator<Taglet> it = customTags.values().iterator();
        ArrayList<Taglet> pTags = new ArrayList(customTags.size());
        ArrayList<Taglet> tTags = new ArrayList(customTags.size());
        ArrayList<Taglet> fTags = new ArrayList(customTags.size());
        ArrayList<Taglet> cTags = new ArrayList(customTags.size());
        ArrayList<Taglet> mTags = new ArrayList(customTags.size());
        ArrayList<Taglet> iTags = new ArrayList(customTags.size());
        ArrayList<Taglet> oTags = new ArrayList(customTags.size());
        ArrayList<Taglet> sTags = new ArrayList();
        Taglet current;
        while (it.hasNext()) {
            current = it.next();
            if (current.inPackage() && !current.isInlineTag()) {
                pTags.add(current);
            }
            if (current.inType() && !current.isInlineTag()) {
                tTags.add(current);
            }
            if (current.inField() && !current.isInlineTag()) {
                fTags.add(current);
            }
            if (current.inConstructor() && !current.isInlineTag()) {
                cTags.add(current);
            }
            if (current.inMethod() && !current.isInlineTag()) {
                mTags.add(current);
            }
            if (current.isInlineTag()) {
                iTags.add(current);
            }
            if (current.inOverview() && !current.isInlineTag()) {
                oTags.add(current);
            }
        }
        packageTags = pTags.toArray(new Taglet[] {});
        typeTags = tTags.toArray(new Taglet[] {});
        fieldTags = fTags.toArray(new Taglet[] {});
        constructorTags = cTags.toArray(new Taglet[] {});
        methodTags = mTags.toArray(new Taglet[] {});
        overviewTags = oTags.toArray(new Taglet[] {});
        inlineTags = iTags.toArray(new Taglet[] {});

        //Init the serialized form tags
        sTags.add(customTags.get("serialData"));
        sTags.add(customTags.get("throws"));
        if (!nosince)
            sTags.add(customTags.get("since"));
        sTags.add(customTags.get("see"));
        serializedFormTags = sTags.toArray(new Taglet[] {});
    }

    /**
     * Initialize standard Javadoc tags for ordering purposes.
     */
    private void initStandardTaglets() {
        if (javafx) {
            initJavaFXTaglets();
        }

        Taglet temp;
        addStandardTaglet(new ParamTaglet());
        addStandardTaglet(new ReturnTaglet());
        addStandardTaglet(new ThrowsTaglet());
        addStandardTaglet(new SimpleTaglet("exception", null,
                SimpleTaglet.METHOD + SimpleTaglet.CONSTRUCTOR));
        addStandardTaglet(!nosince, new SimpleTaglet("since", message.getText("doclet.Since"),
               SimpleTaglet.ALL));
        addStandardTaglet(showversion, new SimpleTaglet("version", message.getText("doclet.Version"),
                SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW));
        addStandardTaglet(showauthor, new SimpleTaglet("author", message.getText("doclet.Author"),
                SimpleTaglet.PACKAGE + SimpleTaglet.TYPE + SimpleTaglet.OVERVIEW));
        addStandardTaglet(new SimpleTaglet("serialData", message.getText("doclet.SerialData"),
            SimpleTaglet.EXCLUDED));
        customTags.put((temp = new SimpleTaglet("factory", message.getText("doclet.Factory"),
            SimpleTaglet.METHOD)).getName(), temp);
        addStandardTaglet(new SeeTaglet());
        //Standard inline tags
        addStandardTaglet(new DocRootTaglet());
        addStandardTaglet(new InheritDocTaglet());
        addStandardTaglet(new ValueTaglet());
        addStandardTaglet(new LiteralTaglet());
        addStandardTaglet(new CodeTaglet());

        // Keep track of the names of standard tags for error
        // checking purposes. The following are not handled above.
        // See, for example, com.sun.tools.javadoc.Comment
        standardTags.add("deprecated");
        standardTags.add("link");
        standardTags.add("linkplain");
        standardTags.add("serial");
        standardTags.add("serialField");
        standardTags.add("Text");
    }

    /**
     * Initialize JavaFX-related tags.
     */
    private void initJavaFXTaglets() {
        addStandardTaglet(new PropertyGetterTaglet());
        addStandardTaglet(new PropertySetterTaglet());
        addStandardTaglet(new SimpleTaglet("propertyDescription",
                message.getText("doclet.PropertyDescription"),
                SimpleTaglet.FIELD + SimpleTaglet.METHOD));
        addStandardTaglet(new SimpleTaglet("defaultValue", message.getText("doclet.DefaultValue"),
            SimpleTaglet.FIELD + SimpleTaglet.METHOD));
        addStandardTaglet(new SimpleTaglet("treatAsPrivate", null,
                SimpleTaglet.FIELD + SimpleTaglet.METHOD + SimpleTaglet.TYPE));
    }

    void addStandardTaglet(Taglet taglet) {
        String name = taglet.getName();
        customTags.put(name, taglet);
        standardTags.add(name);
    }

    void addStandardTaglet(boolean enable, Taglet taglet) {
        String name = taglet.getName();
        if (enable)
            customTags.put(name, taglet);
        standardTags.add(name);
    }

    /**
     * Initialize lowercase version of standard Javadoc tags.
     */
    private void initStandardTagsLowercase() {
        Iterator<String> it = standardTags.iterator();
        while (it.hasNext()) {
            standardTagsLowercase.add(it.next().toLowerCase());
        }
    }

    public boolean isKnownCustomTag(String tagName) {
        return customTags.containsKey(tagName);
    }

    /**
     * Print a list of {@link Taglet}s that might conflict with
     * standard tags in the future and a list of standard tags
     * that have been overriden.
     */
    public void printReport() {
        printReportHelper("doclet.Notice_taglet_conflict_warn", potentiallyConflictingTags);
        printReportHelper("doclet.Notice_taglet_overriden", overridenStandardTags);
        printReportHelper("doclet.Notice_taglet_unseen", unseenCustomTags);
    }

    private void printReportHelper(String noticeKey, Set<String> names) {
        if (names.size() > 0) {
            String[] namesArray = names.toArray(new String[] {});
            String result = " ";
            for (int i = 0; i < namesArray.length; i++) {
                result += "@" + namesArray[i];
                if (i + 1 < namesArray.length) {
                    result += ", ";
                }
            }
            message.notice(noticeKey, result);
        }
    }

    /**
     * Given the name of a tag, return the corresponding taglet.
     * Return null if the tag is unknown.
     *
     * @param name the name of the taglet to retrieve.
     * @return return the corresponding taglet. Return null if the tag is
     *         unknown.
     */
    public Taglet getTaglet(String name) {
        if (name.indexOf("@") == 0) {
            return customTags.get(name.substring(1));
        } else {
            return customTags.get(name);
        }

    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java TagletManager.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.