package net.sourceforge.retroweaver;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import net.sourceforge.retroweaver.translator.NameSpace;
import org.objectweb.asm.commons.EmptyVisitor;
/**
* Applies the RetroWeaver against a set of classes.
*
*/
public class Weaver {
private static final String VERSION;
private static final String BUILD_NUMBER_STRING;
private static final int BUILD_NUMBER;
private static final int UNKNOWN_BUILD_NUMBER = -1;
public static final String getVersion() {
return VERSION + " (build " + BUILD_NUMBER_STRING + ')';
}
public static final int getBuildNumber() {
return BUILD_NUMBER;
}
static {
ResourceBundle bundle = ResourceBundle.getBundle("retroweaver");
VERSION = bundle.getString("retroweaver.version");
BUILD_NUMBER_STRING = bundle.getString("retroweaver.buildNumber");
int n;
try {
n = Integer.parseInt(BUILD_NUMBER_STRING);
} catch (NumberFormatException e) {
n = UNKNOWN_BUILD_NUMBER;
}
BUILD_NUMBER = n;
}
// Read the new class file format spec for how the version is computed.
public static final int VERSION_1_6 = 50;
public static final int VERSION_1_5 = 49;
public static final int VERSION_1_4 = 48;
public static final int VERSION_1_3 = 47;
public static final int VERSION_1_2 = 46;
private static final String nl = System.getProperty("line.separator");
public static void main(String[] args) {
String source = null;
String sourceJar = null;
String destJar = null;
int target = VERSION_1_4;
int currentArg = 0;
boolean lazy = false;
boolean stripSignatures = false;
boolean stripAttributes = false;
boolean verbose = false;
String verifyPath = null;
List<NameSpace> namespaces = new ArrayList<NameSpace>();
while (currentArg < args.length) {
String command = args[currentArg];
++currentArg;
if (command.equals("-source")) {
source = args[currentArg++];
} else if (command.equals("-jar")) {
sourceJar = args[currentArg++];
destJar = args[currentArg++];
if (sourceJar.equals(destJar)) {
System.out.println("source and destination jar files can not be identical"); // NOPMD by xlv
System.out.println(); // NOPMD by xlv
System.exit(1);
}
} else if (command.equals("-namespace")) {
String oldPrefix = args[currentArg++];
String newPrefix = args[currentArg++];
NameSpace n = new NameSpace(oldPrefix, newPrefix);
namespaces.add(n);
} else if (command.equals("-version")) {
System.out.println("Retroweaver version " + getVersion()); // NOPMD by xlv
System.exit(0);
} else if (command.equals("-target")) {
String verStr = args[currentArg++];
if (verStr.equals("1.4")) {
target = VERSION_1_4;
} else if (verStr.equals("1.3")) {
target = VERSION_1_3;
} else if (verStr.equals("1.2")) {
target = VERSION_1_2;
} else {
System.out.println("Invalid target version: " + verStr); // NOPMD by xlv
System.out.println(); // NOPMD by xlv
System.out.println(getUsage()); // NOPMD by xlv
System.exit(1);
}
} else if (command.equals("-lazy")) {
lazy = true;
} else if (command.equals("-stripSignatures")) {
stripSignatures = true;
} else if (command.equals("-stripAttributes")) {
stripAttributes = true;
} else if (command.equals("-verbose")) {
verbose = true;
} else if (command.equals("-verifyrefs")) {
verifyPath = args[currentArg++];
} else {
System.out.println("I don't understand the command: " + command); // NOPMD by xlv
System.out.println(); // NOPMD by xlv
System.out.println(getUsage()); // NOPMD by xlv
System.exit(1);
}
}
if (source == null && sourceJar == null) {
System.out.println("Option \"-source\" or \"-jar\" is required."); // NOPMD by xlv
System.out.println(); // NOPMD by xlv
System.out.println(getUsage()); // NOPMD by xlv
System.exit(1);
}
if (source != null && sourceJar != null) {
System.out.println("Only one of \"-source\" or \"-jar\" can be specified."); // NOPMD by xlv
System.out.println(); // NOPMD by xlv
System.out.println(getUsage()); // NOPMD by xlv
System.exit(1);
}
File sourcePath = null;
RetroWeaver weaver = new RetroWeaver(target);
weaver.setListener(new DefaultWeaveListener(verbose));
weaver.setLazy(lazy);
weaver.setStripSignatures(stripSignatures);
weaver.setStripAttributes(stripAttributes);
weaver.addNameSpaces(namespaces);
if (verifyPath != null) {
List<String> paths = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(verifyPath,
File.pathSeparator);
while (st.hasMoreTokens()) {
paths.add(st.nextToken());
}
RefVerifier rv = new RefVerifier(target, new EmptyVisitor(), paths,
new RefVerifier.DefaultListener(verbose));
weaver.setVerifier(rv);
}
try {
if (source != null) {
sourcePath = new File(source);
weaver.weave(sourcePath);
} else {
weaver.weaveJarFile(sourceJar, destJar);
}
} catch (Exception e) {
throw new RetroWeaverException("Weaving failed", e);
}
}
private static String getUsage() {
return "Usage: Weaver <options>"
+ nl
+ " Options: "
+ nl
+ " -source <source dir>"
+ nl
+ " -jar <source jar> <target jar>"
+ nl
+ " -target <target VM version> (one of {1.4, 1.3, 1.2}, default is 1.4)"
+ nl + " -verifyrefs <classpath>" + nl
+ " -stripSignatures (strip generic signatures, off by default)" + nl
+ " -stripAttributes (strip custom attributes, off by default)" + nl
+ " -verbose (message for each processed class)" + nl
+ " -version (display version number and exit)" + nl + nl
+ "One of \"-source\" or \"-jar\" is required.";
}
}