/** * Generate mapping for the sub-classes for every class in this run. Return the sub-class list for * java.lang.Object which will be having sub-class listing for itself and also for each sub-class * itself will have their own sub-class lists. * * @param classes all the classes in this run. * @param configuration the current configuration of the doclet. */ private void buildTree(ClassDoc[] classes, Configuration configuration) { log.info("ClassTree buildTree"); for (int i = 0; i < classes.length; i++) { if (configuration.nodeprecated && classes[i].tags("deprecated").length > 0) { continue; } if (classes[i].isEnum()) { processType(classes[i], configuration, baseEnums, subEnums); } else if (classes[i].isClass()) { processType(classes[i], configuration, baseclasses, subclasses); } else if (classes[i].isInterface()) { processInterface(classes[i]); List list = (List) implementingclasses.get(classes[i]); if (list != null) { Collections.sort(list); } } else if (classes[i].isAnnotationType()) { processType(classes[i], configuration, baseAnnotationTypes, subAnnotationTypes); } } Collections.sort(baseinterfaces); for (Iterator it = subinterfaces.values().iterator(); it.hasNext(); ) { Collections.sort((List) it.next()); } for (Iterator it = subclasses.values().iterator(); it.hasNext(); ) { Collections.sort((List) it.next()); } }
/** * Add the list of classes that use the given package. * * @param contentTree the content tree to which the class list will be added */ protected void addClassList(Content contentTree) throws IOException { String[] classTableHeader = new String[] { configuration.getText( "doclet.0_and_1", configuration.getText("doclet.Class"), configuration.getText("doclet.Description")) }; Iterator<String> itp = usingPackageToUsedClasses.keySet().iterator(); while (itp.hasNext()) { String packageName = itp.next(); PackageDoc usingPackage = configuration.root.packageNamed(packageName); HtmlTree li = new HtmlTree(HtmlTag.LI); li.addStyle(HtmlStyle.blockList); if (usingPackage != null) { li.addContent(getMarkerAnchor(usingPackage.name())); } String tableSummary = configuration.getText( "doclet.Use_Table_Summary", configuration.getText("doclet.classes")); Content table = HtmlTree.TABLE( HtmlStyle.useSummary, 0, 3, 0, tableSummary, getTableCaption( configuration.getResource( "doclet.ClassUse_Classes.in.0.used.by.1", getPackageLink(pkgdoc, Util.getPackageName(pkgdoc)), getPackageLink(usingPackage, Util.getPackageName(usingPackage))))); table.addContent(getSummaryTableHeader(classTableHeader, "col")); Content tbody = new HtmlTree(HtmlTag.TBODY); Iterator<ClassDoc> itc = usingPackageToUsedClasses.get(packageName).iterator(); for (int i = 0; itc.hasNext(); i++) { HtmlTree tr = new HtmlTree(HtmlTag.TR); if (i % 2 == 0) { tr.addStyle(HtmlStyle.altColor); } else { tr.addStyle(HtmlStyle.rowColor); } addClassRow(itc.next(), packageName, tr); tbody.addContent(tr); } table.addContent(tbody); li.addContent(table); contentTree.addContent(li); } }
/** * 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); } } } }
/** * Add the list of packages that use the given package. * * @param contentTree the content tree to which the package list will be added */ protected void addPackageList(Content contentTree) throws IOException { Content table = HtmlTree.TABLE( HtmlStyle.useSummary, 0, 3, 0, useTableSummary, getTableCaption( configuration.getResource( "doclet.ClassUse_Packages.that.use.0", getPackageLink(pkgdoc, Util.getPackageName(pkgdoc))))); table.addContent(getSummaryTableHeader(packageTableHeader, "col")); Content tbody = new HtmlTree(HtmlTag.TBODY); Iterator<String> it = usingPackageToUsedClasses.keySet().iterator(); for (int i = 0; it.hasNext(); i++) { PackageDoc pkg = configuration.root.packageNamed(it.next()); HtmlTree tr = new HtmlTree(HtmlTag.TR); if (i % 2 == 0) { tr.addStyle(HtmlStyle.altColor); } else { tr.addStyle(HtmlStyle.rowColor); } addPackageUse(pkg, tr); tbody.addContent(tr); } table.addContent(tbody); Content li = HtmlTree.LI(HtmlStyle.blockList, table); contentTree.addContent(li); }
private static void addAllInterfaceTypes( Map<ClassDoc, Type> results, Type type, Type[] interfaceTypes, boolean raw, Configuration configuration) { for (int i = 0; i < interfaceTypes.length; i++) { Type interfaceType = interfaceTypes[i]; ClassDoc interfaceClassDoc = interfaceType.asClassDoc(); if (!(interfaceClassDoc.isPublic() || (configuration != null && isLinkable(interfaceClassDoc, configuration)))) { continue; } if (raw) interfaceType = interfaceType.asClassDoc(); results.put(interfaceClassDoc, interfaceType); List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration); for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) { Type superInterface = iter.next(); results.put(superInterface.asClassDoc(), superInterface); } } if (type instanceof ParameterizedType) findAllInterfaceTypes(results, (ParameterizedType) type, configuration); else if (((ClassDoc) type).typeParameters().length == 0) findAllInterfaceTypes(results, (ClassDoc) type, raw, configuration); else findAllInterfaceTypes(results, (ClassDoc) type, true, configuration); }
/** * Add use information to the documentation tree. * * @param mems list of program elements for which the use information will be added * @param heading the section heading * @param tableSummary the summary for the use table * @param contentTree the content tree to which the use information will be added */ protected void addUseInfo( List<? extends ProgramElementDoc> mems, Content heading, String tableSummary, Content contentTree) { if (mems == null) { return; } List<? extends ProgramElementDoc> members = mems; boolean printedUseTableHeader = false; if (members.size() > 0) { Content caption = writer.getTableCaption(heading); Content table = (configuration.isOutputHtml5()) ? HtmlTree.TABLE(HtmlStyle.useSummary, caption) : HtmlTree.TABLE(HtmlStyle.useSummary, tableSummary, caption); Content tbody = new HtmlTree(HtmlTag.TBODY); Iterator<? extends ProgramElementDoc> it = members.iterator(); for (int i = 0; it.hasNext(); i++) { ProgramElementDoc pgmdoc = it.next(); ClassDoc cd = pgmdoc.containingClass(); if (!printedUseTableHeader) { table.addContent(writer.getSummaryTableHeader(this.getSummaryTableHeader(pgmdoc), "col")); printedUseTableHeader = true; } HtmlTree tr = new HtmlTree(HtmlTag.TR); if (i % 2 == 0) { tr.addStyle(HtmlStyle.altColor); } else { tr.addStyle(HtmlStyle.rowColor); } HtmlTree tdFirst = new HtmlTree(HtmlTag.TD); tdFirst.addStyle(HtmlStyle.colFirst); writer.addSummaryType(this, pgmdoc, tdFirst); tr.addContent(tdFirst); HtmlTree tdLast = new HtmlTree(HtmlTag.TD); tdLast.addStyle(HtmlStyle.colLast); if (cd != null && !(pgmdoc instanceof ConstructorDoc) && !(pgmdoc instanceof ClassDoc)) { HtmlTree name = new HtmlTree(HtmlTag.SPAN); name.addStyle(HtmlStyle.typeNameLabel); name.addContent(cd.name() + "."); tdLast.addContent(name); } addSummaryLink( pgmdoc instanceof ClassDoc ? LinkInfoImpl.Kind.CLASS_USE : LinkInfoImpl.Kind.MEMBER, cd, pgmdoc, tdLast); writer.addSummaryLinkComment(this, pgmdoc, tdLast); tr.addContent(tdLast); tbody.addContent(tr); } table.addContent(tbody); contentTree.addContent(table); } }
/** * Return the list of classes which implement the interface passed. * * @param cd interface whose implementing-classes list is required. */ public List implementingclasses(ClassDoc cd) { List result = get(implementingclasses, cd); List subinterfaces = allSubs(cd, false); // If class x implements a subinterface of cd, then it follows // that class x implements cd. Iterator implementingClassesIter, subInterfacesIter = subinterfaces.listIterator(); ClassDoc c; while (subInterfacesIter.hasNext()) { implementingClassesIter = implementingclasses((ClassDoc) subInterfacesIter.next()).listIterator(); while (implementingClassesIter.hasNext()) { c = (ClassDoc) implementingClassesIter.next(); if (!result.contains(c)) { result.add(c); } } } Collections.sort(result); return result; }
/** * For the class return all implemented interfaces including the superinterfaces of the * implementing interfaces, also iterate over for all the superclasses. For interface return all * the extended interfaces as well as superinterfaces for those extended interfaces. * * @param type type whose implemented or super interfaces are sought. * @param configuration the current configuration of the doclet. * @param sort if true, return list of interfaces sorted alphabetically. * @return List of all the required interfaces. */ public static List<Type> getAllInterfaces(Type type, Configuration configuration, boolean sort) { Map<ClassDoc, Type> results = sort ? new TreeMap<ClassDoc, Type>() : new LinkedHashMap<ClassDoc, Type>(); Type[] interfaceTypes = null; Type superType = null; if (type instanceof ParameterizedType) { interfaceTypes = ((ParameterizedType) type).interfaceTypes(); superType = ((ParameterizedType) type).superclassType(); } else if (type instanceof ClassDoc) { interfaceTypes = ((ClassDoc) type).interfaceTypes(); superType = ((ClassDoc) type).superclassType(); } else { interfaceTypes = type.asClassDoc().interfaceTypes(); superType = type.asClassDoc().superclassType(); } for (int i = 0; i < interfaceTypes.length; i++) { Type interfaceType = interfaceTypes[i]; ClassDoc interfaceClassDoc = interfaceType.asClassDoc(); if (!(interfaceClassDoc.isPublic() || (configuration == null || isLinkable(interfaceClassDoc, configuration)))) { continue; } results.put(interfaceClassDoc, interfaceType); List<Type> superInterfaces = getAllInterfaces(interfaceType, configuration, sort); for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) { Type t = iter.next(); results.put(t.asClassDoc(), t); } } if (superType == null) return new ArrayList<Type>(results.values()); // Try walking the tree. addAllInterfaceTypes( results, superType, superType instanceof ClassDoc ? ((ClassDoc) superType).interfaceTypes() : ((ParameterizedType) superType).interfaceTypes(), false, configuration); List<Type> resultsList = new ArrayList<Type>(results.values()); if (sort) { Collections.sort(resultsList, new TypeComparator()); } return resultsList; }
/** * For the class passed map it to it's own sub-class listing. For the Class passed, get the super * class, if superclass is non null, (it is not "java.lang.Object") get the "value" from the * hashmap for this key Class if entry not found create one and get that. add this Class as a sub * class in the list Recurse till hits java.lang.Object Null SuperClass. * * @param cd class for which sub-class mapping to be generated. * @param configuration the current configurtation of the doclet. */ private void processType(ClassDoc cd, Configuration configuration, List bases, Map subs) { ClassDoc superclass = Util.getFirstVisibleSuperClassCD(cd, configuration); if (superclass != null) { if (!add(subs, superclass, cd)) { return; } else { processType(superclass, configuration, bases, subs); } } else { // cd is java.lang.Object, add it once to the list if (!bases.contains(cd)) { bases.add(cd); } } List intfacs = Util.getAllInterfaces(cd, configuration); for (Iterator iter = intfacs.iterator(); iter.hasNext(); ) { add(implementingclasses, ((Type) iter.next()).asClassDoc(), cd); } }