/** * Parses an annotation type definition * * @param docClass * @return */ protected static Annotation ParseAnnotation(ClassDoc docClass) { AnnotationTypeDoc docAnnotation = (AnnotationTypeDoc) docClass; assert (docAnnotation != null); Annotation xmlAnnotation = new Annotation(); xmlAnnotation.name = docClass.name(); xmlAnnotation.qualifiedName = docClass.qualifiedName(); xmlAnnotation.comment = docClass.commentText(); xmlAnnotation.isIncluded = docClass.isIncluded(); xmlAnnotation.scope = DetermineScope(docClass); AnnotationTypeElementDoc[] elements = docAnnotation.elements(); if (elements != null && elements.length > 0) { ArrayList<AnnotationElement> elementList = new ArrayList<AnnotationElement>(); for (AnnotationTypeElementDoc element : elements) { elementList.add(ParseAnnotationElement(element)); } xmlAnnotation.elements = elementList.toArray(new AnnotationElement[] {}); } else { log.debug("No elements in annotation: " + docClass.name()); } xmlAnnotation.annotationInstances = ParseAnnotationInstances(docClass.annotations(), docClass.qualifiedName()); return xmlAnnotation; }
/** * Constructor. * * @param filename the file to be generated. * @throws IOException * @throws DocletAbortException */ public PackageUseWriter( ConfigurationImpl configuration, ClassUseMapper mapper, DocPath filename, PackageDoc pkgdoc) throws IOException { super(configuration, DocPath.forPackage(pkgdoc).resolve(filename)); this.pkgdoc = pkgdoc; // by examining all classes in this package, find what packages // use these classes - produce a map between using package and // used classes. ClassDoc[] content = pkgdoc.allClasses(); for (int i = 0; i < content.length; ++i) { ClassDoc usedClass = content[i]; Set<ClassDoc> usingClasses = mapper.classToClass.get(usedClass.qualifiedName()); if (usingClasses != null) { for (Iterator<ClassDoc> it = usingClasses.iterator(); it.hasNext(); ) { ClassDoc usingClass = it.next(); PackageDoc usingPackage = usingClass.containingPackage(); Set<ClassDoc> usedClasses = usingPackageToUsedClasses.get(usingPackage.name()); if (usedClasses == null) { usedClasses = new TreeSet<ClassDoc>(); usingPackageToUsedClasses.put(Util.getPackageName(usingPackage), usedClasses); } usedClasses.add(usedClass); } } } }
/** * Parses the enum type definition * * @param docClass * @return */ protected static Enum ParseEnum(ClassDoc docClass) { assert (docClass != null); Enum xmlEnum = new Enum(); xmlEnum.name = docClass.name(); xmlEnum.qualifiedName = docClass.qualifiedName(); xmlEnum.comment = docClass.commentText(); xmlEnum.isIncluded = docClass.isIncluded(); xmlEnum.scope = DetermineScope(docClass); Type superClassType = docClass.superclassType(); if (superClassType != null) { xmlEnum.superClass = superClassType.qualifiedTypeName(); } Type[] interfaces = docClass.interfaceTypes(); ArrayList<String> interfaceTypeNames = new ArrayList<String>(); if (interfaces != null && interfaces.length > 0) { for (Type interfaceType : interfaces) { interfaceTypeNames.add(interfaceType.qualifiedTypeName()); } } xmlEnum.extendedFrom = interfaceTypeNames.toArray(new String[] {}); FieldDoc[] fields = docClass.enumConstants(); if (fields != null && fields.length > 0) { ArrayList<EnumField> fieldList = new ArrayList<EnumField>(); for (FieldDoc field : fields) { fieldList.add(ParseEnumField(field)); } xmlEnum.fields = fieldList.toArray(new EnumField[] {}); } xmlEnum.annotationInstances = ParseAnnotationInstances(docClass.annotations(), docClass.qualifiedName()); return xmlEnum; }
/** * Parses an interface type definition * * @param docClass * @return */ protected static Interface ParseInterface(ClassDoc docClass) { assert (docClass != null); Interface xmlInterface = new Interface(); xmlInterface.name = docClass.name(); xmlInterface.qualifiedName = docClass.qualifiedName(); xmlInterface.comment = docClass.commentText(); xmlInterface.isIncluded = docClass.isIncluded(); xmlInterface.scope = DetermineScope(docClass); xmlInterface.typeVariables = ParseTypeVariables(docClass.typeParameters(), docClass.typeParamTags()); Type[] interfaces = docClass.interfaceTypes(); ArrayList<String> interfaceTypeNames = new ArrayList<String>(); if (interfaces != null && interfaces.length > 0) { for (Type interfaceType : interfaces) { interfaceTypeNames.add(interfaceType.qualifiedTypeName()); } xmlInterface.interfaces = interfaceTypeNames.toArray(new String[] {}); } MethodDoc[] methods = docClass.methods(); if (methods != null && methods.length > 0) { ArrayList<Method> methodList = new ArrayList<Method>(); for (MethodDoc method : methods) { methodList.add(ParseMethod(method)); } xmlInterface.methods = methodList.toArray(new Method[] {}); } else { log.debug("No methods in interface: " + docClass.name()); } xmlInterface.annotationInstances = ParseAnnotationInstances(docClass.annotations(), docClass.qualifiedName()); return xmlInterface; }
/** * Build the field information. * * @param node the XML element that specifies which components to document * @param fieldsContentTree content tree to which the documentation will be added */ public void buildFieldInfo(XMLNode node, Content fieldsContentTree) { if (configuration.nocomment) { return; } FieldDoc field = (FieldDoc) currentMember; ClassDoc cd = field.containingClass(); // Process default Serializable field. if ((field.tags("serial").length == 0) && !field.isSynthetic() && configuration.serialwarn) { configuration.message.warning( field.position(), "doclet.MissingSerialTag", cd.qualifiedName(), field.name()); } fieldWriter.addMemberDescription(field, fieldsContentTree); fieldWriter.addMemberTags(field, fieldsContentTree); }
/** * Given an array of <code>Tag</code>s representing this custom tag, return its string * representation. * * @param throwTags the array of <code>ThrowsTag</code>s to convert. * @param writer the TagletWriter that will write this tag. * @param alreadyDocumented the set of exceptions that have already been documented. * @param allowDups True if we allow duplicate throws tags to be documented. * @return the TagletOutput representation of this <code>Tag</code>. */ protected TagletOutput throwsTagsOutput( ThrowsTag[] throwTags, TagletWriter writer, Set<String> alreadyDocumented, boolean allowDups) { TagletOutput result = writer.getOutputInstance(); if (throwTags.length > 0) { for (int i = 0; i < throwTags.length; ++i) { ThrowsTag tt = throwTags[i]; ClassDoc cd = tt.exception(); if ((!allowDups) && (alreadyDocumented.contains(tt.exceptionName()) || (cd != null && alreadyDocumented.contains(cd.qualifiedName())))) { continue; } if (alreadyDocumented.size() == 0) { result.appendOutput(writer.getThrowsHeader()); } result.appendOutput(writer.throwsTagOutput(tt)); alreadyDocumented.add(cd != null ? cd.qualifiedName() : tt.exceptionName()); } } return result; }
/** * Given a class, return the closest visible super class. * * @param classDoc the class we are searching the parent for. * @param configuration the current configuration of the doclet. * @return the closest visible super class. Return null if it cannot be found (i.e. classDoc is * java.lang.Object). */ public static Type getFirstVisibleSuperClass(ClassDoc classDoc, Configuration configuration) { if (classDoc == null) { return null; } Type sup = classDoc.superclassType(); ClassDoc supClassDoc = classDoc.superclass(); while (sup != null && (!(supClassDoc.isPublic() || isLinkable(supClassDoc, configuration)))) { if (supClassDoc.superclass().qualifiedName().equals(supClassDoc.qualifiedName())) break; sup = supClassDoc.superclassType(); supClassDoc = supClassDoc.superclass(); } if (classDoc.equals(supClassDoc)) { return null; } return sup; }
public ThrowsTagImpl(String text, ClassDocImpl contextClass, MemberDocImpl contextMember) { super(text); char[] textarr = text.toCharArray(); int i = 0; for (; i < textarr.length; ++i) { if (!Parser.isWhitespace(textarr[i])) break; } for (; i < textarr.length; ++i) { if (Parser.isWhitespace(textarr[i])) { this.exceptionName = new String(textarr, 0, i).trim(); this.exceptionComment = new String(textarr, i, textarr.length - i).trim(); break; } } if (null != exceptionName) { if (contextClass == null) { this.exception = Main.getRootDoc().classNamed(exceptionName); } else { this.exception = contextClass.findClass(exceptionName); } if (exception != null) this.exceptionName = exception.qualifiedName(); else { if (text.trim().startsWith("<")) { Main.getRootDoc() .printWarning( "Expected exception name but got '" + text + "' in class " + contextClass.getClassName()); } } } else { Main.getRootDoc() .printWarning( "@throws tag in comment for " + contextClass.qualifiedName() + "." + contextMember.name() + " doesn't specify an exception."); } if (this.exceptionComment != null) { setBody(this.exceptionComment, contextClass, contextMember); } }
/** * The entry point into the Parser class. * * @param root A RootDoc intstance obtained via the doclet API * @return A XML (XStream) serializable element, containing everything parsed from javadoc doclet */ public static Root ParseRoot(RootDoc root) { processingStorage = new HashMap<PackageDoc, ParserMediary>(); try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { log.error("unable to acquire MD5 algorithm", e); return null; } rootXml = new Root(); ClassDoc[] allClasses = root.classes(); for (ClassDoc classDoc : allClasses) { PackageDoc doc = classDoc.containingPackage(); ParserMediary mediary = null; // the age old 'if I have it pull out existing, if I don't make a new one' if (processingStorage.containsKey(doc)) { mediary = processingStorage.get(doc); } else { mediary = new ParserMediary( doc.name(), doc.commentText(), ParseAnnotationInstances(doc.annotations(), doc.name())); processingStorage.put(doc, mediary); } if (classDoc.isIncluded()) { // dev comment--why do enums show up as ordinary class? if (classDoc.isOrdinaryClass() || classDoc.isException() || classDoc.isError()) { mediary.addClass(ParseClass(classDoc)); } else if (classDoc.isEnum()) { mediary.addEnum(ParseEnum(classDoc)); } else if (isAnnotation(classDoc)) { mediary.addAnnotation(ParseAnnotation(classDoc)); } else if (classDoc.isInterface()) { mediary.addInterface(ParseInterface(classDoc)); } } else { log.debug("Skipping not-included class " + classDoc.qualifiedName()); } } if (processingStorage.size() > 0) { List list = new ArrayList<Package>(); for (ParserMediary mediary : processingStorage.values()) { list.add(mediary.wrapup()); } rootXml.packages = (Package[]) list.toArray(new Package[] {}); } else { log.warn("No packages found!"); } return rootXml; }
/** * Parses the data for a class type definition * * @param docClass * @return */ protected static Class ParseClass(ClassDoc docClass) { assert (docClass != null); Class xmlClass = new Class(); // illegal use of this class. assert (xmlClass != null); xmlClass.name = docClass.name(); xmlClass.qualifiedName = docClass.qualifiedName(); xmlClass.isSerializable = docClass.isSerializable(); xmlClass.isExternalizable = docClass.isExternalizable(); xmlClass.isAbstract = docClass.isAbstract(); xmlClass.isException = docClass.isException(); xmlClass.isError = docClass.isError(); xmlClass.comment = docClass.commentText(); xmlClass.scope = DetermineScope(docClass); xmlClass.isIncluded = docClass.isIncluded(); xmlClass.typeVariables = ParseTypeVariables(docClass.typeParameters(), docClass.typeParamTags()); Type superClassType = docClass.superclassType(); if (superClassType != null) { xmlClass.superClass = ParseType(superClassType); } Type[] interfaces = docClass.interfaceTypes(); ArrayList<TypeInfo> interfaceTypeNames = new ArrayList<TypeInfo>(); if (interfaces != null && interfaces.length > 0) { for (Type interfaceType : interfaces) { interfaceTypeNames.add(ParseType(interfaceType)); } xmlClass.interfaces = interfaceTypeNames.toArray(new TypeInfo[] {}); } ConstructorDoc[] constructors = docClass.constructors(); if (constructors != null && constructors.length > 0) { ArrayList<Constructor> constructorList = new ArrayList<Constructor>(); for (ConstructorDoc constructor : constructors) { constructorList.add(ParseConstructor(constructor)); } xmlClass.constructors = constructorList.toArray(new Constructor[] {}); } else { log.debug("No constructors in class: " + docClass.name()); } MethodDoc[] methods = docClass.methods(); if (methods != null && methods.length > 0) { ArrayList<Method> methodList = new ArrayList<Method>(); for (MethodDoc method : methods) { methodList.add(ParseMethod(method)); } xmlClass.methods = methodList.toArray(new Method[] {}); } else { log.debug("No methods in class: " + docClass.name()); } FieldDoc[] fields = docClass.fields(); if (fields != null && fields.length > 0) { ArrayList<Field> fieldList = new ArrayList<Field>(); for (FieldDoc field : fields) { fieldList.add(ParseField(field)); } xmlClass.fields = fieldList.toArray(new Field[] {}); } xmlClass.annotationInstances = ParseAnnotationInstances(docClass.annotations(), docClass.qualifiedName()); return xmlClass; }