Thanks to Stefan Bodewig and the authors of the Exec task here is a SqlPlus
task. Any improvements would be greatly appreciated.
public class SqlPlus extends Task {
private String user = null;
private String password = null;
private String server = null;
private String file = null;
private String os;
private String out;
private File dir;
private String command = "sqlplus";
protected PrintWriter fos = null;
private boolean failOnError = false;
private static final int BUFFER_SIZE = 512;
public void execute() throws BuildException {
run(command);
}
protected int run(String command) throws BuildException {
int err = -1; // assume the worst
// check to see if user has not been set
if ( user == null )
throw new BuildException( "user attribute was not set."
);
// check to see if password has not been set
if ( password == null )
throw new BuildException( "password attribute was not
set." );
// check to see if server has not been set
if ( server == null )
throw new BuildException( "server attribute was not
set." );
// check to see if sqlFile has not been set
if ( file == null )
throw new BuildException( "sqlfile attribute was not
set." );
// test if os match
String myos = System.getProperty("os.name");
log("Myos = " + myos, Project.MSG_VERBOSE);
if ((os != null) && (os.indexOf(myos) < 0)){
// this command will be executed only on the specified OS
log("Not found in " + os, Project.MSG_VERBOSE);
return 0;
}
// default directory to the project's base directory
if (dir == null) dir = project.getBaseDir();
if (myos.toLowerCase().indexOf("windows") >= 0) {
if (!dir.equals(project.resolveFile("."))) {
if (myos.toLowerCase().indexOf("nt") >= 0) {
command = "cmd /c cd " + dir + " && " + command;
}
else {
String ant = project.getProperty("ant.home");
if (ant == null) {
throw new BuildException("Property 'ant.home' not
found", location);
}
String antRun = project.resolveFile(ant +
"/bin/antRun.bat").toString();
command = antRun + " " + dir + " " + command;
}
}
} else {
String ant = project.getProperty("ant.home");
if (ant == null) throw new BuildException("Property 'ant.home'
not found", location);
String antRun = project.resolveFile(ant +
"/bin/antRun").toString();
command = antRun + " " + dir + " " + command;
}
File sqlFile = new File( dir + File.separator + file );
if ( ! sqlFile.exists() )
{
log( sqlFile.getPath() + " not found." , Project.MSG_VERBOSE);
return 0;
}
else
{
log( sqlFile.getPath() + " found." , Project.MSG_VERBOSE);
}
command += " " + user + "/" + password + "@" + server + " @" +
sqlFile.getName();
try {
// show the command
log(command, Project.MSG_VERBOSE);
// exec command on system runtime
Process proc = Runtime.getRuntime().exec(command);
if( out!=null ) {
fos=new PrintWriter( new FileWriter( out ) );
log("Output redirected to " + out, Project.MSG_VERBOSE);
}
// copy input and error to the output stream
StreamPumper inputPumper =
new StreamPumper(proc.getInputStream(), Project.MSG_INFO,
this);
StreamPumper errorPumper =
new StreamPumper(proc.getErrorStream(), Project.MSG_WARN,
this);
// starts pumping away the generated output/error
inputPumper.start();
errorPumper.start();
// Wait for everything to finish
proc.waitFor();
inputPumper.join();
errorPumper.join();
proc.destroy();
// close the output file if required
logFlush();
// check its exit value
err = proc.exitValue();
if (err != 0) {
if (failOnError) {
throw new BuildException("Exec returned: "+err,
location);
} else {
log("Result: " + err, Project.MSG_ERR);
}
}
} catch (IOException ioe) {
throw new BuildException("Error exec: " + command, ioe,
location);
} catch (InterruptedException ex) {}
return err;
}
public void setDir(String d) {
this.dir = project.resolveFile(d);
}
public void setOs(String os) {
this.os = os;
}
public void setOutput(String out) {
this.out = out;
}
public void setFailonerror(String fail) {
failOnError = Project.toBoolean(fail);
}
public void setServer( String server ) {
this.server = server;
}
public void setSqlFile( String file ) {
this.file = file;
}
public void setUser( String user ) {
this.user = user;
}
public void setPassword( String password ) {
this.password = password;
}
protected void outputLog(String line, int messageLevel) {
if (fos == null) {
log(line, messageLevel);
} else {
fos.println(line);
}
};
protected void logFlush() {
if (fos != null) fos.close();
}
// Inner class for continually pumping the input stream during
// Process's runtime.
class StreamPumper extends Thread {
private BufferedReader din;
private int messageLevel;
private boolean endOfStream = false;
private int SLEEP_TIME = 5;
private SqlPlus parent;
public StreamPumper(InputStream is, int messageLevel, SqlPlus
parent) {
this.din = new BufferedReader(new InputStreamReader(is));
this.messageLevel = messageLevel;
this.parent = parent;
}
public void pumpStream()
throws IOException
{
byte[] buf = new byte[BUFFER_SIZE];
if (!endOfStream) {
String line = din.readLine();
if (line != null) {
outputLog(line, messageLevel);
} else {
endOfStream = true;
}
}
}
public void run() {
try {
try {
while (!endOfStream) {
pumpStream();
sleep(SLEEP_TIME);
}
} catch (InterruptedException ie) {}
din.close();
} catch (IOException ioe) {}
}
}
}