package org.codehaus.mojo.runtime.execute; /* * Copyright (c) 2004, Codehaus.org * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Method; import java.util.Iterator; import java.util.List; import java.util.Map; import org.codehaus.mojo.runtime.model.Executable; import org.codehaus.mojo.runtime.model.Runtime; import org.codehaus.mojo.runtime.model.io.xpp3.RuntimeXpp3Reader; /** * The default implementation of an executor for the runtime plugin jar implementation. * <p/> * The executor acts as a conduit to main methods that are keyed in the runtime descriptor. * <p/> * Everything is wrapped up in their own jars with the Executor and the RuntimeClassLoader as * the only classes in the jar. This allows the runtime classloader to load up all of the * underlying dependencies main methods referred to in the runtime descriptor * * @author jesse * @version $Id$ */ public class RuntimeExecutor { private Runtime runtime = null; private Map executables = null; /** * harvest the jar.runtime descriptor from the jar and pull out executables map */ public void init() { try { RuntimeXpp3Reader modelReader = new RuntimeXpp3Reader(); InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( "META-INF/runtimes/jar.runtime" ); if ( is != null ) { runtime = modelReader.read( new InputStreamReader( is ) ); executables = runtime.getJar().getExecutableMap(); List dependencies = runtime.getJar().getDependencies(); for ( Iterator i = dependencies.iterator(); i.hasNext(); ) { System.out.println( "dependency: " + i.next() ); } } else { System.err.println( "unable to retrieve jar.runtime" ); } } catch ( Exception e ) { e.printStackTrace(); } } public void processRequest( String[] args ) { String executableId = args[0]; if ( "list".equalsIgnoreCase( executableId ) ) { System.out.println( "available execution ids:" ); for ( Iterator i = executables.keySet().iterator(); i.hasNext(); ) { System.out.println( "\t" + (String) i.next() ); } } else if ( "help".equalsIgnoreCase( executableId ) ) { printOptions(); } else if ( executables != null && executables.containsKey( executableId ) ) { try { ClassLoader loader = new RuntimeClassLoader( runtime, getClass().getClassLoader() ); Thread.currentThread().setContextClassLoader( loader ); Class c = loader.loadClass( ( (Executable) executables.get( executableId ) ).getImplementation() ); Class types[] = {String[].class}; Method m = c.getMethod( "main", types ); // prune the id off of the args list String[] truncatedArgs = new String[args.length - 1]; System.arraycopy( args, 1, truncatedArgs, 0, args.length - 1 ); m.invoke( m, new Object[]{truncatedArgs} ); } catch ( Exception e ) { e.printStackTrace(); } } else { System.err.println( "unavailable or unknown executable id: " + executableId ); } } private static void printOptions() { System.err.println( "java -jar <jar> [id|help|list] arg1 arg2 ..." ); } public static void main( String[] args ) { if ( args.length < 1 ) { printOptions(); System.exit( -1 ); } RuntimeExecutor executor = new RuntimeExecutor(); executor.init(); executor.processRequest( args ); } }