@@ -56,18 +56,33 @@ package org.apache.tools.ant.taskdefs;
import org.apache.tools.ant.*;
import org.apache.tools.ant.*;
import java.io.*;
import java.io.*;
import java.util.StringTokenizer;
/**
/**
*
* Task to compile RMI stubs and skeletons. This task can take the following
* arguments:
* <ul>
* <li>base: The base directory for the compiled stubs and skeletons
* <li>class: The name of the class to generate the stubs from
* <li>stubVersion: The version of the stub prototol to use (1.1, 1.2, compat)
* <li>sourceBase: The base directory for the generated stubs and skeletons
* <li>classpath: Additional classpath, appended before the system classpath
* </ul>
* Of these arguments, the <b>base</b> and <b>class</b> are required.
* <p>
*
*
* @author duncan@x180.com
* @author duncan@x180.com
* @author ludovic.claude@websitewatchers.co.uk
*/
*/
public class Rmic extends Task {
public class Rmic extends Task {
private String base;
private String base;
private String classname;
private String classname;
private String sourceBase;
private String stubVersion;
private String compileClasspath;
public void setBase(String base) {
public void setBase(String base) {
this.base = base;
this.base = base;
}
}
@@ -76,38 +91,142 @@ public class Rmic extends Task {
this.classname = classname;
this.classname = classname;
}
}
public void setSourceBase(String sourceBase) {
this.sourceBase = sourceBase;
}
public void setStubVersion(String stubVersion) {
this.stubVersion = stubVersion;
}
/**
* Set the classpath to be used for this compilation.
*/
public void setClasspath(String classpath) {
compileClasspath = Project.translatePath(classpath);
}
public void execute() throws BuildException {
public void execute() throws BuildException {
String pathsep = System.getProperty("path.separator");
StringBuffer classpath = new StringBuffer();
File baseFile = project.resolveFile(base);
File baseFile = project.resolveFile(base);
File sourceBaseFile = null;
if (null != sourceBase)
sourceBaseFile = project.resolveFile(sourceBase);
String classpath = getCompileClasspath(baseFile);
// XXX
// need to provide an input stream that we read in from!
sun.rmi.rmic.Main compiler = new sun.rmi.rmic.Main(System.out, "rmic");
int argCount = 5;
int i = 0;
if (null != stubVersion) argCount++;
if (null != sourceBase) argCount++;
String[] args = new String[argCount];
args[i++] = "-d";
args[i++] = baseFile.getAbsolutePath();
args[i++] = "-classpath";
args[i++] = classpath;
args[i++] = classname;
if (null != stubVersion) {
if ("1.1".equals(stubVersion))
args[i++] = "-v1.1";
else if ("1.2".equals(stubVersion))
args[i++] = "-v1.2";
else
args[i++] = "-vcompat";
}
if (null != sourceBase) args[i++] = "-keepgenerated";
compiler.compile(args);
// Move the generated source file to the base directory
if (null != sourceBase) {
String stubFileName = classname.replace('.', '/') + "_Stub.java";
File oldStubFile = new File(baseFile, stubFileName);
File newStubFile = new File(sourceBaseFile, stubFileName);
try {
copyFile(oldStubFile, newStubFile);
oldStubFile.delete();
} catch (IOException ioe) {
String msg = "Failed to copy " + oldStubFile + " to " +
newStubFile + " due to " + ioe.getMessage();
throw new BuildException(msg);
}
if (!"1.2".equals(stubVersion)) {
String skelFileName = classname.replace('.', '/') + "_Skel.java";
File oldSkelFile = new File(baseFile, skelFileName);
File newSkelFile = new File(sourceBaseFile, skelFileName);
try {
copyFile(oldSkelFile, newSkelFile);
oldSkelFile.delete();
} catch (IOException ioe) {
String msg = "Failed to copy " + oldSkelFile + " to " +
newSkelFile + " due to " + ioe.getMessage();
throw new BuildException(msg);
}
}
}
}
/**
* Builds the compilation classpath.
*/
// XXX
// we need a way to not use the current classpath.
private String getCompileClasspath(File baseFile) {
StringBuffer classpath = new StringBuffer();
// add dest dir to classpath so that previously compiled and
// untouched classes are on classpath
classpath.append(baseFile.getAbsolutePath());
classpath.append(baseFile.getAbsolutePath());
classpath.append(pathsep);
classpath.append(System.getProperty("java.class.path"));
// add our classpath to the mix
if (compileClasspath != null) {
addExistingToClasspath(classpath,compileClasspath);
}
// add the system classpath
addExistingToClasspath(classpath,System.getProperty("java.class.path"));
// in jdk 1.2, the system classes are not on the visible classpath.
// in jdk 1.2, the system classes are not on the visible classpath.
if (Project.getJavaVersion().startsWith("1.2")) {
if (Project.getJavaVersion().startsWith("1.2")) {
String bootcp = System.getProperty("sun.boot.class.path");
String bootcp = System.getProperty("sun.boot.class.path");
if (bootcp != null) {
if (bootcp != null) {
classpath.append(pathsep);
classpath.append(bootcp);
addExistingToClasspath(classpath, bootcp);
}
}
}
}
// XXX
// need to provide an input stream that we read in from!
sun.rmi.rmic.Main compiler = new sun.rmi.rmic.Main(System.out, "rmic");
String[] args = new String[5];
args[0] = "-d";
args[1] = baseFile.getAbsolutePath();
args[2] = "-classpath";
args[3] = classpath.toString();
args[4] = classname;
compiler.compile(args);
return classpath.toString();
}
}
/**
* Takes a classpath-like string, and adds each element of
* this string to a new classpath, if the components exist.
* Components that don't exist, aren't added.
* We do this, because jikes issues warnings for non-existant
* files/dirs in his classpath, and these warnings are pretty
* annoying.
* @param target - target classpath
* @param source - source classpath
* to get file objects.
*/
private void addExistingToClasspath(StringBuffer target,String source) {
StringTokenizer tok = new StringTokenizer(source,
System.getProperty("path.separator"), false);
while (tok.hasMoreTokens()) {
File f = project.resolveFile(tok.nextToken());
if (f.exists()) {
target.append(File.pathSeparator);
target.append(f.getAbsolutePath());
} else {
project.log("Dropping from classpath: "+
f.getAbsolutePath(),project.MSG_VERBOSE);
}
}
}
}
}