/** * Renders a package documentation to an AsciiDoc file. * * @param doc the package documentation object */ private void renderPackage(PackageDoc doc){ try { PrintWriter writer = getWriter(doc, "package-info"); writer.println(doc.name()); if (doc.position() != null) { outputText(doc.name(), doc.getRawCommentText(), writer); } if (doc instanceof AnnotationTypeDoc) { for (MemberDoc member : ((AnnotationTypeDoc) doc).elements()) { outputText(member.name(), member.getRawCommentText(), writer); } } writer.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } }
/** * @param usedClassToPackagesMap ClassDoc to (PackageDoc to (UsageType to (Set of Doc))) */ private void addUsedBy(Map usedClassToPackagesMap, ClassDoc usedClass, UsageType usageType, Doc user, PackageDoc userPackage) { Map packageToUsageTypeMap = (Map)usedClassToPackagesMap.get(usedClass); if (null == packageToUsageTypeMap) { packageToUsageTypeMap = new HashMap(); usedClassToPackagesMap.put(usedClass, packageToUsageTypeMap); } Map usageTypeToUsersMap = (Map)packageToUsageTypeMap.get(userPackage); if (null == usageTypeToUsersMap) { usageTypeToUsersMap = new TreeMap(); packageToUsageTypeMap.put(userPackage, usageTypeToUsersMap); } Set userSet = (Set)usageTypeToUsersMap.get(usageType); if (null == userSet) { userSet = new TreeSet(); // FIXME: we need the collator from Main here usageTypeToUsersMap.put(usageType, userSet); } userSet.add(user); }
/** * Returns the XML node corresponding to the specified ClassDoc. * * @param doc The package to transform. */ private static XMLNode toPackageNode(PackageDoc doc) { XMLNode node = new XMLNode("package", doc); // Core attributes node.attribute("name", doc.name()); // Comment node.child(toComment(doc)); // Child nodes node.child(toAnnotationsNode(doc.annotations())); node.child(toStandardTags(doc)); node.child(toTags(doc)); node.child(toSeeNodes(doc.seeTags())); return node; }
private String getExportedPackage(ClassDoc clz) { if (clz == null) { return ""; } PackageDoc cpkg = clz.containingPackage(); String pkg = cpkg == null ? "" : (cpkg.name()); for (AnnotationDesc a : clz.annotations()) { if (a.annotationType().name().equals("ExportPackage")) { for (AnnotationDesc.ElementValuePair p : a.elementValues()) { pkg = p.value().toString(); break; } } } pkg = pkg.replaceAll("\"", ""); return pkg; }
private PackageDoc[] getPackages(PackageDoc[] orig, String... types) { List<PackageDoc> wrapped = new ArrayList<PackageDoc>(); for (PackageDoc p : orig) { // wrap the package ClassLoader loader = WonderlandDoclet.class.getClassLoader(); Class<?>[] interfaces = new Class<?>[] { PackageDoc.class }; InvocationHandler handler = new PackageDocWrapper(p, "ExperimentalAPI"); PackageDoc pkg = (PackageDoc) Proxy.newProxyInstance(loader, interfaces, handler); if (pkg.allClasses().length > 0) { wrapped.add(pkg); } } return wrapped.toArray(new PackageDoc[0]); }
/** * Appends to the current document a valid markdown link * that aims to be the shortest one, by using the * {@link #getPath(String, String)} method. The * built URL will start from the given ``source`` * package to the given ``target`` class. * * @param source Source package to start URL from. * @param target Target class to reach from this package. */ public void classLink(final PackageDoc source, final ClassDoc target) { if (target.isIncluded()) { final String path = getPath(source.name(), target.containingPackage().name()); final StringBuffer urlBuilder = new StringBuffer(); urlBuilder .append(path) .append(target.simpleTypeName()) .append(MarkdownDocumentBuilder.LINK_EXTENSION); link(target.simpleTypeName(), urlBuilder.toString()); } else { // TODO : Process external link here. // TODO : Use marklet-directory project when done. italic(target.qualifiedName()); } }
/** * Appends to the current document the list of parameters * from the given ``type`` if any. * * @param source Source package to start URL from. * @param type Target type to append parameters from. */ private void parameterLinks(final PackageDoc source, final Type type) { final ParameterizedType invocation = type.asParameterizedType(); if (invocation != null) { final Type [] types = invocation.typeArguments(); if (types.length > 0) { character('<'); for (int i = 0; i < types.length; i++) { parameterLink(source, types[i]); if (i < types.length - 1) { text(", "); } } character('>'); } } }
/** * Appends to the current document the given type parameter * as a valid markdown link. * * @param source Source package to start URL from. * @param type Target type parameter to reach from this package. */ private void parameterLink(final PackageDoc source, final Type type) { final WildcardType wildcard = type.asWildcardType(); if (wildcard != null) { character('?'); } else { final TypeVariable variableType = type.asTypeVariable(); if (variableType != null) { final Type [] bounds = variableType.bounds(); if (bounds.length > 0) { text("? extends "); for (int i = 0; i < bounds.length; i++) { typeLink(source, bounds[i]); if (i < bounds.length - 1) { text(" & "); } } } } else { typeLink(source, type); } } }
/** * Appends to the current document the class * header. Consists in the class name with a * level 1 header, the class hierarchy, and * the comment text. */ private void header() { title(); newLine(); newLine(); final PackageDoc packageDoc = classDoc.containingPackage(); final String packageName = packageDoc.name(); item(); text(MarkletConstant.PACKAGE); character(' '); link(packageName, MarkletConstant.README_LINK); newLine(); item(); classHierarchy(); interfaceHierarchy(); newLine(); newLine(); description(classDoc); newLine(); newLine(); }
/** * @return the full JSON for the given PackageDoc */ protected JSONObject processPackageDoc(PackageDoc packageDoc) { if (packageDoc == null) { return null; } JSONObject retMe = processDoc(packageDoc); retMe.put("annotations", processAnnotationDescs(packageDoc.annotations())); retMe.put("annotationTypes", processAnnotationTypeDocStubs(packageDoc.annotationTypes())); retMe.put("enums", processClassDocStubs(packageDoc.enums())); retMe.put("errors", processClassDocStubs(packageDoc.errors())); retMe.put("exceptions", processClassDocStubs(packageDoc.exceptions())); retMe.put("interfaces", processClassDocStubs(packageDoc.interfaces())); retMe.put("ordinaryClasses", processClassDocStubs(packageDoc.ordinaryClasses())); return retMe; }
@Override protected void doRenderOn(HtmlCanvas html) throws IOException { PackagePage page = PageRenderer.getPage(html); PackageDoc packageDoc = page.getPackageDoc(); html.div(class_("api_header")).p().content("package").h1().content(packageDoc.name())._div(); if (packageDoc.inlineTags() != null && packageDoc.inlineTags().length > 0) { html.h2().content("Overview"); html.p().render(new InlineTagsRenderer(generator, packageDoc.inlineTags(), packageDoc.position()))._p(); } renderTypes(packageDoc.interfaces(), "Interfaces", page, html); renderTypes(packageDoc.ordinaryClasses(), "Classes", page, html); renderTypes(packageDoc.errors(), "Exceptions", page, html); renderTypes(packageDoc.enums(), "Enums", page, html); renderTypes(packageDoc.annotationTypes(), "Annotation Types", page, html); }
public PackageDoc containingPackage() { Class outerClass = clazz; while (null != outerClass.getDeclaringClass()) { outerClass = outerClass.getDeclaringClass(); } String packageName = outerClass.getName(); int ndx = packageName.lastIndexOf('.'); if (ndx > 0) { packageName = packageName.substring(0, ndx); } else { packageName = ""; } PackageDoc result = Main.getRootDoc().findOrCreatePackageDoc(packageName); return result; }
public boolean set(String[] optionArr) { try { PackageMatcher packageMatcher = new PackageMatcher(); StringTokenizer tokenizer = new StringTokenizer(optionArr[2], ":"); while (tokenizer.hasMoreTokens()) { String packageWildcard = tokenizer.nextToken(); packageMatcher.addWildcard(packageWildcard); } SortedSet<PackageDoc> groupPackages = packageMatcher.filter(rootDoc.specifiedPackages()); packageGroups.add(new PackageGroup(optionArr[1], groupPackages)); return true; } catch (InvalidPackageWildcardException e) { return false; } }
/** * @param usedClassToPackagesMap ClassDoc to (PackageDoc to (UsageType to (Set of Doc))) */ private void addUsedBy(Map<ClassDoc,Map<PackageDoc,Map<UsageType,Set<Doc>>>> usedClassToPackagesMap, ClassDoc usedClass, UsageType usageType, Doc user, PackageDoc userPackage) { Map<PackageDoc,Map<UsageType,Set<Doc>>> packageToUsageTypeMap = usedClassToPackagesMap.get(usedClass); if (null == packageToUsageTypeMap) { packageToUsageTypeMap = new HashMap<PackageDoc,Map<UsageType,Set<Doc>>>(); usedClassToPackagesMap.put(usedClass, packageToUsageTypeMap); } Map<UsageType,Set<Doc>> usageTypeToUsersMap = packageToUsageTypeMap.get(userPackage); if (null == usageTypeToUsersMap) { usageTypeToUsersMap = new TreeMap<UsageType,Set<Doc>>(); packageToUsageTypeMap.put(userPackage, usageTypeToUsersMap); } Set<Doc> userSet = usageTypeToUsersMap.get(usageType); if (null == userSet) { userSet = new TreeSet<Doc>(); // FIXME: we need the collator from Main here usageTypeToUsersMap.put(usageType, userSet); } userSet.add(user); }
/** * Returns the XML node corresponding to the specified ClassDoc. * * @param doc The package to transform. */ private static XMLNode toPackageNode(PackageDoc doc) { XMLNode node = new XMLNode("package", doc); // Core attributes node.attribute("name", doc.name()); // Comments node.child(toShortComment(doc)); node.child(toComment(doc)); // Child nodes node.child(toAnnotationsNode(doc.annotations())); node.child(toStandardTags(doc)); node.child(toTags(doc)); node.child(toSeeNodes(doc.seeTags())); return node; }
/** * Process the package documentation. * * @param doc The package documentation. */ protected void processPackage(PackageDoc doc) { // (#1) Set foundDoc to false if possible. // foundDoc will be set to true when setRawCommentText() is called, if the method // is called again, JavaDoc will issue a warning about multiple sources for the // package documentation. If there actually *are* multiple sources, the warning // has already been issued at this point, we will, however, use it to set the // resulting HTML. So, we're setting it back to false here, to suppress the // warning. try { Field foundDoc = doc.getClass().getDeclaredField("foundDoc"); foundDoc.setAccessible(true); foundDoc.set(doc, false); } catch ( Exception e ) { printWarning(doc.position(), "Cannot suppress warning about multiple package sources: " + e + "\n" + "Please report this at https://github.com/Abnaxos/markdown-doclet/issues with the exact JavaDoc version you're using"); } defaultProcess(doc, true); }
/** * Returns a prefix for relative URLs from a documentation element relative to the * given package. This prefix can be used to refer to the root URL of the * documentation: * * ```java * doc = "<script type=\"text/javascript\" src=\"" * + rootUrlPrefix(classDoc.containingPackage()) + "highlight.js" * + "\"></script>"; *
*
return "";
StringBuilder buf = new StringBuilder(); buf.append("../"); for ( int i = 0; i < doc.name().length(); i++ ) { if ( doc.name().charAt(i) == '.' ) { buf.append("../"); } } return buf.toString();
```
/** * Return the inverse path for a package. * For example, if the package is java.lang, * the inverse path is ../... */ public static DocPath forRoot(PackageDoc pd) { String name = (pd == null) ? "" : pd.name(); if (name.isEmpty()) return empty; return new DocPath(name.replace('.', '/').replaceAll("[^/]+", "..")); }
@Override public ProfilePackageSummaryWriter getProfilePackageSummaryWriter( PackageDoc arg0, PackageDoc arg1, PackageDoc arg2, Profile arg3) throws Exception { // TODO Auto-generated method stub return null; }
Context(Configuration configuration, Set<PackageDoc> containingPackagesSeen, LayoutParser layoutParser) { this.configuration = configuration; this.containingPackagesSeen = containingPackagesSeen; this.layoutParser = layoutParser; }
/** * Gets a link:PrintWriter[] to export the documentation of a class or package * to an AsciiDoc file. * * @param packageDoc the package documentation object that will be the package that the documentation * is being exported or the package of the class that its documentation * is being exported * @param name the name of the AsciiDoc file to export the documentation to */ private PrintWriter getWriter(PackageDoc packageDoc, String name) throws FileNotFoundException { File packageDirectory = new File(getOutputDir() + packageDoc.name().replace('.', File.separatorChar)); if(!packageDirectory.exists() && !packageDirectory.mkdirs()){ throw new RuntimeException("The directory was not created due to unknown reason."); } File file = new File(packageDirectory, name + ".adoc"); return new PrintWriter(new OutputStreamWriter(new FileOutputStream(file))); }
/** * Reconstitute the class name from the given class JavaDoc object. * * @param doc the Javadoc model for the given class. * @return The (string) class name of the given class. */ protected static String getClassName(ProgramElementDoc doc, boolean binaryName) { PackageDoc containingPackage = doc.containingPackage(); String className = doc.name(); if (binaryName) { className = className.replaceAll("\\.", "\\$"); } return containingPackage.name().length() > 0 ? String.format("%s.%s", containingPackage.name(), className) : String.format("%s", className); }
/** * Instantiates a new Domain model. * */ private SubDomain(final PackageDoc doc, final AnnotationDesc desc) { this.codeName = doc.name(); for (AnnotationDesc.ElementValuePair member : desc.elementValues()) { switch (member.element().name()) { case "name": this.title = getString(member); break; case "description": this.description = getString(member); break; default: } } this.links = Arrays.stream(doc.annotations()) .filter(ad -> isAnnotatedAsLink(ad.annotationType())) .map(LinkModel::makeByLink) .collect(Collectors.toList()); this.links.addAll(Arrays.stream(doc.annotations()) .filter(ad -> isAnnotatedAsLinks(ad.annotationType())) .map(LinkModel::makeByLinks) .flatMap(Collection::stream) .collect(Collectors.toList()) ); this.concepts = new ArrayList<>(); }
void add(PackageDoc doc) { if (doc.name().startsWith(codeName)) { Arrays.stream(doc.allClasses()) .map(ConceptModel::makeBy) .filter(Optional::isPresent) .map(Optional::get) .forEach(concepts::add); } }
/** * Make by optional. * * @param aPackage the a package * @return the optional */ static Optional<SubDomain> makeBy(final PackageDoc aPackage) { final List<AnnotationDesc> types = Arrays.stream(aPackage.annotations()) .filter(ad -> isAnnotatedAsBoundedContext(ad.annotationType())) .collect(Collectors.toList()); switch (types.size()) { case 0: return Optional.empty(); case 1: return Optional.of(new SubDomain(aPackage, types.get(0))); default: throw new IllegalStateException("There are more than one BoundedContext annotations"); } }
public DiagramRenderer addPackage(PackageDoc packageDoc) { try (GlobalPosition gp = new GlobalPosition(packageDoc)) { DiagramRenderer packageDiagram = new DiagramRenderer(config); packageDiagram.children.addAll(children); packageDiagram.children.add(new PackageRenderer(this, packageDoc)); addGlobalCommandsTo(packageDiagram.children); return packageDiagram; } }
/** * Try to determine the source directory for the given package by * looking at the path specified by -sourcepath, or the current * directory if -sourcepath hasn't been specified. * * @throws IOException if the source directory couldn't be * located. * * @return List of File */ protected List getPackageSourceDirs(PackageDoc packageDoc) throws IOException { if (null == sourcePaths) { for (int i=0; i<rootDoc.options().length; ++i) { if ("-sourcepath".equals(rootDoc.options()[i][0]) || "-s".equals(rootDoc.options()[i][0])) { sourcePaths = new LinkedHashSet(); String sourcepathString = rootDoc.options()[i][1]; StringTokenizer st = new StringTokenizer(sourcepathString, File.pathSeparator); while (st.hasMoreTokens()) { sourcePaths.add(new File(st.nextToken())); } } } if (null == sourcePaths) { sourcePaths = new LinkedHashSet(); sourcePaths.add(new File(System.getProperty("user.dir"))); } } String packageSubDir = packageDoc.name().replace('.', File.separatorChar); Iterator it = sourcePaths.iterator(); List result = new LinkedList(); while (it.hasNext()) { File pathComponent = (File)it.next(); File packageDir = new File(pathComponent, packageSubDir); if (packageDir.exists()) { result.add(packageDir); } } if (result.isEmpty()) { throw new IOException("Couldn't locate source directory for package " + packageDoc.name()); } else { return result; } }
protected Set getAllPackages() { if (null == this.allPackages) { allPackages = new TreeSet(); PackageDoc[] specifiedPackages = rootDoc.specifiedPackages(); for (int i=0; i<specifiedPackages.length; ++i) { allPackages.add(specifiedPackages[i]); } ClassDoc[] specifiedClasses = rootDoc.specifiedClasses(); for (int i=0; i<specifiedClasses.length; ++i) { allPackages.add(specifiedClasses[i].containingPackage()); } } return this.allPackages; }
protected boolean omitPackageQualifier(PackageDoc packageDoc) { if (!optionNoQualifier.isSpecified()) { return false; } else { return optionNoQualifier.match(packageDoc); } }
/** * Return a sorted, filtered set of packages. A package from the * array given will be put into the output list if it matches one * or more of the wildcards added to this PackageMatcher before. */ public SortedSet filter(PackageDoc[] packageDocs) { SortedSet result = new TreeSet(); for (int i=0; i<packageDocs.length; ++i) { if (match(packageDocs[i])) { result.add(packageDocs[i]); } } return result; }
/** * Return true when the given PackageDoc matches one or more of * the wildcard added to this PackageMatcher before. */ public boolean match(PackageDoc packageDoc) { Iterator it = patterns.iterator(); while (it.hasNext()) { Pattern pattern = (Pattern)it.next(); Matcher matcher = pattern.matcher(packageDoc.name()); if (matcher.matches()) { return true; } } return false; }
public SortedSet filter(PackageDoc[] packages) { if (null != packageMatcher) { return packageMatcher.filter(packages); } else { SortedSet result = new TreeSet(); for (int i=0; i<packages.length; ++i) { result.add(packages[i]); } return result; } }
public boolean match(PackageDoc packageDoc) { if (null != packageMatcher) { return packageMatcher.match(packageDoc); } else { return true; } }