blob: 10d3f8b6f1e87a505359288d4c4872bf69f4a61a [file] [log] [blame]
/**
* 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.
*/
package org.apache.hadoop.gateway.launcher;
import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
class Command {
private static String MAIN_CLASS = "main.class";
private static String MAIN_METHOD = "main.method";
private static String MAIN_ARGS = "main.args";
private static String CLASS_PATH = "class.path";
private static String CLASS_PATH_DELIM = ",;";
private static String FORK = "fork";
private static String REDIRECT = "redirect";
private static String RESTREAM = "restream";
private static String ENV_PREFIX = "env.";
private static int ENV_PREFIX_LENGTH = ENV_PREFIX.length();
File base;
Properties config;
String mainClass;
String mainMethod = "main";
String[] mainArgs;
List<URL> classPath;
Properties props;
Map<String,String> vars;
Boolean fork = Boolean.FALSE;
Boolean redirect = Boolean.FALSE; // Controls redirecting stderr to stdout if forking.
Boolean restream = Boolean.TRUE; // Controls creation of threads to read/write stdin, stdout, stderr of child if forking.
Command( File base, Properties config, String[] args ) throws MalformedURLException {
this.base = base;
this.config = config;
this.mainArgs = args ;
consumeConfig( config );
}
void consumeConfig( Properties config ) throws MalformedURLException {
mainClass = config.getProperty( MAIN_CLASS );
config.remove( MAIN_CLASS );
mainMethod = config.getProperty( MAIN_METHOD, mainMethod );
config.remove( MAIN_METHOD );
mainArgs = loadMainArgs( mainArgs, config.getProperty( MAIN_ARGS ) );
config.remove( MAIN_ARGS );
classPath = loadClassPath( base, config.getProperty( CLASS_PATH ) );
config.remove( CLASS_PATH );
fork = Boolean.valueOf( config.getProperty( FORK, fork.toString() ) );
config.remove( FORK );
redirect = Boolean.valueOf( config.getProperty( REDIRECT, redirect.toString() ) );
config.remove( REDIRECT );
restream = Boolean.valueOf( config.getProperty( RESTREAM, restream.toString() ) );
config.remove( RESTREAM );
consumeSysPropsAndEnvVars( config );
}
void consumeSysPropsAndEnvVars( Properties config ) {
props = new Properties();
vars = new HashMap<String,String>();
for( String name : config.stringPropertyNames() ) {
String value = config.getProperty( name );
if( name.startsWith( ENV_PREFIX ) ) {
vars.put( name.substring( ENV_PREFIX_LENGTH ), value );
} else {
props.setProperty( name, value );
}
}
}
public void run() throws InvocationTargetException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException {
//TODO ((URLClassLoader)this.getClass().getClassLoader()).getURLs();
if( fork ) {
Forker.fork( this );
} else {
Invoker.invoke( this );
}
}
private static String[] loadMainArgs( String[] current, String override ) {
String[] args = current;
if( args == null || args.length == 0 ) {
if( override != null ) {
args = override.split( " " );
}
}
return args;
}
private static List<URL> loadClassPath( File base, String classPath ) throws MalformedURLException {
List<URL> urls = new ArrayList<URL>();
StringTokenizer parser = new StringTokenizer( classPath, CLASS_PATH_DELIM, false );
while( parser.hasMoreTokens() ) {
String libPath = parser.nextToken().trim();
File libFile = new File( base, libPath );
if( libFile.canRead() && ( libFile.isFile() || libFile.isDirectory() ) ) {
urls.add( libFile.toURI().toURL() );
} else if( libPath.endsWith( "*" ) || libPath.endsWith( "*.jar" ) ) {
File libDir = libFile.getParentFile();
File[] libFiles = libDir.listFiles( new WildcardFilenameFilter( libFile.getName() ) );
if( libFiles != null ) {
for( File file : libFiles ) {
urls.add( file.toURI().toURL() );
}
}
}
}
// for( URL url : urls ) {
// System.out.println( url );
// }
return urls;
}
private static class WildcardFilenameFilter implements FilenameFilter {
private static String SAFE = new String( new char[]{ (char)0 } );
private Pattern pattern;
private WildcardFilenameFilter( String filter ) {
filter = filter.replace( ".", SAFE );
filter = filter.replace( "*", ".*" );
filter = filter.replace( SAFE, "\\." );
pattern = Pattern.compile( filter );
}
@Override
public boolean accept( File dir, String name ) {
return pattern.matcher( name ).matches();
}
}
}