By default, this method returns LanguageVersion.JAVA_1_1. You should override this method and return LanguageVersion.JAVA_1_5.
// If true, Type must be a primitive Type.asClassDoc() == nullIn 1.5, this no longer works because there are other non-classdoc types besides primitives. For example, the asClassDoc method would return null for annotation types as well. You should find all occurances of ?Type.asClassDoc() == null? and replace it with Type.isPrimitive().
Here is the interface that represents a type variable:
Here is the algorithm that the standard doclet uses to process type parameters:
if (type.asTypeVariable()!= null) { Doc owner = type.asTypeVariable().owner(); if (owner instanceof ClassDoc) { // Generate Link to type Parameter } else { // No need to link method type parameters. // Append the name of the type parameter } Type[] bounds = type.asTypeVariable().bounds(); if (! linkInfo.excludeTypeBounds) { for (int i = 0; i < bounds.length; i++) { // If i greater than 0, append " & ". Otherwise, append " extends " // Generate a link to the bound } } }
/** * @param <E> the type parameter for this class. */ public class Foo<E>To retrieve these type parameter @param tags, call ClassDoc. typeParamTags() or ExecutableMemberDoc.typeParamTags().
Type parameter tags can be distinguished from regular parameter tags by calling ParamTag.isTypeParameter().
com.sun.javadoc.AnnotationTypeDoc
Retrieve the annotation type elements by calling method elements(). There are two types of elements:
com.sun.javadoc.AnnotationDesc
Iterate through the list of AnnotationDesc objects and process each one. Here is the algorithm that the standard doclet uses to process AnnotationDesc objects:
for (int i = 0; i < descList.length; i++) { AnnotationTypeDoc annotationDoc = descList[i].annotationType(); if (/**annotationDoc does not have @documented annotation**/){ // ONLY document annotations if they have @documented. continue; } // Generate a link to the annotation. Start with the ?@? character> AnnotationDesc.ElementValuePair[] pairs = descList[i].elementValues(); if (pairs.length > 0) { // Append '(' to indicate start of element list> for (int j = 0; j < pairs.length; j++) { if (j > 0) { // Append ',' to separate previous element from the next> } // Generate a link to the annotation element> // Append '=' to separate element name from value> AnnotationValue annotationValue = pairs[j].value(); List annotationTypeValues = new ArrayList(); if (annotationValue.value() instanceof AnnotationValue[]) { AnnotationValue[] annotationArray = (AnnotationValue[]) annotationValue.value(); for (int k = 0; k < annotationArray.length; k++) { annotationTypeValues.add(annotationArray[k]); } } else { annotationTypeValues.add(annotationValue); } // Append '{' if this is an array of values for (Iterator iter = annotationTypeValues.iterator(); iter.hasNext(); ) { // Append string representation of value // Append ?,? if there is more to append } // Append '}' if this is an array of values } // Append ')' if this is an array of values } }Here is a sample of this output:
An annotation value can be any of the following:
if (annotationValue.value() instanceof Type) { Type type = (Type) annotationValue.value(); if (type.asClassDoc() != null) { LinkInfoImpl linkInfo = new LinkInfoImpl( LinkInfoImpl.CONTEXT_ANNOTATION, type); linkInfo.label = (type.asClassDoc().isIncluded() ? type.typeName() : type.qualifiedTypeName()) + type.dimension() + ".class "; return getLink(linkInfo); } else { return type.typeName() + type.dimension() + ".class"; } } else if (annotationValue.value() instanceof AnnotationDesc) { // Handle nested annotations using recursion. List list = getAnnotations( new AnnotationDesc[]{(AnnotationDesc) annotationValue.value()}, false); StringBuffer buf = new StringBuffer(); for (Iterator iter = list.iterator(); iter.hasNext(); ) { buf.append(iter.next()); } return buf.toString(); } else if (annotationValue.value() instanceof MemberDoc) { // Simply link to the member being references in the annotation. return getDocLink(LinkInfoImpl.CONTEXT_ANNOTATION, (MemberDoc) annotationValue.value(), ((MemberDoc) annotationValue.value()).name(), false); } else { return annotationValue.toString(); }
Here is a sample of Enum documentation:
java.lang.management.MemoryType.html
if (isVarArg) { if (type.dimension().length() > 2) { // Doclet API returns var args as array. // Strip out the first [] from the var arg. // Append type.dimension().substring(2) } // Append "..." } else { // Append type.dimension() }This code should be inserted in the place where you normally document array dimensions. Please note the comment that var args are returned as arrays by the doclet API. We strip out the first ?[]? because it is just a part of the internal representation of the var arg and should not appear in the documetation.
When a wild card is encountered, iterate through the lists of extends and super bounds. Process each bound the same way you would process a regular type. Here is the algorithm the standard doclet uses to process wild cards:
if (type.asWildcardType() != null) { WildcardType wildcardType = type.asWildcardType(); Type[] extendsBounds = wildcardType.extendsBounds(); for (int i = 0; i < extendsBounds.length; i++) { // If i greater than 0, append " , ". Otherwise, append " extends " // Generate link to extendsBounds[i]) } Type[] superBounds = wildcardType.superBounds(); for (int i = 0; i < superBounds.length; i++) { // If i greater than 0, append " , ". Otherwise, append " super " // Generate link to superBounds[i]) } }