package org.codehaus.mojo.gwt.shell; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.maven.plugin.logging.Log; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.cli.CommandLineTimeOutException; import org.codehaus.plexus.util.cli.CommandLineUtils; import org.codehaus.plexus.util.cli.Commandline; import org.codehaus.plexus.util.cli.StreamConsumer; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Properties; /** * @author <a href="mailto:olamy@apache.org">Olivier Lamy</a> * @since 2.1.0-1 */ public class JavaCommand { private String mainClass; private List<File> classpath = new ArrayList<File>(); private List<String> args = new ArrayList<String>(); private Properties systemProperties = new Properties(); private Properties env = new Properties(); private List<String> jvmArgs; private String jvm; private Log log; private int timeOut; private List<ClassPathProcessor> classPathProcessors = new ArrayList<ClassPathProcessor>(); /** * A plexus-util StreamConsumer to redirect messages to plugin log */ private StreamConsumer out = new StreamConsumer() { public void consumeLine( String line ) { log.info( line ); } }; /** * A plexus-util StreamConsumer to redirect errors to plugin log */ private StreamConsumer err = new StreamConsumer() { public void consumeLine( String line ) { log.error( line ); } }; /** * Indicates whether to print the full command (as part of exception message) when encountering error. */ private boolean printCommandOnError = true; public String getMainClass() { return mainClass; } public JavaCommand setMainClass( String mainClass ) { this.mainClass = mainClass; return this; } public List<File> getClasspath() { return classpath; } public JavaCommand setClasspath( List<File> classpath ) { this.classpath = classpath; return this; } public List<String> getArgs() { return args; } public JavaCommand setArgs( List<String> args ) { this.args = args; return this; } public Properties getSystemProperties() { return systemProperties; } public JavaCommand setSystemProperties( Properties systemProperties ) { this.systemProperties = systemProperties; return this; } public Properties getEnv() { return env; } public JavaCommand setEnv( Properties env ) { this.env = env; return this; } public List<String> getJvmArgs() { if (this.jvmArgs == null) { this.jvmArgs = new ArrayList<String>(); } return jvmArgs; } public JavaCommand setJvmArgs( List<String> jvmArgs ) { this.jvmArgs = jvmArgs; return this; } public String getJvm() { return jvm; } public JavaCommand setJvm( String jvm ) { this.jvm = jvm; return this; } public Log getLog() { return log; } public JavaCommand setLog( Log log ) { this.log = log; return this; } public int getTimeOut() { return timeOut; } public JavaCommand setTimeOut( int timeOut ) { this.timeOut = timeOut; return this; } public List<ClassPathProcessor> getClassPathProcessors() { return classPathProcessors; } public JavaCommand addClassPathProcessors( ClassPathProcessor classPathProcessor ) { classPathProcessors.add( classPathProcessor ); return this; } public JavaCommand setClassPathProcessors( List<ClassPathProcessor> classPathProcessors ) { this.classPathProcessors = classPathProcessors; return this; } public JavaCommand setOut( StreamConsumer out ) { this.out = out; return this; } public void setPrintCommandOnError( boolean printCommandOnError ) { this.printCommandOnError = printCommandOnError; } public JavaCommand addToClasspath( File file ) { return addToClasspath( Collections.singleton( file ) ); } public JavaCommand addToClasspath( Collection<File> elements ) { classpath.addAll( elements ); return this; } public JavaCommand prependToClasspath( Collection<File> elements ) { classpath.addAll( 0, elements ); return this; } public JavaCommand arg( String arg ) { args.add( arg ); return this; } public JavaCommand arg( String arg, String value ) { args.add( arg ); args.add( value ); return this; } public JavaCommand arg( boolean condition, String arg ) { if ( condition ) { args.add( arg ); } return this; } public JavaCommand systemProperty( String name, String value ) { systemProperties.setProperty( name, value ); return this; } public JavaCommand environment( String name, String value ) { env.setProperty( name, value ); return this; } public void execute() throws JavaCommandException { for (ClassPathProcessor classPathProcessor : classPathProcessors ) { classPathProcessor.postProcessClassPath( classpath ); } List<String> command = new ArrayList<String>(); if (this.jvmArgs != null) { command.addAll( this.jvmArgs ); } if ( systemProperties != null ) { for ( Map.Entry<?, ?> entry : systemProperties.entrySet() ) { command.add( "-D" + entry.getKey() + "=" + entry.getValue() ); } } command.add( mainClass ); command.addAll( args ); List<String> path = new ArrayList<String>( classpath.size() ); for ( File file : classpath ) path.add( file.getAbsolutePath() ); String classpath = StringUtils.join( path.iterator(), File.pathSeparator ); try { String[] arguments = command.toArray( new String[command.size()] ); Commandline cmd = new Commandline(); cmd.setExecutable( this.getJavaCommand() ); cmd.addEnvironment( "CLASSPATH", classpath ); cmd.addArguments( arguments ); if ( env != null ) { for ( Map.Entry<?, ?> entry : env.entrySet() ) { log.debug( "add env " + (String) entry.getKey() + " with value " + (String) entry.getValue() ); cmd.addEnvironment( (String) entry.getKey(), (String) entry.getValue() ); } } log.debug( "Execute command :\n" + cmd.toString() ); log.debug( "With CLASSPATH :\n" + classpath ); int status = CommandLineUtils.executeCommandLine( cmd, out, err, timeOut ); if ( status != 0 ) { throw new JavaCommandException( "Command failed with status " + status + (printCommandOnError ? ":\n" + cmd : "" ) ); } } catch ( CommandLineTimeOutException e ) { throw new JavaCommandException( "Time-out on command line execution" + (printCommandOnError ? ":\n" + command : ""), e ); } catch ( CommandLineException e ) { throw new JavaCommandException( "Failed to execute command line" + (printCommandOnError ? ":\n" + command : ""), e ); } } private String getJavaCommand() throws JavaCommandException { if ( StringUtils.isEmpty( jvm ) ) { // use the same JVM as the one used to run Maven (the "java.home" one) jvm = System.getProperty( "java.home" ); } // does-it exists ? is-it a directory or a path to a java executable ? File jvmFile = new File( jvm ); if ( !jvmFile.exists() ) { throw new JavaCommandException( "the configured jvm " + jvm + " doesn't exists please check your environment" ); } if ( jvmFile.isDirectory() ) { // it's a directory we construct the path to the java executable return jvmFile.getAbsolutePath() + File.separator + "bin" + File.separator + "java"; } log.debug( "use jvm " + jvm ); return jvm; } }