package com.rc.retroweaver; import java.io.*; import java.util.*; /** * Applies the RetroWeaver against a set of classes. * * @author Toby Reyelts * */ public class Weaver { // Read the new class file format spec for how the version is computed. 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; int version = VERSION_1_4; int currentArg = 0; boolean lazy = false; String verifyPath = null; while ( currentArg < args.length ) { String command = args[ currentArg ]; ++currentArg; if ( command.equals( "-source" ) ) { source = args[ currentArg++ ]; } else if ( command.equals( "-version" ) ) { String verStr = args[ currentArg++ ]; if ( verStr.equals( "1.4" ) ) { version = VERSION_1_4; } else if ( verStr.equals( "1.3" ) ) { version = VERSION_1_3; } else if ( verStr.equals( "1.2" ) ) { version = VERSION_1_2; } else { System.out.println( "Invalid target version: " + verStr ); System.out.println(); System.out.println( getUsage() ); return; } } else if ( command.equals( "-lazy" ) ) { lazy = true; } else if ( command.equals( "-verifyrefs" ) ) { verifyPath = args[ currentArg++ ]; } else { System.out.println( "I don't understand the command: " + command ); System.out.println(); System.out.println( getUsage() ); return; } } if ( source == null ) { System.out.println( "Option \"-source\" is required." ); System.out.println(); System.out.println( getUsage() ); return; } File sourcePath = new File( source ); RetroWeaver weaver = new RetroWeaver( version ); weaver.setLazy( lazy ); try { invokeWeaver( weaver, sourcePath ); } catch ( Exception e ) { throw new RuntimeException( "Weaving failed", e ); } 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( paths, new RefVerifier.Listener() { public void verifyStarted( String msg ) { System.out.println( "[RefVerifier] " + msg ); } public void acceptWarning( String msg ) { System.out.println( "[RefVerifier] " + msg ); } } ); try { invokeVerifier( rv, sourcePath ); } catch ( IOException e ) { throw new RuntimeException( "Verification failed", e ); } } } private static String getUsage() { return "Usage: Weaver <options>" + nl + " Options: " + nl + " -source <source dir> (required)" + nl + " -version <target VM version> (one of {1.4, 1.3, 1.2}, default is 1.4)" + nl + " -verifyrefs <classpath>"; } public static void invokeWeaver( RetroWeaver w, File path ) throws Exception { FileFilter filter = new FileFilter() { public boolean accept( File f ) { return f.isDirectory() || f.getName().endsWith( ".class" ); } }; File[] files = path.listFiles( filter ); if ( files == null ) { files = new File[] {}; } for ( int i = 0; i < files.length; ++i ) { File f = files[ i ]; if ( f.isDirectory() ) { invokeWeaver( w, f ); continue; } String pathStr = f.getCanonicalPath(); w.weave( pathStr, null ); } } public static void invokeVerifier( RefVerifier rv, File path ) throws IOException { FileFilter filter = new FileFilter() { public boolean accept( File f ) { return f.isDirectory() || f.getName().endsWith( ".class" ); } }; File[] files = path.listFiles( filter ); if ( files == null ) { files = new File[] {}; } for ( int i = 0; i < files.length; ++i ) { File f = files[ i ]; if ( f.isDirectory() ) { invokeVerifier( rv, f ); continue; } String pathStr = f.getCanonicalPath(); rv.verify( pathStr ); } } }