pax_global_header00006660000000000000000000000064121043050430014502gustar00rootroot0000000000000052 comment=9aa0966e537fef13822cbfc549d2baba2cd58421 gradle-1.4/000077500000000000000000000000001210430504300126045ustar00rootroot00000000000000gradle-1.4/build.gradle000066400000000000000000000153521210430504300150710ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.gradle.build.Install import org.gradle.build.BuildTypes import org.gradle.build.TestReportAggregator defaultTasks 'assemble' apply plugin: 'java-base' archivesBaseName = 'gradle' extensions.buildTypes = new BuildTypes(project) buildTypes { sanityCheck "classes", "doc:checkstyleApi", "codeQuality", "docs:check" // The minimum to be run before check-in preCommitBuild "doc:checkstyleApi", "docs:check", "codeQuality", "classes", "test", noDistTests: true quickCheck "doc:checkstyleApi", "docs:check", "codeQuality", "classes", "test", noDistTests: true // A full (in-process) test developerBuild "check" // Used by the first phase of the build pipeline quickTest "test", "integTest", noDistTests: true, noDocsTests: true // Used for builds to test the code on certain platforms platformTest "test", "forkingIntegTest", noDistTests: true, noDocsTests: true, useIncomingDistributions: true // Tests using the daemon mode daemonTest "daemonIntegTest", noDistTests: true, noDocsTests: true, useIncomingDistributions: true // Run the integration tests using the parallel executer parallelTest "parallelIntegTest", noDistTests: true, noDocsTests: true, useIncomingDistributions: true // Run the performance tests performanceTest "performance:integTest", useIncomingDistributions: true // Run the performance tests localPerformanceTest "performance:integTest" // Used for cross version tests on CI crossVersionTest "forkingIntegTest", crossVersionTestsOnly: "", testAllVersions: "", noDistTests: true, useIncomingDistributions: true // Used to build production distros and smoke test them packageBuild "verifyIsProductionBuildEnvironment", "clean", "buildDists", "distributions:integTest" // Used to build production distros and smoke test them promotionBuild "verifyIsProductionBuildEnvironment", "clean", "docs:check", "buildDists", "distributions:integTest", "uploadArchives" } ext { jvm = org.gradle.internal.jvm.Jvm.current() javaVersion = JavaVersion.current() isCiServer = System.getenv().containsKey("TEAMCITY_VERSION") isWindows = org.gradle.internal.os.OperatingSystem.current().windows if (project.hasProperty("maxParallelForks")) { project.maxParallelForks = Integer.valueOf(project.maxParallelForks, 10) } else { ext.maxParallelForks = Math.max(2, (int) (Runtime.runtime.availableProcessors() / 2)) } if (project.hasProperty("useIncomingDistributions")) { project.useIncomingDistributions = true } else { ext.useIncomingDistributions = false } internalProjects = subprojects.findAll { it.name.startsWith("internal") || it.name in ["integTest", "distributions"] } groovyProjects = subprojects publicGroovyProjects = groovyProjects - internalProjects publishedProjects = [project(':core'), project(':toolingApi'), project(':wrapper'), project(':baseServices'), project(':messaging')] pluginProjects = [ 'plugins', 'codeQuality', 'jetty', 'antlr', 'wrapper', 'osgi', 'maven', 'ide', 'announce', 'scala', 'sonar', 'signing', 'cpp', 'ear', 'javascript', 'buildComparison', 'diagnostics', 'reporting', 'publish', 'ivy' ].collect { project(it) } } apply from: "gradle/buildReceipt.gradle" apply from: "gradle/incomingDistributions.gradle" apply from: "gradle/versioning.gradle" apply from: "gradle/dependencies.gradle" apply from: "gradle/wrapper.gradle" apply from: "gradle/idea.gradle" apply from: "gradle/eclipse.gradle" apply from: "gradle/classycle.gradle" apply from: "gradle/noDependencyResolutionDuringConfiguration.gradle" allprojects { group = 'org.gradle' repositories { maven { url 'http://repo.gradle.org/gradle/libs' } } } subprojects { version = rootProject.version if (project in groovyProjects) { apply from: "$rootDir/gradle/groovyProject.gradle" apply from: "$rootDir/gradle/testWithUnknownOS.gradle" check.dependsOn ":docs:checkstyleApi" check.dependsOn "codeQuality" } if (project in publishedProjects) { apply from: "$rootDir/gradle/publish.gradle" } apply from: "$rootDir/gradle/codeQuality.gradle" if (isCiServer) { reporting.baseDir "$rootProject.reporting.baseDir/${path.replaceFirst(':', '').replaceAll(':', '.')}" } } configurations { runtime { visible = false } plugins { visible = false } testRuntime { extendsFrom runtime extendsFrom plugins } } dependencies { runtime project(':launcher') runtime project(':wrapper') plugins pluginProjects plugins project(':coreImpl') } task verifyIsProductionBuildEnvironment << { assert javaVersion.java7 : "Must use a Java 7 compatible JVM to perform this build. Current JVM is ${jvm}" def systemCharset = java.nio.charset.Charset.defaultCharset().name() assert systemCharset == "UTF-8" : "Platform encoding must be UTF-8. Is currently $systemCharset. Set -Dfile.encoding=UTF-8." } task waitForDaemonsToDie { if (!project.hasProperty("noWaitForDaemonsToDie")) { if (isWindows && isCiServer) { gradle.startParameter.taskNames.add(0, it.path) } doLast { def mins = 2 println "I'm waiting for $mins mins so that existing daemons can die with honour. It's a workaround until we fix it properly." sleep mins * 60 * 1000 } } } task aggregateTestReports(type: TestReportAggregator) { testReportDir = reporting.file("tests") testResultsDir = file("${buildDir}/test-results") projects = subprojects } evaluationDependsOn ":distributions" task install(type: Install) { description = 'Installs the minimal distribution into directory $gradle_installPath' group = 'build' with project(":distributions").binDistImage installDirPropertyName = 'gradle_installPath' } task installAll(type: Install) { description = 'Installs the full distribution into directory $gradle_installPath' group = 'build' with project(":distributions").allDistImage installDirPropertyName = 'gradle_installPath' } apply from: "gradle/intTestImage.gradle"gradle-1.4/buildSrc/000077500000000000000000000000001210430504300143535ustar00rootroot00000000000000gradle-1.4/buildSrc/build.gradle000066400000000000000000000031421210430504300166320ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ apply plugin: 'groovy' apply plugin: 'checkstyle' apply plugin: 'codenarc' apply plugin: 'idea' apply plugin: 'eclipse' repositories { maven { url 'http://repo.gradle.org/gradle/libs' } mavenCentral() } dependencies { compile gradleApi() compile 'com.google.guava:guava:11.0.2@jar' compile 'commons-lang:commons-lang:2.6@jar' groovy localGroovy() testCompile 'junit:junit:4.11@jar' testCompile 'org.spockframework:spock-core:0.7-groovy-1.8@jar', 'cglib:cglib-nodep:2.2', 'org.objenesis:objenesis:1.2' compile "org.pegdown:pegdown:1.1.0" compile "org.jsoup:jsoup:1.6.3" //below dependency was deployed to the repo.gradle.org //it's built from sources at: https://github.com/szczepiq/jarjar //if code changes are needed in this library we need to figure out a better way of distributing them. compile "org.gradle.jarjar:jarjar:1.2.1" } apply from: '../gradle/compile.gradle' apply from: '../gradle/codeQuality.gradle' apply from: '../gradle/classycle.gradle' gradle-1.4/buildSrc/src/000077500000000000000000000000001210430504300151425ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/000077500000000000000000000000001210430504300160665ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/000077500000000000000000000000001210430504300174135ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/000077500000000000000000000000001210430504300202025ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/000077500000000000000000000000001210430504300214405ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/000077500000000000000000000000001210430504300225375ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/BuildTypes.groovy000066400000000000000000000051441210430504300260760ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build import org.gradle.api.Project import org.gradle.api.GradleException class BuildTypes { private final Project project private final activeNames = [] BuildTypes(Project project) { this.project = project } List getActive() { new LinkedList(activeNames) } boolean isActive(String name) { name in activeNames } def methodMissing(String name, args) { args = args.toList() def properties = [:] if (args.first() instanceof Map) { properties.putAll(args.remove(0)) } def tasks = [] def configure = {} args.each { if (it instanceof Closure) { configure = it } else { tasks << it.toString() } } register(name, tasks, properties, configure) } private register(name, tasks, projectProperties, configure) { project.task(name) { group = "Build Type" def abbreviation = name[0] + name[1..-1].replaceAll("[a-z]", "") def taskNames = project.gradle.startParameter.taskNames def usedName = taskNames.find { it in [name, abbreviation] } if (usedName) { activeNames << name def index = taskNames.indexOf(usedName) taskNames.remove((int)index) tasks.reverse().each { taskNames.add(index, it) } projectProperties.each { k, v -> if (!project.hasProperty(k)) { project.ext."$k" = null } project.properties."$k" = v } project.configure(project.gradle.startParameter, configure) } doFirst { throw new GradleException("'$name' is a build type and has to be invoked directly, and its name can only be abbreviated to '$abbreviation'.") } } } }gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/Install.groovy000066400000000000000000000040741210430504300254210ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build import org.gradle.api.tasks.Sync class Install extends Sync { String installDirPropertyName File installDir def Install() { addPropertyCheck() doLast { ant.chmod(file: "$installDir/bin/gradle", perm: 'ugo+x') } } private void addPropertyCheck() { project.gradle.taskGraph.whenReady {graph -> if (graph.hasTask(path)) { // Do this early to ensure that the properties we need have been set, and fail early if (!project.hasProperty(installDirPropertyName)) { throw new RuntimeException("You can't install without setting the $installDirPropertyName property.") } installDir = project.file(this.project."$installDirPropertyName") if (installDir.file) { throw new RuntimeException("Install directory $installDir does not look like a Gradle installation. Cannot delete it to install.") } if (installDir.directory) { File libDir = new File(installDir, "lib") if (!libDir.directory || !libDir.list().findAll { it.matches('gradle.*\\.jar')}) { throw new RuntimeException("Install directory $installDir does not look like a Gradle installation. Cannot delete it to install.") } } into installDir } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/JarJar.groovy000066400000000000000000000035721210430504300251660ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build import com.tonicsystems.jarjar.Main as JarJarMain import org.gradle.api.* import org.gradle.api.file.* import org.gradle.api.tasks.* class JarJar extends DefaultTask { @InputFiles FileCollection inputJars @OutputDirectory File outputDir @Input def rules = [:] @Input def keeps = [] @TaskAction void nativeJarJar() { File tempRuleFile = new File(getTemporaryDir(), "jarjar.rules.txt") writeRuleFile(tempRuleFile) if (inputJars.empty) { throw new GradleException("Unable to execute JarJar task because there are no input jars."); } for(file in inputJars) { JarJarMain.main("process", tempRuleFile.absolutePath, file.absolutePath, new File(outputDir, "jarjar-$file.name").absolutePath) } } void rule(String pattern, String result) { rules[pattern] = result } void keep(String pattern) { keeps << pattern } private void writeRuleFile(File ruleFile) { ruleFile.withPrintWriter { writer -> rules.each {pattern, result -> writer.println("rule ${pattern} ${result}") } keeps.each {pattern -> writer.println("keep ${pattern}") } } } }gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/JarJarJar.groovy000066400000000000000000000044151210430504300256200ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build import org.gradle.api.tasks.bundling.Jar import org.gradle.api.* import org.gradle.api.file.* import org.gradle.api.tasks.* import com.tonicsystems.jarjar.Main as JarJarMain /* * a Jar task that performs JarJar repackaging after archive is created * */ class JarJarJar extends Jar { @Input def rules = [:] @Input def keeps = [] public JarJarJar() { doLast { executeJarJar(); } doLast { fixEmptyFoldersWithJarJar() } } void executeJarJar() { File tempRuleFile = new File(getTemporaryDir(), "jarjar.rules.txt") writeRuleFile(tempRuleFile) JarJarMain.main("process", tempRuleFile.absolutePath, getArchivePath().absolutePath, getArchivePath().absolutePath) } void fixEmptyFoldersWithJarJar() { def withNoEmptyDirs = "${getTemporaryDir()}/withNoEmptyDirs" project.copy{ from project.zipTree(getArchivePath().absolutePath) into withNoEmptyDirs includeEmptyDirs = false } project.ant { zip(destfile: getArchivePath(), update: false) { fileset(dir: withNoEmptyDirs) } } } void rule(String pattern, String result) { rules[pattern] = result } void keep(String pattern) { keeps << pattern } private void writeRuleFile(File ruleFile) { ruleFile.withPrintWriter { writer -> rules.each {pattern, result -> writer.println("rule ${pattern} ${result}") } keeps.each {pattern -> writer.println("keep ${pattern}") } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/TestReportAggregator.groovy000066400000000000000000000027061210430504300301310ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build import org.gradle.api.tasks.Copy import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.testing.Test; class TestReportAggregator extends Copy { def projects File testResultsDir @OutputDirectory File testReportDir def TestReportAggregator() { dependsOn { testTasks } from { inputTestResultDirs } into { testResultsDir } } @TaskAction def aggregate() { def report = new org.gradle.api.internal.tasks.testing.junit.report.DefaultTestReport(testReportDir: testReportDir, testResultsDir: testResultsDir) report.generateReport() } def getTestTasks() { projects.collect { it.tasks.withType(Test) }.flatten() } def getInputTestResultDirs() { testTasks*.testResultsDir } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/000077500000000000000000000000001210430504300234675ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/AssembleSampleDocsTask.groovy000066400000000000000000000102641210430504300312720ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import groovy.xml.DOMBuilder import org.gradle.api.file.FileVisitDetails import org.gradle.api.tasks.SourceTask import org.gradle.api.tasks.TaskAction import org.w3c.dom.Document import javax.xml.parsers.DocumentBuilderFactory import org.w3c.dom.Element import groovy.xml.dom.DOMCategory import org.gradle.api.tasks.OutputFile import groovy.xml.XmlUtil /** * Generates a chapter containing a summary of the readme files for the samples. */ class AssembleSamplesDocTask extends SourceTask { @OutputFile File destFile @TaskAction def generate() { List samples = [] use(DOMCategory) { // Collect up the source sample.xml files source.visit {FileVisitDetails fvd -> if (fvd.isDirectory()) { return } Element sourceDoc; fvd.file.withReader {Reader reader -> sourceDoc = DOMBuilder.parse(reader).documentElement } Element firstPara = sourceDoc.para[0] if (!firstPara) { throw new RuntimeException("Source file $fvd.file does not contain any elements.") } samples << [ dir: fvd.relativePath.parent as String, firstPara: firstPara, doc: sourceDoc, include: sourceDoc['*'].size() > 1 ] } samples = samples.sort { it.dir } Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() DomBuilder builder = new DomBuilder(doc) builder.appendix(id: 'sample_list') { title('Gradle Samples') para { text('Listed below are some of the stand-alone samples which are included in the Gradle distribution. ') text('You can find these samples in the ') filename { replaceable('GRADLE_HOME') text('/samples') } text(' directory of the distribution.') } table { title('Samples included in the distribution') thead { td('Sample') td('Description') } samples.each {sample -> tr { td { if (sample.include) { link(linkend: sample.hashCode()) { filename(sample.dir) } } else { filename(sample.dir) } } td(sample.firstPara) } } } samples.each {sample -> if (!sample.include) { return } section(id: sample.hashCode()) { title { text('Sample ') filename(sample.dir) } sample.doc.childNodes.each {n -> appendChild n } } } } destFile.withOutputStream {OutputStream stream -> XmlUtil.serialize(doc.documentElement, stream) } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/BuildableDOMCategory.groovy000066400000000000000000000053621210430504300306650ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import org.w3c.dom.Element import org.w3c.dom.Node class BuildableDOMCategory { public static void setText(Element element, String value) { while (element.hasChildNodes()) { element.removeChild(element.getFirstChild()) } element.appendChild(element.ownerDocument.createTextNode(value)) } public static void setChildren(Node element, Closure cl) { while (element.hasChildNodes()) { element.removeChild(element.getFirstChild()) } leftShift(element, cl) } public static def leftShift(Node parent, Closure cl) { DomBuilder builder = new DomBuilder(parent) cl.delegate = builder cl.call() return builder.elements[0] } public static void leftShift(Node parent, Node node) { parent.appendChild(parent.ownerDocument.importNode(node, true)) } public static void addFirst(Node parent, Closure cl) { DomBuilder builder = new DomBuilder(parent.ownerDocument, null) cl.delegate = builder cl.call() def firstChild = parent.firstChild builder.elements.each { element -> parent.insertBefore(element, firstChild) } } public static void addBefore(Node sibling, Closure cl) { DomBuilder builder = new DomBuilder(sibling.ownerDocument, null) cl.delegate = builder cl.call() def parent = sibling.parentNode builder.elements.each { element -> parent.insertBefore(element, sibling) } } public static void addBefore(Element sibling, Node n) { def parent = sibling.parentNode parent.insertBefore(n, sibling) } public static Object addAfter(Element sibling, Closure cl) { DomBuilder builder = new DomBuilder(sibling.ownerDocument, null) cl.delegate = builder cl.call() def parent = sibling.parentNode def next = sibling.nextSibling builder.elements.each { element -> parent.insertBefore(element, next) } return builder.elements.size() == 1 ? builder.elements[0] : builder.elements } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/DocGenerationException.java000066400000000000000000000015631210430504300307370ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs; import org.gradle.api.internal.Contextual; @Contextual public class DocGenerationException extends RuntimeException { public DocGenerationException(String message, Throwable throwable) { super(message, throwable); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/Docbook2XHtml.groovy000077500000000000000000000055251210430504300273670ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import org.gradle.api.InvalidUserDataException import org.gradle.api.file.FileCollection import org.gradle.api.file.FileVisitDetails import org.gradle.util.ClasspathUtil import org.gradle.api.tasks.* import org.gradle.api.logging.LogLevel class Docbook2Xhtml extends SourceTask { @InputFiles FileCollection classpath @OutputFile @Optional File destFile @OutputDirectory @Optional File destDir @InputDirectory File stylesheetsDir String stylesheetName @InputFiles @Optional FileCollection resources @TaskAction def transform() { if (!((destFile != null) ^ (destDir != null))) { throw new InvalidUserDataException("Must specify exactly 1 of output file or dir.") } logging.captureStandardOutput(LogLevel.INFO) logging.captureStandardError(LogLevel.INFO) source.visit { FileVisitDetails fvd -> if (fvd.isDirectory()) { return } File result if (destFile) { result = destFile } else { File outFile = fvd.relativePath.replaceLastName(fvd.file.name.replaceAll('.xml$', '.html')).getFile(destDir) outFile.parentFile.mkdirs() result = outFile } project.javaexec { main = XslTransformer.name args new File(stylesheetsDir, stylesheetName).absolutePath args fvd.file.absolutePath args result.absolutePath args destDir ?: "" jvmArgs '-Xmx256m' classpath ClasspathUtil.getClasspathForClass(XslTransformer) classpath this.classpath classpath new File(stylesheetsDir, 'extensions/xalan27.jar') systemProperty 'xslthl.config', new File("$stylesheetsDir/highlighting/xslthl-config.xml").toURI() systemProperty 'org.apache.xerces.xni.parser.XMLParserConfiguration', 'org.apache.xerces.parsers.XIncludeParserConfiguration' } } if (resources) { project.copy { into this.destDir ?: destFile.parentFile from resources } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/DomBuilder.groovy000066400000000000000000000054031210430504300267660ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import org.w3c.dom.Document import org.w3c.dom.Element import org.w3c.dom.Node import org.w3c.dom.NodeList class DomBuilder extends BuilderSupport { Document document Node parent List elements = [] def DomBuilder(Document document) { this.document = document this.parent = document } def DomBuilder(Node parent) { this.document = parent.ownerDocument this.parent = parent } def DomBuilder(Document document, Node parent) { this.document = document this.parent = parent } protected Element createNode(Object name) { Element element = document.createElement(name as String) if (getCurrent() == null) { elements << element parent?.appendChild(element) } return element } protected Element createNode(Object name, Map attributes) { Element element = createNode(name) attributes.each {key, value -> element.setAttribute(key as String, value as String) } return element } protected Element createNode(Object name, Map attributes, Object value) { Element element = createNode(name, attributes) if (value instanceof Node) { element.appendChild(document.importNode(value, true)) } else { element.appendChild(document.createTextNode(value as String)) } return element } protected Element createNode(Object name, Object value) { return createNode(name, [:], value) } protected void setParent(Object parent, Object child) { parent.appendChild(child) } def appendChild(Node node) { if (!current) { elements << (Element) document.importNode(node, true) } else { current.appendChild(document.importNode(node, true)) } } def appendChildren(Iterable nodes) { nodes.each { appendChild(it) } } def appendChildren(NodeList nodes) { nodes.each { appendChild(it) } } def text(String text) { current.appendChild(document.createTextNode(text)) } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/ExtractSnippetsTask.groovy000066400000000000000000000120361210430504300307230ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import java.util.regex.Matcher import java.util.regex.Pattern import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.SourceTask import org.gradle.api.tasks.OutputDirectory import org.gradle.api.file.FileVisitDetails /** * Produces the snippets files for a set of sample source files. */ public class ExtractSnippetsTask extends SourceTask { @OutputDirectory File destDir @OutputDirectory File snippetsDir @TaskAction def extract() { source.visit { FileVisitDetails details -> String name = details.relativePath.pathString if (details.file.isDirectory()) { File destDir = new File(destDir, name) destDir.mkdirs() destDir = new File(snippetsDir, name) destDir.mkdirs() } else { File srcFile = details.file File destFile = new File(destDir, name) destFile.parentFile.mkdirs() if (['.jar', '.zip', '.gpg'].find{ name.endsWith(it) }) { destFile.withOutputStream { it.write(srcFile.readBytes()) } return } Map writers = [ 0: new SnippetWriter(name, destFile).start(), 1: new SnippetWriter(name, new File(snippetsDir, name)).start() ] Pattern startSnippetPattern Pattern endSnippetPattern if (name.endsWith('.xml')) { startSnippetPattern = Pattern.compile('\\s*') endSnippetPattern = Pattern.compile('\\s*') } else { startSnippetPattern = Pattern.compile('\\s*//\\s*START\\s+SNIPPET\\s+(\\S+)\\s*') endSnippetPattern = Pattern.compile('\\s*//\\s*END\\s+SNIPPET\\s+(\\S+)\\s*') } try { // Can't use eachLine {} because it throws away blank lines srcFile.withReader {Reader r -> BufferedReader reader = new BufferedReader(r) reader.readLines().each {String line -> Matcher m = startSnippetPattern.matcher(line) if (m.matches()) { String snippetName = m.group(1) if (!writers[snippetName]) { File snippetFile = new File(snippetsDir, "$name-$snippetName") writers.put(snippetName, new SnippetWriter("Snippet $snippetName in $name", snippetFile)) } writers[snippetName].start() return } m = endSnippetPattern.matcher(line) if (m.matches()) { String snippetName = m.group(1) writers[snippetName].end() return } writers.values().each {SnippetWriter w -> w.println(line) } } } } finally { writers.values().each {SnippetWriter w -> w.close() } } } } } } class SnippetWriter { private final File dest private final String displayName private boolean appendToFile private PrintWriter writer def SnippetWriter(String displayName, File dest) { this.dest = dest this.displayName = displayName } def start() { if (writer) { throw new RuntimeException("$displayName is already started.") } dest.parentFile.mkdirs() writer = new PrintWriter(dest.newWriter(appendToFile), false) appendToFile = true this } def println(String line) { if (writer) { writer.println(line) } } def end() { if (!writer) { throw new RuntimeException("$displayName was not started.") } close() } def close() { if (writer) { writer.close() } writer = null } }gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/SampleElementLocationHandler.groovy000066400000000000000000000046711210430504300324700ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import org.w3c.dom.Element import org.w3c.dom.Document /** * This class is used by the UserGuideTransformTask to inject the example location into * the first figure or example child of a sample block. *

* I would have included this as an inner class of UserGuideTransformTask but groovy doesn't * support them. */ class SampleElementLocationHandler { private Document doc private Element sampleElement private String srcDir private boolean includeLocation = false private boolean locationIncluded = false def SampleElementLocationHandler(Document doc, Element sampleElement, String srcDir) { this.doc = doc this.srcDir = srcDir this.includeLocation = Boolean.valueOf(sampleElement.'@includeLocation') } public void processSampleLocation(Element parentElement) { if (includeLocation && !locationIncluded) { Element tipElement = doc.createElement('tip') tipElement.setAttribute('role', 'exampleLocation') Element textElement = doc.createElement('para') tipElement.appendChild(textElement) Element emphasisElement = doc.createElement('emphasis') textElement.appendChild(emphasisElement) emphasisElement.appendChild(doc.createTextNode('Note:')) textElement.appendChild(doc.createTextNode(' The code for this example can be found at ')) Element filenameElement = doc.createElement('filename') textElement.appendChild(filenameElement) textElement.appendChild(doc.createTextNode(' which is in both the binary and source distributions of Gradle.')) filenameElement.appendChild(doc.createTextNode("samples/$srcDir")) parentElement.appendChild(tipElement) locationIncluded = true } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/SampleElementValidator.groovy000066400000000000000000000043011210430504300313350ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import org.w3c.dom.Element /** * Validates sample element - looks for missing attributes. * * @author Tomek Kaczanowski */ public class SampleElementValidator { void validate(Element element) { String id = element.'@id' if (!id) { throw new RuntimeException("No id attribute specified for sample.") } String srcDir = element.'@dir' if (!srcDir) { throw new RuntimeException("No dir attribute specified for sample '$id'.") } String title = element.'@title' if (!title) { throw new RuntimeException("No title attribute specified for sample '$id'.") } element.children().each {Element child -> switch (child.name()) { case 'sourcefile': if (!child.'@file') { throw new RuntimeException("No file attribute specified for source file in sample '$id'.") } break case 'output': case 'test': if (child.'@args' == null) { throw new RuntimeException(" No args attribute specified for output for sample '$id'. ") } break; case 'layout': // nothing, makes no sense to do the validation here, cause I'd have to copy all the logic also break; default: throw new RuntimeException("Unrecognised sample type ${child.name()} found.") } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/SampleLayoutHandler.groovy000066400000000000000000000112321210430504300306520ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import org.w3c.dom.Element class SampleLayoutHandler { private final String srcDir SampleLayoutHandler(String srcDir) { this.srcDir = srcDir } void handle(String locationText, Element parentElement, Element sampleManifestElement) { def doc = parentElement.ownerDocument Element outputTitle = doc.createElement("para") outputTitle.appendChild(doc.createTextNode("Build layout")) parentElement.appendChild(outputTitle) Element programListingElement = doc.createElement('programlisting') parentElement.appendChild(programListingElement) StringBuilder content = new StringBuilder() TreeNode tree = new TreeNode(srcDir.tokenize('/').last() + '/', '', true) locationText.eachLine { line -> def fileName = line.trim().replace('\\', '/').replaceAll(/^\//, '').replaceAll(/\/+/, '/') if (fileName) { def node = new TreeNode(fileName, fileName, true) def nodeElement = sampleManifestElement.ownerDocument.createElement(node.file ? 'file' : 'dir') nodeElement.setAttribute('path', fileName) sampleManifestElement.appendChild(nodeElement) tree.children << node } } tree.normalise() tree.writeTo(content) programListingElement.appendChild(doc.createTextNode(content.toString())) } } class TreeNode { String path final List nameParts List children = [] String name final mustInclude TreeNode(String name, String path = name, boolean mustInclude = true) { this.name = name this.path = path this.mustInclude = mustInclude } @Override String toString() { return path } boolean isFile() { return !path.endsWith('/') } void normalise() { if (children.isEmpty()) { return } TreeNode currentContext = null int pos = 0; while (pos < children.size()) { def child = children.get(pos) if (child.depth == 1) { currentContext = child pos++ } else if (currentContext == null || !child.path.startsWith(currentContext.path)) { // Start a new stack def path = child.parentPath currentContext = new TreeNode(path, path, false) children.add(pos, currentContext) pos++ } else { // Move this child down one level if (!currentContext.path.endsWith('/')) { throw new RuntimeException("Parent directory '$currentContext.path' should end with a slash.") } def path = child.path.substring(currentContext.path.length()) currentContext.children.add(new TreeNode(path, path, child.mustInclude)) children.remove(pos) } } children.each { child -> child.normalise() } // Collapse this node if it has a single child which is a directory if (!mustInclude && children.size() == 1 && children[0].path.endsWith('/')) { path = path + children[0].path name = name + children[0].name children = children[0].children } } def getDepth() { return path.tokenize('/').size() } def getParentPath() { return path.tokenize('/')[0] + '/' } def commonPrefix(String a, String b) { def partsA = a.tokenize('/') def partsB = b.tokenize('/') int i = 0 for (; i < partsA.size() && i < partsB.size() && partsA[i] == partsB[i]; i++) { } if (i == 0) { return null } return partsA.subList(0, i).join('/') } void writeTo(Appendable target, int depth = 0) { depth.times { target.append(' ') } target.append(name) target.append('\n') children.each { child -> child.writeTo(target, depth + 1) } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/UserGuideTransformTask.groovy000066400000000000000000000254211210430504300313550ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import groovy.xml.dom.DOMCategory import org.gradle.api.DefaultTask import org.gradle.api.InvalidUserDataException import org.gradle.build.docs.dsl.links.ClassLinkMetaData import org.gradle.build.docs.dsl.links.LinkMetaData import org.gradle.build.docs.model.ClassMetaDataRepository import org.gradle.build.docs.model.SimpleClassMetaDataRepository import org.w3c.dom.Document import org.w3c.dom.Element import org.gradle.api.tasks.* /** * Transforms userguide source into docbook, replacing custom xml elements. * * Takes the following as input: *

*/ public class UserGuideTransformTask extends DefaultTask { @Input String getVersion() { return project.version.toString() } def javadocUrl def groovydocUrl def dsldocUrl def websiteUrl @InputFile File sourceFile @InputFile File linksFile @OutputFile File destFile @InputDirectory File snippetsDir @Input Set tags = new HashSet() final SampleElementValidator validator = new SampleElementValidator(); @Input String getJavadocUrl() { javadocUrl } @Input String getGroovydocUrl() { groovydocUrl } @Input String getDsldocUrl() { dsldocUrl } @Input String getWebsiteUrl() { websiteUrl } @TaskAction def transform() { XIncludeAwareXmlProvider provider = new XIncludeAwareXmlProvider() provider.parse(sourceFile) transform(provider.document) provider.write(destFile) } private def transform(Document doc) { use(DOMCategory) { use(BuildableDOMCategory) { addVersionInfo(doc) applyConditionalChunks(doc) transformSamples(doc) transformApiLinks(doc) transformWebsiteLinks(doc) fixProgramListings(doc) } } } def addVersionInfo(Document doc) { Element releaseInfo = doc.createElement('releaseinfo') releaseInfo.appendChild(doc.createTextNode(version.toString())) if (doc.documentElement.bookinfo[0]) { doc.documentElement.bookinfo[0].appendChild(releaseInfo) } } def fixProgramListings(Document doc) { doc.documentElement.depthFirst().findAll { it.name() == 'programlisting' || it.name() == 'screen' }.each {Element element -> element.setTextContent(normalise(element.getTextContent())) } } String normalise(String content) { return content.trim().replace('\t', ' ').replace('\r\n', '\n') } def transformApiLinks(Document doc) { ClassMetaDataRepository linkRepository = new SimpleClassMetaDataRepository() linkRepository.load(linksFile) doc.documentElement.depthFirst().findAll { it.name() == 'apilink' }.each {Element element -> String className = element.'@class' if (!className) { throw new RuntimeException('No "class" attribute specified for element.') } String methodName = element.'@method' def classMetaData = linkRepository.get(className) LinkMetaData linkMetaData = methodName ? classMetaData.getMethod(methodName) : classMetaData.classLink String style = element.'@style' ?: linkMetaData.style.toString().toLowerCase() Element ulinkElement = doc.createElement('ulink') String href if (style == 'dsldoc') { href = "$dsldocUrl/${className}.html" } else if (style == "groovydoc" || style == "javadoc") { def base = style == "groovydoc" ? groovydocUrl : javadocUrl def packageName = classMetaData.packageName href = "$base/${packageName.replace('.', '/')}/${className.substring(packageName.length()+1)}.html" } else { throw new InvalidUserDataException("Unknown api link style '$style'.") } if (linkMetaData.urlFragment) { href = "$href#$linkMetaData.urlFragment" } ulinkElement.setAttribute('url', href) Element classNameElement = doc.createElement('classname') ulinkElement.appendChild(classNameElement) classNameElement.appendChild(doc.createTextNode(linkMetaData.displayName)) element.parentNode.replaceChild(ulinkElement, element) } } def transformWebsiteLinks(Document doc) { doc.documentElement.depthFirst().findAll { it.name() == 'ulink' }.each {Element element -> String url = element.'@url' if (url.startsWith('website:')) { url = url.substring(8) if (websiteUrl) { url = "${websiteUrl}/${url}" } element.setAttribute('url', url) } } } def transformSamples(Document doc) { XIncludeAwareXmlProvider samplesXmlProvider = new XIncludeAwareXmlProvider() samplesXmlProvider.emptyDoc() << { samples() } Element samplesXml = samplesXmlProvider.root.documentElement doc.documentElement.depthFirst().findAll { it.name() == 'sample' }.each { Element element -> validator.validate(element) String sampleId = element.'@id' String srcDir = element.'@dir' // This class handles the responsibility of adding the location tips to the first child of first // example defined in the sample. SampleElementLocationHandler locationHandler = new SampleElementLocationHandler(doc, element, srcDir) SampleLayoutHandler layoutHandler = new SampleLayoutHandler(srcDir) samplesXml << { sample(id: sampleId, dir: srcDir) } String title = element.'@title' Element exampleElement = doc.createElement('example') exampleElement.setAttribute('id', sampleId) Element titleElement = doc.createElement('title') titleElement.appendChild(doc.createTextNode(title)) exampleElement.appendChild(titleElement); element.children().each {Element child -> if (child.name() == 'sourcefile') { String file = child.'@file' Element sourcefileTitle = doc.createElement("para") Element commandElement = doc.createElement('filename') commandElement.appendChild(doc.createTextNode(file)) sourcefileTitle.appendChild(commandElement) exampleElement.appendChild(sourcefileTitle); Element programListingElement = doc.createElement('programlisting') if (file.endsWith('.gradle') || file.endsWith('.groovy') || file.endsWith('.java')) { programListingElement.setAttribute('language', 'java') } else if (file.endsWith('.xml')) { programListingElement.setAttribute('language', 'xml') } File srcFile String snippet = child.'@snippet' if (snippet) { srcFile = new File(snippetsDir, "$srcDir/$file-$snippet") } else { srcFile = new File(snippetsDir, "$srcDir/$file") } programListingElement.appendChild(doc.createTextNode(normalise(srcFile.text))) exampleElement.appendChild(programListingElement) } else if (child.name() == 'output') { String args = child.'@args' String outputFile = child.'@outputFile' ?: "${sampleId}.out" boolean ignoreExtraLines = child.'@ignoreExtraLines' ?: false samplesXml << { sample(id: sampleId, dir: srcDir, args: args, outputFile: outputFile, ignoreExtraLines: ignoreExtraLines) } Element outputTitle = doc.createElement("para") outputTitle.appendChild(doc.createTextNode("Output of ")) Element commandElement = doc.createElement('userinput') commandElement.appendChild(doc.createTextNode("gradle $args")) outputTitle.appendChild(commandElement) exampleElement.appendChild(outputTitle) Element screenElement = doc.createElement('screen') File srcFile = new File(sourceFile.parentFile, "../../../src/samples/userguideOutput/${outputFile}").canonicalFile screenElement.appendChild(doc.createTextNode("> gradle $args\n" + normalise(srcFile.text))) exampleElement.appendChild(screenElement) } else if (child.name() == 'test') { String args = child.'@args' samplesXml << { sample(id: sampleId, dir: srcDir, args: args) } } else if (child.name() == 'layout') { String args = child.'@after' Element sampleElement = samplesXml << { sample(id: sampleId, dir: srcDir, args: args) } layoutHandler.handle(child.text(), exampleElement, sampleElement) } locationHandler.processSampleLocation(exampleElement) } element.parentNode.insertBefore(exampleElement, element) element.parentNode.removeChild(element) } File samplesFile = new File(destFile.parentFile, 'samples.xml') samplesXmlProvider.write(samplesFile, true) } void applyConditionalChunks(Document doc) { doc.documentElement.depthFirst().findAll { it.'@condition' }.each {Element element -> if (!tags.contains(element.'@condition')) { element.parentNode.removeChild(element) } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/XIncludeAwareXmlProvider.groovy000066400000000000000000000044131210430504300316270ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import javax.xml.parsers.DocumentBuilder import javax.xml.parsers.DocumentBuilderFactory import javax.xml.transform.OutputKeys import javax.xml.transform.Transformer import javax.xml.transform.TransformerFactory import javax.xml.transform.dom.DOMSource import javax.xml.transform.stream.StreamResult import org.w3c.dom.Document import org.w3c.dom.Element import org.w3c.dom.Node class XIncludeAwareXmlProvider { Document root Element parse(File sourceFile) { root = parseSourceFile(sourceFile) return root.documentElement } Node emptyDoc() { root = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() } void write(File destFile, boolean indent = false) { destFile.withOutputStream {OutputStream stream -> TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); if (indent) { transformer.setOutputProperty(OutputKeys.INDENT, "yes") } transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text/xml"); transformer.transform(new DOMSource(root), new StreamResult(stream)); } } Document getDocument() { return root } private Document parseSourceFile(File sourceFile) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance() factory.setNamespaceAware(true) factory.setXIncludeAware(true) DocumentBuilder builder = factory.newDocumentBuilder() return builder.parse(sourceFile) } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/XslTransformer.java000077500000000000000000000043711210430504300273330ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class XslTransformer { public static void main(String[] args) throws TransformerException, IOException { if (args.length < 3 || args.length > 4) { throw new IllegalArgumentException("USAGE: [dest-dir]"); } File stylesheet = new File(args[0]); File source = new File(args[1]); File dest = new File(args[2]); String destDir = ""; if (args.length > 3) { destDir = args[3]; } System.out.format("=> stylesheet %s%n", stylesheet); System.out.format("=> source %s%n", source); System.out.format("=> dest %s%n", dest); System.out.format("=> destDir %s%n", destDir); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(new StreamSource(stylesheet)); System.out.format("=> transformer %s (%s)%n", transformer, transformer.getClass().getName()); if (destDir.length() > 0) { transformer.setParameter("base.dir", destDir + "/"); } FileOutputStream outstr = new FileOutputStream(dest); try { transformer.transform(new StreamSource(source), new StreamResult(outstr)); } finally { outstr.close(); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/000077500000000000000000000000001210430504300242515ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/000077500000000000000000000000001210430504300256715ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/AssembleDslDocTask.groovy000066400000000000000000000213161210430504300326120ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook import groovy.xml.dom.DOMCategory import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.build.docs.BuildableDOMCategory import org.gradle.build.docs.DocGenerationException import org.gradle.build.docs.XIncludeAwareXmlProvider import org.gradle.build.docs.dsl.links.ClassLinkMetaData import org.gradle.build.docs.dsl.links.LinkMetaData import org.gradle.build.docs.dsl.docbook.model.ClassExtensionMetaData import org.gradle.build.docs.dsl.source.model.ClassMetaData import org.gradle.build.docs.model.ClassMetaDataRepository import org.gradle.build.docs.model.SimpleClassMetaDataRepository import org.w3c.dom.Document import org.w3c.dom.Element import org.gradle.build.docs.dsl.docbook.model.BlockDoc import org.gradle.build.docs.dsl.docbook.model.ClassDoc /** * Generates the docbook source for the DSL reference guide. * * Uses the following as input: *
    *
  • Meta-data extracted from the source by {@link org.gradle.build.docs.dsl.source.ExtractDslMetaDataTask}.
  • *
  • Meta-data about the plugins, in the form of an XML file.
  • *
  • {@code sourceFile} - A main docbook template file containing the introductory material and a list of classes to document.
  • *
  • {@code classDocbookDir} - A directory that should contain docbook template for each class referenced in main docbook template.
  • *
* * Produces the following: *
    *
  • A docbook book XML file containing the reference.
  • *
  • A meta-data file containing information about where the canonical documentation for each class can be found: * as dsl doc, javadoc or groovydoc.
  • *
*/ class AssembleDslDocTask extends DefaultTask { @InputFile File sourceFile @InputFile File classMetaDataFile @InputFile File pluginsMetaDataFile @InputDirectory File classDocbookDir @OutputFile File destFile @OutputFile File linksFile @TaskAction def transform() { XIncludeAwareXmlProvider provider = new XIncludeAwareXmlProvider() provider.parse(sourceFile) transformDocument(provider.document) provider.write(destFile) } private def transformDocument(Document mainDocbookTemplate) { ClassMetaDataRepository classRepository = new SimpleClassMetaDataRepository() classRepository.load(classMetaDataFile) ClassMetaDataRepository linkRepository = new SimpleClassMetaDataRepository() //for every method found in class meta, create a javadoc/groovydoc link classRepository.each {name, ClassMetaData metaData -> linkRepository.put(name, new ClassLinkMetaData(metaData)) } use(DOMCategory) { use(BuildableDOMCategory) { Map extensions = loadPluginsMetaData() DslDocModel model = new DslDocModel(classDocbookDir, mainDocbookTemplate, classRepository, extensions) def root = mainDocbookTemplate.documentElement root.section.table.each { Element table -> mergeContent(table, model) } model.classes.each { generateDocForType(root.ownerDocument, model, linkRepository, it) } } } linkRepository.store(linksFile) } def loadPluginsMetaData() { XIncludeAwareXmlProvider provider = new XIncludeAwareXmlProvider() provider.parse(pluginsMetaDataFile) Map extensions = [:] provider.root.plugin.each { Element plugin -> def pluginId = plugin.'@id' if (!pluginId) { throw new RuntimeException("No id specified for plugin: ${plugin.'@description' ?: 'unknown'}") } plugin.extends.each { Element e -> def targetClass = e.'@targetClass' if (!targetClass) { throw new RuntimeException("No targetClass specified for extention provided by plugin '$pluginId'.") } def extension = extensions[targetClass] if (!extension) { extension = new ClassExtensionMetaData(targetClass) extensions[targetClass] = extension } def mixinClass = e.'@mixinClass' if (mixinClass) { extension.addMixin(pluginId, mixinClass) } def extensionClass = e.'@extensionClass' if (extensionClass) { def extensionId = e.'@id' if (!extensionId) { throw new RuntimeException("No id specified for extension '$extensionClass' for plugin '$pluginId'.") } extension.addExtension(pluginId, extensionId, extensionClass) } } } return extensions } def mergeContent(Element typeTable, DslDocModel model) { def title = typeTable.title[0].text() //TODO below checks makes it harder to add new sections //because the new section will work correctly only when the section title ends with 'types' :) if (title.matches('(?i).* types')) { mergeTypes(typeTable, model) } else if (title.matches('(?i).* blocks')) { mergeBlocks(typeTable, model) } else { return } typeTable['@role'] = 'dslTypes' } def mergeBlocks(Element blocksTable, DslDocModel model) { blocksTable.addFirst { thead { tr { td('Block') td('Description') } } } def project = model.getClassDoc(Project.class.name) blocksTable.tr.each { Element tr -> mergeBlock(tr, project) } } def mergeBlock(Element tr, ClassDoc project) { String blockName = tr.td[0].text().trim() BlockDoc blockDoc = project.getBlock(blockName) tr.children = { td { link(linkend: blockDoc.id) { literal("$blockName { }")} } td(blockDoc.description) } } def mergeTypes(Element typeTable, DslDocModel model) { typeTable.addFirst { thead { tr { td('Type') td('Description') } } } typeTable.tr.each { Element tr -> mergeType(tr, model) } } def mergeType(Element typeTr, DslDocModel model) { String className = typeTr.td[0].text().trim() ClassDoc classDoc = model.getClassDoc(className) typeTr.children = { td { link(linkend: classDoc.id) { literal(classDoc.simpleName) } } td(classDoc.description) } } def generateDocForType(Document document, DslDocModel model, ClassMetaDataRepository linkRepository, ClassDoc classDoc) { try { //classDoc renderer renders the content of the class and also links to properties/methods new ClassDocRenderer(new LinkRenderer(document, model)).mergeContent(classDoc, document.documentElement) def linkMetaData = linkRepository.get(classDoc.name) linkMetaData.style = LinkMetaData.Style.Dsldoc classDoc.classMethods.each { methodDoc -> linkMetaData.addMethod(methodDoc.metaData, LinkMetaData.Style.Dsldoc) } classDoc.classBlocks.each { blockDoc -> linkMetaData.addBlockMethod(blockDoc.blockMethod.metaData) } classDoc.classProperties.each { propertyDoc -> linkMetaData.addGetterMethod(propertyDoc.name, propertyDoc.metaData.getter) } } catch (Exception e) { throw new DocGenerationException("Failed to generate documentation for class '$classDoc.name'.", e) } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/BasicJavadocLexer.java000066400000000000000000000147131210430504300320530ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; /** * Converts the main description of a javadoc comment into a stream of tokens. */ class BasicJavadocLexer implements JavadocLexer { private static final Pattern HTML_ELEMENT = Pattern.compile("(?s)<\\\\?.+?>"); private static final Pattern ELEMENT_ATTRIBUTE = Pattern.compile("(?s)\\w+(\\s*=\\s*('.*?')|(\".*?\"))?"); private static final Pattern END_ATTRIBUTE_NAME = Pattern.compile("=|(\\s)|(/>)|>"); private static final Pattern ATTRIBUTE_SEPARATOR = Pattern.compile("\\s*=\\s*"); private static final Pattern END_ELEMENT_NAME = Pattern.compile("\\s+|(/>)|>"); private static final Pattern END_ELEMENT = Pattern.compile("(/>)|>"); private static final Pattern HTML_ENCODED_CHAR = Pattern.compile("&#\\d+;"); private static final Pattern HTML_ENTITY = Pattern.compile("&.+?;"); private static final Pattern TAG = Pattern.compile("(?s)\\{@.+?\\}"); private static final Pattern END_TAG_NAME = Pattern.compile("(?s)\\s|}"); private static final Pattern WHITESPACE_WITH_EOL = Pattern.compile("(?s)\\s+"); private static final Map ENTITIES = new HashMap(); static { ENTITIES.put("amp", "&"); ENTITIES.put("lt", "<"); ENTITIES.put("gt", ">"); ENTITIES.put("quot", "\""); ENTITIES.put("apos", "'"); } private final JavadocScanner scanner; BasicJavadocLexer(JavadocScanner scanner) { this.scanner = scanner; } public void pushText(String rawCommentText) { scanner.pushText(rawCommentText); } public void visit(TokenVisitor visitor) { while (!scanner.isEmpty()) { if (scanner.lookingAt(HTML_ELEMENT)) { parseStartElement(visitor); continue; } if (scanner.lookingAt(TAG)) { parseJavadocTag(visitor); continue; } StringBuilder text = new StringBuilder(); while (!scanner.isEmpty()) { if (scanner.lookingAt(HTML_ELEMENT)) { break; } if (scanner.lookingAt(TAG)) { break; } if (scanner.lookingAt(HTML_ENCODED_CHAR)) { parseHtmlEncodedChar(text); } else if (scanner.lookingAt(HTML_ENTITY)) { parseHtmlEntity(text); } else { text.append(scanner.getFirst()); scanner.next(); } } visitor.onText(text.toString()); } visitor.onEnd(); } private void parseHtmlEntity(StringBuilder buffer) { scanner.next(); scanner.mark(); scanner.find(';'); String value = ENTITIES.get(scanner.region().toLowerCase()); buffer.append(value); scanner.next(); } private void parseHtmlEncodedChar(StringBuilder buffer) { scanner.next(2); scanner.mark(); scanner.find(';'); String value = new String(new char[]{(char) Integer.parseInt(scanner.region())}); buffer.append(value); scanner.next(); } private void parseJavadocTag(TokenVisitor visitor) { // start of tag marker scanner.next(2); // tag name scanner.mark(); scanner.find(END_TAG_NAME); String tagName = scanner.region(); visitor.onStartJavadocTag(tagName); scanner.skip(WHITESPACE_WITH_EOL); // value if (!scanner.lookingAt('}')) { scanner.mark(); scanner.find('}'); String value = scanner.region(); visitor.onText(value); } // end of tag marker if (scanner.lookingAt('}')) { visitor.onEndJavadocTag(tagName); scanner.next(); } } private void parseStartElement(TokenVisitor visitor) { // start element marker scanner.next(); boolean isEnd = false; if (scanner.lookingAt('/')) { isEnd = true; scanner.next(); } // element name scanner.skip(WHITESPACE_WITH_EOL); scanner.mark(); scanner.find(END_ELEMENT_NAME); String elementName = scanner.region().toLowerCase(); if (isEnd) { visitor.onEndHtmlElement(elementName); } else { visitor.onStartHtmlElement(elementName); } // attributes scanner.skip(WHITESPACE_WITH_EOL); while (!scanner.isEmpty() && scanner.lookingAt(ELEMENT_ATTRIBUTE)) { // attribute name scanner.mark(); scanner.find(END_ATTRIBUTE_NAME); String attrName = scanner.region(); // separator scanner.skip(ATTRIBUTE_SEPARATOR); // value char quote = scanner.getFirst(); scanner.next(); StringBuilder attrValue = new StringBuilder(); while (!scanner.isEmpty() && !scanner.lookingAt(quote)) { if (scanner.lookingAt(HTML_ENCODED_CHAR)) { parseHtmlEncodedChar(attrValue); } else if (scanner.lookingAt(HTML_ENTITY)) { parseHtmlEntity(attrValue); } else { attrValue.append(scanner.getFirst()); scanner.next(); } } visitor.onHtmlElementAttribute(attrName, attrValue.toString()); scanner.next(); scanner.skip(WHITESPACE_WITH_EOL); } if (!isEnd) { visitor.onStartHtmlElementComplete(elementName); } // end element marker if (scanner.lookingAt('/')) { visitor.onEndHtmlElement(elementName); } scanner.skip(END_ELEMENT); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/BlockDetailRenderer.java000066400000000000000000000073101210430504300324010ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.BlockDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; public class BlockDetailRenderer { private final GenerationListener listener; private final LinkRenderer linkRenderer; private final ElementWarningsRenderer warningsRenderer = new ElementWarningsRenderer(); public BlockDetailRenderer(LinkRenderer linkRenderer, GenerationListener listener) { this.linkRenderer = linkRenderer; this.listener = listener; } public void renderTo(BlockDoc blockDoc, Element parent) { Document document = parent.getOwnerDocument(); Element section = document.createElement("section"); parent.appendChild(section); section.setAttribute("id", blockDoc.getId()); section.setAttribute("role", "detail"); Element title = document.createElement("title"); section.appendChild(title); Element literal = document.createElement("literal"); title.appendChild(literal); literal.appendChild(document.createTextNode(blockDoc.getName())); title.appendChild(document.createTextNode(" { }")); warningsRenderer.renderTo(blockDoc, "script block", section); for (Element element : blockDoc.getComment()) { section.appendChild(document.importNode(element, true)); } Element segmentedlist = document.createElement("segmentedlist"); section.appendChild(segmentedlist); Element segtitle = document.createElement("segtitle"); segmentedlist.appendChild(segtitle); segtitle.appendChild(document.createTextNode("Delegates to")); Element seglistitem = document.createElement("seglistitem"); segmentedlist.appendChild(seglistitem); Element seg = document.createElement("seg"); seglistitem.appendChild(seg); if (blockDoc.isMultiValued()) { seg.appendChild(document.createTextNode("Each ")); seg.appendChild(linkRenderer.link(blockDoc.getType(), listener)); seg.appendChild(document.createTextNode(" in ")); // TODO - add linkRenderer.link(property) Element link = document.createElement("link"); seg.appendChild(link); link.setAttribute("linkend", blockDoc.getBlockProperty().getId()); literal = document.createElement("literal"); link.appendChild(literal); literal.appendChild(document.createTextNode(blockDoc.getBlockProperty().getName())); } else { seg.appendChild(linkRenderer.link(blockDoc.getType(), listener)); seg.appendChild(document.createTextNode(" from ")); // TODO - add linkRenderer.link(property) Element link = document.createElement("link"); seg.appendChild(link); link.setAttribute("linkend", blockDoc.getBlockProperty().getId()); literal = document.createElement("literal"); link.appendChild(literal); literal.appendChild(document.createTextNode(blockDoc.getBlockProperty().getName())); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/BlockTableRenderer.java000066400000000000000000000055111210430504300322270ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.BlockDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; public class BlockTableRenderer { public void renderTo(Iterable blocks, Element parent) { Document document = parent.getOwnerDocument(); // // // Block // Description // // Element thead = document.createElement("thead"); parent.appendChild(thead); Element tr = document.createElement("tr"); thead.appendChild(tr); Element td = document.createElement("td"); tr.appendChild(td); td.appendChild(document.createTextNode("Block")); td = document.createElement("td"); tr.appendChild(td); td.appendChild(document.createTextNode("Description")); for (BlockDoc blockDoc : blocks) { // // $name // $description // tr = document.createElement("tr"); parent.appendChild(tr); td = document.createElement("td"); tr.appendChild(td); Element link = document.createElement("link"); td.appendChild(link); link.setAttribute("linkend", blockDoc.getId()); Element literal = document.createElement("literal"); link.appendChild(literal); literal.appendChild(document.createTextNode(blockDoc.getName())); td = document.createElement("td"); tr.appendChild(td); if (blockDoc.isDeprecated()) { Element caution = document.createElement("caution"); td.appendChild(caution); caution.appendChild(document.createTextNode("Deprecated")); } if (blockDoc.isIncubating()) { Element caution = document.createElement("caution"); td.appendChild(caution); caution.appendChild(document.createTextNode("Incubating")); } td.appendChild(document.importNode(blockDoc.getDescription(), true)); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/BlocksRenderer.java000066400000000000000000000067351210430504300314530ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.BlockDoc; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; import org.gradle.build.docs.dsl.docbook.model.ClassExtensionDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.util.Collection; public class BlocksRenderer { private final BlockTableRenderer blockTableRenderer = new BlockTableRenderer(); private final ExtensionBlocksSummaryRenderer extensionBlocksSummaryRenderer; private final BlockDetailRenderer blockDetailRenderer; public BlocksRenderer(LinkRenderer linkRenderer, GenerationListener listener) { blockDetailRenderer = new BlockDetailRenderer(linkRenderer, listener); extensionBlocksSummaryRenderer = new ExtensionBlocksSummaryRenderer(blockTableRenderer); } public void renderTo(ClassDoc classDoc, Element parent) { Document document = parent.getOwnerDocument(); Element summarySection = document.createElement("section"); parent.appendChild(summarySection); Element title = document.createElement("title"); summarySection.appendChild(title); title.appendChild(document.createTextNode("Script blocks")); boolean hasBlocks = false; Collection classBlocks = classDoc.getClassBlocks(); if (!classBlocks.isEmpty()) { hasBlocks = true; Element table = document.createElement("table"); summarySection.appendChild(table); title = document.createElement("title"); table.appendChild(title); title.appendChild(document.createTextNode("Script blocks - " + classDoc.getSimpleName())); blockTableRenderer.renderTo(classBlocks, table); } for (ClassExtensionDoc extensionDoc : classDoc.getClassExtensions()) { hasBlocks |= !extensionDoc.getExtensionBlocks().isEmpty(); extensionBlocksSummaryRenderer.renderTo(extensionDoc, summarySection); } if (!hasBlocks) { Element para = document.createElement("para"); summarySection.appendChild(para); para.appendChild(document.createTextNode("No script blocks")); return; } Element detailsSection = document.createElement("section"); parent.appendChild(detailsSection); title = document.createElement("title"); detailsSection.appendChild(title); title.appendChild(document.createTextNode("Script block details")); for (BlockDoc blockDoc : classBlocks) { blockDetailRenderer.renderTo(blockDoc, detailsSection); } for (ClassExtensionDoc extensionDoc : classDoc.getClassExtensions()) { for (BlockDoc blockDoc : extensionDoc.getExtensionBlocks()) { blockDetailRenderer.renderTo(blockDoc, detailsSection); } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ClassDescriptionRenderer.java000066400000000000000000000047161210430504300335040ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class ClassDescriptionRenderer { private final ElementWarningsRenderer warningsRenderer = new ElementWarningsRenderer(); public void renderTo(ClassDoc classDoc, Element parent) { Document document = parent.getOwnerDocument(); Element title = document.createElement("title"); parent.appendChild(title); title.appendChild(document.createTextNode(classDoc.getSimpleName())); Element list = document.createElement("segmentedlist"); parent.appendChild(list); Element segtitle = document.createElement("segtitle"); list.appendChild(segtitle); segtitle.appendChild(document.createTextNode("API Documentation")); Element listItem = document.createElement("seglistitem"); list.appendChild(listItem); Element seg = document.createElement("seg"); listItem.appendChild(seg); Element apilink = document.createElement("apilink"); seg.appendChild(apilink); apilink.setAttribute("class", classDoc.getName()); apilink.setAttribute("style", classDoc.getStyle()); warningsRenderer.renderTo(classDoc, "class", parent); for (Element element : classDoc.getComment()) { parent.appendChild(document.importNode(element, true)); } NodeList otherContent = classDoc.getClassSection().getChildNodes(); for (int i = 0; i < otherContent.getLength(); i++) { Node child = otherContent.item(i); if (child instanceof Element && !((Element) child).getTagName().equals("section")) { parent.appendChild(document.importNode(child, true)); } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ClassDocBuilder.java000066400000000000000000000040351210430504300315400ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; public class ClassDocBuilder { private final ClassDocCommentBuilder commentBuilder; private final ClassDocPropertiesBuilder propertiesBuilder; private final ClassDocMethodsBuilder methodsBuilder; private final ClassDocExtensionsBuilder extensionsBuilder; private final ClassDocSuperTypeBuilder superTypeBuilder; private final GenerationListener listener = new DefaultGenerationListener(); public ClassDocBuilder(DslDocModel model, JavadocConverter javadocConverter) { commentBuilder = new ClassDocCommentBuilder(javadocConverter, listener); propertiesBuilder = new ClassDocPropertiesBuilder(javadocConverter, listener); methodsBuilder = new ClassDocMethodsBuilder(javadocConverter, listener); extensionsBuilder = new ClassDocExtensionsBuilder(model, listener); superTypeBuilder = new ClassDocSuperTypeBuilder(model, listener); } void build(ClassDoc classDoc) { listener.start(String.format("class %s", classDoc.getName())); try { superTypeBuilder.build(classDoc); commentBuilder.build(classDoc); propertiesBuilder.build(classDoc); methodsBuilder.build(classDoc); extensionsBuilder.build(classDoc); classDoc.mergeContent(); } finally { listener.finish(); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ClassDocCommentBuilder.java000066400000000000000000000023631210430504300330650ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; public class ClassDocCommentBuilder { private final JavadocConverter javadocConverter; private final GenerationListener listener; public ClassDocCommentBuilder(JavadocConverter javadocConverter, GenerationListener listener) { this.javadocConverter = javadocConverter; this.listener = listener; } /** * Builds the class comment for the given class. */ void build(ClassDoc classDoc) { classDoc.setComment(javadocConverter.parse(classDoc.getClassMetaData(), listener).getDocbook()); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ClassDocExtensionsBuilder.java000066400000000000000000000116471210430504300336270ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import groovy.lang.Closure; import org.gradle.build.docs.dsl.docbook.model.*; import org.gradle.build.docs.dsl.source.model.MethodMetaData; import org.gradle.build.docs.dsl.source.model.PropertyMetaData; import org.gradle.build.docs.dsl.source.model.TypeMetaData; import org.gradle.internal.UncheckedException; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class ClassDocExtensionsBuilder { private final DslDocModel model; private final GenerationListener listener; public ClassDocExtensionsBuilder(DslDocModel model, GenerationListener listener) { this.model = model; this.listener = listener; } /** * Builds the extension meta-data for the given class. */ public void build(ClassDoc classDoc) { Map plugins = new HashMap(); for (MixinMetaData mixin : classDoc.getExtensionMetaData().getMixinClasses()) { String pluginId = mixin.getPluginId(); ClassExtensionDoc classExtensionDoc = plugins.get(pluginId); if (classExtensionDoc == null) { classExtensionDoc = new ClassExtensionDoc(pluginId, classDoc); plugins.put(pluginId, classExtensionDoc); } classExtensionDoc.getMixinClasses().add(model.getClassDoc(mixin.getMixinClass())); } for (ExtensionMetaData extension : classDoc.getExtensionMetaData().getExtensionClasses()) { String pluginId = extension.getPluginId(); ClassExtensionDoc classExtensionDoc = plugins.get(pluginId); if (classExtensionDoc == null) { classExtensionDoc = new ClassExtensionDoc(pluginId, classDoc); plugins.put(pluginId, classExtensionDoc); } classExtensionDoc.getExtensionClasses().put(extension.getExtensionId(), model.getClassDoc(extension.getExtensionClass())); } for (ClassExtensionDoc extensionDoc : plugins.values()) { build(extensionDoc); classDoc.addClassExtension(extensionDoc); } } private void build(ClassExtensionDoc extensionDoc) { Document doc; try { doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } catch (ParserConfigurationException e) { throw UncheckedException.throwAsUncheckedException(e); } LinkRenderer linkRenderer = new LinkRenderer(doc, model); for (Map.Entry entry : extensionDoc.getExtensionClasses().entrySet()) { String id = entry.getKey(); ClassDoc type = entry.getValue(); PropertyMetaData propertyMetaData = new PropertyMetaData(id, extensionDoc.getTargetClass().getClassMetaData()); propertyMetaData.setType(new TypeMetaData(type.getName())); Element para = doc.createElement("para"); para.appendChild(doc.createTextNode("The ")); para.appendChild(linkRenderer.link(propertyMetaData.getType(), listener)); para.appendChild(doc.createTextNode(String.format(" added by the %s plugin.", extensionDoc.getPluginId()))); PropertyDoc propertyDoc = new PropertyDoc(propertyMetaData, Collections.singletonList(para), Collections.emptyList()); extensionDoc.getExtraProperties().add(propertyDoc); para = doc.createElement("para"); para.appendChild(doc.createTextNode("Configures the ")); para.appendChild(linkRenderer.link(propertyMetaData.getType(), listener)); para.appendChild(doc.createTextNode(String.format(" added by the %s plugin.", extensionDoc.getPluginId()))); MethodMetaData methodMetaData = new MethodMetaData(id, extensionDoc.getTargetClass().getClassMetaData()); methodMetaData.addParameter("configClosure", new TypeMetaData(Closure.class.getName())); MethodDoc methodDoc = new MethodDoc(methodMetaData, Collections.singletonList(para)); extensionDoc.getExtraBlocks().add(new BlockDoc(methodDoc, propertyDoc, propertyMetaData.getType(), false)); } } } ClassDocGenerationException.java000066400000000000000000000016151210430504300340460ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.DocGenerationException; public class ClassDocGenerationException extends DocGenerationException { public ClassDocGenerationException(String message, Throwable throwable) { super(message, throwable); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ClassDocMethodsBuilder.java000066400000000000000000000103531210430504300330640ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import groovy.lang.Closure; import org.gradle.build.docs.dsl.docbook.model.BlockDoc; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; import org.gradle.build.docs.dsl.docbook.model.MethodDoc; import org.gradle.build.docs.dsl.docbook.model.PropertyDoc; import org.gradle.build.docs.dsl.source.model.MethodMetaData; import org.gradle.build.docs.dsl.source.model.TypeMetaData; import org.w3c.dom.Element; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; public class ClassDocMethodsBuilder extends ModelBuilderSupport { private final JavadocConverter javadocConverter; private final GenerationListener listener; public ClassDocMethodsBuilder(JavadocConverter converter, GenerationListener listener) { this.javadocConverter = converter; this.listener = listener; } /** * Builds the methods and script blocks of the given class. Assumes properties have already been built. */ public void build(ClassDoc classDoc) { Set signatures = new HashSet(); for (Element tr : children(classDoc.getMethodsTable(), "tr")) { List cells = children(tr, "td"); if (cells.size() != 1) { throw new RuntimeException(String.format("Expected 1 cell in , found: %s", tr)); } String methodName = cells.get(0).getTextContent().trim(); Collection methods = classDoc.getClassMetaData().findDeclaredMethods(methodName); if (methods.isEmpty()) { throw new RuntimeException(String.format("No metadata for method '%s.%s()'. Available methods: %s", classDoc.getName(), methodName, classDoc.getClassMetaData().getDeclaredMethodNames())); } for (MethodMetaData method : methods) { DocComment docComment = javadocConverter.parse(method, listener); MethodDoc methodDoc = new MethodDoc(method, docComment.getDocbook()); if (methodDoc.getDescription() == null) { throw new RuntimeException(String.format("Docbook content for '%s %s' does not contain a description paragraph.", classDoc.getName(), method.getSignature())); } PropertyDoc property = classDoc.findProperty(methodName); boolean multiValued = false; if (property != null && method.getParameters().size() == 1 && method.getParameters().get(0).getType().getSignature().equals(Closure.class.getName())) { TypeMetaData type = property.getMetaData().getType(); if (type.getName().equals("java.util.List") || type.getName().equals("java.util.Collection") || type.getName().equals("java.util.Set") || type.getName().equals("java.util.Iterable")) { type = type.getTypeArgs().get(0); multiValued = true; } classDoc.addClassBlock(new BlockDoc(methodDoc, property, type, multiValued)); } else { classDoc.addClassMethod(methodDoc); signatures.add(method.getOverrideSignature()); } } } ClassDoc supertype = classDoc.getSuperClass(); if (supertype != null) { for (MethodDoc method: supertype.getClassMethods()){ if (signatures.add(method.getMetaData().getOverrideSignature())) { classDoc.addClassMethod(method); } } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ClassDocPropertiesBuilder.java000066400000000000000000000137331210430504300336220ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; import org.gradle.build.docs.dsl.docbook.model.ExtraAttributeDoc; import org.gradle.build.docs.dsl.docbook.model.PropertyDoc; import org.gradle.build.docs.dsl.source.model.PropertyMetaData; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; import java.util.*; public class ClassDocPropertiesBuilder extends ModelBuilderSupport { private final JavadocConverter javadocConverter; private final GenerationListener listener; public ClassDocPropertiesBuilder(JavadocConverter javadocConverter, GenerationListener listener) { this.javadocConverter = javadocConverter; this.listener = listener; } /** * Builds the properties of the given class */ void build(ClassDoc classDoc) { Element thead = getChild(classDoc.getPropertiesTable(), "thead"); Element tr = getChild(thead, "tr"); List header = children(tr, "td"); if (header.size() < 1) { throw new RuntimeException(String.format("Expected at least 1 in /, found: %s", header)); } Map inheritedValueTitleMapping = new HashMap(); List valueTitles = new ArrayList(); for (int i = 1; i < header.size(); i++) { Element element = header.get(i); Element override = findChild(element, "overrides"); if (override != null) { element.removeChild(override); inheritedValueTitleMapping.put(override.getTextContent(), element); } Node firstChild = element.getFirstChild(); if (firstChild instanceof Text) { firstChild.setTextContent(firstChild.getTextContent().replaceFirst("^\\s+", "")); } Node lastChild = element.getLastChild(); if (lastChild instanceof Text) { lastChild.setTextContent(lastChild.getTextContent().replaceFirst("\\s+$", "")); } valueTitles.add(element); } ClassDoc superClass = classDoc.getSuperClass(); //adding the properties from the super class onto the inheriting class Map props = new TreeMap(); if (superClass != null) { for (PropertyDoc propertyDoc : superClass.getClassProperties()) { Map additionalValues = new LinkedHashMap(); for (ExtraAttributeDoc attributeDoc : propertyDoc.getAdditionalValues()) { String key = attributeDoc.getKey(); if (inheritedValueTitleMapping.get(key) != null) { ExtraAttributeDoc newAttribute = new ExtraAttributeDoc(inheritedValueTitleMapping.get(key), attributeDoc.getValueCell()); additionalValues.put(newAttribute.getKey(), newAttribute); } else { additionalValues.put(key, attributeDoc); } } props.put(propertyDoc.getName(), propertyDoc.forClass(classDoc, additionalValues.values())); } } for (Element row : children(classDoc.getPropertiesTable(), "tr")) { List cells = children(row, "td"); if (cells.size() != header.size()) { throw new RuntimeException(String.format("Expected %s elements in , found: %s", header.size(), tr)); } String propName = cells.get(0).getTextContent().trim(); PropertyMetaData property = classDoc.getClassMetaData().findProperty(propName); if (property == null) { throw new RuntimeException(String.format("No metadata for property '%s.%s'. Available properties: %s", classDoc.getName(), propName, classDoc.getClassMetaData().getPropertyNames())); } Map additionalValues = new LinkedHashMap(); if (superClass != null) { PropertyDoc overriddenProp = props.get(propName); if (overriddenProp != null) { for (ExtraAttributeDoc attributeDoc : overriddenProp.getAdditionalValues()) { additionalValues.put(attributeDoc.getKey(), attributeDoc); } } } for (int i = 1; i < header.size(); i++) { if (cells.get(i).getFirstChild() == null) { continue; } ExtraAttributeDoc attributeDoc = new ExtraAttributeDoc(valueTitles.get(i - 1), cells.get(i)); additionalValues.put(attributeDoc.getKey(), attributeDoc); } PropertyDoc propertyDoc = new PropertyDoc(property, javadocConverter.parse(property, listener).getDocbook(), new ArrayList(additionalValues.values())); if (propertyDoc.getDescription() == null) { throw new RuntimeException(String.format("Docbook content for '%s.%s' does not contain a description paragraph.", classDoc.getName(), propName)); } props.put(propName, propertyDoc); } for (PropertyDoc propertyDoc : props.values()) { classDoc.addClassProperty(propertyDoc); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ClassDocRenderer.java000066400000000000000000000045151210430504300317230ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; import org.w3c.dom.Element; public class ClassDocRenderer { private final GenerationListener listener = new DefaultGenerationListener(); private final ClassDescriptionRenderer descriptionRenderer = new ClassDescriptionRenderer(); private final PropertiesRenderer propertiesRenderer; private final MethodsRenderer methodsRenderer; final BlocksRenderer blocksRenderer; public ClassDocRenderer(LinkRenderer linkRenderer) { propertiesRenderer = new PropertiesRenderer(linkRenderer, listener); methodsRenderer = new MethodsRenderer(linkRenderer, listener); blocksRenderer = new BlocksRenderer(linkRenderer, listener); } public void mergeContent(ClassDoc classDoc, Element parent) { listener.start(String.format("class %s", classDoc.getName())); try { Element chapter = parent.getOwnerDocument().createElement("chapter"); parent.appendChild(chapter); chapter.setAttribute("id", classDoc.getId()); descriptionRenderer.renderTo(classDoc, chapter); mergeProperties(classDoc, chapter); mergeBlocks(classDoc, chapter); mergeMethods(classDoc, chapter); } finally { listener.finish(); } } void mergeProperties(ClassDoc classDoc, Element classContent) { propertiesRenderer.renderTo(classDoc, classContent); } void mergeMethods(ClassDoc classDoc, Element classContent) { methodsRenderer.renderTo(classDoc, classContent); } void mergeBlocks(ClassDoc classDoc, Element classContent) { blocksRenderer.renderTo(classDoc, classContent); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ClassDocSuperTypeBuilder.java000066400000000000000000000051151210430504300334210ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; import org.gradle.build.docs.dsl.source.model.ClassMetaData; import java.util.ArrayList; import java.util.List; public class ClassDocSuperTypeBuilder { private final DslDocModel model; private final GenerationListener listener; public ClassDocSuperTypeBuilder(DslDocModel model, GenerationListener listener) { this.model = model; this.listener = listener; } /** * Builds and attaches the supertype of the given class */ void build(ClassDoc classDoc) { ClassMetaData classMetaData = classDoc.getClassMetaData(); String superClassName = classMetaData.getSuperClassName(); if (superClassName != null) { // Assume this is a class and so has implemented all properties and methods somewhere in the superclass hierarchy ClassDoc superClass = model.getClassDoc(superClassName); classDoc.setSuperClass(superClass); return; } // Assume this is an interface - pick one interface to be the supertype // TODO - improve the property and methods builders to handle stuff inherited from multiple interfaces List interfaceNames = classMetaData.getInterfaceNames(); List candidates = new ArrayList(); for (String interfaceName : interfaceNames) { ClassDoc superInterface = model.findClassDoc(interfaceName); if (superInterface != null) { candidates.add(superInterface); } } if (candidates.isEmpty()) { // No documented supertypes return; } ClassDoc superInterface = candidates.get(0); if (candidates.size() > 1) { listener.warning("Ignoring properties and methods inherited from interfaces " + candidates.subList(1, candidates.size())); } classDoc.setSuperClass(superInterface); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/DefaultGenerationListener.java000066400000000000000000000024041210430504300336420ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.LinkedList; public class DefaultGenerationListener implements GenerationListener { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultGenerationListener.class); private final LinkedList contextStack = new LinkedList(); public void warning(String message) { LOGGER.warn(String.format("%s: %s", contextStack.getFirst(), message)); } public void start(String context) { contextStack.addFirst(context); } public void finish() { contextStack.removeFirst(); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/DocBookBuilder.java000066400000000000000000000054111210430504300313640ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; class DocBookBuilder { final LinkedList stack = new LinkedList(); final Document document; DocBookBuilder(Document document) { this.document = document; stack.addFirst(document.createElement("root")); } List getElements() { List elements = new ArrayList(); for (Node node = stack.getLast().getFirstChild(); node != null; node = node.getNextSibling()) { elements.add((Element) node); } return elements; } public void appendChild(String text) { appendChild(document.createTextNode(text)); } public void appendChild(Node node) { boolean inPara = false; if (node instanceof Element) { Element element = (Element) node; if (element.getTagName().equals("para") && stack.getFirst().getTagName().equals("para")) { pop(); inPara = true; } } stack.getFirst().appendChild(node); if (inPara) { Element para = document.createElement("para"); push(para); } } public void push(Element element) { stack.getFirst().appendChild(element); stack.addFirst(element); } public Element pop() { Element element = stack.removeFirst(); if (emptyPara(element)) { element.getParentNode().removeChild(element); } return element; } private boolean emptyPara(Element element) { if (!element.getTagName().equals("para")) { return false; } for (Node node = element.getFirstChild(); node != null; node = node.getNextSibling()) { if (!(node instanceof Text)) { return false; } Text text = (Text) node; if (!text.getTextContent().matches("\\s*")) { return false; } } return true; } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/DocComment.java000066400000000000000000000014111210430504300305610ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.w3c.dom.Element; import java.util.List; public interface DocComment { List getDocbook(); } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/DslDocModel.groovy000066400000000000000000000112411210430504300312700ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook import org.gradle.build.docs.XIncludeAwareXmlProvider import org.gradle.build.docs.dsl.source.TypeNameResolver import org.gradle.build.docs.dsl.docbook.model.ClassExtensionMetaData import org.gradle.build.docs.dsl.source.model.ClassMetaData import org.gradle.build.docs.model.ClassMetaDataRepository import org.w3c.dom.Document import org.gradle.build.docs.dsl.docbook.model.ClassDoc class DslDocModel { private final File classDocbookDir private final Document document private final Map classes = [:] private final ClassMetaDataRepository classMetaData private final Map extensionMetaData private final JavadocConverter javadocConverter private final ClassDocBuilder docBuilder private final LinkedList currentlyBuilding = new LinkedList() DslDocModel(File classDocbookDir, Document document, ClassMetaDataRepository classMetaData, Map extensionMetaData) { this.classDocbookDir = classDocbookDir this.document = document this.classMetaData = classMetaData this.extensionMetaData = extensionMetaData javadocConverter = new JavadocConverter(document, new JavadocLinkConverter(document, new TypeNameResolver(classMetaData), new LinkRenderer(document, this), classMetaData)) docBuilder = new ClassDocBuilder(this, javadocConverter) } Collection getClasses() { return classes.values().findAll { !it.name.contains('.internal.') } } boolean isKnownType(String className) { return classMetaData.find(className) != null } ClassDoc findClassDoc(String className) { ClassDoc classDoc = classes[className] if (classDoc == null && getFileForClass(className).isFile()) { return getClassDoc(className) } return classDoc } ClassDoc getClassDoc(String className) { ClassDoc classDoc = classes[className] if (classDoc == null) { classDoc = loadClassDoc(className) classes[className] = classDoc new ReferencedTypeBuilder(this).build(classDoc) } return classDoc } private ClassDoc loadClassDoc(String className) { if (currentlyBuilding.contains(className)) { throw new RuntimeException("Cycle building $className. Currently building $currentlyBuilding") } currentlyBuilding.addLast(className) try { ClassMetaData classMetaData = classMetaData.find(className) if (!classMetaData) { if (!className.contains('.internal.')) { throw new RuntimeException("No meta-data found for class '$className'.") } classMetaData = new ClassMetaData(className) } try { ClassExtensionMetaData extensionMetaData = extensionMetaData[className] if (!extensionMetaData) { extensionMetaData = new ClassExtensionMetaData(className) } File classFile = getFileForClass(className) if (!classFile.isFile()) { throw new RuntimeException("Docbook source file not found for class '$className' in $classDocbookDir.") } XIncludeAwareXmlProvider provider = new XIncludeAwareXmlProvider() def doc = new ClassDoc(className, provider.parse(classFile), document, classMetaData, extensionMetaData) docBuilder.build(doc) return doc } catch (ClassDocGenerationException e) { throw e } catch (Exception e) { throw new ClassDocGenerationException("Could not load the class documentation for class '$className'.", e) } } finally { currentlyBuilding.removeLast() } } private File getFileForClass(String className) { File classFile = new File(classDocbookDir, "${className}.xml") classFile } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ElementWarningsRenderer.java000066400000000000000000000046051210430504300333320ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.DslElementDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; public class ElementWarningsRenderer { public void renderTo(DslElementDoc elementDoc, String type, Element parent) { if (elementDoc.isDeprecated()) { Document document = parent.getOwnerDocument(); Element caution = document.createElement("caution"); parent.appendChild(caution); Element para = document.createElement("para"); caution.appendChild(para); para.appendChild(document.createTextNode(String.format("Note: This %s is ", type))); Element link = document.createElement("ulink"); para.appendChild(link); link.setAttribute("url", "../userguide/feature_lifecycle.html"); link.appendChild(document.createTextNode("deprecated")); para.appendChild(document.createTextNode(" and will be removed in the next major version of Gradle.")); } if (elementDoc.isIncubating()) { Document document = parent.getOwnerDocument(); Element caution = document.createElement("caution"); parent.appendChild(caution); Element para = document.createElement("para"); caution.appendChild(para); para.appendChild(document.createTextNode(String.format("Note: This %s is ", type))); Element link = document.createElement("ulink"); para.appendChild(link); link.setAttribute("url", "../userguide/feature_lifecycle.html"); link.appendChild(document.createTextNode("incubating")); para.appendChild(document.createTextNode(" and may change in a future version of Gradle.")); } } } ExtensionBlocksSummaryRenderer.java000066400000000000000000000051731210430504300346420ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassExtensionDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; public class ExtensionBlocksSummaryRenderer { private final BlockTableRenderer blockTableRenderer; public ExtensionBlocksSummaryRenderer(BlockTableRenderer blockTableRenderer) { this.blockTableRenderer = blockTableRenderer; } public void renderTo(ClassExtensionDoc extension, Element parent) { if (extension.getExtensionBlocks().isEmpty()) { return; } Document document = parent.getOwnerDocument(); Element section = document.createElement("section"); parent.appendChild(section); Element title = document.createElement("title"); section.appendChild(title); title.appendChild(document.createTextNode("Script blocks added by the ")); Element literal = document.createElement("literal"); title.appendChild(literal); literal.appendChild(document.createTextNode(extension.getPluginId())); title.appendChild(document.createTextNode(" plugin")); Element titleabbrev = document.createElement("titleabbrev"); section.appendChild(titleabbrev); literal = document.createElement("literal"); titleabbrev.appendChild(literal); literal.appendChild(document.createTextNode(extension.getPluginId())); titleabbrev.appendChild(document.createTextNode(" plugin")); Element table = document.createElement("table"); section.appendChild(table); title = document.createElement("title"); table.appendChild(title); title.appendChild(document.createTextNode("Script blocks - ")); literal = document.createElement("literal"); title.appendChild(literal); literal.appendChild(document.createTextNode(extension.getPluginId())); title.appendChild(document.createTextNode(" plugin")); blockTableRenderer.renderTo(extension.getExtensionBlocks(), table); } } ExtensionMethodsSummaryRenderer.java000066400000000000000000000051721210430504300350270ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassExtensionDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; public class ExtensionMethodsSummaryRenderer { private final MethodTableRenderer methodTableRenderer; public ExtensionMethodsSummaryRenderer(MethodTableRenderer methodTableRenderer) { this.methodTableRenderer = methodTableRenderer; } public void renderTo(ClassExtensionDoc extension, Element parent) { if (extension.getExtensionMethods().isEmpty()) { return; } Document document = parent.getOwnerDocument(); Element section = document.createElement("section"); parent.appendChild(section); Element title = document.createElement("title"); section.appendChild(title); title.appendChild(document.createTextNode("Methods added by the ")); Element literal = document.createElement("literal"); title.appendChild(literal); literal.appendChild(document.createTextNode(extension.getPluginId())); title.appendChild(document.createTextNode(" plugin")); Element titleabbrev = document.createElement("titleabbrev"); section.appendChild(titleabbrev); literal = document.createElement("literal"); titleabbrev.appendChild(literal); literal.appendChild(document.createTextNode(extension.getPluginId())); titleabbrev.appendChild(document.createTextNode(" plugin")); Element table = document.createElement("table"); section.appendChild(table); title = document.createElement("title"); table.appendChild(title); title.appendChild(document.createTextNode("Methods - ")); literal = document.createElement("literal"); title.appendChild(literal); literal.appendChild(document.createTextNode(extension.getPluginId())); title.appendChild(document.createTextNode(" plugin")); methodTableRenderer.renderTo(extension.getExtensionMethods(), table); } } ExtensionPropertiesSummaryRenderer.java000066400000000000000000000052321210430504300355550ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassExtensionDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; public class ExtensionPropertiesSummaryRenderer { private final PropertyTableRenderer propertyTableRenderer; public ExtensionPropertiesSummaryRenderer(PropertyTableRenderer propertyTableRenderer) { this.propertyTableRenderer = propertyTableRenderer; } public void renderTo(ClassExtensionDoc extension, Element parent) { if (extension.getExtensionProperties().isEmpty()) { return; } Document document = parent.getOwnerDocument(); Element section = document.createElement("section"); parent.appendChild(section); Element title = document.createElement("title"); section.appendChild(title); title.appendChild(document.createTextNode("Properties added by the ")); Element literal = document.createElement("literal"); title.appendChild(literal); literal.appendChild(document.createTextNode(extension.getPluginId())); title.appendChild(document.createTextNode(" plugin")); Element titleabbrev = document.createElement("titleabbrev"); section.appendChild(titleabbrev); literal = document.createElement("literal"); titleabbrev.appendChild(literal); literal.appendChild(document.createTextNode(extension.getPluginId())); titleabbrev.appendChild(document.createTextNode(" plugin")); Element table = document.createElement("table"); section.appendChild(table); title = document.createElement("title"); table.appendChild(title); title.appendChild(document.createTextNode("Properties - ")); literal = document.createElement("literal"); title.appendChild(literal); literal.appendChild(document.createTextNode(extension.getPluginId())); title.appendChild(document.createTextNode(" plugin")); propertyTableRenderer.renderTo(extension.getExtensionProperties(), table); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/GenerationListener.java000066400000000000000000000014231210430504300323350ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; public interface GenerationListener { void warning(String message); void start(String context); void finish(); } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/HtmlToXmlJavadocLexer.java000066400000000000000000000135151210430504300327210ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import java.util.*; /** * Normalises and cleans up HTML to convert it to XML semantics. */ public class HtmlToXmlJavadocLexer implements JavadocLexer { private final JavadocLexer lexer; private final Set blockElements = new HashSet(); private final Set blockContent = new HashSet(); public HtmlToXmlJavadocLexer(JavadocLexer lexer) { this.lexer = lexer; blockElements.add("p"); blockElements.add("pre"); blockElements.add("ul"); blockElements.add("ol"); blockElements.add("li"); blockElements.add("h1"); blockElements.add("h2"); blockElements.add("h3"); blockElements.add("h4"); blockElements.add("h5"); blockElements.add("h6"); blockElements.add("table"); blockElements.add("thead"); blockElements.add("tbody"); blockElements.add("tr"); blockElements.add("dl"); blockElements.add("dt"); blockElements.add("dd"); blockContent.add("ul"); blockContent.add("ol"); blockContent.add("table"); blockContent.add("thead"); blockContent.add("tbody"); blockContent.add("tr"); blockContent.add("dl"); } public void visit(TokenVisitor visitor) { lexer.visit(new VisitorImpl(visitor)); } private class VisitorImpl extends TokenVisitor { private final TokenVisitor visitor; private final LinkedList elementStack = new LinkedList(); private final Map attributes = new HashMap(); public VisitorImpl(TokenVisitor visitor) { this.visitor = visitor; } private void unwindTo(String element, TokenVisitor visitor) { if (elementStack.contains(element)) { while (!elementStack.getFirst().equals(element)) { visitor.onEndHtmlElement(elementStack.removeFirst()); } elementStack.removeFirst(); visitor.onEndHtmlElement(element); } } private void unwindTo(Collection ancestors, TokenVisitor visitor) { for (int i = 0; i < elementStack.size(); i++) { if (ancestors.contains(elementStack.get(i))) { for (; i > 0; i--) { visitor.onEndHtmlElement(elementStack.removeFirst()); } break; } } } @Override public void onStartHtmlElement(String name) { attributes.clear(); } @Override public void onHtmlElementAttribute(String name, String value) { attributes.put(name, value); } @Override public void onStartHtmlElementComplete(String name) { if (name.equals("li")) { unwindTo(Arrays.asList("ul", "ol"), visitor); } else if (name.equals("dt") || name.endsWith("dd")) { unwindTo(Arrays.asList("dl"), visitor); } else if (name.equals("tr")) { unwindTo(Arrays.asList("table", "thead", "tbody"), visitor); } else if (name.equals("th") || name.endsWith("td")) { unwindTo(Arrays.asList("tr", "table", "thead", "tbody"), visitor); } else if (blockElements.contains(name)) { unwindTo("p", visitor); } else if (!blockContent.contains(name) && !(name.equals("a") && attributes.containsKey("name"))) { onInlineContent(); } elementStack.addFirst(name); visitor.onStartHtmlElement(name); for (Map.Entry entry : attributes.entrySet()) { visitor.onHtmlElementAttribute(entry.getKey(), entry.getValue()); } attributes.clear(); visitor.onStartHtmlElementComplete(name); } @Override public void onEndHtmlElement(String name) { unwindTo(name, visitor); } private void onInlineContent() { if (elementStack.isEmpty() || blockContent.contains(elementStack.getFirst())) { elementStack.addFirst("p"); visitor.onStartHtmlElement("p"); visitor.onStartHtmlElementComplete("p"); } } @Override public void onStartJavadocTag(String name) { onInlineContent(); visitor.onStartJavadocTag(name); } @Override public void onEndJavadocTag(String name) { onInlineContent(); visitor.onEndJavadocTag(name); } @Override public void onText(String text) { boolean ws = text.matches("\\s*"); if (!ws) { onInlineContent(); visitor.onText(text); } else if (!elementStack.isEmpty() && !blockContent.contains(elementStack.getFirst())) { visitor.onText(text); } } @Override void onEnd() { while (!elementStack.isEmpty()) { visitor.onEndHtmlElement(elementStack.removeFirst()); } visitor.onEnd(); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/JavadocConverter.java000066400000000000000000000676411210430504300320110ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.api.GradleException; import org.gradle.build.docs.dsl.source.model.ClassMetaData; import org.gradle.build.docs.dsl.source.model.MethodMetaData; import org.gradle.build.docs.dsl.source.model.PropertyMetaData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Converts raw javadoc comments into docbook. */ public class JavadocConverter { private static final Pattern HEADER_PATTERN = Pattern.compile("h(\\d)", Pattern.CASE_INSENSITIVE); private final Document document; private final JavadocLinkConverter linkConverter; public JavadocConverter(Document document, JavadocLinkConverter linkConverter) { this.document = document; this.linkConverter = linkConverter; } public DocComment parse(ClassMetaData classMetaData, GenerationListener listener) { listener.start(String.format("class %s", classMetaData)); try { String rawCommentText = classMetaData.getRawCommentText(); try { return parse(rawCommentText, classMetaData, new NoOpCommentSource(), listener); } catch (Exception e) { throw new GradleException(String.format("Could not convert javadoc comment to docbook.%nClass: %s%nComment: %s", classMetaData, rawCommentText), e); } } finally { listener.finish(); } } public DocComment parse(final PropertyMetaData propertyMetaData, final GenerationListener listener) { listener.start(String.format("property %s", propertyMetaData)); try { ClassMetaData ownerClass = propertyMetaData.getOwnerClass(); String rawCommentText = propertyMetaData.getRawCommentText(); try { CommentSource commentSource = new InheritedPropertyCommentSource(propertyMetaData, listener); DocCommentImpl docComment = parse(rawCommentText, ownerClass, commentSource, listener); adjustGetterComment(docComment); return docComment; } catch (Exception e) { throw new GradleException(String.format("Could not convert javadoc comment to docbook.%nClass: %s%nProperty: %s%nComment: %s", ownerClass.getClassName(), propertyMetaData.getName(), rawCommentText), e); } } finally { listener.finish(); } } public DocComment parse(final MethodMetaData methodMetaData, final GenerationListener listener) { listener.start(String.format("method %s", methodMetaData)); try { ClassMetaData ownerClass = methodMetaData.getOwnerClass(); String rawCommentText = methodMetaData.getRawCommentText(); try { CommentSource commentSource = new InheritedMethodCommentSource(listener, methodMetaData); return parse(rawCommentText, ownerClass, commentSource, listener); } catch (Exception e) { throw new GradleException(String.format( "Could not convert javadoc comment to docbook.%nClass: %s%nMethod: %s%nComment: %s", ownerClass.getClassName(), methodMetaData.getSignature(), rawCommentText), e); } } finally { listener.finish(); } } private void adjustGetterComment(DocCommentImpl docComment) { // Replace 'Returns the ...' with 'The ...' List nodes = docComment.getDocbook(); if (nodes.isEmpty()) { return; } Element firstNode = nodes.get(0); if (!firstNode.getNodeName().equals("para") || !(firstNode.getFirstChild() instanceof Text)) { return; } Text comment = (Text) firstNode.getFirstChild(); Pattern getterPattern = Pattern.compile("returns\\s+the\\s+", Pattern.CASE_INSENSITIVE); Matcher matcher = getterPattern.matcher(comment.getData()); if (matcher.lookingAt()) { comment.setData("The " + comment.getData().substring(matcher.end())); } } private DocCommentImpl parse(String rawCommentText, ClassMetaData classMetaData, CommentSource inheritedCommentSource, GenerationListener listener) { JavadocLexer lexer = new HtmlToXmlJavadocLexer(new BasicJavadocLexer(new JavadocScanner(rawCommentText))); DocBookBuilder nodes = new DocBookBuilder(document); final HtmlGeneratingTokenHandler handler = new HtmlGeneratingTokenHandler(nodes, document); handler.add(new HtmlElementTranslatingHandler(nodes, document)); handler.add(new PreElementHandler(nodes, document)); handler.add(new JavadocTagToElementTranslatingHandler(nodes, document)); handler.add(new HeaderHandler(nodes, document)); handler.add(new LinkHandler(nodes, linkConverter, classMetaData, listener)); handler.add(new InheritDocHandler(nodes, inheritedCommentSource)); handler.add(new ValueTagHandler(nodes, linkConverter, classMetaData, listener)); handler.add(new TableHandler(nodes, document)); handler.add(new DlElementHandler(nodes, document)); handler.add(new AnchorElementHandler(nodes, document, classMetaData)); handler.add(new AToLinkTranslatingHandler(nodes, document, classMetaData)); handler.add(new AToUlinkTranslatingHandler(nodes, document)); handler.add(new UnknownJavadocTagHandler(nodes, document, listener)); handler.add(new UnknownHtmlElementHandler(nodes, document, listener)); lexer.visit(handler); return new DocCommentImpl(nodes.getElements()); } private static class DocCommentImpl implements DocComment { private final List nodes; public DocCommentImpl(List nodes) { this.nodes = nodes; } public List getDocbook() { return nodes; } } private static class HtmlGeneratingTokenHandler extends JavadocLexer.TokenVisitor { final DocBookBuilder nodes; final List elementHandlers = new ArrayList(); final List tagHandlers = new ArrayList(); final LinkedList handlerStack = new LinkedList(); final LinkedList tagStack = new LinkedList(); final Map attributes = new HashMap(); StringBuilder tagValue; final Document document; public HtmlGeneratingTokenHandler(DocBookBuilder nodes, Document document) { this.nodes = nodes; this.document = document; } public void add(HtmlElementHandler handler) { elementHandlers.add(handler); } public void add(JavadocTagHandler handler) { tagHandlers.add(handler); } @Override void onStartHtmlElement(String name) { attributes.clear(); } @Override void onHtmlElementAttribute(String name, String value) { attributes.put(name, value); } @Override void onStartHtmlElementComplete(String name) { for (HtmlElementHandler handler : elementHandlers) { if (handler.onStartElement(name, attributes)) { handlerStack.addFirst(handler); tagStack.addFirst(name); return; } } throw new UnsupportedOperationException(); } @Override void onEndHtmlElement(String name) { if (!tagStack.isEmpty() && tagStack.getFirst().equals(name)) { tagStack.removeFirst(); handlerStack.removeFirst().onEndElement(name); } } @Override void onStartJavadocTag(String name) { tagValue = new StringBuilder(); } public void onText(String text) { if (tagValue != null) { tagValue.append(text); return; } if (!handlerStack.isEmpty()) { handlerStack.getFirst().onText(text); return; } nodes.appendChild(text); } @Override void onEndJavadocTag(String name) { for (JavadocTagHandler handler : tagHandlers) { if (handler.onJavadocTag(name, tagValue.toString())) { tagValue = null; return; } } throw new UnsupportedOperationException(); } } private interface JavadocTagHandler { boolean onJavadocTag(String tag, String value); } private interface HtmlElementHandler { boolean onStartElement(String element, Map attributes); void onText(String text); void onEndElement(String element); } private static class UnknownJavadocTagHandler implements JavadocTagHandler { private final DocBookBuilder nodes; private final Document document; private final GenerationListener listener; private UnknownJavadocTagHandler(DocBookBuilder nodes, Document document, GenerationListener listener) { this.nodes = nodes; this.document = document; this.listener = listener; } public boolean onJavadocTag(String tag, String value) { listener.warning(String.format("Unsupported Javadoc tag '%s'", tag)); Element element = document.createElement("UNHANDLED-TAG"); element.appendChild(document.createTextNode(String.format("{@%s %s}", tag, value))); nodes.appendChild(element); return true; } } private static class UnknownHtmlElementHandler implements HtmlElementHandler { private final DocBookBuilder nodes; private final Document document; private final GenerationListener listener; private UnknownHtmlElementHandler(DocBookBuilder nodes, Document document, GenerationListener listener) { this.nodes = nodes; this.document = document; this.listener = listener; } public boolean onStartElement(String elementName, Map attributes) { listener.warning(String.format("Unsupported HTML element <%s>", elementName)); Element element = document.createElement("UNHANDLED-ELEMENT"); element.appendChild(document.createTextNode(String.format("<%s>", elementName))); nodes.push(element); return true; } public void onText(String text) { nodes.appendChild(text); } public void onEndElement(String elementName) { nodes.appendChild(String.format("", elementName)); nodes.pop(); } } private static class JavadocTagToElementTranslatingHandler implements JavadocTagHandler { private final DocBookBuilder nodes; private final Document document; private final Map tagToElementMap = new HashMap(); private JavadocTagToElementTranslatingHandler(DocBookBuilder nodes, Document document) { this.nodes = nodes; this.document = document; tagToElementMap.put("code", "literal"); } public boolean onJavadocTag(String tag, String value) { String elementName = tagToElementMap.get(tag); if (elementName == null) { return false; } Element element = document.createElement(elementName); element.appendChild(document.createTextNode(value)); nodes.appendChild(element); return true; } } private static class HtmlElementTranslatingHandler implements HtmlElementHandler { private final DocBookBuilder nodes; private final Document document; private final Map elementToElementMap = new HashMap(); private HtmlElementTranslatingHandler(DocBookBuilder nodes, Document document) { this.nodes = nodes; this.document = document; elementToElementMap.put("p", "para"); elementToElementMap.put("ul", "itemizedlist"); elementToElementMap.put("ol", "orderedlist"); elementToElementMap.put("li", "listitem"); elementToElementMap.put("em", "emphasis"); elementToElementMap.put("i", "emphasis"); elementToElementMap.put("b", "emphasis"); elementToElementMap.put("code", "literal"); elementToElementMap.put("tt", "literal"); } public boolean onStartElement(String element, Map attributes) { String newElementName = elementToElementMap.get(element); if (newElementName == null) { return false; } nodes.push(document.createElement(newElementName)); return true; } public void onText(String text) { nodes.appendChild(text); } public void onEndElement(String element) { nodes.pop(); } } private static class PreElementHandler implements HtmlElementHandler { private final DocBookBuilder nodes; private final Document document; private PreElementHandler(DocBookBuilder nodes, Document document) { this.nodes = nodes; this.document = document; } public boolean onStartElement(String element, Map attributes) { if (!"pre".equals(element)) { return false; } Element newElement = document.createElement("programlisting"); //we're making an assumption that all
 elements contain java code
            //this should mostly be true :)
            //if it isn't true then the syntax highlighting won't spoil the view too much anyway
            newElement.setAttribute("language", "java");
            nodes.push(newElement);
            return true;
        }

        public void onText(String text) {
            nodes.appendChild(text);
        }

        public void onEndElement(String element) {
            nodes.pop();
        }
    }

    private static class HeaderHandler implements HtmlElementHandler {
        final DocBookBuilder nodes;
        final Document document;
        int sectionDepth;

        private HeaderHandler(DocBookBuilder nodes, Document document) {
            this.nodes = nodes;
            this.document = document;
        }

        public boolean onStartElement(String element, Map attributes) {
            Matcher matcher = HEADER_PATTERN.matcher(element);
            if (!matcher.matches()) {
                return false;
            }
            int depth = Integer.parseInt(matcher.group(1));
            if (sectionDepth == 0) {
                sectionDepth = depth - 1;
            }
            while (sectionDepth >= depth) {
                nodes.pop();
                sectionDepth--;
            }
            Element section = document.createElement("section");
            while (sectionDepth < depth) {
                nodes.push(section);
                sectionDepth++;
            }
            nodes.push(document.createElement("title"));
            sectionDepth = depth;
            return true;
        }

        public void onText(String text) {
            nodes.appendChild(text);
        }

        public void onEndElement(String element) {
            nodes.pop();
        }
    }

    private static class TableHandler implements HtmlElementHandler {
        private final DocBookBuilder nodes;
        private final Document document;
        private Element currentTable;
        private Element currentRow;
        private Element header;

        public TableHandler(DocBookBuilder nodes, Document document) {
            this.nodes = nodes;
            this.document = document;
        }

        public boolean onStartElement(String elementName, Map attributes) {
            if (elementName.equals("table")) {
                if (currentTable != null) {
                    throw new UnsupportedOperationException("A table within a table is not supported.");
                }
                currentTable = document.createElement("table");
                nodes.push(currentTable);
                return true;
            }
            if (elementName.equals("tr")) {
                currentRow = document.createElement("tr");
                nodes.push(currentRow);
                return true;
            }
            if (elementName.equals("th")) {
                if (header == null) {
                    header = document.createElement("thead");
                    currentTable.insertBefore(header, null);
                    header.appendChild(currentRow);
                }
                nodes.push(document.createElement("td"));
                return true;
            }
            if (elementName.equals("td")) {
                nodes.push(document.createElement("td"));
                return true;
            }
            return false;
        }

        public void onEndElement(String elementName) {
            if (elementName.equals("table")) {
                currentTable = null;
                header = null;
            }
            if (elementName.equals("tr")) {
                currentRow = null;
            }
            nodes.pop();
        }

        public void onText(String text) {
            nodes.appendChild(text);
        }
    }

    private static class AnchorElementHandler implements HtmlElementHandler {
        private final DocBookBuilder nodes;
        private final Document document;
        private final ClassMetaData classMetaData;

        private AnchorElementHandler(DocBookBuilder nodes, Document document, ClassMetaData classMetaData) {
            this.nodes = nodes;
            this.document = document;
            this.classMetaData = classMetaData;
        }

        public boolean onStartElement(String elementName, Map attributes) {
            if (!elementName.equals("a") || !attributes.containsKey("name")) {
                return false;
            }
            Element element = document.createElement("anchor");
            String id = String.format("%s.%s", classMetaData.getClassName(), attributes.get("name"));
            element.setAttribute("id", id);
            nodes.appendChild(element);
            return true;
        }

        public void onEndElement(String element) {
        }

        public void onText(String text) {
        }
    }

    private static class AToLinkTranslatingHandler implements HtmlElementHandler {
        private final DocBookBuilder nodes;
        private final Document document;
        private final ClassMetaData classMetaData;

        private AToLinkTranslatingHandler(DocBookBuilder nodes, Document document, ClassMetaData classMetaData) {
            this.nodes = nodes;
            this.document = document;
            this.classMetaData = classMetaData;
        }

        public boolean onStartElement(String elementName, Map attributes) {
            if (!elementName.equals("a") || !attributes.containsKey("href")) {
                return false;
            }
            String href = attributes.get("href");
            if (!href.startsWith("#")) {
                return false;
            }
            Element element = document.createElement("link");
            String targetId = String.format("%s.%s", classMetaData.getClassName(), href.substring(1));
            element.setAttribute("linkend", targetId);
            nodes.push(element);
            return true;
        }

        public void onEndElement(String element) {
            nodes.pop();
        }

        public void onText(String text) {
            nodes.appendChild(text);
        }
    }

    private static class AToUlinkTranslatingHandler implements HtmlElementHandler {
        private final DocBookBuilder nodes;
        private final Document document;

        private AToUlinkTranslatingHandler(DocBookBuilder nodes, Document document) {
            this.nodes = nodes;
            this.document = document;
        }

        public boolean onStartElement(String elementName, Map attributes) {
            if (!elementName.equals("a") || !attributes.containsKey("href")) {
                return false;
            }
            String href = attributes.get("href");
            if (href.startsWith("#")) {
                return false;
            }
            Element element = document.createElement("ulink");
            element.setAttribute("url", href);
            nodes.push(element);
            return true;
        }

        public void onEndElement(String element) {
            nodes.pop();
        }

        public void onText(String text) {
            nodes.appendChild(text);
        }
    }

    private static class DlElementHandler implements HtmlElementHandler {
        private final DocBookBuilder nodes;
        private final Document document;
        private Element currentList;
        private Element currentItem;

        public DlElementHandler(DocBookBuilder nodes, Document document) {
            this.nodes = nodes;
            this.document = document;
        }

        public boolean onStartElement(String elementName, Map attributes) {
            if (elementName.equals("dl")) {
                if (currentList != null) {
                    throw new UnsupportedOperationException("
within a
is not supported."); } currentList = document.createElement("variablelist"); nodes.push(currentList); return true; } if (elementName.equals("dt")) { if (currentItem != null) { nodes.pop(); } currentItem = document.createElement("varlistentry"); nodes.push(currentItem); nodes.push(document.createElement("term")); return true; } if (elementName.equals("dd")) { if (currentItem == null) { throw new IllegalStateException("No
element preceeding
element."); } nodes.push(document.createElement("listitem")); return true; } return false; } public void onEndElement(String element) { if (element.equals("dl")) { currentList = null; if (currentItem != null) { currentItem = null; nodes.pop(); } nodes.pop(); } if (element.equals("dt")) { nodes.pop(); } if (element.equals("dd")) { nodes.pop(); } } public void onText(String text) { nodes.appendChild(text); } } private static class ValueTagHandler implements JavadocTagHandler { private final JavadocLinkConverter linkConverter; private final ClassMetaData classMetaData; private final DocBookBuilder nodes; private final GenerationListener listener; public ValueTagHandler(DocBookBuilder nodes, JavadocLinkConverter linkConverter, ClassMetaData classMetaData, GenerationListener listener) { this.nodes = nodes; this.linkConverter = linkConverter; this.classMetaData = classMetaData; this.listener = listener; } public boolean onJavadocTag(String tag, String value) { if (!tag.equals("value")) { return false; } nodes.appendChild(linkConverter.resolveValue(value, classMetaData, listener)); return true; } } private static class LinkHandler implements JavadocTagHandler { private final DocBookBuilder nodes; private final JavadocLinkConverter linkConverter; private final ClassMetaData classMetaData; private final GenerationListener listener; private LinkHandler(DocBookBuilder nodes, JavadocLinkConverter linkConverter, ClassMetaData classMetaData, GenerationListener listener) { this.nodes = nodes; this.linkConverter = linkConverter; this.classMetaData = classMetaData; this.listener = listener; } public boolean onJavadocTag(String tag, String value) { if (!tag.equals("link")) { return false; } nodes.appendChild(linkConverter.resolve(value, classMetaData, listener)); return true; } } private static class InheritDocHandler implements JavadocTagHandler { private final CommentSource source; private final DocBookBuilder nodeStack; private InheritDocHandler(DocBookBuilder nodeStack, CommentSource source) { this.nodeStack = nodeStack; this.source = source; } public boolean onJavadocTag(String tag, String value) { if (!tag.equals("inheritDoc")) { return false; } for (Node node : source.getCommentText()) { nodeStack.appendChild(node); } return true; } } private interface CommentSource { Iterable getCommentText(); } private static class NoOpCommentSource implements CommentSource { public List getCommentText() { throw new UnsupportedOperationException(); } } private class InheritedPropertyCommentSource implements CommentSource { private final PropertyMetaData propertyMetaData; private final GenerationListener listener; public InheritedPropertyCommentSource(PropertyMetaData propertyMetaData, GenerationListener listener) { this.propertyMetaData = propertyMetaData; this.listener = listener; } public Iterable getCommentText() { PropertyMetaData overriddenProperty = propertyMetaData.getOverriddenProperty(); if (overriddenProperty == null) { listener.warning("No inherited javadoc comment found."); return Arrays.asList(document.createTextNode("!!NO INHERITED DOC COMMENT!!")); } return parse(overriddenProperty, listener).getDocbook(); } } private class InheritedMethodCommentSource implements CommentSource { private final GenerationListener listener; private final MethodMetaData methodMetaData; public InheritedMethodCommentSource(GenerationListener listener, MethodMetaData methodMetaData) { this.listener = listener; this.methodMetaData = methodMetaData; } public Iterable getCommentText() { MethodMetaData overriddenMethod = methodMetaData.getOverriddenMethod(); if (overriddenMethod == null) { listener.warning("No inherited javadoc comment found."); return Arrays.asList(document.createTextNode("!!NO INHERITED DOC COMMENT!!")); } return parse(overriddenMethod, listener).getDocbook(); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/JavadocLexer.java000066400000000000000000000024501210430504300311040ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; public interface JavadocLexer { /** * Visits the tokens in the input stream for this lexer. Reads to the end of the input. */ void visit(TokenVisitor visitor); class TokenVisitor { void onStartHtmlElement(String name) { } void onHtmlElementAttribute(String name, String value) { } void onStartHtmlElementComplete(String name) { } void onEndHtmlElement(String name) { } void onStartJavadocTag(String name) { } void onEndJavadocTag(String name) { } void onText(String text) { } void onEnd() { } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/JavadocLinkConverter.java000066400000000000000000000147501210430504300326200ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.source.TypeNameResolver; import org.gradle.build.docs.dsl.source.model.ClassMetaData; import org.gradle.build.docs.dsl.source.model.MethodMetaData; import org.gradle.build.docs.dsl.source.model.TypeMetaData; import org.gradle.build.docs.model.ClassMetaDataRepository; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Converts a javadoc link into docbook. */ public class JavadocLinkConverter { private final Pattern linkPattern = Pattern.compile("(?s)\\s*([\\w\\.]*)(#(\\w+)(\\((.*)\\))?)?.*"); private final Document document; private final TypeNameResolver typeNameResolver; private final LinkRenderer linkRenderer; private final ClassMetaDataRepository repository; public JavadocLinkConverter(Document document, TypeNameResolver typeNameResolver, LinkRenderer linkRenderer, ClassMetaDataRepository repository) { this.document = document; this.typeNameResolver = typeNameResolver; this.linkRenderer = linkRenderer; this.repository = repository; } /** * Converts a javadoc link into docbook. */ public Node resolve(String link, ClassMetaData classMetaData, GenerationListener listener) { Node node = doResolve(link, classMetaData, listener); if (node != null) { return node; } listener.warning(String.format("Could not convert Javadoc link '%s'", link)); Element element = document.createElement("UNHANDLED-LINK"); element.appendChild(document.createTextNode(link)); return element; } private Node doResolve(String link, ClassMetaData classMetaData, GenerationListener listener) { Matcher matcher = linkPattern.matcher(link); if (!matcher.matches()) { return null; } String className = null; if (matcher.group(1).length() > 0) { className = typeNameResolver.resolve(matcher.group(1), classMetaData); if (className == null) { return null; } } if (matcher.group(2) == null) { return linkRenderer.link(new TypeMetaData(className), listener); } ClassMetaData targetClass; if (className != null) { targetClass = repository.find(className); if (targetClass == null) { return null; } } else { targetClass = classMetaData; } String methodSignature = matcher.group(3); if (matcher.group(5) != null) { StringBuilder signature = new StringBuilder(); signature.append(methodSignature); signature.append("("); if (matcher.group(5).length() > 0) { String[] types = matcher.group(5).split(",\\s*"); for (int i = 0; i < types.length; i++) { String type = types[i]; Matcher typeMatcher = Pattern.compile("(\\w+)(.*)").matcher(type); if (!typeMatcher.matches()) { return null; } if (i > 0) { signature.append(", "); } signature.append(typeNameResolver.resolve(typeMatcher.group(1), classMetaData)); signature.append(typeMatcher.group(2)); } } signature.append(")"); methodSignature = signature.toString(); } MethodMetaData method = findMethod(methodSignature, targetClass); if (method == null) { return null; } return linkRenderer.link(method, listener); } private MethodMetaData findMethod(String name, ClassMetaData targetClass) { List candidates = new ArrayList(); for (MethodMetaData methodMetaData : targetClass.getDeclaredMethods()) { if (name.equals(methodMetaData.getOverrideSignature())) { return methodMetaData; } if (name.equals(methodMetaData.getName())) { candidates.add(methodMetaData); } } if (candidates.size() != 1) { return null; } return candidates.get(0); } /** * Converts a javadoc value link into docbook. */ public Node resolveValue(String fieldName, ClassMetaData classMetaData, GenerationListener listener) { String[] parts = fieldName.split("#"); ClassMetaData targetClass; if (parts[0].length() > 0) { String targetClassName = typeNameResolver.resolve(parts[0], classMetaData); targetClass = repository.find(targetClassName); if (targetClass == null) { listener.warning(String.format("Could not local target class '%s' for field value link '%s'", targetClass, fieldName)); Element element = document.createElement("UNHANDLED-VALUE"); element.appendChild(document.createTextNode(targetClassName + ":" + parts[1])); return element; } } else { targetClass = classMetaData; } String value = targetClass.getConstants().get(parts[1]); if (value == null) { listener.warning(String.format("Field '%s' does not have any value", fieldName)); Element element = document.createElement("NO-VALUE-FOR_FIELD"); element.appendChild(document.createTextNode(targetClass.getClassName() + ":" + parts[1])); return element; } Element element = document.createElement("literal"); element.appendChild(document.createTextNode(value)); return element; } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/JavadocScanner.java000066400000000000000000000104711210430504300314200ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.internal.UncheckedException; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Extracts the main description of a javadoc comment from its raw text, as a stream of characters. See * http://download.oracle.com/javase/1.5.0/docs/tooldocs/solaris/javadoc.html#documentationcomments for details. * *
    *
  • Removes leading '*' characters.
  • *
  • Removes block tags.
  • *
  • Removes leading and trailing empty lines.
  • *
*/ class JavadocScanner { private final StringBuilder input = new StringBuilder(); private int pos; private int markPos; JavadocScanner(String rawCommentText) { pushText(rawCommentText); } @Override public String toString() { return input.substring(pos); } public boolean isEmpty() { return pos == input.length(); } public void mark() { markPos = pos; } public void next() { next(1); } public void next(int n) { pos += n; } public boolean lookingAt(char c) { return input.charAt(pos) == c; } public boolean lookingAt(CharSequence prefix) { int i = 0; int cpos = pos; while (i < prefix.length() && cpos < input.length()) { if (prefix.charAt(i) != input.charAt(cpos)) { return false; } i++; cpos++; } return true; } public boolean lookingAt(Pattern pattern) { Matcher m = pattern.matcher(input); m.region(pos, input.length()); return m.lookingAt(); } public String region() { return input.substring(markPos, pos); } /** * Moves the position to the next instance of the given character, or the end of the input if not found. */ public void find(char c) { int cpos = pos; while (cpos < input.length()) { if (input.charAt(cpos) == c) { break; } cpos++; } pos = cpos; } /** * Moves the position to the start of the next instance of the given pattern, or the end of the input if not * found. */ public void find(Pattern pattern) { Matcher m = pattern.matcher(input); m.region(pos, input.length()); if (m.find()) { pos = m.start(); } else { pos = input.length(); } } /** * Moves the position over the given pattern if currently looking at the pattern. Does nothing if not. */ public void skip(Pattern pattern) { Matcher m = pattern.matcher(input); m.region(pos, input.length()); if (m.lookingAt()) { pos = m.end(); } } public void pushText(String rawCommentText) { if (rawCommentText == null) { return; } StringBuilder builder = new StringBuilder(); try { BufferedReader reader = new BufferedReader(new StringReader(rawCommentText)); String line; while ((line = reader.readLine()) != null) { line = line.replaceFirst("\\s*\\* ?", ""); if (line.startsWith("@")) { // Ignore the tag section of the comment break; } builder.append(line); builder.append("\n"); } } catch (IOException e) { throw UncheckedException.throwAsUncheckedException(e); } input.insert(pos, builder.toString().trim()); } public char getFirst() { return input.charAt(pos); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/LinkRenderer.java000066400000000000000000000121211210430504300311150ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.apache.commons.lang.StringUtils; import org.gradle.build.docs.dsl.source.model.MethodMetaData; import org.gradle.build.docs.dsl.source.model.TypeMetaData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import java.util.HashSet; import java.util.Set; public class LinkRenderer { private final Document document; private final DslDocModel model; private final Set primitiveTypes = new HashSet(); public LinkRenderer(Document document, DslDocModel model) { this.document = document; this.model = model; primitiveTypes.add("boolean"); primitiveTypes.add("byte"); primitiveTypes.add("short"); primitiveTypes.add("int"); primitiveTypes.add("long"); primitiveTypes.add("char"); primitiveTypes.add("float"); primitiveTypes.add("double"); primitiveTypes.add("void"); } Node link(TypeMetaData type, final GenerationListener listener) { final Element linkElement = document.createElement("classname"); type.visitSignature(new TypeMetaData.SignatureVisitor() { public void visitText(String text) { linkElement.appendChild(document.createTextNode(text)); } public void visitType(String name) { linkElement.appendChild(addType(name, listener)); } }); linkElement.normalize(); if (linkElement.getChildNodes().getLength() == 1 && linkElement.getFirstChild() instanceof Element) { return linkElement.getFirstChild(); } return linkElement; } private Node addType(String className, GenerationListener listener) { if (model.isKnownType(className)) { Element linkElement = document.createElement("apilink"); linkElement.setAttribute("class", className); return linkElement; } if (primitiveTypes.contains(className)) { Element classNameElement = document.createElement("classname"); classNameElement.appendChild(document.createTextNode(className)); return classNameElement; } if (className.startsWith("java.")) { Element linkElement = document.createElement("ulink"); linkElement.setAttribute("url", String.format("http://download.oracle.com/javase/1.5.0/docs/api/%s.html", className.replace(".", "/"))); Element classNameElement = document.createElement("classname"); classNameElement.appendChild(document.createTextNode(StringUtils.substringAfterLast(className, "."))); linkElement.appendChild(classNameElement); return linkElement; } if (className.startsWith("groovy.")) { Element linkElement = document.createElement("ulink"); linkElement.setAttribute("url", String.format("http://groovy.codehaus.org/gapi/%s.html", className.replace( ".", "/"))); Element classNameElement = document.createElement("classname"); classNameElement.appendChild(document.createTextNode(StringUtils.substringAfterLast(className, "."))); linkElement.appendChild(classNameElement); return linkElement; } //this if is a bit cheesy but 1-letter classname surely means a generic type and the warning will be useless if (className.length() > 1) { listener.warning(String.format("Could not generate link for unknown class '%s'", className)); } Element element = document.createElement("classname"); element.appendChild(document.createTextNode(className)); return element; } public Node link(MethodMetaData method, GenerationListener listener) { if (model.isKnownType(method.getOwnerClass().getClassName())) { Element apilink = document.createElement("apilink"); apilink.setAttribute("class", method.getOwnerClass().getClassName()); apilink.setAttribute("method", method.getOverrideSignature()); return apilink; } else { listener.warning(String.format("Could not generate link for method %s", method)); Element element = document.createElement("UNKNOWN-METHOD"); element.appendChild(document.createTextNode(String.format("%s.%s()", method.getOwnerClass().getClassName(), method.getName()))); return element; } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/MethodDetailRenderer.java000066400000000000000000000053521210430504300325730ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.MethodDoc; import org.gradle.build.docs.dsl.source.model.ParameterMetaData; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.util.List; public class MethodDetailRenderer { private final GenerationListener listener; private final LinkRenderer linkRenderer; private final ElementWarningsRenderer warningsRenderer = new ElementWarningsRenderer(); public MethodDetailRenderer(LinkRenderer linkRenderer, GenerationListener listener) { this.linkRenderer = linkRenderer; this.listener = listener; } public void renderTo(MethodDoc methodDoc, Element parent) { Document document = parent.getOwnerDocument(); Element section = document.createElement("section"); parent.appendChild(section); section.setAttribute("id", methodDoc.getId()); section.setAttribute("role", "detail"); Element title = document.createElement("title"); section.appendChild(title); title.appendChild(linkRenderer.link(methodDoc.getMetaData().getReturnType(), listener)); title.appendChild(document.createTextNode(" ")); Element literal = document.createElement("literal"); title.appendChild(literal); literal.appendChild(document.createTextNode(methodDoc.getName())); title.appendChild(document.createTextNode("(")); List parameters = methodDoc.getMetaData().getParameters(); for (int i = 0; i < parameters.size(); i++) { ParameterMetaData param = parameters.get(i); if (i > 0) { title.appendChild(document.createTextNode(", ")); } title.appendChild(linkRenderer.link(param.getType(), listener)); title.appendChild(document.createTextNode(" " + param.getName())); } title.appendChild(document.createTextNode(")")); warningsRenderer.renderTo(methodDoc, "method", section); for (Element element : methodDoc.getComment()) { section.appendChild(document.importNode(element, true)); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/MethodTableRenderer.java000066400000000000000000000065171210430504300324240ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.MethodDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; public class MethodTableRenderer { public void renderTo(Iterable methods, Element parent) { Document document = parent.getOwnerDocument(); // // // Method // Description // // Element thead = document.createElement("thead"); parent.appendChild(thead); Element tr = document.createElement("tr"); thead.appendChild(tr); Element td = document.createElement("td"); tr.appendChild(td); td.appendChild(document.createTextNode("Method")); td = document.createElement("td"); tr.appendChild(td); td.appendChild(document.createTextNode("Description")); for (MethodDoc methodDoc : methods) { // // $name$signature // $description // tr = document.createElement("tr"); parent.appendChild(tr); td = document.createElement("td"); tr.appendChild(td); Element literal = document.createElement("literal"); td.appendChild(literal); Element link = document.createElement("link"); literal.appendChild(link); link.setAttribute("linkend", methodDoc.getId()); link.appendChild(document.createTextNode(methodDoc.getName())); StringBuilder signature = new StringBuilder(); signature.append("("); for (int i = 0; i < methodDoc.getMetaData().getParameters().size(); i++) { if (i > 0) { signature.append(", "); } signature.append(methodDoc.getMetaData().getParameters().get(i).getName()); } signature.append(")"); literal.appendChild(document.createTextNode(signature.toString())); td = document.createElement("td"); tr.appendChild(td); if (methodDoc.isDeprecated()) { Element caution = document.createElement("caution"); td.appendChild(caution); caution.appendChild(document.createTextNode("Deprecated")); } if (methodDoc.isIncubating()) { Element caution = document.createElement("caution"); td.appendChild(caution); caution.appendChild(document.createTextNode("Incubating")); } td.appendChild(document.importNode(methodDoc.getDescription(), true)); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/MethodsRenderer.java000066400000000000000000000067521210430504300316400ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; import org.gradle.build.docs.dsl.docbook.model.ClassExtensionDoc; import org.gradle.build.docs.dsl.docbook.model.MethodDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.util.Collection; public class MethodsRenderer { private final MethodTableRenderer methodTableRenderer = new MethodTableRenderer(); private final ExtensionMethodsSummaryRenderer extensionMethodsSummaryRenderer; private final MethodDetailRenderer methodDetailRenderer; public MethodsRenderer(LinkRenderer linkRenderer, GenerationListener listener) { methodDetailRenderer = new MethodDetailRenderer(linkRenderer, listener); extensionMethodsSummaryRenderer = new ExtensionMethodsSummaryRenderer(methodTableRenderer); } public void renderTo(ClassDoc classDoc, Element parent) { Document document = parent.getOwnerDocument(); Element summarySection = document.createElement("section"); parent.appendChild(summarySection); Element title = document.createElement("title"); summarySection.appendChild(title); title.appendChild(document.createTextNode("Methods")); boolean hasMethods = false; Collection classMethods = classDoc.getClassMethods(); if (!classMethods.isEmpty()) { hasMethods = true; Element table = document.createElement("table"); summarySection.appendChild(table); title = document.createElement("title"); table.appendChild(title); title.appendChild(document.createTextNode("Methods - " + classDoc.getSimpleName())); methodTableRenderer.renderTo(classMethods, table); } for (ClassExtensionDoc extensionDoc : classDoc.getClassExtensions()) { hasMethods |= !extensionDoc.getExtensionMethods().isEmpty(); extensionMethodsSummaryRenderer.renderTo(extensionDoc, summarySection); } if (!hasMethods) { Element para = document.createElement("para"); summarySection.appendChild(para); para.appendChild(document.createTextNode("No methods")); return; } Element detailsSection = document.createElement("section"); parent.appendChild(detailsSection); title = document.createElement("title"); detailsSection.appendChild(title); title.appendChild(document.createTextNode("Method details")); for (MethodDoc methodDoc : classMethods) { methodDetailRenderer.renderTo(methodDoc, detailsSection); } for (ClassExtensionDoc extensionDoc : classDoc.getClassExtensions()) { for (MethodDoc methodDoc : extensionDoc.getExtensionMethods()) { methodDetailRenderer.renderTo(methodDoc, detailsSection); } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ModelBuilderSupport.java000066400000000000000000000042561210430504300325070ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.util.ArrayList; import java.util.List; public class ModelBuilderSupport { protected List children(Element element, String childName) { List matches = new ArrayList(); NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node instanceof Element) { Element childElement = (Element) node; if (childElement.getTagName().equals(childName)) { matches.add(childElement); } } } return matches; } protected Element getChild(Element element, String childName) { Element child = findChild(element, childName); if (child != null) { return child; } throw new RuntimeException(String.format("No <%s> element found in <%s>", childName, element.getTagName())); } protected Element findChild(Element element, String childName) { NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node instanceof Element) { Element childElement = (Element) node; if (childElement.getTagName().equals(childName)) { return childElement; } } } return null; } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/PropertiesRenderer.java000066400000000000000000000071351210430504300323650ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; import org.gradle.build.docs.dsl.docbook.model.ClassExtensionDoc; import org.gradle.build.docs.dsl.docbook.model.PropertyDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.util.Collection; public class PropertiesRenderer { private final PropertyTableRenderer propertyTableRenderer = new PropertyTableRenderer(); private final ExtensionPropertiesSummaryRenderer extensionPropertiesSummaryRenderer; private final PropertyDetailRenderer propertiesDetailRenderer; public PropertiesRenderer(LinkRenderer linkRenderer, GenerationListener listener) { propertiesDetailRenderer = new PropertyDetailRenderer(linkRenderer, listener); extensionPropertiesSummaryRenderer = new ExtensionPropertiesSummaryRenderer(propertyTableRenderer); } public void renderTo(ClassDoc classDoc, Element parent) { Document document = parent.getOwnerDocument(); Element summarySection = document.createElement("section"); parent.appendChild(summarySection); Element title = document.createElement("title"); summarySection.appendChild(title); title.appendChild(document.createTextNode("Properties")); boolean hasProperties = false; Collection classProperties = classDoc.getClassProperties(); if (!classProperties.isEmpty()) { hasProperties = true; Element table = document.createElement("table"); summarySection.appendChild(table); title = document.createElement("title"); table.appendChild(title); title.appendChild(document.createTextNode("Properties - " + classDoc.getSimpleName())); propertyTableRenderer.renderTo(classProperties, table); } for (ClassExtensionDoc extensionDoc : classDoc.getClassExtensions()) { hasProperties |= !extensionDoc.getExtensionProperties().isEmpty(); extensionPropertiesSummaryRenderer.renderTo(extensionDoc, summarySection); } if (!hasProperties) { Element para = document.createElement("para"); summarySection.appendChild(para); para.appendChild(document.createTextNode("No properties")); return; } Element detailsSection = document.createElement("section"); parent.appendChild(detailsSection); title = document.createElement("title"); detailsSection.appendChild(title); title.appendChild(document.createTextNode("Property details")); for (PropertyDoc classProperty : classProperties) { propertiesDetailRenderer.renderTo(classProperty, detailsSection); } for (ClassExtensionDoc extensionDoc : classDoc.getClassExtensions()) { for (PropertyDoc propertyDoc : extensionDoc.getExtensionProperties()) { propertiesDetailRenderer.renderTo(propertyDoc, detailsSection); } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/PropertyDetailRenderer.java000066400000000000000000000065371210430504300332050ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ExtraAttributeDoc; import org.gradle.build.docs.dsl.docbook.model.PropertyDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; public class PropertyDetailRenderer { private final GenerationListener listener; private final LinkRenderer linkRenderer; private final ElementWarningsRenderer warningsRenderer = new ElementWarningsRenderer(); public PropertyDetailRenderer(LinkRenderer linkRenderer, GenerationListener listener) { this.linkRenderer = linkRenderer; this.listener = listener; } public void renderTo(PropertyDoc propertyDoc, Element parent) { Document document = parent.getOwnerDocument(); Element section = document.createElement("section"); parent.appendChild(section); section.setAttribute("id", propertyDoc.getId()); section.setAttribute("role", "detail"); Element title = document.createElement("title"); section.appendChild(title); title.appendChild(linkRenderer.link(propertyDoc.getMetaData().getType(), listener)); title.appendChild(document.createTextNode(" ")); Element literal = document.createElement("literal"); title.appendChild(literal); literal.appendChild(document.createTextNode(propertyDoc.getName())); if (!propertyDoc.getMetaData().isWriteable()) { title.appendChild(document.createTextNode(" (read-only)")); } warningsRenderer.renderTo(propertyDoc, "property", section); for (Element element : propertyDoc.getComment()) { section.appendChild(document.importNode(element, true)); } if (!propertyDoc.getAdditionalValues().isEmpty()) { Element segmentedlist = document.createElement("segmentedlist"); section.appendChild(segmentedlist); for (ExtraAttributeDoc attributeDoc : propertyDoc.getAdditionalValues()) { Element segtitle = document.createElement("segtitle"); segmentedlist.appendChild(segtitle); for (Node node : attributeDoc.getTitle()) { segtitle.appendChild(document.importNode(node, true)); } } Element seglistitem = document.createElement("seglistitem"); segmentedlist.appendChild(seglistitem); for (ExtraAttributeDoc attributeDoc : propertyDoc.getAdditionalValues()) { Element seg = document.createElement("seg"); seglistitem.appendChild(seg); for (Node node : attributeDoc.getValue()) { seg.appendChild(document.importNode(node, true)); } } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/PropertyTableRenderer.java000066400000000000000000000055351210430504300330270ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.PropertyDoc; import org.w3c.dom.Document; import org.w3c.dom.Element; public class PropertyTableRenderer { public void renderTo(Iterable properties, Element parent) { Document document = parent.getOwnerDocument(); // // // Property // Description // // Element thead = document.createElement("thead"); parent.appendChild(thead); Element tr = document.createElement("tr"); thead.appendChild(tr); Element td = document.createElement("td"); tr.appendChild(td); td.appendChild(document.createTextNode("Property")); td = document.createElement("td"); tr.appendChild(td); td.appendChild(document.createTextNode("Description")); for (PropertyDoc propDoc : properties) { // // $name // $description // tr = document.createElement("tr"); parent.appendChild(tr); td = document.createElement("td"); tr.appendChild(td); Element link = document.createElement("link"); td.appendChild(link); link.setAttribute("linkend", propDoc.getId()); Element literal = document.createElement("literal"); link.appendChild(literal); literal.appendChild(document.createTextNode(propDoc.getName())); td = document.createElement("td"); tr.appendChild(td); if (propDoc.isDeprecated()) { Element caution = document.createElement("caution"); td.appendChild(caution); caution.appendChild(document.createTextNode("Deprecated")); } if (propDoc.isIncubating()) { Element caution = document.createElement("caution"); td.appendChild(caution); caution.appendChild(document.createTextNode("Incubating")); } td.appendChild(document.importNode(propDoc.getDescription(), true)); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/ReferencedTypeBuilder.java000066400000000000000000000025611210430504300327530ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook; import org.gradle.build.docs.dsl.docbook.model.ClassDoc; import org.gradle.build.docs.dsl.docbook.model.PropertyDoc; public class ReferencedTypeBuilder { private final DslDocModel model; public ReferencedTypeBuilder(DslDocModel model) { this.model = model; } /** * Builds the docs for types referenced by properties and methods of the given class. */ public void build(ClassDoc classDoc) { for (PropertyDoc propertyDoc : classDoc.getClassProperties()) { String referencedType = propertyDoc.getMetaData().getType().getName(); if (!referencedType.equals(classDoc.getName())) { model.findClassDoc(referencedType); } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/000077500000000000000000000000001210430504300267715ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/BlockDoc.groovy000066400000000000000000000040111210430504300317140ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model import org.w3c.dom.Element import org.gradle.build.docs.dsl.source.model.TypeMetaData class BlockDoc implements DslElementDoc { private final MethodDoc blockMethod private final PropertyDoc blockProperty private final TypeMetaData type private boolean multiValued BlockDoc(MethodDoc blockMethod, PropertyDoc blockProperty, TypeMetaData type, boolean multiValued) { this.blockMethod = blockMethod this.type = type this.blockProperty = blockProperty this.multiValued = multiValued } BlockDoc forClass(ClassDoc referringClass) { return new BlockDoc(blockMethod.forClass(referringClass), blockProperty.forClass(referringClass), type, multiValued) } String getId() { return blockMethod.id } String getName() { return blockMethod.name } boolean isMultiValued() { return multiValued } TypeMetaData getType() { return type } Element getDescription() { return blockMethod.description; } List getComment() { return blockMethod.comment } boolean isDeprecated() { return blockProperty.deprecated || blockMethod.deprecated } boolean isIncubating() { return blockProperty.incubating || blockMethod.incubating } PropertyDoc getBlockProperty() { return blockProperty } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/ClassDoc.groovy000066400000000000000000000133141210430504300317350ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model import org.gradle.build.docs.dsl.source.model.ClassMetaData import org.w3c.dom.Document import org.w3c.dom.Element import org.w3c.dom.Node class ClassDoc implements DslElementDoc { private final String className private final String id private final String simpleName final ClassMetaData classMetaData private final Element classSection final ClassExtensionMetaData extensionMetaData private final List classProperties = [] private final List classMethods = [] private final List classBlocks = [] private final List classExtensions = [] private final Element propertiesTable private final Element methodsTable private final Element propertiesSection private final Element methodsSection ClassDoc superClass List comment = [] ClassDoc(String className, Element classContent, Document targetDocument, ClassMetaData classMetaData, ClassExtensionMetaData extensionMetaData) { this.className = className id = className simpleName = className.tokenize('.').last() this.classMetaData = classMetaData this.extensionMetaData = extensionMetaData classSection = targetDocument.createElement('chapter') classContent.childNodes.each { Node n -> classSection << n } propertiesTable = getTable('Properties') propertiesSection = propertiesTable.parentNode methodsTable = getTable('Methods') methodsSection = methodsTable.parentNode } String getId() { return id } String getName() { return className } String getSimpleName() { return simpleName } boolean isDeprecated() { return classMetaData.deprecated } boolean isIncubating() { return classMetaData.incubating } Collection getClassProperties() { return classProperties } void addClassProperty(PropertyDoc propertyDoc) { classProperties.add(propertyDoc.forClass(this)) } Collection getClassMethods() { return classMethods } void addClassMethod(MethodDoc methodDoc) { classMethods.add(methodDoc.forClass(this)) } Collection getClassBlocks() { return classBlocks } void addClassBlock(BlockDoc blockDoc) { classBlocks.add(blockDoc.forClass(this)) } Collection getClassExtensions() { return classExtensions } void addClassExtension(ClassExtensionDoc extensionDoc) { classExtensions.add(extensionDoc) } Element getClassSection() { return classSection } Element getPropertiesTable() { return propertiesTable } def getPropertiesSection() { return propertiesSection } def getPropertyDetailsSection() { return getSection('Property details') } Element getMethodsTable() { return methodsTable } def getMethodsSection() { return methodsSection } def getMethodDetailsSection() { return getSection('Method details') } def getBlocksTable() { return getTable('Script blocks') } def getBlockDetailsSection() { return getSection('Script block details') } ClassDoc mergeContent() { classProperties.sort { it.name } classMethods.sort { it.metaData.overrideSignature } classBlocks.sort { it.name } classExtensions.sort { it.pluginId } return this } String getStyle() { return classMetaData.groovy ? 'groovydoc' : 'javadoc' } private Element getTable(String title) { def table = getSection(title).table[0] if (!table) { throw new RuntimeException("Section '$title' does not contain a element.") } if (!table.thead[0]) { throw new RuntimeException("Table '$title' does not contain a element.") } if (!table.thead[0].tr[0]) { throw new RuntimeException("Table '$title' does not contain a / element.") } return table } private Element getSection(String title) { def sections = classSection.section.findAll { it.title[0] && it.title[0].text().trim() == title } if (sections.size() < 1) { throw new RuntimeException("Docbook content for $className does not contain a '$title' section.") } return sections[0] } Element getDescription() { if (comment.isEmpty() || comment[0].tagName != 'para') { throw new RuntimeException("Class $className does not have a description paragraph.") } return comment[0] } PropertyDoc findProperty(String name) { return classProperties.find { it.name == name } } BlockDoc getBlock(String name) { def block = classBlocks.find { it.name == name } if (block) { return block } for (extensionDoc in classExtensions) { block = extensionDoc.extensionBlocks.find { it.name == name } if (block) { return block } } throw new RuntimeException("Class $className does not have a script block '$name'.") } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/ClassExtensionDoc.groovy000066400000000000000000000047221210430504300336350ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model /** * Represents the documentation model for extensions contributed by a given plugin. */ class ClassExtensionDoc { private final Set mixinClasses = [] private final Map extensionClasses = [:] private final String pluginId final ClassDoc targetClass final List extraProperties = [] final List extraBlocks = [] ClassExtensionDoc(String pluginId, ClassDoc targetClass) { this.pluginId = pluginId this.targetClass = targetClass } String getPluginId() { return pluginId } Set getMixinClasses() { mixinClasses } Map getExtensionClasses() { return extensionClasses } List getExtensionProperties() { List properties = [] mixinClasses.each { mixin -> mixin.classProperties.each { prop -> properties << prop.forClass(targetClass) } } extraProperties.each { prop -> properties << prop.forClass(targetClass) } return properties.sort { it.name } } List getExtensionMethods() { List methods = [] mixinClasses.each { mixin -> mixin.classMethods.each { method -> methods << method.forClass(targetClass) } } return methods.sort { it.metaData.overrideSignature } } List getExtensionBlocks() { List blocks = [] mixinClasses.each { mixin -> mixin.classBlocks.each { block -> blocks << block.forClass(targetClass) } } extraBlocks.each { block-> blocks << block.forClass(targetClass) } return blocks.sort { it.name } } } ClassExtensionMetaData.groovy000066400000000000000000000023171210430504300345270ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model class ClassExtensionMetaData { final String targetClass final Set mixinClasses = [] final Set extensionClasses = [] ClassExtensionMetaData(String targetClass) { this.targetClass = targetClass } def void addMixin(String plugin, String mixinClass) { mixinClasses.add(new MixinMetaData(plugin, mixinClass)) } def void addExtension(String plugin, String extension, String extensionClass) { extensionClasses.add(new ExtensionMetaData(plugin, extension, extensionClass)) } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/DslElementDoc.java000066400000000000000000000016011210430504300323140ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model; import org.w3c.dom.Element; import java.util.List; public interface DslElementDoc { String getId(); Element getDescription(); List getComment(); boolean isDeprecated(); boolean isIncubating(); } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/ExtensionMetaData.groovy000066400000000000000000000017341210430504300336220ustar00rootroot00000000000000/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model class ExtensionMetaData { final String pluginId final String extensionId final String extensionClass ExtensionMetaData(String pluginId, String extensionId, String extensionClass) { this.pluginId = pluginId this.extensionId = extensionId this.extensionClass = extensionClass } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/ExtraAttributeDoc.groovy000066400000000000000000000024141210430504300336360ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model import org.w3c.dom.Element import org.w3c.dom.Node class ExtraAttributeDoc { final Element titleCell final Element valueCell ExtraAttributeDoc(Element titleCell, Element valueCell) { this.titleCell = titleCell this.valueCell = valueCell } @Override String toString() { return "attribute[key: $key, value: $valueCell.textContent]" } String getKey() { return titleCell.textContent } List getTitle() { return titleCell.childNodes.collect { it } } List getValue() { return valueCell.childNodes.collect { it } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/MethodDoc.groovy000066400000000000000000000042541210430504300321130ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model import org.gradle.build.docs.dsl.source.model.ClassMetaData import org.gradle.build.docs.dsl.source.model.MethodMetaData import org.w3c.dom.Element class MethodDoc implements DslElementDoc { private final String id private final MethodMetaData metaData private final List comment private final ClassMetaData referringClass MethodDoc(MethodMetaData metaData, List comment) { this(metaData.ownerClass, metaData, comment) } MethodDoc(ClassMetaData referringClass, MethodMetaData metaData, List comment) { this.metaData = metaData this.referringClass = referringClass id = "$referringClass.className:$metaData.overrideSignature" this.comment = comment } MethodDoc forClass(ClassDoc referringClass) { def refererMetaData = referringClass.classMetaData if (refererMetaData == this.referringClass) { return this } return new MethodDoc(refererMetaData, metaData, comment) } String getId() { return id } String getName() { return metaData.name } MethodMetaData getMetaData() { return metaData } boolean isDeprecated() { return metaData.deprecated && !referringClass.deprecated } boolean isIncubating() { return metaData.incubating || metaData.ownerClass.incubating } Element getDescription() { return comment.find { it.nodeName == 'para' } } List getComment() { return comment } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/MixinMetaData.groovy000066400000000000000000000015541210430504300327320ustar00rootroot00000000000000/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model class MixinMetaData { final String pluginId final String mixinClass MixinMetaData(String pluginId, String mixinClass) { this.pluginId = pluginId this.mixinClass = mixinClass } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/docbook/model/PropertyDoc.groovy000066400000000000000000000056711210430504300325230ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook.model import org.gradle.build.docs.dsl.source.model.PropertyMetaData import org.w3c.dom.Element import org.gradle.build.docs.dsl.source.model.ClassMetaData class PropertyDoc implements DslElementDoc { private final String id private final String name private final List comment private final List additionalValues private final PropertyMetaData metaData private final ClassMetaData referringClass PropertyDoc(PropertyMetaData propertyMetaData, List comment, List additionalValues) { this(propertyMetaData.ownerClass, propertyMetaData, comment, additionalValues) } PropertyDoc(ClassMetaData referringClass, PropertyMetaData propertyMetaData, List comment, List additionalValues) { name = propertyMetaData.name this.referringClass = referringClass this.metaData = propertyMetaData id = "${referringClass.className}:$name" this.comment = comment if (additionalValues == null) { throw new NullPointerException("additionalValues constructor var is null for referringClass: $referringClass") } this.additionalValues = additionalValues } PropertyDoc forClass(ClassDoc referringClass) { return forClass(referringClass, []) } PropertyDoc forClass(ClassDoc referringClass, Collection additionalValues) { def refererMetaData = referringClass.classMetaData if (refererMetaData == this.referringClass && additionalValues.isEmpty()) { return this } return new PropertyDoc(refererMetaData, metaData, comment, additionalValues as List) } String getId() { return id } String getName() { return name } PropertyMetaData getMetaData() { return metaData } boolean isDeprecated() { return metaData.deprecated && !referringClass.deprecated } boolean isIncubating() { return metaData.incubating || metaData.ownerClass.incubating } Element getDescription() { return comment.find { it.nodeName == 'para' } } List getComment() { return comment } List getAdditionalValues() { return additionalValues } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/links/000077500000000000000000000000001210430504300253715ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/links/ClassLinkMetaData.java000066400000000000000000000145761210430504300315350ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.links; import org.gradle.build.docs.dsl.source.model.ClassMetaData; import org.gradle.build.docs.dsl.source.model.MethodMetaData; import org.gradle.build.docs.model.Attachable; import org.gradle.build.docs.model.ClassMetaDataRepository; import org.gradle.util.CollectionUtils; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class ClassLinkMetaData implements Serializable, Attachable { private final String className; private final String simpleName; private final String packageName; private LinkMetaData.Style style; private final Map methods = new HashMap(); public ClassLinkMetaData(ClassMetaData classMetaData) { this.className = classMetaData.getClassName(); this.simpleName = classMetaData.getSimpleName(); this.packageName = classMetaData.getPackageName(); this.style = classMetaData.isGroovy() ? LinkMetaData.Style.Groovydoc : LinkMetaData.Style.Javadoc; for (MethodMetaData method : classMetaData.getDeclaredMethods()) { addMethod(method, style); } } public LinkMetaData getClassLink() { return new LinkMetaData(style, simpleName, null); } public String getPackageName() { return packageName; } public LinkMetaData getMethod(String method) { MethodLinkMetaData methodMetaData = findMethod(method); String displayName; String urlFragment = methodMetaData.getUrlFragment(className); displayName = String.format("%s.%s", simpleName, methodMetaData.getDisplayName()); return new LinkMetaData(methodMetaData.style, displayName, urlFragment); } private MethodLinkMetaData findMethod(String method) { MethodLinkMetaData metaData = methods.get(method); if (metaData != null) { return metaData; } List candidates = new ArrayList(); for (MethodLinkMetaData methodLinkMetaData : methods.values()) { if (methodLinkMetaData.name.equals(method)) { candidates.add(methodLinkMetaData); } } if (candidates.isEmpty()) { String message = String.format("No method '%s' found for class '%s'.", method, className); message += "\nThis problem may happen when some apilink from docbook template xmls refers to unknown method." + "\nExample: "; throw new RuntimeException(message); } if (candidates.size() != 1) { String message = String.format("Found multiple methods called '%s' in class '%s'. Candidates: %s", method, className, CollectionUtils.join(", ", candidates)); message += "\nThis problem may happen when some apilink from docbook template xmls is incorrect. Example:" + "\nIncorrect: " + "\nCorrect: "; throw new RuntimeException(message); } return candidates.get(0); } public LinkMetaData.Style getStyle() { return style; } public void setStyle(LinkMetaData.Style style) { this.style = style; } public void addMethod(MethodMetaData method, LinkMetaData.Style style) { methods.put(method.getOverrideSignature(), new MethodLinkMetaData(method.getName(), method.getOverrideSignature(), style)); } public void addBlockMethod(MethodMetaData method) { methods.put(method.getOverrideSignature(), new BlockLinkMetaData(method.getName(), method.getOverrideSignature())); } public void addGetterMethod(String propertyName, MethodMetaData method) { methods.put(method.getOverrideSignature(), new GetterLinkMetaData(propertyName, method.getName(), method.getOverrideSignature())); } public void attach(ClassMetaDataRepository linkMetaDataClassMetaDataRepository) { } private static class MethodLinkMetaData implements Serializable { final String name; final String signature; final LinkMetaData.Style style; private MethodLinkMetaData(String name, String signature, LinkMetaData.Style style) { this.name = name; this.signature = signature; this.style = style; } public String getDisplayName() { return String.format("%s()", name); } public String getUrlFragment(String className) { return style == LinkMetaData.Style.Dsldoc ? String.format("%s:%s", className, signature) : signature; } @Override public String toString() { return signature; } } private static class BlockLinkMetaData extends MethodLinkMetaData { private BlockLinkMetaData(String name, String signature) { super(name, signature, LinkMetaData.Style.Dsldoc); } @Override public String getDisplayName() { return String.format("%s{}", name); } } private static class GetterLinkMetaData extends MethodLinkMetaData { private final String propertyName; private GetterLinkMetaData(String propertyName, String methodName, String signature) { super(methodName, signature, LinkMetaData.Style.Dsldoc); this.propertyName = propertyName; } @Override public String getUrlFragment(String className) { return String.format("%s:%s", className, propertyName); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/links/LinkMetaData.java000066400000000000000000000024241210430504300305340ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.links; import java.io.Serializable; public class LinkMetaData implements Serializable { public enum Style { Javadoc, Groovydoc, Dsldoc } private final Style style; private final String displayName; private final String urlFragment; public LinkMetaData(Style style, String displayName, String urlFragment) { this.style = style; this.displayName = displayName; this.urlFragment = urlFragment; } public Style getStyle() { return style; } public String getDisplayName() { return displayName; } public String getUrlFragment() { return urlFragment; } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/000077500000000000000000000000001210430504300255515ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/ExtractDslMetaDataTask.groovy000066400000000000000000000137611210430504300333310ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source import groovyjarjarantlr.collections.AST import org.codehaus.groovy.antlr.AntlrASTProcessor import org.codehaus.groovy.antlr.SourceBuffer import org.codehaus.groovy.antlr.UnicodeEscapingReader import org.codehaus.groovy.antlr.java.Java2GroovyConverter import org.codehaus.groovy.antlr.java.JavaLexer import org.codehaus.groovy.antlr.java.JavaRecognizer import org.codehaus.groovy.antlr.parser.GroovyLexer import org.codehaus.groovy.antlr.parser.GroovyRecognizer import org.codehaus.groovy.antlr.treewalker.PreOrderTraversal import org.codehaus.groovy.antlr.treewalker.SourceCodeTraversal import org.codehaus.groovy.antlr.treewalker.Visitor import org.gradle.api.Action import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.SourceTask import org.gradle.api.tasks.TaskAction import org.gradle.build.docs.dsl.source.model.ClassMetaData import org.gradle.build.docs.dsl.source.model.TypeMetaData import org.gradle.build.docs.model.ClassMetaDataRepository import org.gradle.build.docs.model.SimpleClassMetaDataRepository import org.gradle.util.Clock import org.gradle.build.docs.DocGenerationException import org.gradle.api.Transformer /** * Extracts meta-data from the Groovy and Java source files which make up the Gradle DSL. Persists the meta-data to a file * for later use in generating the docbook source for the DSL, such as by {@link org.gradle.build.docs.dsl.docbook.AssembleDslDocTask}. */ class ExtractDslMetaDataTask extends SourceTask { @OutputFile def File destFile @TaskAction def extract() { Clock clock = new Clock() //parsing all input files into metadata //and placing them in the repository object SimpleClassMetaDataRepository repository = new SimpleClassMetaDataRepository() int counter = 0 source.each { File f -> parse(f, repository) counter++ } //updating/modifying the metadata and making sure every type reference across the metadata is fully qualified //so, the superClassName, interafaces and types needed by declared properties and declared methods will have fully qualified name TypeNameResolver resolver = new TypeNameResolver(repository) repository.each { name, metaData -> fullyQualifyAllTypeNames(metaData, resolver) } repository.store(destFile) println "Parsed $counter classes in ${clock.time}" } def parse(File sourceFile, ClassMetaDataRepository repository) { try { sourceFile.withReader { reader -> if (sourceFile.name.endsWith('.java')) { parseJava(sourceFile, reader, repository) } else { parseGroovy(sourceFile, reader, repository) } } } catch (Exception e) { throw new DocGenerationException("Could not parse '$sourceFile'.", e) } } def parseJava(File sourceFile, Reader input, ClassMetaDataRepository repository) { SourceBuffer sourceBuffer = new SourceBuffer(); UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(input, sourceBuffer); JavaLexer lexer = new JavaLexer(unicodeReader); unicodeReader.setLexer(lexer); JavaRecognizer parser = JavaRecognizer.make(lexer); parser.setSourceBuffer(sourceBuffer); String[] tokenNames = parser.getTokenNames(); parser.compilationUnit(); AST ast = parser.getAST(); // modify the Java AST into a Groovy AST (just token types) Visitor java2groovyConverter = new Java2GroovyConverter(tokenNames); AntlrASTProcessor java2groovyTraverser = new PreOrderTraversal(java2groovyConverter); java2groovyTraverser.process(ast); def visitor = new SourceMetaDataVisitor(sourceBuffer, repository, false) AntlrASTProcessor traverser = new SourceCodeTraversal(visitor); traverser.process(ast); visitor.complete() } def parseGroovy(File sourceFile, Reader input, ClassMetaDataRepository repository) { SourceBuffer sourceBuffer = new SourceBuffer(); UnicodeEscapingReader unicodeReader = new UnicodeEscapingReader(input, sourceBuffer); GroovyLexer lexer = new GroovyLexer(unicodeReader); unicodeReader.setLexer(lexer); GroovyRecognizer parser = GroovyRecognizer.make(lexer); parser.setSourceBuffer(sourceBuffer); parser.compilationUnit(); AST ast = parser.getAST(); def visitor = new SourceMetaDataVisitor(sourceBuffer, repository, true) AntlrASTProcessor traverser = new SourceCodeTraversal(visitor); traverser.process(ast); visitor.complete() } def fullyQualifyAllTypeNames(ClassMetaData classMetaData, TypeNameResolver resolver) { try { classMetaData.resolveTypes(new Transformer(){ String transform(String i) { return resolver.resolve(i, classMetaData) } }) classMetaData.visitTypes(new Action() { void execute(TypeMetaData t) { resolver.resolve(t, classMetaData) } }) } catch (Exception e) { throw new RuntimeException("Could not resolve types in class '$classMetaData.className'.", e) } } }gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/SourceMetaDataVisitor.java000066400000000000000000000444211210430504300326420ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source; import groovyjarjarantlr.collections.AST; import org.apache.commons.lang.StringUtils; import org.codehaus.groovy.antlr.GroovySourceAST; import org.codehaus.groovy.antlr.LineColumn; import org.codehaus.groovy.antlr.SourceBuffer; import org.codehaus.groovy.antlr.treewalker.VisitorAdapter; import org.gradle.build.docs.dsl.source.model.*; import org.gradle.build.docs.model.ClassMetaDataRepository; import java.lang.reflect.Modifier; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import static org.codehaus.groovy.antlr.parser.GroovyTokenTypes.*; public class SourceMetaDataVisitor extends VisitorAdapter { private static final Pattern PREV_JAVADOC_COMMENT_PATTERN = Pattern.compile("(?s)/\\*\\*(.*?)\\*/"); private static final Pattern GETTER_METHOD_NAME = Pattern.compile("(get|is)(.+)"); private static final Pattern SETTER_METHOD_NAME = Pattern.compile("set(.+)"); private final SourceBuffer sourceBuffer; private final LinkedList parseStack = new LinkedList(); private final List imports = new ArrayList(); private final ClassMetaDataRepository repository; private final List allClasses = new ArrayList(); private final LinkedList classStack = new LinkedList(); private final Map typeTokens = new HashMap(); private final boolean groovy; private String packageName; private LineColumn lastLineCol; SourceMetaDataVisitor(SourceBuffer sourceBuffer, ClassMetaDataRepository repository, boolean isGroovy) { this.sourceBuffer = sourceBuffer; this.repository = repository; groovy = isGroovy; lastLineCol = new LineColumn(1, 1); } public void complete() { for (String anImport : imports) { for (ClassMetaData classMetaData : allClasses) { classMetaData.addImport(anImport); } } } @Override public void visitPackageDef(GroovySourceAST t, int visit) { if (visit == OPENING_VISIT) { packageName = extractName(t); } } @Override public void visitImport(GroovySourceAST t, int visit) { if (visit == OPENING_VISIT) { imports.add(extractName(t)); } } @Override public void visitClassDef(GroovySourceAST t, int visit) { visitTypeDef(t, visit, false); } @Override public void visitInterfaceDef(GroovySourceAST t, int visit) { visitTypeDef(t, visit, true); } @Override public void visitEnumDef(GroovySourceAST t, int visit) { visitTypeDef(t, visit, false); } @Override public void visitAnnotationDef(GroovySourceAST t, int visit) { visitTypeDef(t, visit, false); } private void visitTypeDef(GroovySourceAST t, int visit, boolean isInterface) { if (visit == OPENING_VISIT) { ClassMetaData outerClass = getCurrentClass(); String baseName = extractIdent(t); String className = outerClass != null ? outerClass.getClassName() + '.' + baseName : packageName + '.' + baseName; String comment = getJavaDocCommentsBeforeNode(t); ClassMetaData currentClass = new ClassMetaData(className, packageName, isInterface, groovy, comment); if (outerClass != null) { outerClass.addInnerClassName(className); currentClass.setOuterClassName(outerClass.getClassName()); } findAnnotations(t, currentClass); classStack.addFirst(currentClass); allClasses.add(currentClass); typeTokens.put(t, currentClass); repository.put(className, currentClass); } } private ClassMetaData getCurrentClass() { return classStack.isEmpty() ? null : classStack.getFirst(); } @Override public void visitExtendsClause(GroovySourceAST t, int visit) { if (visit == OPENING_VISIT) { ClassMetaData currentClass = getCurrentClass(); for ( GroovySourceAST child = (GroovySourceAST) t.getFirstChild(); child != null; child = (GroovySourceAST) child.getNextSibling()) { if (!currentClass.isInterface()) { currentClass.setSuperClassName(extractName(child)); } else { currentClass.addInterfaceName(extractName(child)); } } } } @Override public void visitImplementsClause(GroovySourceAST t, int visit) { if (visit == OPENING_VISIT) { ClassMetaData currentClass = getCurrentClass(); for ( GroovySourceAST child = (GroovySourceAST) t.getFirstChild(); child != null; child = (GroovySourceAST) child.getNextSibling()) { currentClass.addInterfaceName(extractName(child)); } } } @Override public void visitMethodDef(GroovySourceAST t, int visit) { if (visit == OPENING_VISIT) { maybeAddMethod(t); skipJavaDocComment(t); } } private void maybeAddMethod(GroovySourceAST t) { String name = extractName(t); if (!groovy && name.equals(getCurrentClass().getSimpleName())) { // A constructor. The java grammar treats a constructor as a method, the groovy grammar does not. return; } ASTIterator children = new ASTIterator(t); if (groovy) { children.skip(TYPE_PARAMETERS); children.skip(MODIFIERS); } else { children.skip(MODIFIERS); children.skip(TYPE_PARAMETERS); } String rawCommentText = getJavaDocCommentsBeforeNode(t); TypeMetaData returnType = extractTypeName(children.current); MethodMetaData method = getCurrentClass().addMethod(name, returnType, rawCommentText); findAnnotations(t, method); extractParameters(t, method); Matcher matcher = GETTER_METHOD_NAME.matcher(name); if (matcher.matches()) { int startName = matcher.start(2); String propName = name.substring(startName, startName + 1).toLowerCase() + name.substring(startName + 1); PropertyMetaData property = getCurrentClass().addReadableProperty(propName, returnType, rawCommentText, method); for (String annotation : method.getAnnotationTypeNames()) { property.addAnnotationTypeName(annotation); } return; } if (method.getParameters().size() != 1) { return; } matcher = SETTER_METHOD_NAME.matcher(name); if (matcher.matches()) { int startName = matcher.start(1); String propName = name.substring(startName, startName + 1).toLowerCase() + name.substring(startName + 1); TypeMetaData type = method.getParameters().get(0).getType(); getCurrentClass().addWriteableProperty(propName, type, rawCommentText, method); } } private void extractParameters(GroovySourceAST t, MethodMetaData method) { GroovySourceAST paramsAst = t.childOfType(PARAMETERS); for ( GroovySourceAST child = (GroovySourceAST) paramsAst.getFirstChild(); child != null; child = (GroovySourceAST) child.getNextSibling()) { assert child.getType() == PARAMETER_DEF || child.getType() == VARIABLE_PARAMETER_DEF; TypeMetaData type = extractTypeName((GroovySourceAST) child.getFirstChild().getNextSibling()); if (child.getType() == VARIABLE_PARAMETER_DEF) { type.setVarargs(); } method.addParameter(extractIdent(child), type); } } @Override public void visitVariableDef(GroovySourceAST t, int visit) { if (visit == OPENING_VISIT) { maybeAddPropertyFromField(t); skipJavaDocComment(t); } } private void maybeAddPropertyFromField(GroovySourceAST t) { GroovySourceAST parentNode = getParentNode(); boolean isField = parentNode != null && parentNode.getType() == OBJBLOCK; if (!isField) { return; } int modifiers = extractModifiers(t); boolean isConst = getCurrentClass().isInterface() || (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)); if (isConst) { visitConst(t); return; } boolean isProp = groovy && !Modifier.isStatic(modifiers) && !Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers) && !Modifier.isPrivate(modifiers); if (!isProp) { return; } ASTIterator children = new ASTIterator(t); children.skip(MODIFIERS); String propertyName = extractIdent(t); TypeMetaData propertyType = extractTypeName(children.current); ClassMetaData currentClass = getCurrentClass(); MethodMetaData getterMethod = currentClass.addMethod(String.format("get%s", StringUtils.capitalize( propertyName)), propertyType, ""); PropertyMetaData property = currentClass.addReadableProperty(propertyName, propertyType, getJavaDocCommentsBeforeNode(t), getterMethod); findAnnotations(t, property); if (!Modifier.isFinal(modifiers)) { MethodMetaData setterMethod = currentClass.addMethod(String.format("set%s", StringUtils.capitalize( propertyName)), TypeMetaData.VOID, ""); setterMethod.addParameter(propertyName, propertyType); currentClass.addWriteableProperty(propertyName, propertyType, getJavaDocCommentsBeforeNode(t), setterMethod); } } private void visitConst(GroovySourceAST t) { String constName = extractIdent(t); GroovySourceAST assign = t.childOfType(ASSIGN); String value = null; if (assign != null) { value = extractLiteral(assign.getFirstChild()); } getCurrentClass().getConstants().put(constName, value); } private String extractLiteral(AST ast) { switch (ast.getType()) { case EXPR: // The java grammar wraps initialisers in an EXPR token return extractLiteral(ast.getFirstChild()); case NUM_INT: case NUM_LONG: case NUM_FLOAT: case NUM_DOUBLE: case NUM_BIG_INT: case NUM_BIG_DECIMAL: case STRING_LITERAL: return ast.getText(); } return null; } public GroovySourceAST pop() { if (!parseStack.isEmpty()) { GroovySourceAST ast = parseStack.removeFirst(); ClassMetaData classMetaData = typeTokens.remove(ast); if (classMetaData != null) { assert classMetaData == classStack.getFirst(); classStack.removeFirst(); } return ast; } return null; } @Override public void push(GroovySourceAST t) { parseStack.addFirst(t); } private GroovySourceAST getParentNode() { if (parseStack.size() > 1) { return parseStack.get(1); } return null; } private int extractModifiers(GroovySourceAST ast) { GroovySourceAST modifiers = ast.childOfType(MODIFIERS); if (modifiers == null) { return 0; } int modifierFlags = 0; for ( GroovySourceAST child = (GroovySourceAST) modifiers.getFirstChild(); child != null; child = (GroovySourceAST) child.getNextSibling()) { switch (child.getType()) { case LITERAL_private: modifierFlags |= Modifier.PRIVATE; break; case LITERAL_protected: modifierFlags |= Modifier.PROTECTED; break; case LITERAL_public: modifierFlags |= Modifier.PUBLIC; break; case FINAL: modifierFlags |= Modifier.FINAL; break; case LITERAL_static: modifierFlags |= Modifier.STATIC; break; } } return modifierFlags; } private TypeMetaData extractTypeName(GroovySourceAST ast) { TypeMetaData type = new TypeMetaData(); switch (ast.getType()) { case TYPE: GroovySourceAST typeName = (GroovySourceAST) ast.getFirstChild(); extractTypeName(typeName, type); break; case WILDCARD_TYPE: // In the groovy grammar, the bounds are sibling of the ?, in the java grammar, they are the child GroovySourceAST bounds = (GroovySourceAST) (groovy ? ast.getNextSibling() : ast.getFirstChild()); if (bounds == null) { type.setWildcard(); } else if (bounds.getType() == TYPE_UPPER_BOUNDS) { type.setUpperBounds(extractTypeName((GroovySourceAST) bounds.getFirstChild())); } else if (bounds.getType() == TYPE_LOWER_BOUNDS) { type.setLowerBounds(extractTypeName((GroovySourceAST) bounds.getFirstChild())); } break; case IDENT: case DOT: extractTypeName(ast, type); break; default: throw new RuntimeException(String.format("Unexpected token in type name: %s", ast)); } return type; } private void extractTypeName(GroovySourceAST ast, TypeMetaData type) { if (ast == null) { type.setName("java.lang.Object"); return; } switch (ast.getType()) { case LITERAL_boolean: type.setName("boolean"); return; case LITERAL_byte: type.setName("byte"); return; case LITERAL_char: type.setName("char"); return; case LITERAL_double: type.setName("double"); return; case LITERAL_float: type.setName("float"); return; case LITERAL_int: type.setName("int"); return; case LITERAL_long: type.setName("long"); return; case LITERAL_void: type.setName("void"); return; case ARRAY_DECLARATOR: extractTypeName((GroovySourceAST) ast.getFirstChild(), type); type.addArrayDimension(); return; } type.setName(extractName(ast)); GroovySourceAST typeArgs = ast.childOfType(TYPE_ARGUMENTS); if (typeArgs != null) { for ( GroovySourceAST child = (GroovySourceAST) typeArgs.getFirstChild(); child != null; child = (GroovySourceAST) child.getNextSibling()) { assert child.getType() == TYPE_ARGUMENT; type.addTypeArg(extractTypeName((GroovySourceAST) child.getFirstChild())); } } } private void skipJavaDocComment(GroovySourceAST t) { lastLineCol = new LineColumn(t.getLine(), t.getColumn()); } private String getJavaDocCommentsBeforeNode(GroovySourceAST t) { String result = ""; LineColumn thisLineCol = new LineColumn(t.getLine(), t.getColumn()); String text = sourceBuffer.getSnippet(lastLineCol, thisLineCol); if (text != null) { Matcher m = PREV_JAVADOC_COMMENT_PATTERN.matcher(text); if (m.find()) { result = m.group(1); } } lastLineCol = thisLineCol; return result; } private void findAnnotations(GroovySourceAST t, AbstractLanguageElement currentElement) { GroovySourceAST modifiers = t.childOfType(MODIFIERS); if (modifiers != null) { List children = modifiers.childrenOfType(ANNOTATION); for (GroovySourceAST child : children) { String identifier = extractIdent(child); currentElement.addAnnotationTypeName(identifier); } } } private String extractIdent(GroovySourceAST t) { return t.childOfType(IDENT).getText(); } private String extractName(GroovySourceAST t) { if (t.getType() == DOT) { GroovySourceAST firstChild = (GroovySourceAST) t.getFirstChild(); GroovySourceAST secondChild = (GroovySourceAST) firstChild.getNextSibling(); return extractName(firstChild) + "." + extractName(secondChild); } if (t.getType() == IDENT) { return t.getText(); } if (t.getType() == STAR) { return t.getText(); } GroovySourceAST child = t.childOfType(DOT); if (child != null) { return extractName(child); } child = t.childOfType(IDENT); if (child != null) { return extractName(child); } throw new RuntimeException(String.format("Unexpected token in name: %s", t)); } private static class ASTIterator { GroovySourceAST current; private ASTIterator(GroovySourceAST parent) { this.current = (GroovySourceAST) parent.getFirstChild(); } void skip(int token) { if (current != null && current.getType() == token) { current = (GroovySourceAST) current.getNextSibling(); } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/TypeNameResolver.java000066400000000000000000000142361210430504300316660ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source; import org.apache.commons.lang.StringUtils; import org.gradle.api.Action; import org.gradle.build.docs.dsl.source.model.ClassMetaData; import org.gradle.build.docs.dsl.source.model.TypeMetaData; import org.gradle.build.docs.model.ClassMetaDataRepository; import org.gradle.internal.UncheckedException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Resolves partial type names into fully qualified type names. */ public class TypeNameResolver { private final Set primitiveTypes = new HashSet(); private final List groovyImplicitImportPackages = new ArrayList(); private final List groovyImplicitTypes = new ArrayList(); private final ClassMetaDataRepository metaDataRepository; public TypeNameResolver(ClassMetaDataRepository metaDataRepository) { this.metaDataRepository = metaDataRepository; primitiveTypes.add("boolean"); primitiveTypes.add("byte"); primitiveTypes.add("char"); primitiveTypes.add("short"); primitiveTypes.add("int"); primitiveTypes.add("long"); primitiveTypes.add("float"); primitiveTypes.add("double"); primitiveTypes.add("void"); groovyImplicitImportPackages.add("java.util."); groovyImplicitImportPackages.add("java.io."); groovyImplicitImportPackages.add("java.net."); groovyImplicitImportPackages.add("groovy.lang."); groovyImplicitImportPackages.add("groovy.util."); groovyImplicitTypes.add("java.math.BigDecimal"); groovyImplicitTypes.add("java.math.BigInteger"); // check that groovy is visible. try { getClass().getClassLoader().loadClass("groovy.lang.Closure"); } catch (ClassNotFoundException e) { throw UncheckedException.throwAsUncheckedException(e); } } /** * Resolves the names in the given type into fully qualified names. */ public void resolve(final TypeMetaData type, final ClassMetaData classMetaData) { type.visitTypes(new Action() { public void execute(TypeMetaData t) { t.setName(resolve(t.getName(), classMetaData)); } }); } /** * Resolves a source type name into a fully qualified type name. */ public String resolve(String name, ClassMetaData classMetaData) { if (primitiveTypes.contains(name)) { return name; } String candidateClassName; String[] innerNames = name.split("\\."); ClassMetaData pos = classMetaData; for (int i = 0; i < innerNames.length; i++) { String innerName = innerNames[i]; candidateClassName = pos.getClassName() + '.' + innerName; if (!pos.getInnerClassNames().contains(candidateClassName)) { break; } if (i == innerNames.length - 1) { return candidateClassName; } pos = metaDataRepository.get(candidateClassName); } String outerClassName = classMetaData.getOuterClassName(); while (outerClassName != null) { if (name.equals(StringUtils.substringAfterLast(outerClassName, "."))) { return outerClassName; } ClassMetaData outerClass = metaDataRepository.get(outerClassName); candidateClassName = outerClassName + '.' + name; if (outerClass.getInnerClassNames().contains(candidateClassName)) { return candidateClassName; } outerClassName = outerClass.getOuterClassName(); } if (name.contains(".")) { return name; } for (String importedClass : classMetaData.getImports()) { String baseName = StringUtils.substringAfterLast(importedClass, "."); if (baseName.equals("*")) { candidateClassName = StringUtils.substringBeforeLast(importedClass, ".") + "." + name; if (metaDataRepository.find(candidateClassName) != null) { return candidateClassName; } if (importedClass.startsWith("java.") && isVisibleClass(candidateClassName)) { return candidateClassName; } } else if (name.equals(baseName)) { return importedClass; } } candidateClassName = classMetaData.getPackageName() + "." + name; if (metaDataRepository.find(candidateClassName) != null) { return candidateClassName; } candidateClassName = "java.lang." + name; if (isVisibleClass(candidateClassName)) { return candidateClassName; } if (classMetaData.isGroovy()) { candidateClassName = "java.math." + name; if (groovyImplicitTypes.contains(candidateClassName)) { return candidateClassName; } for (String prefix : groovyImplicitImportPackages) { candidateClassName = prefix + name; if (isVisibleClass(candidateClassName)) { return candidateClassName; } } } return name; } private boolean isVisibleClass(String candidateClassName) { try { getClass().getClassLoader().loadClass(candidateClassName); return true; } catch (ClassNotFoundException e) { // Ignore } return false; } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/model/000077500000000000000000000000001210430504300266515ustar00rootroot00000000000000AbstractLanguageElement.java000066400000000000000000000037171210430504300341660ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/model/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source.model; import org.gradle.api.Transformer; import java.io.Serializable; import java.util.ArrayList; import java.util.List; public abstract class AbstractLanguageElement implements LanguageElement, Serializable { private String rawCommentText; private final List annotationNames = new ArrayList(); protected AbstractLanguageElement() { } protected AbstractLanguageElement(String rawCommentText) { this.rawCommentText = rawCommentText; } public String getRawCommentText() { return rawCommentText; } public void setRawCommentText(String rawCommentText) { this.rawCommentText = rawCommentText; } public List getAnnotationTypeNames() { return annotationNames; } public void addAnnotationTypeName(String annotationType) { annotationNames.add(annotationType); } public boolean isDeprecated() { return annotationNames.contains(Deprecated.class.getName()); } public boolean isIncubating() { return annotationNames.contains("org.gradle.api.Incubating"); } public void resolveTypes(Transformer transformer) { for (int i = 0; i < annotationNames.size(); i++) { annotationNames.set(i, transformer.transform(annotationNames.get(i))); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/model/ClassMetaData.java000066400000000000000000000223151210430504300321650ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source.model; import org.apache.commons.lang.StringUtils; import org.gradle.api.Action; import org.gradle.api.Transformer; import org.gradle.build.docs.model.Attachable; import org.gradle.build.docs.model.ClassMetaDataRepository; import org.gradle.util.GUtil; import java.io.Serializable; import java.util.*; /** * Static meta-data about a class extracted from the source for the class. */ public class ClassMetaData extends AbstractLanguageElement implements Serializable, Attachable, TypeContainer { private final String className; private String superClassName; private final String packageName; private final boolean isInterface; private final boolean isGroovy; private final List imports = new ArrayList(); private final List interfaceNames = new ArrayList(); private final Map declaredProperties = new HashMap(); private final Set declaredMethods = new HashSet(); private final List innerClassNames = new ArrayList(); private String outerClassName; private transient ClassMetaDataRepository metaDataRepository; public final HashMap constants = new HashMap(); public ClassMetaData(String className, String packageName, boolean isInterface, boolean isGroovy, String rawClassComment) { super(rawClassComment); this.className = className; this.packageName = packageName; this.isInterface = isInterface; this.isGroovy = isGroovy; } public ClassMetaData(String className) { this(className, StringUtils.substringBeforeLast(className, "."), false, false, ""); } @Override public String toString() { return className; } public String getClassName() { return className; } public String getSimpleName() { return StringUtils.substringAfterLast(className, "."); } public String getPackageName() { return packageName; } public boolean isInterface() { return isInterface; } public boolean isGroovy() { return isGroovy; } public String getSuperClassName() { return superClassName; } public void setSuperClassName(String superClassName) { this.superClassName = superClassName; } public ClassMetaData getSuperClass() { return superClassName == null ? null : metaDataRepository.find(superClassName); } public List getInterfaceNames() { return interfaceNames; } public void addInterfaceName(String name) { interfaceNames.add(name); } public List getInterfaces() { List interfaces = new ArrayList(); for (String interfaceName : interfaceNames) { ClassMetaData interfaceMetaData = metaDataRepository.find(interfaceName); if (interfaceMetaData != null) { interfaces.add(interfaceMetaData); } } return interfaces; } public List getInnerClassNames() { return innerClassNames; } public void addInnerClassName(String innerClassName) { innerClassNames.add(innerClassName); } public String getOuterClassName() { return outerClassName; } public void setOuterClassName(String outerClassName) { this.outerClassName = outerClassName; } public List getImports() { return imports; } public void addImport(String importName) { imports.add(importName); } public PropertyMetaData addReadableProperty(String name, TypeMetaData type, String rawCommentText, MethodMetaData getterMethod) { PropertyMetaData property = getProperty(name); property.setType(type); property.setRawCommentText(rawCommentText); property.setGetter(getterMethod); return property; } public PropertyMetaData addWriteableProperty(String name, TypeMetaData type, String rawCommentText, MethodMetaData setterMethod) { PropertyMetaData property = getProperty(name); if (property.getType() == null) { property.setType(type); } if (!GUtil.isTrue(property.getRawCommentText())) { property.setRawCommentText(rawCommentText); } property.setSetter(setterMethod); return property; } public PropertyMetaData findDeclaredProperty(String name) { return declaredProperties.get(name); } public Set getDeclaredPropertyNames() { return declaredProperties.keySet(); } public Set getDeclaredProperties() { return new HashSet(declaredProperties.values()); } public Set getDeclaredMethods() { return declaredMethods; } public Set getDeclaredMethodNames() { Set names = new HashSet(); for (MethodMetaData declaredMethod : declaredMethods) { names.add(declaredMethod.getName()); } return names; } public MethodMetaData findDeclaredMethod(String signature) { for (MethodMetaData method : declaredMethods) { if (method.getOverrideSignature().equals(signature)) { return method; } } return null; } public List findDeclaredMethods(String name) { List methods = new ArrayList(); for (MethodMetaData method : declaredMethods) { if (method.getName().equals(name)) { methods.add(method); } } return methods; } /** * Finds a property by name. Includes inherited properties. * * @param name The property name. * @return The property, or null if no such property exists. */ public PropertyMetaData findProperty(String name) { PropertyMetaData propertyMetaData = declaredProperties.get(name); if (propertyMetaData != null) { return propertyMetaData; } ClassMetaData superClass = getSuperClass(); if (superClass != null) { return superClass.findProperty(name); } return null; } /** * Returns the set of property names for this class, including inherited properties. * * @return The set of property names. */ public Set getPropertyNames() { Set propertyNames = new TreeSet(); propertyNames.addAll(declaredProperties.keySet()); ClassMetaData superClass = getSuperClass(); if (superClass != null) { propertyNames.addAll(superClass.getPropertyNames()); } return propertyNames; } private PropertyMetaData getProperty(String name) { PropertyMetaData property = declaredProperties.get(name); if (property == null) { property = new PropertyMetaData(name, this); declaredProperties.put(name, property); } return property; } public Map getConstants() { return constants; } public void attach(ClassMetaDataRepository metaDataRepository) { this.metaDataRepository = metaDataRepository; } public MethodMetaData addMethod(String name, TypeMetaData returnType, String rawCommentText) { MethodMetaData method = new MethodMetaData(name, this); declaredMethods.add(method); method.setReturnType(returnType); method.setRawCommentText(rawCommentText); return method; } public void resolveTypes(Transformer transformer) { super.resolveTypes(transformer); if (superClassName != null) { superClassName = transformer.transform(superClassName); } for (int i = 0; i < interfaceNames.size(); i++) { interfaceNames.set(i, transformer.transform(interfaceNames.get(i))); } for (PropertyMetaData propertyMetaData : declaredProperties.values()) { propertyMetaData.resolveTypes(transformer); } for (MethodMetaData methodMetaData : declaredMethods) { methodMetaData.resolveTypes(transformer); } } public void visitTypes(Action action) { for (PropertyMetaData propertyMetaData : declaredProperties.values()) { propertyMetaData.visitTypes(action); } for (MethodMetaData methodMetaData : declaredMethods) { methodMetaData.visitTypes(action); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/model/LanguageElement.java000066400000000000000000000015341210430504300325540ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source.model; import java.util.List; public interface LanguageElement { String getRawCommentText(); List getAnnotationTypeNames(); boolean isDeprecated(); boolean isIncubating(); } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/model/MethodMetaData.java000066400000000000000000000102041210430504300323320ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source.model; import org.gradle.api.Action; import java.io.Serializable; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; /** * Static meta-data about a method extracted from the source for the class. */ public class MethodMetaData extends AbstractLanguageElement implements Serializable, TypeContainer { private final String name; private final ClassMetaData ownerClass; private final List parameters = new ArrayList(); private TypeMetaData returnType; public MethodMetaData(String name, ClassMetaData ownerClass) { this.name = name; this.ownerClass = ownerClass; } public String getName() { return name; } @Override public String toString() { return String.format("%s.%s()", ownerClass, name); } public ClassMetaData getOwnerClass() { return ownerClass; } public TypeMetaData getReturnType() { return returnType; } public void setReturnType(TypeMetaData returnType) { this.returnType = returnType; } public MethodMetaData getOverriddenMethod() { LinkedList queue = new LinkedList(); queue.add(ownerClass.getSuperClass()); queue.addAll(ownerClass.getInterfaces()); String overrideSignature = getOverrideSignature(); while (!queue.isEmpty()) { ClassMetaData cl = queue.removeFirst(); if (cl == null) { continue; } MethodMetaData overriddenMethod = cl.findDeclaredMethod(overrideSignature); if (overriddenMethod != null) { return overriddenMethod; } queue.add(cl.getSuperClass()); queue.addAll(cl.getInterfaces()); } return null; } public List getParameters() { return parameters; } public ParameterMetaData addParameter(String name, TypeMetaData type) { ParameterMetaData param = new ParameterMetaData(name); param.setType(type); parameters.add(param); return param; } public String getSignature() { StringBuilder builder = new StringBuilder(); builder.append(returnType.getSignature()); builder.append(' '); builder.append(name); builder.append('('); for (int i = 0; i < parameters.size(); i++) { ParameterMetaData param = parameters.get(i); if (i > 0) { builder.append(", "); } builder.append(param.getSignature()); } builder.append(')'); return builder.toString(); } /** * Returns the signature of this method, excluding the return type, and converting generic types to their raw types. */ public String getOverrideSignature() { StringBuilder builder = new StringBuilder(); builder.append(name); builder.append('('); for (int i = 0; i < parameters.size(); i++) { ParameterMetaData param = parameters.get(i); if (i > 0) { builder.append(", "); } builder.append(param.getType().getRawType().getSignature()); } builder.append(')'); return builder.toString(); } public void visitTypes(Action action) { action.execute(returnType); for (ParameterMetaData parameter : parameters) { parameter.visitTypes(action); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/model/ParameterMetaData.java000066400000000000000000000030331210430504300330340ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source.model; import org.gradle.api.Action; import java.io.Serializable; /** * Static meta-data about a method parameter extracted from the source for the method. */ public class ParameterMetaData implements Serializable, TypeContainer { private final String name; private TypeMetaData type; public ParameterMetaData(String name) { this.name = name; } public String getName() { return name; } public TypeMetaData getType() { return type; } public void setType(TypeMetaData type) { this.type = type; } public String getSignature() { StringBuilder builder = new StringBuilder(); builder.append(type.getSignature()); builder.append(" "); builder.append(name); return builder.toString(); } public void visitTypes(Action action) { action.execute(type); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/model/PropertyMetaData.java000066400000000000000000000054141210430504300327450ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source.model; import org.gradle.api.Action; import java.io.Serializable; /** * Static meta-data about a property extracted from the source for the class. */ public class PropertyMetaData extends AbstractLanguageElement implements Serializable, TypeContainer { private TypeMetaData type; private final String name; private final ClassMetaData ownerClass; private MethodMetaData setter; private MethodMetaData getter; public PropertyMetaData(String name, ClassMetaData ownerClass) { this.name = name; this.ownerClass = ownerClass; } public String getName() { return name; } @Override public String toString() { return String.format("%s.%s", ownerClass, name); } public TypeMetaData getType() { return type; } public void setType(TypeMetaData type) { this.type = type; } public boolean isWriteable() { return setter != null; } public ClassMetaData getOwnerClass() { return ownerClass; } public String getSignature() { StringBuilder builder = new StringBuilder(); builder.append(type.getSignature()); builder.append(' '); builder.append(name); return builder.toString(); } public MethodMetaData getGetter() { return getter; } public void setGetter(MethodMetaData getter) { this.getter = getter; } public MethodMetaData getSetter() { return setter; } public void setSetter(MethodMetaData setter) { this.setter = setter; } public PropertyMetaData getOverriddenProperty() { MethodMetaData overriddenMethod = null; if (getter != null) { overriddenMethod = getter.getOverriddenMethod(); } if (overriddenMethod == null && setter != null) { overriddenMethod = setter.getOverriddenMethod(); } if (overriddenMethod != null) { return overriddenMethod.getOwnerClass().findDeclaredProperty(name); } return null; } public void visitTypes(Action action) { action.execute(type); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/model/TypeContainer.java000066400000000000000000000014151210430504300323010ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source.model; import org.gradle.api.Action; public interface TypeContainer { void visitTypes(Action action); } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/dsl/source/model/TypeMetaData.java000066400000000000000000000123051210430504300320370ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.source.model; import org.gradle.api.Action; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /** * Static meta-data about a type reference extracted from source. */ public class TypeMetaData implements Serializable, TypeContainer { public static final TypeMetaData VOID = new TypeMetaData("void"); public static final TypeMetaData OBJECT = new TypeMetaData("java.lang.Object"); private String name; private int arrayDimensions; private boolean varargs; private List typeArgs; private boolean wildcard; private TypeMetaData upperBounds; private TypeMetaData lowerBounds; public TypeMetaData(String name) { this.name = name; } public TypeMetaData() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getArrayDimensions() { return arrayDimensions + (varargs ? 1 : 0); } public TypeMetaData addArrayDimension() { arrayDimensions++; return this; } public boolean isVarargs() { return varargs; } public TypeMetaData setVarargs() { this.varargs = true; return this; } public List getTypeArgs() { return typeArgs; } public TypeMetaData getRawType() { if (wildcard || lowerBounds != null) { return OBJECT; } if (upperBounds != null) { return upperBounds.getRawType(); } TypeMetaData rawType = new TypeMetaData(name); rawType.arrayDimensions = arrayDimensions; rawType.varargs = varargs; return rawType; } public String getSignature() { final StringBuilder builder = new StringBuilder(); visitSignature(new SignatureVisitor() { public void visitText(String text) { builder.append(text); } public void visitType(String name) { builder.append(name); } }); return builder.toString(); } public String getArraySuffix() { StringBuilder builder = new StringBuilder(); for (int i = 0; i < arrayDimensions; i++) { builder.append("[]"); } if (varargs) { builder.append("..."); } return builder.toString(); } public TypeMetaData addTypeArg(TypeMetaData typeArg) { if (typeArgs == null) { typeArgs = new ArrayList(); } typeArgs.add(typeArg); return this; } public void visitTypes(Action action) { if (wildcard) { return; } if (upperBounds != null) { upperBounds.visitTypes(action); return; } if (lowerBounds != null) { lowerBounds.visitTypes(action); return; } action.execute(this); if (typeArgs != null) { for (TypeMetaData typeArg : typeArgs) { typeArg.visitTypes(action); } } } public void visitSignature(SignatureVisitor visitor) { if (wildcard) { visitor.visitText("?"); } else if (upperBounds != null) { visitor.visitText("? extends "); upperBounds.visitSignature(visitor); } else if (lowerBounds != null) { visitor.visitText("? super "); lowerBounds.visitSignature(visitor); } else { visitor.visitType(name); if (typeArgs != null) { visitor.visitText("<"); for (int i = 0; i < typeArgs.size(); i++) { if (i > 0) { visitor.visitText(", "); } TypeMetaData typeArg = typeArgs.get(i); typeArg.visitSignature(visitor); } visitor.visitText(">"); } String suffix = getArraySuffix(); if (suffix.length() > 0) { visitor.visitText(suffix); } } } public TypeMetaData setWildcard() { wildcard = true; return this; } public TypeMetaData setUpperBounds(TypeMetaData upperBounds) { this.upperBounds = upperBounds; return this; } public TypeMetaData setLowerBounds(TypeMetaData lowerBounds) { this.lowerBounds = lowerBounds; return this; } public interface SignatureVisitor { void visitText(String text); void visitType(String name); } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/model/000077500000000000000000000000001210430504300245675ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/model/Attachable.java000066400000000000000000000013511210430504300274620ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.model; public interface Attachable { void attach(ClassMetaDataRepository repository); } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/model/ClassMetaDataRepository.java000066400000000000000000000017421210430504300322040ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.model; import groovy.lang.Closure; import org.gradle.api.UnknownDomainObjectException; public interface ClassMetaDataRepository { T get(String fullyQualifiedClassName) throws UnknownDomainObjectException; T find(String fullyQualifiedClassName); void put(String fullyQualifiedClassName, T metaData); void each(Closure cl); } gradle-1.4/buildSrc/src/main/groovy/org/gradle/build/docs/model/SimpleClassMetaDataRepository.java000066400000000000000000000057351210430504300333640ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.model; import groovy.lang.Closure; import org.gradle.api.GradleException; import org.gradle.api.UnknownDomainObjectException; import java.io.*; import java.util.HashMap; import java.util.Map; public class SimpleClassMetaDataRepository> implements ClassMetaDataRepository { private final Map classes = new HashMap(); @SuppressWarnings("unchecked") public void load(File repoFile) { try { FileInputStream inputStream = new FileInputStream(repoFile); try { ObjectInputStream objInputStream = new ObjectInputStream(new BufferedInputStream(inputStream)); classes.clear(); classes.putAll((Map) objInputStream.readObject()); } finally { inputStream.close(); } } catch (Exception e) { throw new GradleException(String.format("Could not load meta-data from %s.", repoFile), e); } } public void store(File repoFile) { try { FileOutputStream outputStream = new FileOutputStream(repoFile); try { ObjectOutputStream objOutputStream = new ObjectOutputStream(new BufferedOutputStream(outputStream)); objOutputStream.writeObject(classes); objOutputStream.close(); } finally { outputStream.close(); } } catch (IOException e) { throw new GradleException(String.format("Could not write meta-data to %s.", repoFile), e); } } public T get(String fullyQualifiedClassName) { T t = find(fullyQualifiedClassName); if (t == null) { throw new UnknownDomainObjectException(String.format("No meta-data is available for class '%s'.", fullyQualifiedClassName)); } return t; } public T find(String fullyQualifiedClassName) { T t = classes.get(fullyQualifiedClassName); if (t != null) { t.attach(this); } return t; } public void put(String fullyQualifiedClassName, T metaData) { classes.put(fullyQualifiedClassName, metaData); } public void each(Closure cl) { for (Map.Entry entry : classes.entrySet()) { cl.call(new Object[]{entry.getKey(), entry.getValue()}); } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/plugins/000077500000000000000000000000001210430504300231215ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/plugins/jsoup/000077500000000000000000000000001210430504300242615ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/plugins/jsoup/Jsoup.groovy000066400000000000000000000032051210430504300266300ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.plugins.jsoup import org.gradle.api.tasks.SourceTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.OutputFile import org.gradle.util.ConfigureUtil import org.jsoup.nodes.Document class Jsoup extends SourceTask { @Input String inputEncoding @Input String outputEncoding List transforms = [] private destination void setDestination(destination) { this.destination = destination } @OutputFile File getDestination() { project.file(destination) } @TaskAction void doTransform() { Document document = org.jsoup.Jsoup.parse(getSource().singleFile.getText(getInputEncoding())) document.outputSettings().charset(getOutputEncoding()) getTransforms().each { ConfigureUtil.configure(it, document) } getDestination().setText(document.toString(), getOutputEncoding()) } void transform(Closure transform) { this.transforms << transform } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/plugins/jsoup/JsoupPlugin.groovy000066400000000000000000000020651210430504300300120ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.plugins.jsoup import org.gradle.api.Project import org.gradle.api.Plugin import java.nio.charset.Charset class JsoupPlugin implements Plugin { void apply(Project project) { project.tasks.withType(Jsoup) { Jsoup task -> task.conventionMapping.with { inputEncoding = { Charset.defaultCharset().name() } outputEncoding = { task.inputEncoding } } } } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/plugins/pegdown/000077500000000000000000000000001210430504300245645ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/groovy/org/gradle/plugins/pegdown/PegDown.groovy000066400000000000000000000042271210430504300274030ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.plugins.pegdown import org.gradle.api.tasks.Input import org.gradle.api.tasks.Optional import org.gradle.api.tasks.SourceTask import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.pegdown.Extensions import org.gradle.api.InvalidUserDataException import org.pegdown.PegDownProcessor class PegDown extends SourceTask { @Input @Optional List options = [] @Input String inputEncoding @Input String outputEncoding private destination void setDestination(destination) { this.destination = destination } @OutputFile File getDestination() { project.file(destination) } @TaskAction void process() { int optionsValue = getCalculatedOptions() PegDownProcessor processor = new PegDownProcessor(optionsValue) String markdown = getSource().singleFile.getText(getInputEncoding()) String html = processor.markdownToHtml(markdown) getDestination().write(html, getOutputEncoding()) } int getCalculatedOptions() { getOptions().inject(0) { acc, val -> acc | toOptionValue(val) } as int } protected int toOptionValue(String optionName) { String upName = val.toUpperCase() try { Extensions."$upName" } catch (MissingPropertyException e) { throw new InvalidUserDataException("$optionName is not a valid PegDown extension name") } } void options(String... options) { this.options.addAll(options) } } gradle-1.4/buildSrc/src/main/groovy/org/gradle/plugins/pegdown/PegDownPlugin.groovy000066400000000000000000000020651210430504300305600ustar00rootroot00000000000000/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.plugins.pegdown import org.gradle.api.Plugin import org.gradle.api.Project import java.nio.charset.Charset class PegDownPlugin implements Plugin { void apply(Project project) { project.tasks.withType(PegDown) { task -> task.conventionMapping.with { inputEncoding = { Charset.defaultCharset().name() } outputEncoding = { task.inputEncoding } } } } } gradle-1.4/buildSrc/src/main/resources/000077500000000000000000000000001210430504300201005ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/resources/META-INF/000077500000000000000000000000001210430504300212405ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/resources/META-INF/gradle-plugins/000077500000000000000000000000001210430504300241555ustar00rootroot00000000000000gradle-1.4/buildSrc/src/main/resources/META-INF/gradle-plugins/jsoup.properties000066400000000000000000000000711210430504300274310ustar00rootroot00000000000000implementation-class=org.gradle.plugins.jsoup.JsoupPlugingradle-1.4/buildSrc/src/main/resources/META-INF/gradle-plugins/pegdown.properties000066400000000000000000000000751210430504300277400ustar00rootroot00000000000000implementation-class=org.gradle.plugins.pegdown.PegDownPlugingradle-1.4/buildSrc/src/test/000077500000000000000000000000001210430504300161215ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/000077500000000000000000000000001210430504300174465ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/000077500000000000000000000000001210430504300202355ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/000077500000000000000000000000001210430504300214735ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/000077500000000000000000000000001210430504300225725ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/000077500000000000000000000000001210430504300235225ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/SampleLayoutHandlerTest.groovy000066400000000000000000000064561210430504300315610ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import org.w3c.dom.Element class SampleLayoutHandlerTest extends XmlSpecification { final Element samples = document.createElement('samples') final SampleLayoutHandler builder = new SampleLayoutHandler('samples/name') final Element parent = document.createElement("root") def buildsLayoutForFileNames() { when: builder.handle(''' build.gradle settings.gradle ''', parent, samples) then: expectLayout('''name/ build.gradle settings.gradle ''') } def buildsLayoutForDirNames() { when: builder.handle(''' src/ build/ ''', parent, samples) then: expectLayout('''name/ src/ build/ ''') } def buildsLayoutForNestedNames() { when: builder.handle(''' api/build/ api/build.gradle ''', parent, samples) then: expectLayout('''name/ api/ build/ build.gradle ''') } def addsMetaDataToSamplesManifest() { when: builder.handle(''' build.gradle build/libs/ ''', parent, samples) then: formatTree(samples) == ''' ''' } def buildsLayoutForMultipleNestingLevels() { when: builder.handle(''' src/main/java/Source1.java src/main/java/org/ src/test/java/SourceTest.java build/libs/test.jar ''', parent, samples) then: expectLayout('''name/ src/ main/java/ Source1.java org/ test/java/ SourceTest.java build/libs/ test.jar ''') } def buildsLayoutForMultipleNestingLevelsWithExplicitDir() { when: builder.handle(''' src/main/java/ src/main/java/org/gradle/Source1.java src/main/java/org/gradle/Source2.java src/test/java/ src/test/java/org/gradle/SourceTest.java ''', parent, samples) then: expectLayout('''name/ src/ main/java/ org/gradle/ Source1.java Source2.java test/java/ org/gradle/ SourceTest.java ''') } def failsWhenFileHasChildren() { when: builder.handle(''' src/main/java src/main/java/org/gradle/Source1.java ''', parent, samples) then: RuntimeException e = thrown() e.message == 'Parent directory \'java\' should end with a slash.' } def removesLeadingSlashAndEmptyElements() { when: builder.handle(''' /src//java// src//java/Source.java ''', parent, samples) then: expectLayout('''name/ src/java/ Source.java ''') } void expectLayout(String layout) { assert format(parent.childNodes.collect {it}) == """Build layout$layout""" } } gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/XmlSpecification.groovy000066400000000000000000000103441210430504300302340ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs import groovy.xml.dom.DOMCategory import javax.xml.parsers.DocumentBuilder import javax.xml.parsers.DocumentBuilderFactory import org.xml.sax.InputSource import spock.lang.Specification import org.w3c.dom.* abstract class XmlSpecification extends Specification { final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() def parse(String str, Document document = null) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance() factory.setNamespaceAware(true) DocumentBuilder builder = factory.newDocumentBuilder() def parsed = builder.parse(new InputSource(new StringReader(str))).documentElement return document ? document.importNode(parsed, true) : parsed } def formatTree(Closure cl) { withCategories { return formatTree(cl.call()) } } def withCategories(Closure cl) { use(DOMCategory) { use(BuildableDOMCategory) { return cl.call() } } } def format(Node... nodes) { format(nodes as List) } def formatTree(Node... nodes) { formatTree(nodes as List) } def formatTree(Iterable nodes) { format(nodes, true) } def format(Iterable nodes, boolean prettyPrint = false) { StringBuilder builder = new StringBuilder() nodes.each { node -> format(node, builder, 0, prettyPrint, prettyPrint) } return builder.toString() } def format(Node node, Appendable target, int depth, boolean prettyPrint, boolean indentSelf) { if (node instanceof Element) { Element element = (Element) node if (indentSelf && depth > 0) { target.append('\n') depth.times { target.append(' ') } } target.append("<${element.tagName}") for (int i = 0; i < element.attributes.length; i++) { Attr attr = element.attributes.item(i) target.append(" $attr.name=\"$attr.value\"") } element.childNodes.findAll { it instanceof Text }.each { assert it.textContent != null : "Found null text element in <$element.tagName>" } List trimmedContent = element.childNodes.collect { it }; boolean inlineContent = trimmedContent.find { it instanceof Text && it.textContent.trim() } if (prettyPrint && !inlineContent) { trimmedContent = element.childNodes.inject([]) { list, child -> if (!(child instanceof Text) || child.textContent.trim().length() != 0) { list << child } return list } } if (trimmedContent.isEmpty()) { target.append('/>') return } target.append('>') trimmedContent.each { child -> format(child, target, depth + 1, prettyPrint, prettyPrint && !inlineContent) } if (prettyPrint && indentSelf && !inlineContent) { target.append('\n') depth.times { target.append(' ') } } target.append("") return } if (node instanceof Text) { target.append(node.nodeValue.replace('&', '&').replace('<', '<').replace('>', '>')) return } throw new UnsupportedOperationException("Don't know how to format DOM node: $node") } } gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/dsl/000077500000000000000000000000001210430504300243045ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/dsl/docbook/000077500000000000000000000000001210430504300257245ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/dsl/docbook/BasicJavadocLexerTest.groovy000066400000000000000000000121671210430504300333530ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook import spock.lang.Specification class BasicJavadocLexerTest extends Specification { final BasicJavadocLexer lexer = new BasicJavadocLexer(new JavadocScanner("")) final JavadocLexer.TokenVisitor visitor = Mock() def parsesHtmlElements() { when: lexer.pushText("

text

") lexer.visit(visitor) then: 1 * visitor.onStartHtmlElement('p') 1 * visitor.onStartHtmlElementComplete('p') 1 * visitor.onText(' text ') 1 * visitor.onEndHtmlElement('p') 1 * visitor.onEnd() 0 * visitor._ } def normalizesHtmlElementNamesToLowercase() { when: lexer.pushText("

") lexer.visit(visitor) then: 1 * visitor.onStartHtmlElement('p') 1 * visitor.onStartHtmlElementComplete('p') 1 * visitor.onEndHtmlElement('end') 1 * visitor.onEnd() 0 * visitor._ } def parsesHtmlEntities() { when: lexer.pushText("before & after") lexer.visit(visitor) then: 1 * visitor.onText('before & after') 1 * visitor.onEnd() 0 * visitor._ } def parsesStartHtmlElementWithAttributes() { when: lexer.pushText("") lexer.visit(visitor) then: 1 * visitor.onStartHtmlElement('a') 1 * visitor.onHtmlElementAttribute('name', 'value') 1 * visitor.onHtmlElementAttribute('other', '\n& \'\n \"') 1 * visitor.onStartHtmlElementComplete('a') 1 * visitor.onEnd() 0 * visitor._ } def canUseSingleOrDoubleQuotesForAttributeValues() { when: lexer.pushText("") lexer.visit(visitor) then: 1 * visitor.onStartHtmlElement('a') 1 * visitor.onHtmlElementAttribute('single', 'a=\"b\"') 1 * visitor.onHtmlElementAttribute('double', 'a=\'b\'') 1 * visitor.onStartHtmlElementComplete('a') 1 * visitor.onEnd() 0 * visitor._ } def splitsHtmlElementWithNoContentIntoSeparateStartAndEndTokens() { when: lexer.pushText("

") lexer.visit(visitor) then: 1 * visitor.onStartHtmlElement('p') 1 * visitor.onStartHtmlElementComplete('p') 1 * visitor.onEndHtmlElement('p') 1 * visitor.onEnd() 0 * visitor._ } def parsesJavadocTags() { when: lexer.pushText("{@tag some value}") lexer.visit(visitor) then: 1 * visitor.onStartJavadocTag('tag') 1 * visitor.onText('some value') 1 * visitor.onEndJavadocTag('tag') 1 * visitor.onEnd() 0 * visitor._ } def javadocTagCanBeEmpty() { when: lexer.pushText("{@empty}") lexer.visit(visitor) then: 1 * visitor.onStartJavadocTag('empty') 1 * visitor.onEndJavadocTag('empty') 1 * visitor.onEnd() 0 * visitor._ } def ignoresWhitespaceAndEOLCharsBetweenJavadocTagNameAndValue() { when: lexer.pushText("* {@link\n * Something}") lexer.visit(visitor) then: 1 * visitor.onStartJavadocTag('link') 1 * visitor.onText('Something') 1 * visitor.onEndJavadocTag('link') 1 * visitor.onEnd() 0 * visitor._ } def javadocTagCanContainEOLChars() { when: lexer.pushText(" * {@link #Something(Object,\n * String\n * }") lexer.visit(visitor) then: 1 * visitor.onStartJavadocTag('link') 1 * visitor.onText('#Something(Object,\nString\n') 1 * visitor.onEndJavadocTag('link') 1 * visitor.onEnd() 0 * visitor._ } def doesNotParseHtmlElementsInsideJavadocTag() { when: lexer.pushText("{@link & < }") lexer.visit(visitor) then: 1 * visitor.onStartJavadocTag('link') 1 * visitor.onText(' & < ') 1 * visitor.onEndJavadocTag('link') 1 * visitor.onEnd() 0 * visitor._ } def javadocTagCannotHaveWhitespaceInsideMarker() { when: lexer.pushText("{ @code} {@ code} { @ code}") lexer.visit(visitor) then: 1 * visitor.onText('{ @code} ') 1 * visitor.onStartJavadocTag('') 1 * visitor.onText('code') 1 * visitor.onEndJavadocTag('') 1 * visitor.onText(' { @ code}') 1 * visitor.onEnd() 0 * visitor._ } } ClassDocExtensionsBuilderTest.groovy000066400000000000000000000170551210430504300350460ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/dsl/docbook/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook import org.gradle.build.docs.XmlSpecification import org.gradle.build.docs.dsl.source.model.ClassMetaData import org.gradle.build.docs.dsl.source.model.MethodMetaData import org.gradle.build.docs.dsl.source.model.ParameterMetaData import org.gradle.build.docs.dsl.source.model.PropertyMetaData import org.gradle.build.docs.dsl.source.model.TypeMetaData import org.gradle.build.docs.dsl.docbook.model.ClassExtensionMetaData import org.gradle.build.docs.dsl.docbook.model.PropertyDoc import org.gradle.build.docs.dsl.docbook.model.MethodDoc import org.gradle.build.docs.dsl.docbook.model.ClassDoc class ClassDocExtensionsBuilderTest extends XmlSpecification { final DslDocModel docModel = Mock() final ClassDocExtensionsBuilder builder = new ClassDocExtensionsBuilder(docModel, null) def buildsExtensionsForClassMixins() { ClassMetaData classMetaData = classMetaData() ClassExtensionMetaData extensionMetaData = new ClassExtensionMetaData('org.gradle.Class') extensionMetaData.addMixin('a', 'org.gradle.ExtensionA1') extensionMetaData.addMixin('a', 'org.gradle.ExtensionA2') extensionMetaData.addMixin('b', 'org.gradle.ExtensionB') ClassDoc extensionA1 = classDoc('org.gradle.ExtensionA1') ClassDoc extensionA2 = classDoc('org.gradle.ExtensionA2') ClassDoc extensionB = classDoc('org.gradle.ExtensionB') _ * docModel.getClassDoc('org.gradle.ExtensionA1') >> extensionA1 _ * docModel.getClassDoc('org.gradle.ExtensionA2') >> extensionA2 _ * docModel.getClassDoc('org.gradle.ExtensionB') >> extensionB def content = parse('''

Properties
Methods
''') when: ClassDoc doc = withCategories { def doc = new ClassDoc('org.gradle.Class', content, document, classMetaData, extensionMetaData) builder.build(doc) doc.mergeContent() } then: doc.classExtensions.size() == 2 doc.classExtensions[0].pluginId == 'a' doc.classExtensions[0].mixinClasses == [extensionA1, extensionA2] as Set doc.classExtensions[1].pluginId == 'b' doc.classExtensions[1].mixinClasses == [extensionB] as Set } def buildsExtensionsForClassExtensions() { ClassMetaData classMetaData = classMetaData() ClassExtensionMetaData extensionMetaData = new ClassExtensionMetaData('org.gradle.Class') extensionMetaData.addExtension('a', 'n1', 'org.gradle.ExtensionA1') extensionMetaData.addExtension('a', 'n2', 'org.gradle.ExtensionA2') extensionMetaData.addExtension('b', 'n1', 'org.gradle.ExtensionB') ClassDoc extensionA1 = classDoc('org.gradle.ExtensionA1') ClassDoc extensionA2 = classDoc('org.gradle.ExtensionA2') ClassDoc extensionB = classDoc('org.gradle.ExtensionB') _ * docModel.getClassDoc('org.gradle.ExtensionA1') >> extensionA1 _ * docModel.isKnownType('org.gradle.ExtensionA1') >> true _ * docModel.getClassDoc('org.gradle.ExtensionA2') >> extensionA2 _ * docModel.isKnownType('org.gradle.ExtensionA2') >> true _ * docModel.getClassDoc('org.gradle.ExtensionB') >> extensionB _ * docModel.isKnownType('org.gradle.ExtensionB') >> true def content = parse('''
Properties
Methods
''') when: ClassDoc doc = withCategories { def doc = new ClassDoc('org.gradle.Class', content, document, classMetaData, extensionMetaData) builder.build(doc) doc.mergeContent() } then: doc.classExtensions.size() == 2 doc.classExtensions[0].pluginId == 'a' doc.classExtensions[0].extensionClasses == [n1: extensionA1, n2: extensionA2] doc.classExtensions[0].extensionProperties.size() == 2 doc.classExtensions[0].extensionBlocks.size() == 2 doc.classExtensions[1].pluginId == 'b' doc.classExtensions[1].extensionClasses == [n1: extensionB] doc.classExtensions[1].extensionProperties.size() == 1 doc.classExtensions[1].extensionBlocks.size() == 1 } def classMetaData(String name = 'org.gradle.Class') { ClassMetaData classMetaData = Mock() _ * classMetaData.className >> name return classMetaData } def classDoc(String name = 'org.gradle.Class') { ClassDoc doc = Mock() _ * doc.name >> name _ * doc.toString() >> "ClassDoc '$name'" return doc } def property(String name, ClassMetaData classMetaData) { return property([:], name, classMetaData) } def property(Map args, String name, ClassMetaData classMetaData) { PropertyMetaData property = Mock() _ * property.name >> name _ * property.ownerClass >> classMetaData def type = args.type instanceof TypeMetaData ? args.type : new TypeMetaData(args.type ?: 'org.gradle.Type') _ * property.type >> type _ * property.signature >> "$name-signature" _ * javadocConverter.parse(property, !null) >> ({[parse("${args.comment ?: 'comment'}")]} as DocComment) return property } def propertyDoc(Map args = [:], String name) { return new PropertyDoc(classMetaData(), property(name, null), [parse("$name comment")], args.additionalValues ?: []) } def method(String name, ClassMetaData classMetaData) { return method([:], name, classMetaData) } def method(Map args, String name, ClassMetaData classMetaData) { MethodMetaData method = Mock() List paramTypes = args.paramTypes ?: [] _ * method.name >> name _ * method.overrideSignature >> "$name(${paramTypes.join(', ')})" _ * method.parameters >> paramTypes.collect { def param = new ParameterMetaData("p"); param.type = new TypeMetaData(it) return param } _ * method.ownerClass >> classMetaData _ * method.returnType >> new TypeMetaData(args.returnType ?: 'ReturnType') _ * javadocConverter.parse(method, !null) >> ({[parse("${args.comment ?: 'comment'}")]} as DocComment) return method } def methodDoc(String name) { MethodDoc methodDoc = Mock() _ * methodDoc.name >> name _ * methodDoc.metaData >> method(name, null) _ * methodDoc.forClass(!null) >> methodDoc return methodDoc } } ClassDocMethodsBuilderTest.groovy000066400000000000000000000173371210430504300343150ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/dsl/docbook/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook import org.gradle.build.docs.XmlSpecification import org.gradle.build.docs.dsl.docbook.model.ClassDoc import org.gradle.build.docs.dsl.docbook.model.MethodDoc import org.gradle.build.docs.dsl.docbook.model.PropertyDoc import org.gradle.build.docs.dsl.source.model.* class ClassDocMethodsBuilderTest extends XmlSpecification { final JavadocConverter javadocConverter = Mock() final ClassDocMethodsBuilder builder = new ClassDocMethodsBuilder(javadocConverter, null) def buildsMethodsForClass() { ClassMetaData classMetaData = classMetaData() MethodMetaData methodA = method('a', classMetaData) MethodMetaData methodB = method('b', classMetaData) MethodMetaData methodBOverload = method('b', classMetaData) MethodDoc methodAOverridden = methodDoc('a') MethodDoc methodC = methodDoc('c') ClassDoc superClass = classDoc('org.gradle.SuperClass') def content = parse('''
Methods
Name
a
b
PropertiesName
''') when: ClassDoc doc = withCategories { def doc = new ClassDoc('org.gradle.Class', content, document, classMetaData, null) doc.superClass = superClass builder.build(doc) doc } then: doc.classMethods.size() == 4 doc.classMethods[0].name == 'a' doc.classMethods[1].name == 'b' doc.classMethods[2].name == 'b' doc.classMethods[3].name == 'c' _ * classMetaData.declaredMethods >> ([methodA, methodB, methodBOverload] as Set) _ * classMetaData.findDeclaredMethods("a") >> [methodA] _ * classMetaData.findDeclaredMethods("b") >> [methodB, methodBOverload] _ * classMetaData.superClassName >> 'org.gradle.SuperClass' _ * superClass.classMethods >> [methodC, methodAOverridden] } def buildsBlocksForClass() { ClassMetaData classMetaData = classMetaData() PropertyMetaData blockProperty = property('block', classMetaData) MethodMetaData blockMethod = method('block', classMetaData, paramTypes: [Closure.class.name]) PropertyMetaData compositeBlockProperty = property('listBlock', classMetaData, type: new TypeMetaData('java.util.List').addTypeArg(new TypeMetaData('BlockType'))) MethodMetaData compositeBlockMethod = method('listBlock', classMetaData, paramTypes: [Closure.class.name]) MethodMetaData tooManyParams = method('block', classMetaData, paramTypes: ['String', 'boolean']) MethodMetaData notAClosure = method('block', classMetaData, paramTypes: ['String']) MethodMetaData noBlockProperty = method('notBlock', classMetaData, paramTypes: [Closure.class.name]) _ * classMetaData.findProperty('block') >> blockProperty _ * classMetaData.findProperty('listBlock') >> compositeBlockProperty _ * classMetaData.declaredMethods >> [blockMethod, compositeBlockMethod, tooManyParams, notAClosure, noBlockProperty] _ * classMetaData.findDeclaredMethods('listBlock') >> [compositeBlockMethod] _ * classMetaData.findDeclaredMethods('block') >> [tooManyParams, notAClosure, blockMethod] _ * classMetaData.findDeclaredMethods('notBlock') >> [noBlockProperty] def content = parse('''
Methods
Name
block
listBlock
notBlock
Properties
Name
block
listBlock
''') when: ClassDoc doc = withCategories { def doc = new ClassDoc('org.gradle.Class', content, document, classMetaData, null) new ClassDocPropertiesBuilder(javadocConverter, Mock(GenerationListener)).build(doc) new ClassDocMethodsBuilder(javadocConverter, Mock(GenerationListener)).build(doc) doc } then: doc.classProperties.size() == 2 doc.classProperties[0].name == 'block' doc.classProperties[1].name == 'listBlock' doc.classMethods.size() == 3 doc.classBlocks.size() == 2 doc.classBlocks[0].name == 'block' doc.classBlocks[0].type.signature == 'org.gradle.Type' !doc.classBlocks[0].multiValued doc.classBlocks[1].name == 'listBlock' doc.classBlocks[1].type.signature == 'BlockType' doc.classBlocks[1].multiValued } def classMetaData(String name = 'org.gradle.Class') { ClassMetaData classMetaData = Mock() _ * classMetaData.className >> name return classMetaData } def classDoc(String name = 'org.gradle.Class') { ClassDoc doc = Mock() _ * doc.name >> name _ * doc.toString() >> "ClassDoc '$name'" return doc } def property(String name, ClassMetaData classMetaData) { return property([:], name, classMetaData) } def property(Map args, String name, ClassMetaData classMetaData) { PropertyMetaData property = Mock() _ * property.name >> name _ * property.ownerClass >> classMetaData def type = args.type instanceof TypeMetaData ? args.type : new TypeMetaData(args.type ?: 'org.gradle.Type') _ * property.type >> type _ * property.signature >> "$name-signature" _ * javadocConverter.parse(property, !null) >> ({[parse("${args.comment ?: 'comment'}")]} as DocComment) return property } def propertyDoc(Map args = [:], String name) { return new PropertyDoc(classMetaData(), property(name, null), [parse("$name comment")], args.additionalValues ?: []) } def method(String name, ClassMetaData classMetaData) { return method([:], name, classMetaData) } def method(Map args, String name, ClassMetaData classMetaData) { MethodMetaData method = Mock() List paramTypes = args.paramTypes ?: [] _ * method.name >> name _ * method.overrideSignature >> "$name(${paramTypes.join(', ')})" _ * method.parameters >> paramTypes.collect { def param = new ParameterMetaData("p"); param.type = new TypeMetaData(it) return param } _ * method.ownerClass >> classMetaData _ * method.returnType >> new TypeMetaData(args.returnType ?: 'ReturnType') _ * javadocConverter.parse(method, _) >> ({[parse("comment")]} as DocComment) return method } def methodDoc(String name) { MethodDoc methodDoc = Mock() _ * methodDoc.name >> name _ * methodDoc.metaData >> method(name, null) _ * methodDoc.forClass(!null) >> methodDoc return methodDoc } } ClassDocPropertiesBuilderTest.groovy000066400000000000000000000161221210430504300350350ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/dsl/docbook/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook import org.gradle.build.docs.XmlSpecification import org.gradle.build.docs.dsl.docbook.model.ClassDoc import org.gradle.build.docs.dsl.docbook.model.ExtraAttributeDoc import org.gradle.build.docs.dsl.docbook.model.PropertyDoc import org.gradle.build.docs.dsl.source.model.ClassMetaData import org.gradle.build.docs.dsl.source.model.PropertyMetaData import org.gradle.build.docs.dsl.source.model.TypeMetaData class ClassDocPropertiesBuilderTest extends XmlSpecification { final JavadocConverter javadocConverter = Mock() final GenerationListener listener = Mock() final ClassDocPropertiesBuilder builder = new ClassDocPropertiesBuilder(javadocConverter, listener) def buildsPropertiesForClass() { ClassMetaData classMetaData = classMetaData() PropertyMetaData propertyA = property('a', classMetaData, comment: 'prop a') PropertyMetaData propertyB = property('b', classMetaData, comment: 'prop b') ClassDoc superDoc = classDoc() PropertyDoc propertyDocA = propertyDoc('a') PropertyDoc propertyDocC = propertyDoc('c') def content = parse('''
Properties
Name
b
a
Methods
''') when: ClassDoc doc = withCategories { def doc = new ClassDoc('org.gradle.Class', content, document, classMetaData, null) doc.superClass = superDoc builder.build(doc) return doc } then: doc.classProperties.size() == 3 doc.classProperties[0].name == 'a' doc.classProperties[1].name == 'b' doc.classProperties[2].name == 'c' _ * classMetaData.findProperty('b') >> propertyB _ * classMetaData.findProperty('a') >> propertyA _ * classMetaData.superClassName >> 'org.gradle.SuperType' _ * superDoc.getClassProperties() >> [propertyDocC, propertyDocA] } def canAttachAdditionalValuesToProperty() { ClassMetaData classMetaData = classMetaData() PropertyMetaData propertyA = property('a', classMetaData, comment: 'prop a') PropertyMetaData propertyB = property('b', classMetaData, comment: 'prop b') ClassDoc superDoc = classDoc() ExtraAttributeDoc inheritedValue = new ExtraAttributeDoc(parse('inherited'), parse('inherited')) ExtraAttributeDoc overriddenValue = new ExtraAttributeDoc(parse('general value'), parse('general')) PropertyDoc inheritedPropertyA = propertyDoc('a', additionalValues: [inheritedValue, overriddenValue]) PropertyDoc inheritedPropertyB = propertyDoc('b', additionalValues: [inheritedValue, overriddenValue]) PropertyDoc inheritedPropertyC = propertyDoc('c', additionalValues: [inheritedValue, overriddenValue]) def content = parse('''
Properties
Nameinheritedaddedoverridden general value
aspecific1specific2specific3
b
Methods
''') when: ClassDoc doc = withCategories { def doc = new ClassDoc('org.gradle.Class', content, document, classMetaData, null) doc.superClass = superDoc builder.build(doc) return doc } then: doc.classProperties.size() == 3 def prop = doc.classProperties[0] prop.name == 'a' prop.additionalValues.size() == 3 format(prop.additionalValues[0].title) == 'inherited' format(prop.additionalValues[0].value) == 'specific1' format(prop.additionalValues[1].title) == 'overridden' format(prop.additionalValues[1].value) == 'specific3' format(prop.additionalValues[2].title) == 'added' format(prop.additionalValues[2].value) == 'specific2' def prop2 = doc.classProperties[1] prop2.name == 'b' prop2.additionalValues.size() == 2 format(prop2.additionalValues[0].title) == 'inherited' format(prop2.additionalValues[0].value) == 'inherited' format(prop2.additionalValues[1].title) == 'overridden' format(prop2.additionalValues[1].value) == 'general' def prop3 = doc.classProperties[2] prop3.name == 'c' prop3.additionalValues.size() == 2 format(prop3.additionalValues[0].title) == 'inherited' format(prop3.additionalValues[0].value) == 'inherited' format(prop3.additionalValues[1].title) == 'overridden' format(prop3.additionalValues[1].value) == 'general' _ * classMetaData.findProperty('b') >> propertyB _ * classMetaData.findProperty('a') >> propertyA _ * classMetaData.superClassName >> 'org.gradle.SuperType' _ * superDoc.classProperties >> [inheritedPropertyA, inheritedPropertyB, inheritedPropertyC] } def classMetaData(String name = 'org.gradle.Class') { ClassMetaData classMetaData = Mock() _ * classMetaData.className >> name return classMetaData } def classDoc(String name = 'org.gradle.Class') { ClassDoc doc = Mock() _ * doc.name >> name _ * doc.toString() >> "ClassDoc '$name'" return doc } def property(String name, ClassMetaData classMetaData) { return property([:], name, classMetaData) } def property(Map args, String name, ClassMetaData classMetaData) { PropertyMetaData property = Mock() _ * property.name >> name _ * property.ownerClass >> classMetaData def type = args.type instanceof TypeMetaData ? args.type : new TypeMetaData(args.type ?: 'org.gradle.Type') _ * property.type >> type _ * property.signature >> "$name-signature" _ * javadocConverter.parse(property, !null) >> ({[parse("${args.comment ?: 'comment'}")]} as DocComment) return property } def propertyDoc(Map args = [:], String name) { return new PropertyDoc(classMetaData(), property(name, null), [parse("$name comment")], args.additionalValues ?: []) } } gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/dsl/docbook/ClassDocRendererTest.groovy000066400000000000000000000717131210430504300332260ustar00rootroot00000000000000/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook import org.gradle.build.docs.XmlSpecification import org.gradle.build.docs.dsl.source.model.PropertyMetaData import org.gradle.build.docs.dsl.source.model.TypeMetaData import org.gradle.build.docs.dsl.source.model.MethodMetaData import org.gradle.build.docs.dsl.source.model.ParameterMetaData import org.gradle.build.docs.dsl.docbook.model.BlockDoc import org.gradle.build.docs.dsl.docbook.model.ExtraAttributeDoc import org.gradle.build.docs.dsl.docbook.model.MethodDoc import org.gradle.build.docs.dsl.docbook.model.PropertyDoc import org.gradle.build.docs.dsl.docbook.model.ClassDoc import org.gradle.build.docs.dsl.docbook.model.ClassExtensionDoc class ClassDocRendererTest extends XmlSpecification { final LinkRenderer linkRenderer = linkRenderer() final ClassDocRenderer renderer = new ClassDocRenderer(linkRenderer) def rendersContentForEmptyClass() { def sourceContent = parse('''
Properties
''') ClassDoc classDoc = classDoc('org.gradle.Class', id: 'classId', content: sourceContent, comment: 'class comment') _ * classDoc.classProperties >> [] _ * classDoc.classMethods >> [] _ * classDoc.classBlocks >> [] _ * classDoc.classExtensions >> [] when: def result = parse('') withCategories { renderer.mergeContent(classDoc, result) } then: formatTree(result) == ''' Class API Documentation class comment
Properties No properties
Script blocks No script blocks
Methods No methods
''' } def mergesClassMetaDataIntoMainSection() { def sourceContent = parse(''' Some custom content ''') ClassDoc classDoc = classDoc('org.gradle.Class', id: 'classId', content: sourceContent, comment: 'class comment') _ * classDoc.classProperties >> [] _ * classDoc.classMethods >> [] _ * classDoc.classBlocks >> [] _ * classDoc.classExtensions >> [] when: def result = parse('') withCategories { renderer.mergeContent(classDoc, result) } then: formatTree(result) == ''' Class API Documentation class comment Some custom content
Properties No properties
Script blocks No script blocks
Methods No methods
''' } def mergesPropertyMetaDataIntoPropertiesSection() { def content = parse('''
Properties
NameExtra column
propNamesome value
''') def extraAttribute = new ExtraAttributeDoc(parse('Extra column'), parse('some value')) ClassDoc classDoc = classDoc('Class', content: content) PropertyDoc propDoc = propertyDoc('propName', id: 'propId', description: 'prop description', comment: 'prop comment', type: 'org.gradle.Type', attributes: [extraAttribute]) _ * classDoc.classProperties >> [propDoc] _ * classDoc.classExtensions >> [] when: def result = parse('', document) withCategories { renderer.mergeProperties(classDoc, result) } then: formatTree(result) == '''
Properties Properties - Class
Property Description
propName prop description
Property details
<classname>org.gradle.Type</classname> <literal>propName</literal> (read-only) prop comment Extra column some value
''' } def rendersDeprecatedAndIncubatingProperties() { def content = parse('''
Properties
Name
deprecatedProperty
incubatingProperty
''') ClassDoc classDoc = classDoc('Class', content: content) PropertyDoc deprecatedProp = propertyDoc('deprecatedProperty', id: 'prop1', description: 'prop1 description', comment: 'prop1 comment', type: 'org.gradle.Type', deprecated: true) PropertyDoc incubatingProp = propertyDoc('incubatingProperty', id: 'prop2', description: 'prop2 description', comment: 'prop2 comment', type: 'org.gradle.Type', incubating: true) _ * classDoc.classProperties >> [deprecatedProp, incubatingProp] _ * classDoc.classExtensions >> [] when: def result = parse('', document) withCategories { renderer.mergeProperties(classDoc, result) } then: formatTree(result) == '''
Properties Properties - Class
Property Description
deprecatedProperty Deprecated prop1 description
incubatingProperty Incubating prop2 description
Property details
<classname>org.gradle.Type</classname> <literal>deprecatedProperty</literal> (read-only) Note: This property is deprecated and will be removed in the next major version of Gradle. prop1 comment
<classname>org.gradle.Type</classname> <literal>incubatingProperty</literal> (read-only) Note: This property is incubating and may change in a future version of Gradle. prop2 comment
''' } def mergesExtensionPropertyMetaDataIntoPropertiesSection() { def content = parse('''
Properties
Name
Property details
''') ClassDoc targetClassDoc = classDoc('Class', content: content) ClassExtensionDoc extensionDoc = extensionDoc('thingo') PropertyDoc propertyDoc = propertyDoc('propName', id: 'propId') _ * targetClassDoc.classProperties >> [] _ * targetClassDoc.classExtensions >> [extensionDoc] _ * extensionDoc.extensionProperties >> [propertyDoc] when: def result = parse('', document) withCategories { renderer.mergeProperties(targetClassDoc, result) } then: formatTree(result) == '''
Properties
Properties added by the <literal>thingo</literal> plugin thingo plugin Properties - <literal>thingo</literal> plugin
Property Description
propName description
Property details
<classname>SomeType</classname> <literal>propName</literal> (read-only) comment
''' } def mergesMethodMetaDataIntoMethodsSection() { def content = parse('''
Methods
Name
methodName
''') ClassDoc classDoc = classDoc('Class', content: content) MethodDoc method1 = methodDoc('methodName', id: 'method1Id', returnType: 'ReturnType1', description: 'method description', comment: 'method comment') MethodDoc method2 = methodDoc('methodName', id: 'method2Id', returnType: 'ReturnType2', description: 'overloaded description', comment: 'overloaded comment', paramTypes: ['ParamType']) _ * classDoc.classMethods >> [method1, method2] _ * classDoc.classExtensions >> [] when: def result = parse('', document) withCategories { renderer.mergeMethods(classDoc, result) } then: formatTree(result) == '''
Methods Methods - Class
Method Description
methodName() method description
methodName(p) overloaded description
Method details
<classname>ReturnType1</classname> <literal>methodName</literal>() method comment
<classname>ReturnType2</classname> <literal>methodName</literal>(<classname>ParamType</classname> p) overloaded comment
''' } def rendersDeprecatedAndIncubatingMethods() { def content = parse('''
Methods
Name
deprecated
incubating
''') ClassDoc classDoc = classDoc('Class', content: content) MethodDoc method1 = methodDoc('deprecated', id: 'method1Id', returnType: 'ReturnType1', description: 'method description', comment: 'method comment', deprecated: true) MethodDoc method2 = methodDoc('incubating', id: 'method2Id', returnType: 'ReturnType2', description: 'overloaded description', comment: 'overloaded comment', paramTypes: ['ParamType'], incubating: true) _ * classDoc.classMethods >> [method1, method2] _ * classDoc.classExtensions >> [] when: def result = parse('', document) withCategories { renderer.mergeMethods(classDoc, result) } then: formatTree(result) == '''
Methods Methods - Class
Method Description
deprecated() Deprecated method description
incubating(p) Incubating overloaded description
Method details
<classname>ReturnType1</classname> <literal>deprecated</literal>() Note: This method is deprecated and will be removed in the next major version of Gradle. method comment
<classname>ReturnType2</classname> <literal>incubating</literal>(<classname>ParamType</classname> p) Note: This method is incubating and may change in a future version of Gradle. overloaded comment
''' } def mergesExtensionMethodMetaDataIntoMethodsSection() { def content = parse('''
Methods
Name
Method details
''') ClassDoc targetClassDoc = classDoc('Class', content: content) ClassExtensionDoc extensionDoc = extensionDoc('thingo') MethodDoc methodDoc = methodDoc('methodName', id: 'methodId') _ * targetClassDoc.classMethods >> [] _ * targetClassDoc.classExtensions >> [extensionDoc] _ * extensionDoc.extensionMethods >> [methodDoc] when: def result = parse('', document) withCategories { renderer.mergeMethods(targetClassDoc, result) } then: formatTree(result) == '''
Methods
Methods added by the <literal>thingo</literal> plugin thingo plugin Methods - <literal>thingo</literal> plugin
Method Description
methodName() description
Method details
<classname>ReturnType</classname> <literal>methodName</literal>() comment
''' } def mergesBlockMetaDataIntoBlocksSection() { def content = parse('''
Methods
''') ClassDoc classDoc = classDoc('Class', content: content) BlockDoc block1 = blockDoc('block1', id: 'block1', description: 'block1 description', comment: 'block1 comment', type: 'org.gradle.Type') BlockDoc block2 = blockDoc('block2', id: 'block2', description: 'block2 description', comment: 'block2 comment', type: 'org.gradle.Type', multivalued: true) _ * classDoc.classBlocks >> [block1, block2] _ * classDoc.classExtensions >> [] when: def result = parse('', document) withCategories { renderer.mergeBlocks(classDoc, result) } then: formatTree(result) == '''
Script blocks Script blocks - Class
Block Description
block1 block1 description
block2 block2 description
Script block details
<literal>block1</literal> { } block1 comment Delegates to org.gradle.Type from block1
<literal>block2</literal> { } block2 comment Delegates to Each org.gradle.Type in block2
''' } def mergesExtensionBlockMetaDataIntoBlocksSection() { def content = parse('''
Script blocks
Script block details
''') ClassDoc targetClassDoc = classDoc('Class', content: content) ClassExtensionDoc extensionDoc = extensionDoc('thingo') BlockDoc blockDoc = blockDoc('blockName', id: 'blockId') _ * targetClassDoc.classBlocks >> [] _ * targetClassDoc.classExtensions >> [extensionDoc] _ * extensionDoc.extensionBlocks >> [blockDoc] when: def result = parse('', document) withCategories { renderer.mergeBlocks(targetClassDoc, result) } then: formatTree(result) == '''
Script blocks
Script blocks added by the <literal>thingo</literal> plugin thingo plugin Script blocks - <literal>thingo</literal> plugin
Block Description
blockName description
Script block details
<literal>blockName</literal> { } comment Delegates to BlockType from blockName
''' } def linkRenderer() { LinkRenderer renderer = Mock() _ * renderer.link(!null, !null) >> { args -> parse("${args[0].signature}", document) } return renderer } def classDoc(Map args = [:], String name) { ClassDoc classDoc = Mock() def content = args.content ?: parse('
') def propertiesSection = withCategories { content.section.find { it.title[0].text().trim() == 'Properties' } } def propertyDetailsSection = withCategories { content.section.find { it.title[0].text().trim() == 'Property details' } } def propertiesTable = withCategories { propertiesSection ? propertiesSection.table[0] : parse('')} def methodsSection = withCategories { content.section.find { it.title[0].text().trim() == 'Methods' } } def methodDetailsSection = withCategories { content.section.find { it.title[0].text().trim() == 'Method details' } } def methodsTable = withCategories { methodsSection ? methodsSection.table[0] : parse('
') } def blocksSection = withCategories { content.section.find { it.title[0].text().trim() == 'Script blocks' } } def blockDetailsSection = withCategories { content.section.find { it.title[0].text().trim() == 'Script block details' } } def blocksTable = withCategories { blocksSection ? blocksSection.table[0] : parse('
') } _ * classDoc.simpleName >> name.split('\\.').last() _ * classDoc.name >> name _ * classDoc.id >> (args.id ?: name) _ * classDoc.classSection >> content _ * classDoc.propertiesSection >> propertiesSection _ * classDoc.propertiesTable >> propertiesTable _ * classDoc.propertyDetailsSection >> propertyDetailsSection _ * classDoc.methodsSection >> methodsSection _ * classDoc.methodsTable >> methodsTable _ * classDoc.methodDetailsSection >> methodDetailsSection _ * classDoc.blocksTable >> blocksTable _ * classDoc.blockDetailsSection >> blockDetailsSection _ * classDoc.description >> parse("${args.description ?: 'description'}") _ * classDoc.comment >> [parse("${args.comment ?: 'comment'}")] _ * classDoc.style >> 'java' return classDoc } def propertyDoc(Map args = [:], String name) { PropertyDoc propDoc = Mock() PropertyMetaData propMetaData = Mock() _ * propDoc.name >> name _ * propDoc.id >> (args.id ?: name) _ * propDoc.description >> parse("${args.description ?: 'description'}") _ * propDoc.comment >> [parse("${args.comment ?: 'comment'}")] _ * propDoc.metaData >> propMetaData _ * propDoc.deprecated >> (args.deprecated ?: false) _ * propDoc.incubating >> (args.incubating ?: false) _ * propDoc.additionalValues >> (args.attributes ?: []) _ * propMetaData.type >> new TypeMetaData(args.type ?: 'SomeType') return propDoc } def methodDoc(Map args = [:], String name) { MethodDoc methodDoc = Mock() MethodMetaData metaData = Mock() _ * methodDoc.name >> name _ * methodDoc.id >> args.id _ * methodDoc.description >> parse("${args.description ?: 'description'}") _ * methodDoc.comment >> [parse("${args.comment ?: 'comment'}")] _ * methodDoc.metaData >> metaData _ * methodDoc.deprecated >> (args.deprecated ?: false) _ * methodDoc.incubating >> (args.incubating ?: false) _ * metaData.returnType >> new TypeMetaData(args.returnType ?: 'ReturnType') def paramTypes = args.paramTypes ?: [] _ * metaData.parameters >> paramTypes.collect { def param = new ParameterMetaData("p"); param.type = new TypeMetaData(it) return param } return methodDoc } def blockDoc(Map args = [:], String name) { BlockDoc blockDoc = Mock() PropertyDoc blockPropDoc = propertyDoc(name) _ * blockDoc.name >> name _ * blockDoc.id >> (args.id ?: name) _ * blockDoc.description >> parse("${args.description ?: 'description'}") _ * blockDoc.comment >> [parse("${args.comment ?: 'comment'}")] _ * blockDoc.type >> new TypeMetaData(args.type ?: 'BlockType') _ * blockDoc.blockProperty >> blockPropDoc _ * blockDoc.multiValued >> (args.multivalued ?: false) blockDoc } def extensionDoc(Map args = [:], String name) { ClassExtensionDoc doc = Mock() doc.pluginId >> name doc } } HtmlToXmlJavadocLexerTest.groovy000066400000000000000000000147431210430504300341450ustar00rootroot00000000000000gradle-1.4/buildSrc/src/test/groovy/org/gradle/build/docs/dsl/docbook/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.build.docs.dsl.docbook import spock.lang.Specification class HtmlToXmlJavadocLexerTest extends Specification { def "discards whitespace around block elements"() { expect: parse(source) == transformed where: source | transformed "

text

" | "

text

" "

text

text

" | "

text

text

" "

text

text

" | "

text

text

" " \r\n
text
" | "
text
" } def "does not discard whitespace around inline elements"() { expect: parse(source) == transformed where: source | transformed " code " | "

code

" "

code \ttext\t\tem

" | "

code \ttext\t\tem

" "

text

text \t" | "

text

text

" "