javajavadoctaglet

How to register multiple instances of custom doclets with configuration differences


I'm writing a custom Javadoc doclet to print a table of javax.validation constraints for the containing class. It basically works, but I'm finding the Doclet framework is pretty restrictive and inflexible.

For background, it's very possible that a property in a class will have more than one validation constraint. When I initially wrote the Taglet, I rendered separate rows in the table for each constraint, even if the property name was the same.

Someone commented that they'd like to have the option of rendering all the constraints for a single property on the same row, comma-separated. I personally didn't think I'd want that, but I saw no reason to restrict that, as it's a reasonable thing to ask for.

So, I figured, how hard could it be to allow for configuration options on a Taglet? Pretty hard, as I'm finding out.

First, I assumed that it would be possible to define Taglets that take configuration options. I then discovered there's no way to do that.

Ok, so then I thought I would use a little bit of trickery.

Here's a block of code from my taglet class:

public static void register(Map<String, Taglet> tagletMap)  {
    ValidationConstraintsTaglet taglet  = new ValidationConstraintsTaglet();
    registerInstance(tagletMap, taglet, taglet.getName());
    //ValidationConstraintsTaglet tagletCombined  = new ValidationConstraintsTaglet().combineConstraints(true);
    //registerInstance(tagletMap, tagletCombined, taglet.getName() + "Combined");
}

private static void registerInstance(Map<String, Taglet> tagletMap, Taglet taglet, String name) {
    if (tagletMap.get(name) != null) {
        tagletMap.remove(name);
    }
    tagletMap.put(name, taglet);
}

With the code like this, it works perfectly fine, rendering one row per constraint.

If I commented back in the two lines that are commented out, this is an attempt to register a SECOND instance of the taglet with a different name, adding "Combined" to the end of the name. In my "toString(Tag)" method, I check for that "isCombinedConstraints" option, rendering all the constraints for a single property on a single line. I made sure this functionality works, if "combinedConstraints" is set by default.

So, if I run this with those two lines commented in, I get a perplexing error:

javadoc: error - com.sun.tools.doclets.internal.toolkit.util.DocletAbortException: java.lang.ClassCastException: com.att.det.taglet.ValidationConstraintsTaglet cannot be cast to com.sun.tools.doclets.internal.toolkit.taglets.Taglet

That's all the info I get. No stacktrace to even tell me where this is happening.

When I first saw this, I assumed that I must have also changed something else at the same time that would cause this. I then commented out the two new lines and retested, and the error went away.


Solution

  • I gave up on this approach, as I couldn't get it working and got no response here.

    What I'm forced to do is implement configuration changes in a subclass, with its own "register" method, and a different tag name.