blob: b783bafda6d2979bba5aeac37bf2aabd16aea4ed [file] [log] [blame]
package org.codehaus.groovy.tools
import groovy.xml.StreamingMarkupBuilder
import java.io.File
import com.thoughtworks.qdox.JavaDocBuilder
import com.thoughtworks.qdox.model.JavaSource
import com.thoughtworks.qdox.model.JavaClass
import com.thoughtworks.qdox.model.JavaMethod
import com.thoughtworks.qdox.model.JavaParameter
import com.thoughtworks.qdox.model.Type
import java.util.*;
/**
* Generate documentation about the methods provided by the Groovy Development Kit
* enhancing the standard JDK classes.
*
* @author Guillaume Laforge, John Wilson
*/
class DocGenerator
{
File file
File outputFile
JavaDocBuilder builder
DocGenerator(File fileToParse, File outputFile)
{
this.file = fileToParse
this.outputFile = outputFile
}
/**
* Parse the DefaultGroovyMethods class to build a graph representing the structure of the class,
* with its methods, javadoc comments and tags.
*/
private void parse()
{
def reader = file.newReader()
builder = new JavaDocBuilder()
builder.addSource(reader)
}
/**
* Builds an HTML page from the structure of DefaultGroovyMethods.
*/
def generate() {
parse()
def sources = builder.getSources()
def firstSource = sources[0]
def classes = firstSource.getClasses()
def groovyMeth = classes[0]
// categorize all groovy methods per core JDK class to which it applies
def jdkEnhancedClasses = [:]
def methods = groovyMeth.getMethods()
def start = System.currentTimeMillis();
for (method in methods) {
if (method.isPublic() && method.isStatic()) {
def parameters = method.getParameters()
def jdkClass = parameters[0].getType().toString()
if (jdkEnhancedClasses.containsKey(jdkClass)) {
List l = jdkEnhancedClasses[jdkClass];
l.add(method)
}
else
jdkEnhancedClasses[jdkClass] = [method]
}
}
//start = System.currentTimeMillis();
println " added classes in ${System.currentTimeMillis() - start} ms"
def headElement = { head {
mkp.comment 'generated by Groovy using Streaming Markup'
title 'GDK : Groovy methods'
style(['type':'text/css'], ' @import url("./style/maven-base.css"); ')
style(['type':'text/css'], ' @import url("http://codehaus.org/codehaus-style.css"); ')
}
}
def sortedClasses = new TreeSet(jdkEnhancedClasses.keySet())
def ind = 0
def cellsInRow = 4
// Split sortedClasses into list of 4-element lists
def rowList = sortedClasses.inject([]) { list, item ->
if (ind++ % cellsInRow == 0)
list << [item]
else
list[-1] << item
return list
}
def classLinks = { mkp.yield {
def classCounter = 0
table(width:'100%') {
tr {
th(colspan:"${cellsInRow}", "Groovy JDK classes")
}
for (row in rowList) {
if (row.size() < cellsInRow) {
(cellsInRow - row.size()).times { row << "" }
}
tr {
for (className in row) {
td(width:'25%') {
a(href:"#cls${classCounter}", "${className}")
}
classCounter++;
}
}
}
}
}
}
def summary = { mkp.yield {
def counter = 0
def classCounter = 0
// lets iterate in sorted class name order
for (String className in sortedClasses) {
p { a(name:"cls${classCounter}") }
b className
classCounter++
def listOfMethods = jdkEnhancedClasses[className]
listOfMethods.sort{ it.name }
table(width:'100%') {
for (JavaMethod meth in listOfMethods) {
counter++
tr {
td(width:'30%') {
mkp.yield getReturnType(meth)
}
td(width:'70%') {
a(href:"#meth${counter}") {
mkp.yield meth.getName()
}
mkp.yield "(${getParametersDecl(meth)})"
}
}
}
}
}
}
}
def details = { mkp.yield {
def counter = 0
for (className in sortedClasses) {
h2 className
def listOfMethods = jdkEnhancedClasses[className]
listOfMethods.sort{ it.name }
for (JavaMethod meth in listOfMethods) {
counter++
a(name:"meth${counter}")
p {
b "${getReturnType(meth)} ${meth.getName()}(${getParametersDecl(meth)})"
}
ul {
//
// Java comments can contain markup - pass it through as is
//
mkp.yieldUnescaped "${getComment(meth)} "
ul {
def params = meth.getTags()
def count = 0
for (param in params) {
if (count++ != 0 && param.getName() != "throws" && param.getName() != "return") {
li "${param.getName()} ${param.getValue()}"
}
}
def returnType = getReturnType(meth)
if (returnType != "") {
if (returnType != "void") {
li {
b "returns"
mkp.yield ": ${returnType}"
def returnTag = meth.getTagByName("return")
if (returnTag != null) {
mkp.yield " - "
i returnTag.getValue()
}
}
}
def exceptions = meth.getExceptions()
for (ex in exceptions) {
if (ex != null) {
li {
b "throws"
mkp.yield ": ${ex}"
def exMsg = meth.getTagByName("throws")
if (exMsg != null) {
mkp.yield " - "
i exMsg.getValue()
}
}
}
}
}
}
}
}
}
}
}
def bodyElement = { body {
h1 'Groovy JDK methods'
p 'New methods added to the JDK to make it more groovy.'
mkp.yield classLinks
mkp.yield summary
mkp.yield details
}
}
outputFile.getParentFile().mkdirs()
outputFile.newPrintWriter() << new StreamingMarkupBuilder().bind{ html {
mkp.yield headElement
mkp.yield bodyElement
}
}
}
/**
* Retrieves a String representing the return type
*/
private getReturnType(method)
{
def returnType = method.getReturns()
if (returnType != null) {
return returnType.toString()
} else {
return ""
}
}
/**
* Retrieve a String representing the declaration of the parameters of the method passed as parameter.
*
* @param method a method
* @return the declaration of the method (long version)
*/
private getParametersDecl(method)
{
getParameters(method).collect{ "${it.getType()} ${it.getName()}" }.join(", ")
}
/**
* Retrieve the parameters of the method.
*
* @param method a method
* @return a list of parameters without the first one
*/
private getParameters(method)
{
if (method.getParameters().size() > 1)
return method.getParameters().toList()[1..-1]
else
return []
}
/**
* Retrieve the JavaDoc comment associated with the method passed as parameter.
*
* @param method a method
* @return the JavaDoc comment associated with this method
*/
private getComment(method)
{
def ans = method.getComment()
if (ans == null) return ""
return ans
}
/**
* Main entry point.
*/
static void main(args)
{
def defaultGroovyMethodSource =
//new File("D:/cvs-groovy/groovy/groovy-core/src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java")
new File("src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java")
def outFileName =
//new File("D:/cvs-groovy/groovy/groovy-core/target/html/groovy-jdk.html")
new File("target/html/groovy-jdk.html")
def start = System.currentTimeMillis();
def docGen = new DocGenerator(defaultGroovyMethodSource, outFileName)
docGen.generate()
def end = System.currentTimeMillis();
println "Done. in ${end - start} millis"
}
}