/** * 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); } }
/** * Add the package use information. * * @param pkg the package that used the given package * @param contentTree the content tree to which the information will be added */ protected void addPackageUse(PackageDoc pkg, Content contentTree) throws IOException { Content tdFirst = HtmlTree.TD( HtmlStyle.colFirst, getHyperLink(Util.getPackageName(pkg), new StringContent(Util.getPackageName(pkg)))); contentTree.addContent(tdFirst); HtmlTree tdLast = new HtmlTree(HtmlTag.TD); tdLast.addStyle(HtmlStyle.colLast); if (pkg != null && pkg.name().length() != 0) { addSummaryComment(pkg, tdLast); } else { tdLast.addContent(getSpace()); } contentTree.addContent(tdLast); }
/** * Given a PackageDoc, return the source path for that package. * * @param configuration The Configuration for the current Doclet. * @param pkgDoc The package to seach the path for. * @return A string representing the path to the given package. */ public static String getPackageSourcePath(Configuration configuration, PackageDoc pkgDoc) { try { String pkgPath = DirectoryManager.getDirectoryPath(pkgDoc); String completePath = new SourcePath(configuration.sourcepath).getDirectory(pkgPath) + DirectoryManager.URL_FILE_SEPERATOR; // Make sure that both paths are using the same seperators. completePath = Util.replaceText(completePath, File.separator, DirectoryManager.URL_FILE_SEPERATOR); pkgPath = Util.replaceText(pkgPath, File.separator, DirectoryManager.URL_FILE_SEPERATOR); return completePath.substring(0, completePath.indexOf(pkgPath)); } catch (Exception e) { return ""; } }
/** * 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); }
/** * Given a string, escape all special html characters and return the result. * * @param s The string to check. * @return the original string with all of the HTML characters escaped. * @see #HTML_ESCAPE_CHARS */ public static String escapeHtmlChars(String s) { String result = s; for (int i = 0; i < HTML_ESCAPE_CHARS.length; i++) { result = Util.replaceText(result, HTML_ESCAPE_CHARS[i][0], HTML_ESCAPE_CHARS[i][1]); } return result; }
/** * Write out class use pages. * * @throws DocletAbortException */ public static void generate(ConfigurationImpl configuration, ClassTree classtree) { ClassUseMapper mapper = new ClassUseMapper(configuration.root, classtree); for (ClassDoc aClass : configuration.root.classes()) { // If -nodeprecated option is set and the containing package is marked // as deprecated, do not generate the class-use page. We will still generate // the class-use page if the class is marked as deprecated but the containing // package is not since it could still be linked from that package-use page. if (!(configuration.nodeprecated && Util.isDeprecated(aClass.containingPackage()))) ClassUseWriter.generate(configuration, mapper, aClass); } for (PackageDoc pkg : configuration.packages) { // If -nodeprecated option is set and the package is marked // as deprecated, do not generate the package-use page. if (!(configuration.nodeprecated && Util.isDeprecated(pkg))) PackageUseWriter.generate(configuration, mapper, pkg); } }
protected void printIndexComment(Doc member, Tag[] firstSentenceTags) { Tag[] deprs = member.tags("deprecated"); if (Util.isDeprecated((ProgramElementDoc) member)) { boldText("doclet.Deprecated"); space(); if (deprs.length > 0) { printInlineDeprecatedComment(member, deprs[0]); } return; } else { ClassDoc cd = ((ProgramElementDoc) member).containingClass(); if (cd != null && Util.isDeprecated(cd)) { boldText("doclet.Deprecated"); space(); } } printSummaryComment(member, firstSentenceTags); }
/** Copy the doc files for the current ClassDoc if necessary. */ private void copyDocFiles() { PackageDoc containingPackage = annotationTypeDoc.containingPackage(); if ((configuration.packages == null || Arrays.binarySearch(configuration.packages, containingPackage) < 0) && !containingPackagesSeen.contains(containingPackage.name())) { // Only copy doc files dir if the containing package is not // documented AND if we have not documented a class from the same // package already. Otherwise, we are making duplicate copies. Util.copyDocFiles( configuration, Util.getPackageSourcePath(configuration, annotationTypeDoc.containingPackage()) + DirectoryManager.getDirectoryPath(annotationTypeDoc.containingPackage()) + File.separator, DocletConstants.DOC_FILES_DIR_NAME, true); containingPackagesSeen.add(containingPackage.name()); } }
/** * 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); } }
/** * Add the package use information. * * @param pkg the package that uses the given class * @param contentTree the content tree to which the package use information will be added */ protected void addPackageUse(PackageDoc pkg, Content contentTree) throws IOException { Content tdFirst = HtmlTree.TD( HtmlStyle.colFirst, getHyperLink(pkg.name(), new StringContent(Util.getPackageName(pkg)))); contentTree.addContent(tdFirst); HtmlTree tdLast = new HtmlTree(HtmlTag.TD); tdLast.addStyle(HtmlStyle.colLast); addSummaryComment(pkg, tdLast); contentTree.addContent(tdLast); }
/** * Copy the given directory contents from the source package directory to the generated * documentation directory. For example for a package java.lang this method find out the source * location of the package using {@link SourcePath} and if given directory is found in the source * directory structure, copy the entire directory, to the generated documentation hierarchy. * * @param configuration The configuration of the current doclet. * @param path The relative path to the directory to be copied. * @param dir The original directory name to copy from. * @param overwrite Overwrite files if true. */ public static void copyDocFiles( Configuration configuration, String path, String dir, boolean overwrite) { if (checkCopyDocFilesErrors(configuration, path, dir)) { return; } String destname = configuration.docFileDestDirName; File srcdir = new File(path + dir); if (destname.length() > 0 && !destname.endsWith(DirectoryManager.URL_FILE_SEPERATOR)) { destname += DirectoryManager.URL_FILE_SEPERATOR; } String dest = destname + dir; try { File destdir = new File(dest); DirectoryManager.createDirectory(configuration, dest); String[] files = srcdir.list(); for (int i = 0; i < files.length; i++) { File srcfile = new File(srcdir, files[i]); File destfile = new File(destdir, files[i]); if (srcfile.isFile()) { if (destfile.exists() && !overwrite) { configuration.message.warning( (SourcePosition) null, "doclet.Copy_Overwrite_warning", srcfile.toString(), destdir.toString()); } else { configuration.message.notice( "doclet.Copying_File_0_To_Dir_1", srcfile.toString(), destdir.toString()); Util.copyFile(destfile, srcfile); } } else if (srcfile.isDirectory()) { if (configuration.copydocfilesubdirs && !configuration.shouldExcludeDocFileDir(srcfile.getName())) { copyDocFiles( configuration, path, dir + DirectoryManager.URL_FILE_SEPERATOR + srcfile.getName(), overwrite); } } } } catch (SecurityException exc) { throw new DocletAbortException(); } catch (IOException exc) { throw new DocletAbortException(); } }
/** * Add the class list that use the given class. * * @param contentTree the content tree to which the class list will be added */ protected void addClassList(Content contentTree) throws IOException { HtmlTree ul = new HtmlTree(HtmlTag.UL); ul.addStyle(HtmlStyle.blockList); for (PackageDoc pkg : pkgSet) { Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(pkg.name())); Content link = getResource( "doclet.ClassUse_Uses.of.0.in.1", getLink( new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc)), getPackageLink(pkg, Util.getPackageName(pkg))); Content heading = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, link); li.addContent(heading); addClassUse(pkg, li); ul.addContent(li); } Content li = HtmlTree.LI(HtmlStyle.blockList, ul); contentTree.addContent(li); }
private void startGeneration(RootDoc root) throws Exception { if (root.classes().length == 0) { configuration.message.error("doclet.No_Public_Classes_To_Document"); return; } configuration.setOptions(); configuration .getDocletSpecificMsg() .notice("doclet.build_version", configuration.getDocletSpecificBuildDate()); configuration.tagletManager.addCustomTag(new SequenceDiagramTag()); configuration.tagletManager.addCustomTag(new DotDiagramTag()); configuration.tagletManager.addNewSimpleCustomTag("ArchitectureDocument", "", "X"); ClassTree classtree = new ClassTree(configuration, configuration.nodeprecated); generateClassFiles(root, classtree); if (configuration.sourcepath != null && configuration.sourcepath.length() > 0) { StringTokenizer pathTokens = new StringTokenizer(configuration.sourcepath, String.valueOf(File.pathSeparatorChar)); boolean first = true; while (pathTokens.hasMoreTokens()) { Util.copyDocFiles( configuration, pathTokens.nextToken() + File.separator, DocletConstants.DOC_FILES_DIR_NAME, first); first = false; } } PackageListWriter.generate(configuration); generatePackageFiles(classtree); generateOtherFiles(root, classtree); configuration.tagletManager.printReport(); }
/** * Add the class use information. * * @param pkg the package that uses the given class * @param contentTree the content tree to which the class use information will be added */ protected void addClassUse(PackageDoc pkg, Content contentTree) throws IOException { Content classLink = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, classdoc)); Content pkgLink = getPackageLink(pkg, Util.getPackageName(pkg)); classSubWriter.addUseInfo( pkgToClassAnnotations.get(pkg.name()), configuration.getResource("doclet.ClassUse_Annotation", classLink, pkgLink), classUseTableSummary, contentTree); classSubWriter.addUseInfo( pkgToClassTypeParameter.get(pkg.name()), configuration.getResource("doclet.ClassUse_TypeParameter", classLink, pkgLink), classUseTableSummary, contentTree); classSubWriter.addUseInfo( pkgToSubclass.get(pkg.name()), configuration.getResource("doclet.ClassUse_Subclass", classLink, pkgLink), subclassUseTableSummary, contentTree); classSubWriter.addUseInfo( pkgToSubinterface.get(pkg.name()), configuration.getResource("doclet.ClassUse_Subinterface", classLink, pkgLink), subinterfaceUseTableSummary, contentTree); classSubWriter.addUseInfo( pkgToImplementingClass.get(pkg.name()), configuration.getResource("doclet.ClassUse_ImplementingClass", classLink, pkgLink), classUseTableSummary, contentTree); fieldSubWriter.addUseInfo( pkgToField.get(pkg.name()), configuration.getResource("doclet.ClassUse_Field", classLink, pkgLink), fieldUseTableSummary, contentTree); fieldSubWriter.addUseInfo( pkgToFieldAnnotations.get(pkg.name()), configuration.getResource("doclet.ClassUse_FieldAnnotations", classLink, pkgLink), fieldUseTableSummary, contentTree); fieldSubWriter.addUseInfo( pkgToFieldTypeParameter.get(pkg.name()), configuration.getResource("doclet.ClassUse_FieldTypeParameter", classLink, pkgLink), fieldUseTableSummary, contentTree); methodSubWriter.addUseInfo( pkgToMethodAnnotations.get(pkg.name()), configuration.getResource("doclet.ClassUse_MethodAnnotations", classLink, pkgLink), methodUseTableSummary, contentTree); methodSubWriter.addUseInfo( pkgToMethodParameterAnnotations.get(pkg.name()), configuration.getResource("doclet.ClassUse_MethodParameterAnnotations", classLink, pkgLink), methodUseTableSummary, contentTree); methodSubWriter.addUseInfo( pkgToMethodTypeParameter.get(pkg.name()), configuration.getResource("doclet.ClassUse_MethodTypeParameter", classLink, pkgLink), methodUseTableSummary, contentTree); methodSubWriter.addUseInfo( pkgToMethodReturn.get(pkg.name()), configuration.getResource("doclet.ClassUse_MethodReturn", classLink, pkgLink), methodUseTableSummary, contentTree); methodSubWriter.addUseInfo( pkgToMethodReturnTypeParameter.get(pkg.name()), configuration.getResource("doclet.ClassUse_MethodReturnTypeParameter", classLink, pkgLink), methodUseTableSummary, contentTree); methodSubWriter.addUseInfo( pkgToMethodArgs.get(pkg.name()), configuration.getResource("doclet.ClassUse_MethodArgs", classLink, pkgLink), methodUseTableSummary, contentTree); methodSubWriter.addUseInfo( pkgToMethodArgTypeParameter.get(pkg.name()), configuration.getResource("doclet.ClassUse_MethodArgsTypeParameters", classLink, pkgLink), methodUseTableSummary, contentTree); methodSubWriter.addUseInfo( pkgToMethodThrows.get(pkg.name()), configuration.getResource("doclet.ClassUse_MethodThrows", classLink, pkgLink), methodUseTableSummary, contentTree); constrSubWriter.addUseInfo( pkgToConstructorAnnotations.get(pkg.name()), configuration.getResource("doclet.ClassUse_ConstructorAnnotations", classLink, pkgLink), constructorUseTableSummary, contentTree); constrSubWriter.addUseInfo( pkgToConstructorParameterAnnotations.get(pkg.name()), configuration.getResource( "doclet.ClassUse_ConstructorParameterAnnotations", classLink, pkgLink), constructorUseTableSummary, contentTree); constrSubWriter.addUseInfo( pkgToConstructorArgs.get(pkg.name()), configuration.getResource("doclet.ClassUse_ConstructorArgs", classLink, pkgLink), constructorUseTableSummary, contentTree); constrSubWriter.addUseInfo( pkgToConstructorArgTypeParameter.get(pkg.name()), configuration.getResource( "doclet.ClassUse_ConstructorArgsTypeParameters", classLink, pkgLink), constructorUseTableSummary, contentTree); constrSubWriter.addUseInfo( pkgToConstructorThrows.get(pkg.name()), configuration.getResource("doclet.ClassUse_ConstructorThrows", classLink, pkgLink), constructorUseTableSummary, contentTree); }
/** * Build the package header. * * @param node the XML element that specifies which components to document * @param packageSerializedTree content tree to which the documentation will be added */ public void buildPackageHeader(XMLNode node, Content packageSerializedTree) { packageSerializedTree.addContent(writer.getPackageHeader(Util.getPackageName(currentPackage))); }
/** * Build the signature of the current annotation type. * * @param node the XML element that specifies which components to document * @param annotationInfoTree the content tree to which the documentation will be added */ public void buildAnnotationTypeSignature(XMLNode node, Content annotationInfoTree) { StringBuffer modifiers = new StringBuffer(annotationTypeDoc.modifiers() + " "); writer.addAnnotationTypeSignature( Util.replaceText(modifiers.toString(), "interface", "@interface"), annotationInfoTree); }
/** * Return true if this link is linkable and false if we can't link to the desired place. * * @return true if this link is linkable and false if we can't link to the desired place. */ public boolean isLinkable() { return Util.isLinkable(classDoc, ConfigurationImpl.getInstance()); }