org.gradle.api.tasks.javadoc.Groovydoc Maven / Gradle / Ivy
/*
* Copyright 2009 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.api.tasks.javadoc;
import org.gradle.api.InvalidUserDataException;
import org.gradle.api.Nullable;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.FileTree;
import org.gradle.api.internal.ClassPathRegistry;
import org.gradle.api.internal.project.IsolatedAntBuilder;
import org.gradle.api.internal.tasks.AntGroovydoc;
import org.gradle.api.logging.LogLevel;
import org.gradle.api.resources.TextResource;
import org.gradle.api.tasks.CacheableTask;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.PathSensitive;
import org.gradle.api.tasks.PathSensitivity;
import org.gradle.api.tasks.SourceTask;
import org.gradle.api.tasks.TaskAction;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
// This import must be here due to a clash in Java 8 between this and java.util.Optional.
// Be careful running “Optimize Imports” as it will wipe this out.
// If there's no import below this comment, this has happened.
/**
* Generates HTML API documentation for Groovy source, and optionally, Java source.
*
*
This task uses Groovy's Groovydoc tool to generate the API documentation. Please note
* that the Groovydoc tool has some limitations at the moment. The version of the Groovydoc
* that is used, is the one from the Groovy dependency defined in the build script.
*/
@CacheableTask
public class Groovydoc extends SourceTask {
private FileCollection groovyClasspath;
private FileCollection classpath;
private File destinationDir;
private AntGroovydoc antGroovydoc;
private boolean use;
private boolean noTimestamp;
private boolean noVersionStamp;
private String windowTitle;
private String docTitle;
private String header;
private String footer;
private TextResource overview;
private Set links = new LinkedHashSet();
boolean includePrivate;
public Groovydoc() {
getLogging().captureStandardOutput(LogLevel.INFO);
}
@TaskAction
protected void generate() {
checkGroovyClasspathNonEmpty(getGroovyClasspath().getFiles());
getAntGroovydoc().execute(getSource(), getDestinationDir(), isUse(), isNoTimestamp(), isNoVersionStamp(), getWindowTitle(),
getDocTitle(), getHeader(), getFooter(), getPathToOverview(), isIncludePrivate(), getLinks(), getGroovyClasspath(),
getClasspath(), getProject());
}
@Nullable @Internal
private String getPathToOverview() {
TextResource overview = getOverviewText();
if (overview!=null) {
return overview.asFile().getAbsolutePath();
}
return null;
}
private void checkGroovyClasspathNonEmpty(Collection classpath) {
if (classpath.isEmpty()) {
throw new InvalidUserDataException("You must assign a Groovy library to the groovy configuration!");
}
}
/**
* {@inheritDoc}
*/
@PathSensitive(PathSensitivity.RELATIVE)
@Override
public FileTree getSource() {
return super.getSource();
}
/**
* Returns the directory to generate the documentation into.
*
* @return The directory to generate the documentation into
*/
@OutputDirectory
public File getDestinationDir() {
return destinationDir;
}
/**
* Sets the directory to generate the documentation into.
*/
public void setDestinationDir(File destinationDir) {
this.destinationDir = destinationDir;
}
/**
* Returns the classpath containing the Groovy library to be used.
*
* @return The classpath containing the Groovy library to be used
*/
@Classpath
public FileCollection getGroovyClasspath() {
return groovyClasspath;
}
/**
* Sets the classpath containing the Groovy library to be used.
*/
public void setGroovyClasspath(FileCollection groovyClasspath) {
this.groovyClasspath = groovyClasspath;
}
/**
* Returns the classpath used to locate classes referenced by the documented sources.
*
* @return The classpath used to locate classes referenced by the documented sources
*/
@Classpath
public FileCollection getClasspath() {
return classpath;
}
/**
* Sets the classpath used to locate classes referenced by the documented sources.
*/
public void setClasspath(FileCollection classpath) {
this.classpath = classpath;
}
@Internal
public AntGroovydoc getAntGroovydoc() {
if (antGroovydoc == null) {
IsolatedAntBuilder antBuilder = getServices().get(IsolatedAntBuilder.class);
ClassPathRegistry classPathRegistry = getServices().get(ClassPathRegistry.class);
antGroovydoc = new AntGroovydoc(antBuilder, classPathRegistry);
}
return antGroovydoc;
}
public void setAntGroovydoc(AntGroovydoc antGroovydoc) {
this.antGroovydoc = antGroovydoc;
}
/**
* Returns whether to create class and package usage pages.
*/
@Input
public boolean isUse() {
return use;
}
/**
* Sets whether to create class and package usage pages.
*/
public void setUse(boolean use) {
this.use = use;
}
/**
* Returns whether to include timestamp within hidden comment in generated HTML (Groovy >= 2.4.6).
*/
@Input
public boolean isNoTimestamp() {
return noTimestamp;
}
/**
* Sets whether to include timestamp within hidden comment in generated HTML (Groovy >= 2.4.6).
*/
public void setNoTimestamp(boolean noTimestamp) {
this.noTimestamp = noTimestamp;
}
/**
* Returns whether to include version stamp within hidden comment in generated HTML (Groovy >= 2.4.6).
*/
@Input
public boolean isNoVersionStamp() {
return noVersionStamp;
}
/**
* Sets whether to include version stamp within hidden comment in generated HTML (Groovy >= 2.4.6).
*/
public void setNoVersionStamp(boolean noVersionStamp) {
this.noVersionStamp = noVersionStamp;
}
/**
* Returns the browser window title for the documentation. Set to {@code null} when there is no window title.
*/
@Input
@Optional
public String getWindowTitle() {
return windowTitle;
}
/**
* Sets the browser window title for the documentation.
*
* @param windowTitle A text for the windows title
*/
public void setWindowTitle(String windowTitle) {
this.windowTitle = windowTitle;
}
/**
* Returns the title for the package index(first) page. Set to {@code null} when there is no document title.
*/
@Input
@Optional
public String getDocTitle() {
return docTitle;
}
/**
* Sets title for the package index(first) page (optional).
*
* @param docTitle the docTitle as HTML
*/
public void setDocTitle(String docTitle) {
this.docTitle = docTitle;
}
/**
* Returns the HTML header for each page. Set to {@code null} when there is no header.
*/
@Input
@Optional
public String getHeader() {
return header;
}
/**
* Sets header text for each page (optional).
*
* @param header the header as HTML
*/
public void setHeader(String header) {
this.header = header;
}
/**
* Returns the HTML footer for each page. Set to {@code null} when there is no footer.
*/
@Input
@Optional
public String getFooter() {
return footer;
}
/**
* Sets footer text for each page (optional).
*
* @param footer the footer as HTML
*/
public void setFooter(String footer) {
this.footer = footer;
}
/**
* Returns a HTML text to be used for overview documentation. Set to {@code null} when there is no overview text.
*/
@Nested
@Optional
public TextResource getOverviewText() {
return overview;
}
/**
* Sets a HTML text to be used for overview documentation (optional).
*
* Example: {@code overviewText = resources.text.fromFile("/overview.html")}
*/
public void setOverviewText(TextResource overviewText) {
this.overview = overviewText;
}
/**
* Returns whether to include all classes and members (i.e. including private ones).
*/
@Input
public boolean isIncludePrivate() {
return includePrivate;
}
/**
* Sets whether to include all classes and members (i.e. including private ones) if set to true.
*/
public void setIncludePrivate(boolean includePrivate) {
this.includePrivate = includePrivate;
}
/**
* Returns the links to groovydoc/javadoc output at the given URL.
*/
@Input
public Set getLinks() {
return Collections.unmodifiableSet(links);
}
/**
* Sets links to groovydoc/javadoc output at the given URL.
*
* @param links The links to set
* @see #link(String, String...)
*/
public void setLinks(Set links) {
this.links = links;
}
/**
* Add links to groovydoc/javadoc output at the given URL.
*
* @param url Base URL of external site
* @param packages list of package prefixes
*/
public void link(String url, String... packages) {
links.add(new Link(url, packages));
}
/**
* A Link class represent a link between groovydoc/javadoc output and url.
*/
public static class Link implements Serializable {
private List packages = new ArrayList();
private String url;
/**
* Constructs a {@code Link}.
*
* @param url Base URL of external site
* @param packages list of package prefixes
*/
public Link(String url, String... packages) {
throwExceptionIfNull(url, "Url must not be null");
if (packages.length == 0) {
throw new InvalidUserDataException("You must specify at least one package!");
}
for (String aPackage : packages) {
throwExceptionIfNull(aPackage, "A package must not be null");
}
this.packages = Arrays.asList(packages);
this.url = url;
}
private void throwExceptionIfNull(String value, String message) {
if (value == null) {
throw new InvalidUserDataException(message);
}
}
/**
* Returns a list of package prefixes to be linked with an external site.
*/
public List getPackages() {
return Collections.unmodifiableList(packages);
}
/**
* Returns the base url for the external site.
*/
public String getUrl() {
return url;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Link link = (Link) o;
if (packages != null ? !packages.equals(link.packages) : link.packages != null) {
return false;
}
if (url != null ? !url.equals(link.url) : link.url != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = packages != null ? packages.hashCode() : 0;
result = 31 * result + (url != null ? url.hashCode() : 0);
return result;
}
}
}