org.ops4j.pax.runner.CommandLineImpl Maven / Gradle / Ivy
/*
* Copyright 2006 Niclas Hedhman.
* Copyright 2007 Alin Dreghiciu.
*
* Licensed 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.ops4j.pax.runner;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Default implementation of Command Line.
*
* @author Alin Dreghiciu
* @since August 26, 2007
*/
public class CommandLineImpl implements CommandLine
{
/**
* Option profix.
*/
private static final String OPTION_PREFIX = "--";
/**
* Option pattern.
*/
public static final Pattern OPTION_PATTERN = Pattern.compile( "(.*?)=(.*)" );
/**
* Default arguments file name.
*/
private static final String DEFAULT_ARGS_FILE_NAME = "runner.args";
/**
* Default line comment for DEFAULT_ARGS_FILE_NAME files
*/
private static final char LINE_COMMENT_PREFIX = '#';
/**
* Default character, the presence of this at the end of line indicates continuity
*/
private static final String LINE_CONTINUE_CHAR = "\\";
/**
* Options as properties.
*/
private final Map> m_options;
/**
* List of arguments.
*/
private final List m_arguments;
/**
* URL of configuration file (if any);
*/
private final String m_localArgsURL;
/**
* URL of global configuration file (if any);
*/
private final String m_globalArgsURL;
/**
* Creates a new Command line by parsing every argument into an option or argument.
*
* @param args an array of arguments to be parsed
*/
public CommandLineImpl( final String... args )
{
m_options = new HashMap>();
m_arguments = new ArrayList();
parseArguments( args == null ? Collections.emptyList() : Arrays.asList( args ) );
final String argsURL = getOption( "args" );
boolean useArgsFile = argsURL == null || !argsURL.equalsIgnoreCase( "false" );
m_localArgsURL = useArgsFile ? parseLocalArgs() : null;
m_globalArgsURL = useArgsFile ? parseGlobalArgs() : null;
}
/**
* Parse arguments form local arguments. This can be specified by using a property named "args" or if not specified
* a default ./runner.args will be searched.
*
* @return url of local args file or null if not set and no default found
*/
private String parseLocalArgs()
{
String argsURL = getOption( "args" );
if( argsURL == null )
{
// use a default args file if available
final File defaultArgsFile = new File( DEFAULT_ARGS_FILE_NAME );
if( defaultArgsFile.exists() )
{
try
{
argsURL = defaultArgsFile.toURL().toExternalForm();
}
catch( MalformedURLException ignore )
{
// ignore as this should not happen
}
}
}
if( argsURL != null )
{
try
{
parseArguments( readTextFile( new URL( argsURL ), true ) );
}
catch( IOException e )
{
throw new RuntimeException( "Arguments could not be read from [" + argsURL + "]", e );
}
}
return argsURL;
}
/**
* Parse arguments from global user arguments. This can be specified by using a property named "globalArgs" or if
* not specified a default ${user.home}/.pax/runner/runner.args will be searched.
*
* @return url of global args file or null if not set and no default found
*/
private String parseGlobalArgs()
{
String globalArgsURL = getOption( "globalArgs" );
String userHome = System.getProperty( "user.home" );
if( globalArgsURL == null && userHome != null )
{
// use a default
final File defaultGlobalArgsFile = new File(
userHome + File.separator + ".pax" + File.separator + "runner" + File.separator + DEFAULT_ARGS_FILE_NAME
);
if( defaultGlobalArgsFile.exists() )
{
try
{
globalArgsURL = defaultGlobalArgsFile.toURL().toExternalForm();
}
catch( MalformedURLException ignore )
{
// ignore as this should not happen
}
}
}
if( globalArgsURL != null )
{
try
{
parseArguments( readTextFile( new URL( globalArgsURL ), true ) );
}
catch( IOException e )
{
throw new RuntimeException( "Arguments could not be read from [" + globalArgsURL + "]", e );
}
}
return globalArgsURL;
}
/**
* Parses a list of arguments.
*
* @param args a list of arguments
*/
private void parseArguments( List args )
{
for( String arg : args )
{
if( arg.startsWith( OPTION_PREFIX ) )
{
parseOption( arg );
}
else
{
parseArgument( arg );
}
}
initializeProxy();
}
/**
* {@inheritDoc}
*/
public String getOption( final String key )
{
final List values = m_options.get( key );
return values == null || values.size() == 0 ? null : values.get( 0 );
}
/**
* {@inheritDoc}
*/
public String[] getMultipleOption( final String key )
{
final List values = m_options.get( key );
return values == null || values.size() == 0 ? new String[0] : values.toArray( new String[values.size()] );
}
/**
* {@inheritDoc}
*/
public List getArguments()
{
return m_arguments;
}
/**
* {@inheritDoc}
*/
public String getArgumentsFileURL()
{
return m_localArgsURL;
}
/**
* Parses an option of type --name=value
*
* @param arg a command line argument to be parsed
*/
private void parseOption( final String arg )
{
String key = arg.substring( 2 ).trim();
if( key != null && key.length() > 0 )
{
String value = null;
final Matcher matcher = OPTION_PATTERN.matcher( key );
if( matcher.matches() && matcher.groupCount() == 2 )
{
key = matcher.group( 1 );
value = matcher.group( 2 );
if( OPTION_PROFILES.equals( key ) )
{
value = value.replace( ',', ':' );
}
}
if( value == null )
{
value = "true";
if( key.startsWith( "no" ) && key.length() > 2 )
{
String actualKey = key.substring( 2, 3 ).toLowerCase();
if( key.length() >= 3 )
{
key = actualKey + key.substring( 3 );
}
value = "false";
}
}
List values = m_options.get( key );
if( values == null )
{
values = new ArrayList();
m_options.put( key, values );
}
values.add( value );
if( OPTION_SHELL.equals( key ) )
{
m_options.put( OPTION_CONSOLE, Arrays.asList( "false" ) );
addProfile( value );
}
}
}
/**
* Parses an argument (does not start with --).
*
* @param arg a command line argument to be parsed
*/
private void parseArgument( final String arg )
{
// first check if it is a profile
// do our best to not confuse a spec with a profile
if( !arg.startsWith( "scan" )
&& !arg.startsWith( "/" )
&& !arg.contains( ":" )
&& arg.split( "/" ).length <= 3
&& !new File( arg ).exists() )
{
addProfile( arg );
}
else if( !m_arguments.contains( arg ) )
{
m_arguments.add( arg );
}
}
/**
* Adds a profile to profile list.
*
* @param profile profile to add
*/
private void addProfile( final String profile )
{
if( profile == null || profile.trim().length() == 0 )
{
return;
}
List profileOption = m_options.get( OPTION_PROFILES );
if( profileOption == null )
{
profileOption = new ArrayList();
profileOption.add( profile );
m_options.put( OPTION_PROFILES, profileOption );
}
else
{
String value = profileOption.get( 0 );
value = value + ":" + profile;
profileOption.set( 0, value );
}
}
/**
* Reads content of a text files and returns every line as an entry to a List.
*
* @param fileURL url of the file to be read
* @param skipEmptyLines if empty lines should be skippied
*
* @return a list of strings, one entry for each line (depending if it should skip empty lines or not)
*
* @throws IOException re-thrown if an exception appear during processing of input stream
*/
private static List readTextFile( final URL fileURL, final boolean skipEmptyLines )
throws IOException
{
final List content = new ArrayList();
BufferedReader bufferedReader = null;
try
{
bufferedReader = new BufferedReader( new InputStreamReader( fileURL.openStream() ) );
String line;
StringBuffer entry = new StringBuffer();
boolean readMore = false;
while( ( line = bufferedReader.readLine() ) != null )
{
if( ( !skipEmptyLines || line.trim().length() > 0 ) && line.charAt( 0 ) != LINE_COMMENT_PREFIX )
{
if( line.endsWith( LINE_CONTINUE_CHAR ) )
{
entry.append( line.substring( 0, line.length() - 1 ) );
continue;
}
else
{
entry.append( line );
content.add( entry.toString().trim() );
entry.delete( 0, entry.length() );
continue;
}
}
if( line.trim().length() == 0 && entry.length() > 0 )
{
content.add( entry.toString().trim() );
entry.delete( 0, entry.length() );
}
}
if( entry != null && entry.length() > 0 )
{
content.add( entry.toString().trim() );
}
}
finally
{
if( bufferedReader != null )
{
bufferedReader.close();
}
}
return content;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
if( m_localArgsURL != null )
{
builder.append( " and " ).append( m_localArgsURL );
}
if( m_globalArgsURL != null )
{
builder.append( " and " ).append( m_globalArgsURL );
}
if( builder.length() > 0 )
{
builder.insert( 0, "Using arguments from command line" );
}
else
{
builder.append( "Using only arguments from command line" );
}
return builder.toString();
}
private String toStringAdvanced()
{
StringBuilder builder = new StringBuilder();
builder.append( "Arguments: " );
for( String entry : m_arguments )
{
builder
.append( "[" )
.append( entry )
.append( "]" );
}
builder.append( "Options: " );
for( Map.Entry> entry : m_options.entrySet() )
{
builder
.append( "[" )
.append( entry.getKey() )
.append( "=" )
.append( entry.getValue() )
.append( "]" );
}
return builder.toString();
}
/**
* Set system properties for proxies based on provided command line arguments.
*/
private void initializeProxy()
{
initializeProxy( "http" );
initializeProxy( "https" );
initializeProxy( "ftp" );
initializeSocksProxy();
}
/**
* Set system properties for proxies based on provided command line arguments.
*
* @param protocol protocol
*/
private void initializeProxy( final String protocol )
{
final String proxy = getOption( protocol + ".proxyHost" );
if( proxy != null )
{
System.setProperty( protocol + ".proxyHost", proxy );
}
final String port = getOption( protocol + ".proxyPort" );
if( port != null )
{
System.setProperty( protocol + ".proxyPort", port );
}
final String nonHosts = getOption( protocol + ".nonProxyHosts" );
if( nonHosts != null )
{
System.setProperty( protocol + ".nonProxyHosts", nonHosts );
}
}
/**
* Set system properties for proxies based on provided command line arguments.
*/
private void initializeSocksProxy()
{
final String proxy = getOption( "socksProxyHost" );
if( proxy != null )
{
System.setProperty( "socksProxyHost", proxy );
}
final String port = getOption( "socksProxyPort" );
if( port != null )
{
System.setProperty( "socksProxyPort", port );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy