// Copyright (c) 2004 Dustin Sallings <dustin@spy.net>
package net.spy.ant;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;
import net.spy.util.CloseUtil;
import net.spy.util.SpyToker;
import net.spy.util.SpyUtil;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
/**
* Task to build a build info class for a package.
*
* An example ant recipe for building a build info class is as follows:
* <pre>
* <propertyfile file="${BUILDDIR}/com/me/build.properties">
* <entry key="java.vendor" value="${java.vendor}"/>
* <entry key="java.version" value="${java.version}"/>
* <entry key="os.name" value="${os.name}"/>
* <entry key="os.version" value="${os.version}"/>
* <entry key="build.date" type="date" value="now"/>
* <entry key="tree.version" value="${tree.version}"/>
* </propertyfile>
* <buildinfo package="com.me" buildprops="com/me/build.properties"
* changelog="com/me/changelog.txt"
* destdir="${GENDIR}"/>
* </pre>
*
* In your jar task, you can now do the following:
*
* <pre>
* <manifest>
* <attribute name="Main-Class" value="com.me.BuildInfo"/>
* </manifest>
* </pre>
*
* The changelog is optional, and may be displayed from the jar main with the
* -c option if it is present.
*/
public class BuildInfoTask extends Task {
private static final String BUILDINFO="net/spy/ant/BuildInfo.txt";
private String pkg=null;
private String buildProps=null;
private String changelog=null;
private String destdir=".";
/**
* Get an instance of BuildInfoTask.
*/
public BuildInfoTask() {
super();
}
/**
* Set the name of the package that will have the buildinfo file.
*/
public void setPackage(String to) {
this.pkg=to;
}
/**
* Set the path to the build properties.
*/
public void setBuildprops(String to) {
this.buildProps=to;
}
/**
* Set the path to the change log.
*/
public void setChangelog(String to) {
this.changelog=to;
}
/**
* Set the destination directory (top level generated code directory).
*/
public void setDestdir(String to) {
this.destdir=to;
}
/**
* Create the BuildInfo class.
*/
@Override
public void execute() throws BuildException {
if(pkg == null) {
throw new BuildException("package name required");
}
if(buildProps == null) {
throw new BuildException("buildprops required");
}
ClassLoader cl=getClass().getClassLoader();
URL u=cl.getResource(BUILDINFO);
if(u == null) {
throw new BuildException("Can't find " + BUILDINFO);
}
try {
InputStreamReader ir=new InputStreamReader(u.openStream());
String s=null;
try {
s=SpyUtil.getReaderAsString(ir);
} finally {
CloseUtil.close(ir);
}
HashMap<String, String> tokens=new HashMap<String, String>();
tokens.put("PACKAGE", pkg);
tokens.put("CHANGELOG", changelog);
tokens.put("BUILDPROPS", buildProps);
String output=new SpyToker().tokenizeString(s, tokens);
String outFileName=destdir + File.separatorChar
+ pkg.replace('.', File.separatorChar);
// Make sure the directories exist for the package
new File(outFileName).mkdirs();
outFileName += File.separatorChar + "BuildInfo.java";
// Get the output file and write it
File outFile=new File(outFileName);
FileWriter fw=new FileWriter(outFile);
try {
fw.write(output);
} finally {
CloseUtil.close(fw);
}
System.out.println("Wrote " + pkg + ".BuildInfo");
} catch(IOException e) {
e.printStackTrace();
throw new BuildException("Could not process buildinfo", e);
}
}
}