/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
*
Current known limitations are: * *
If no doclet is set, then the version and
* author are by default "yes".
*
*
Note: This task is run on another VM because the Javadoc code calls
* System.exit() which would break Ant functionality.
*
* @author Jon S. Stevens jon@clearink.com
* @author Stefano Mazzocchi stefano@apache.org
* @author Patrick Chanezon chanezon@netscape.com
* @author Ernst de Haan ernst@jollem.com
*/
public class Javadoc extends Exec {
public class DocletParam {
private String name;
private String value;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
public class DocletInfo {
private String name;
private Path path;
private Vector params = new Vector();
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setPath(Path path) {
if (this.path == null) {
this.path = path;
} else {
this.path.append(path);
}
}
public Path getPath() {
return path;
}
public Path createPath() {
if (path == null) {
path = new Path(getProject());
}
return path;
}
public DocletParam createParam() {
DocletParam param = new DocletParam();
params.addElement(param);
return param;
}
public Enumeration getParams() {
return params.elements();
}
}
private String maxmemory = null;
private Path sourcePath = null;
private String additionalParam = null;
private File destDir = null;
private File overviewFile = null;
private String sourceFiles = null;
private String packageNames = null;
private boolean pub = false;
private boolean prot = false;
private boolean pack = false;
private boolean priv = false;
private boolean author = true;
private boolean version = true;
private DocletInfo doclet = null;
private boolean old = false;
private Path classpath = null;
private Path bootclasspath = null;
private String extdirs = null;
private boolean verbose = false;
private String locale = null;
private String encoding = null;
private boolean use = false;
private boolean splitindex = false;
private String windowtitle = null;
private String doctitle = null;
private String header = null;
private String footer = null;
private String bottom = null;
private String linkoffline = null;
private String link = null;
private String group = null;
private boolean nodeprecated = false;
private boolean nodeprecatedlist = false;
private boolean notree = false;
private boolean noindex = false;
private boolean nohelp = false;
private boolean nonavbar = false;
private boolean serialwarn = false;
private File stylesheetfile = null;
private File helpfile = null;
private String docencoding = null;
private Vector compileList = new Vector(10);
private String packageList = null;
private Vector links = new Vector(2);
private Vector groups = new Vector(2);
private String charset = null;
public void setMaxmemory(String src){
maxmemory = src;
}
public void setadditionalParam(String src){
additionalParam = src;
}
public void setSourcepath(Path src) {
if (sourcePath == null) {
sourcePath = src;
} else {
sourcePath.append(src);
}
}
public Path createSourcepath() {
if (sourcePath == null) {
sourcePath = new Path(project);
}
return sourcePath;
}
public void setDestdir(String src) {
destDir = project.resolveFile(src);
}
public void setSourcefiles(String src) {
sourceFiles = src;
}
public void setPackagenames(String src) {
packageNames = src;
}
public void setOverview(String src) {
overviewFile = project.resolveFile(src);
}
public void setPublic(String src) {
pub = Project.toBoolean(src);
}
public void setProtected(String src) {
prot = Project.toBoolean(src);
}
public void setPackage(String src) {
pack = Project.toBoolean(src);
}
public void setPrivate(String src) {
priv = Project.toBoolean(src);
}
public void setDoclet(String src) {
if (doclet == null) {
doclet = new DocletInfo();
}
doclet.setName(src);
}
public void setDocletPath(Path src) {
if (doclet == null) {
doclet = new DocletInfo();
}
doclet.setPath(src);
}
public DocletInfo createDoclet() {
doclet = new DocletInfo();
return doclet;
}
public void setOld(String src) {
old = Project.toBoolean(src);
}
public void setClasspath(Path src) {
if (classpath == null) {
classpath = src;
} else {
classpath.append(src);
}
}
public Path createClasspath() {
if (classpath == null) {
classpath = new Path(project);
}
return classpath;
}
public void setBootclasspath(Path src) {
if (bootclasspath == null) {
bootclasspath = src;
} else {
bootclasspath.append(src);
}
}
public Path createBootclasspath() {
if (bootclasspath == null) {
bootclasspath = new Path(project);
}
return bootclasspath;
}
public void setExtdirs(String src) {
extdirs = src;
}
public void setVerbose(String src) {
verbose = Project.toBoolean(src);
}
public void setLocale(String src) {
locale = src;
}
public void setEncoding(String src) {
encoding = src;
}
public void setVersion(String src) {
version = Project.toBoolean(src);
}
public void setUse(String src) {
use = Project.toBoolean(src);
}
public void setAuthor(String src) {
author = Project.toBoolean(src);
}
public void setSplitindex(String src) {
splitindex = Project.toBoolean(src);
}
public void setWindowtitle(String src) {
windowtitle = src;
}
public void setDoctitle(String src) {
doctitle = src;
}
public void setHeader(String src) {
header = src;
}
public void setFooter(String src) {
footer = src;
}
public void setBottom(String src) {
bottom = src;
}
public void setLinkoffline(String src) {
linkoffline = src;
}
public void setGroup(String src) {
group = src;
}
public void setLink(String src) {
link = src;
}
public void setNodeprecated(String src) {
nodeprecated = Project.toBoolean(src);
}
public void setNodeprecatedlist(String src) {
nodeprecatedlist = Project.toBoolean(src);
}
public void setNotree(String src) {
notree = Project.toBoolean(src);
}
public void setNoindex(String src) {
noindex = Project.toBoolean(src);
}
public void setNohelp(String src) {
nohelp = Project.toBoolean(src);
}
public void setNonavbar(String src) {
nonavbar = Project.toBoolean(src);
}
public void setSerialwarn(String src) {
serialwarn = Project.toBoolean(src);
}
public void setStylesheetfile(String src) {
stylesheetfile = project.resolveFile(src);
}
public void setDocencoding(String src) {
docencoding = src;
}
public void setPackageList(String src) {
packageList = src;
}
public LinkArgument createLink() {
LinkArgument la = new LinkArgument();
links.addElement(la);
return la;
}
public class LinkArgument {
private String href;
private boolean offline = false;
private String packagelistLoc;
public LinkArgument() {
}
public void setHref(String hr) {
href = hr;
}
public String getHref() {
return href;
}
public void setPackagelistLoc(String src) {
packagelistLoc = src;
}
public String getPackagelistLoc() {
return packagelistLoc;
}
public void setOffline(String offline) {
this.offline = Project.toBoolean(offline);
}
public boolean isLinkOffline() {
return offline;
}
}
public GroupArgument createGroup() {
GroupArgument ga = new GroupArgument();
groups.addElement(ga);
return ga;
}
public class GroupArgument {
private String title;
private String packages;
public GroupArgument() {
}
public void setTitle(String src) {
title = src;
}
public String getTitle() {
return title;
}
public void setPackages(String src) {
packages = src;
}
public String getPackages() {
return packages;
}
}
public void setCharset(String src) {
charset = src;
}
public void execute() throws BuildException {
if ("javadoc2".equals(taskType)) {
log("!! javadoc2 is deprecated. Use javadoc instead. !!");
}
if (sourcePath == null || destDir == null ) {
String msg = "sourcePath and destDir attributes must be set!";
throw new BuildException(msg);
}
boolean javadoc1 = (Project.getJavaVersion() == Project.JAVA_1_1);
log("Generating Javadoc", Project.MSG_INFO);
Vector argList = new Vector();
// ------------------------------------------------ general javadoc arguments
if (classpath == null)
classpath = Path.systemClasspath;
if(maxmemory != null){
if(javadoc1){
argList.addElement("-J-mx" + maxmemory);
}
else{
argList.addElement("-J-Xmx" + maxmemory);
}
}
if ( (!javadoc1) || (sourcePath == null) ) {
argList.addElement("-classpath");
argList.addElement(classpath.toString());
if (sourcePath != null) {
argList.addElement("-sourcepath");
argList.addElement(sourcePath.toString());
}
} else {
argList.addElement("-classpath");
argList.addElement(sourcePath.toString() +
System.getProperty("path.separator") + classpath.toString());
}
if (destDir != null) {
argList.addElement("-d");
argList.addElement(destDir.getAbsolutePath());
}
if (version && doclet == null)
argList.addElement ("-version");
if (nodeprecated)
argList.addElement ("-nodeprecated");
if (author && doclet == null)
argList.addElement ("-author");
if (noindex)
argList.addElement ("-noindex");
if (notree)
argList.addElement ("-notree");
if (pub)
argList.addElement ("-public");
if (prot)
argList.addElement ("-protected");
if (pack)
argList.addElement ("-package");
if (priv)
argList.addElement ("-private");
if (encoding != null) {
argList.addElement("-encoding");
argList.addElement(encoding);
}
if (docencoding != null) {
argList.addElement("-docencoding");
argList.addElement(docencoding);
}
// --------------------------------- javadoc2 arguments for default doclet
// XXX: how do we handle a custom doclet?
if (!javadoc1) {
if (overviewFile != null) {
argList.addElement("-overview");
argList.addElement(overviewFile.getAbsolutePath());
}
if (old)
argList.addElement("-1.1");
if (verbose)
argList.addElement("-verbose");
if (use)
argList.addElement("-use");
if (splitindex)
argList.addElement("-splitindex");
if (nodeprecatedlist)
argList.addElement("-nodeprecatedlist");
if (nohelp)
argList.addElement("-nohelp");
if (nonavbar)
argList.addElement("-nonavbar");
if (serialwarn)
argList.addElement("-serialwarn");
if (doclet != null) {
if (doclet.getName() == null) {
throw new BuildException("The doclet name must be specified.");
}
else {
argList.addElement("-doclet");
argList.addElement(doclet.getName());
if (doclet.getPath() != null) {
argList.addElement("-docletpath");
argList.addElement(doclet.getPath().toString());
}
for (Enumeration e = doclet.getParams(); e.hasMoreElements();) {
DocletParam param = (DocletParam)e.nextElement();
if (param.getName() == null) {
throw new BuildException("Doclet parameters must have a name");
}
argList.addElement(param.getName());
if (param.getValue() != null) {
argList.addElement(param.getValue());
}
}
}
}
if (bootclasspath != null) {
argList.addElement("-bootclasspath");
argList.addElement(bootclasspath.toString());
}
if (extdirs != null) {
argList.addElement("-extdirs");
argList.addElement(extdirs);
}
if (locale != null) {
argList.addElement("-locale");
argList.addElement(locale);
}
if (encoding != null) {
argList.addElement("-encoding");
argList.addElement(encoding);
}
if (windowtitle != null) {
argList.addElement("-windowtitle");
argList.addElement(windowtitle);
}
if (doctitle != null) {
argList.addElement("-doctitle");
argList.addElement(doctitle);
}
if (header != null) {
argList.addElement("-header");
argList.addElement(header);
}
if (footer != null) {
argList.addElement("-footer");
argList.addElement(footer);
}
if (bottom != null) {
argList.addElement("-bottom");
argList.addElement(bottom);
}
// add the single link arguments
if (link != null) {
argList.addElement("-link");
argList.addElement(link);
}
// add the links arguments
if (links.size() != 0) {
for (Enumeration e = links.elements(); e.hasMoreElements(); ) {
LinkArgument la = (LinkArgument)e.nextElement();
if (la.getHref() == null) {
throw new BuildException("Links must provide the RUL to the external class documentation.");
}
if (la.isLinkOffline()) {
String packageListLocation = la.getPackagelistLoc();
if (packageListLocation == null) {
throw new BuildException("The package list location for link " + la.getHref() +
" must be provided because the link is offline");
}
argList.addElement("-linkoffline");
argList.addElement(la.getHref());
argList.addElement(packageListLocation);
}
else {
argList.addElement("-link");
argList.addElement(la.getHref());
}
}
}
// add the single linkoffline arguments
if (linkoffline != null) {
argList.addElement("-linkoffline");
argList.addElement(linkoffline);
}
// add the single group arguments
// Javadoc 1.2 rules:
// Multiple -group args allowed.
// Each arg includes 3 strings: -group [name] [packagelist].
// Elements in [packagelist] are colon-delimited.
// An element in [packagelist] may end with the * wildcard.
// Ant javadoc task rules for group attribute:
// Args are comma-delimited.
// Each arg is 2 space-delimited strings.
// E.g., group="XSLT_Packages org.apache.xalan.xslt*,XPath_Packages orgapache.xalan.xpath*"
if (group != null) {
StringTokenizer tok = new StringTokenizer(group, ",", false);
while (tok.hasMoreTokens()) {
String grp = tok.nextToken().trim();
int space = grp.indexOf(" ");
if (space > 0){
String name = grp.substring(0, space);
String pkgList = grp.substring(space + 1);
argList.addElement("-group");
argList.addElement(name);
argList.addElement(pkgList);
}
}
}
// add the group arguments
if (groups.size() != 0) {
for (Enumeration e = groups.elements(); e.hasMoreElements(); ) {
GroupArgument ga = (GroupArgument)e.nextElement();
String title = ga.getTitle();
String packages = ga.getPackages();
if (title == null || packages == null) {
throw new BuildException("The title and packages must be specified for group elements.");
}
argList.addElement("-group");
argList.addElement(title);
argList.addElement(packages);
}
}
if (stylesheetfile != null) {
argList.addElement("-stylesheetfile");
argList.addElement(stylesheetfile.getAbsolutePath());
}
if (helpfile != null) {
argList.addElement("-helpfile");
argList.addElement(helpfile.getAbsolutePath());
}
if (charset != null) {
argList.addElement("-charset");
argList.addElement(charset);
}
if (additionalParam != null) {
argList.addElement(additionalParam);
}
}
if ((packageNames != null) && (packageNames.length() > 0)) {
Vector packages = new Vector();
StringTokenizer tok = new StringTokenizer(packageNames, ",", false);
while (tok.hasMoreTokens()) {
String name = tok.nextToken().trim();
if (name.endsWith(".*")) {
packages.addElement(name);
} else {
argList.addElement(name);
}
}
if (packages.size() > 0) {
evaluatePackages(sourcePath, packages, argList);
}
}
if ((sourceFiles != null) && (sourceFiles.length() > 0)) {
StringTokenizer tok = new StringTokenizer(sourceFiles, ",", false);
while (tok.hasMoreTokens()) {
argList.addElement(tok.nextToken().trim());
}
}
if (packageList != null) {
argList.addElement("@" + packageList);
}
log("Javadoc args: " + argList.toString(), Project.MSG_VERBOSE);
log("Javadoc execution", Project.MSG_INFO);
StringBuffer b = new StringBuffer();
b.append("javadoc ");
Enumeration e = argList.elements();
while (e.hasMoreElements()) {
String arg = (String) e.nextElement();
if (!arg.startsWith("-")) {
b.append("\"");
b.append(arg);
b.append("\"");
} else {
b.append(arg);
}
if (e.hasMoreElements()) b.append(" ");
}
run(b.toString());
}
/**
* Given a source path, a list of package patterns, fill the given list
* with the packages found in that path subdirs matching one of the given
* patterns.
*/
private void evaluatePackages(Path sourcePath, Vector packages, Vector argList) {
log("Parsing source files for packages", Project.MSG_INFO);
log("Source path = " + sourcePath.toString(), Project.MSG_VERBOSE);
log("Packages = " + packages, Project.MSG_VERBOSE);
Vector addedPackages = new Vector();
String[] list = sourcePath.list();
for (int j=0; j