| /* |
| * 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.any23.cli; |
| |
| import com.beust.jcommander.JCommander; |
| import com.beust.jcommander.Parameter; |
| import com.beust.jcommander.converters.FileConverter; |
| import org.apache.any23.Any23; |
| import org.apache.any23.plugin.Any23PluginManager; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.PrintStream; |
| import java.util.Date; |
| import java.util.Iterator; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import static java.lang.System.currentTimeMillis; |
| import static java.lang.System.exit; |
| |
| /** |
| * This class is the main class responsible to provide a uniform command-line |
| * access points to all the others tools like {@link Rover}. |
| * |
| * @see ExtractorDocumentation |
| * @see Rover |
| */ |
| public final class ToolRunner { |
| |
| public static final File DEFAULT_PLUGIN_DIR = new File(new File(System.getProperty("user.home")), ".any23/plugins"); |
| |
| private static final PrintStream infoStream = System.err; |
| |
| @Parameter( names = { "-h", "--help" }, description = "Display help information." ) |
| private boolean printHelp; |
| |
| @Parameter( names = { "-v", "--version" }, description = "Display version information." ) |
| private boolean showVersion; |
| |
| @Parameter( names = { "-X", "--verbose" }, description = "Produce execution verbose output." ) |
| private boolean verbose; |
| |
| @Parameter( |
| names = { "--plugins-dir" }, |
| description = "The Any23 plugins directory.", |
| converter = FileConverter.class |
| ) |
| private File pluginsDir = DEFAULT_PLUGIN_DIR; |
| |
| public static void main( String[] args ) throws Exception { |
| exit( new ToolRunner().execute( args ) ); |
| } |
| |
| public int execute(String... args) throws Exception { |
| return execute(false, args); |
| } |
| |
| int execute(boolean concise, String... args) throws Exception { |
| JCommander commander = new JCommander(this); |
| commander.setProgramName(System.getProperty("app.name")); |
| |
| // TODO (low) : this dirty solution has been introduced because it is not possible to |
| // parse arguments ( commander.parse() ) twice. |
| final File pluginsDirOption; |
| try { |
| pluginsDirOption = parsePluginDirOption(args); |
| } catch (Exception e) { |
| System.err.println(e.getMessage()); |
| return 1; |
| } |
| if(pluginsDirOption != null) { |
| pluginsDir = pluginsDirOption; |
| } |
| |
| // add all plugins first |
| final Iterator<Tool> tools = getToolsInClasspath(); |
| while (tools.hasNext()) { |
| Tool tool = tools.next(); |
| commander.addCommand(tool); |
| } |
| |
| commander.parse(args); |
| |
| Map<String, JCommander> commands = commander.getCommands(); |
| String parsedCommand = commander.getParsedCommand(); |
| |
| if (printHelp) { |
| commander.usage(); |
| return 0; |
| } |
| |
| if (showVersion) { |
| printVersionInfo(); |
| return 0; |
| } |
| |
| if(parsedCommand == null) { |
| infoStream.println("A command must be specified."); |
| commander.usage(); |
| return 1; |
| } |
| |
| long start = currentTimeMillis(); |
| int exit = 0; |
| |
| Throwable error = null; |
| |
| // execute the parsed command |
| infoStream.println(); |
| infoStream.println( "------------------------------------------------------------------------" ); |
| infoStream.printf(Locale.ROOT, "Apache Any23 :: %s%n", parsedCommand ); |
| infoStream.println( "------------------------------------------------------------------------" ); |
| infoStream.println(); |
| |
| try { |
| Tool tool = Tool.class.cast(commands.get(parsedCommand).getObjects().get(0)); |
| if (tool instanceof BaseTool) { |
| ((BaseTool) tool).run(concise); |
| } else { |
| tool.run(); |
| } |
| } catch (Throwable t) { |
| exit = 1; |
| error = t; |
| } finally { |
| infoStream.println(); |
| infoStream.println( "------------------------------------------------------------------------" ); |
| infoStream.printf(Locale.ROOT, "Apache Any23 %s%n", ( exit != 0 ) ? "FAILURE" : "SUCCESS" ); |
| |
| if (exit != 0) { |
| infoStream.println(); |
| |
| if (verbose) { |
| System.err.println( "Execution terminated with errors:" ); |
| error.printStackTrace(infoStream); |
| } else { |
| infoStream.printf(Locale.ROOT, "Execution terminated with errors: %s%n", error.getMessage() ); |
| } |
| |
| infoStream.println(); |
| } |
| |
| infoStream.printf(Locale.ROOT, "Total time: %ss%n", ( ( currentTimeMillis() - start ) / 1000 ) ); |
| infoStream.printf(Locale.ROOT, "Finished at: %s%n", new Date() ); |
| |
| final Runtime runtime = Runtime.getRuntime(); |
| final int megaUnit = 1024 * 1024; |
| infoStream.printf(Locale.ROOT, "Final Memory: %sM/%sM%n", ( runtime.totalMemory() - runtime.freeMemory() ) / megaUnit, |
| runtime.totalMemory() / megaUnit ); |
| |
| infoStream.println( "------------------------------------------------------------------------" ); |
| } |
| |
| return exit; |
| } |
| |
| Iterator<Tool> getToolsInClasspath() throws IOException { |
| final Any23PluginManager pluginManager = Any23PluginManager.getInstance(); |
| if (pluginsDir.exists() && pluginsDir.isDirectory()) { |
| pluginManager.loadJARDir(pluginsDir); |
| } |
| return pluginManager.getTools(); |
| } |
| |
| private static void printVersionInfo() { |
| Properties properties = new Properties(); |
| InputStream input = ToolRunner.class.getClassLoader().getResourceAsStream( "META-INF/maven/org.apache.any23/any23-core/pom.properties" ); |
| |
| if ( input != null ) { |
| try { |
| properties.load( input ); |
| } catch ( IOException e ) { |
| // ignore, just don't load the properties |
| } finally { |
| try { |
| input.close(); |
| } catch (IOException e) { |
| // close quietly |
| } |
| } |
| } |
| |
| infoStream.printf(Locale.ROOT, "Apache Any23 %s%n", Any23.VERSION ); |
| infoStream.printf(Locale.ROOT, "Java version: %s, vendor: %s%n", |
| System.getProperty( "java.version" ), |
| System.getProperty( "java.vendor" ) ); |
| infoStream.printf(Locale.ROOT, "Java home: %s%n", System.getProperty( "java.home" ) ); |
| infoStream.printf(Locale.ROOT, "Default locale: %s_%s, platform encoding: %s%n", |
| System.getProperty( "user.language" ), |
| System.getProperty( "user.country" ), |
| System.getProperty( "sun.jnu.encoding" ) ); |
| infoStream.printf(Locale.ROOT, "OS name: \"%s\", version: \"%s\", arch: \"%s\", family: \"%s\"%n", |
| System.getProperty( "os.name" ), |
| System.getProperty( "os.version" ), |
| System.getProperty( "os.arch" ), |
| getOsFamily() ); |
| } |
| |
| private static final String getOsFamily() { |
| String osName = System.getProperty( "os.name" ).toLowerCase(Locale.ROOT); |
| String pathSep = System.getProperty( "path.separator" ); |
| |
| if (osName.contains("windows")) { |
| return "windows"; |
| } else if (osName.contains("os/2")) { |
| return "os/2"; |
| } else if (osName.contains("z/os") || osName.contains("os/390")) { |
| return "z/os"; |
| } else if (osName.contains("os/400")) { |
| return "os/400"; |
| } else if (";".equals(pathSep)) { |
| return "dos"; |
| } else if (osName.contains("mac")) { |
| if (osName.endsWith("x")) { |
| return "mac"; // MACOSX |
| } |
| return "unix"; |
| } else if (osName.contains("nonstop_kernel")) { |
| return "tandem"; |
| } else if (osName.contains("openvms")) { |
| return "openvms"; |
| } else if (":".equals(pathSep)) { |
| return "unix"; |
| } |
| |
| return "undefined"; |
| } |
| |
| private static File parsePluginDirOption(String[] args) { |
| int optionIndex = -1; |
| for(int i = 0; i < args.length; i++) { |
| if("--plugins-dir".equals(args[i])) { |
| optionIndex = i; |
| } |
| } |
| if(optionIndex == -1) |
| return null; |
| |
| if(optionIndex == args.length - 1) { |
| throw new IllegalArgumentException("Missing argument for --plugins-dir option."); |
| } |
| final File pluginsDir = new File( args[optionIndex + 1] ); |
| if( ! pluginsDir.isDirectory() ) { |
| throw new IllegalArgumentException("Expected a directory for --plugins-dir option value."); |
| } |
| return pluginsDir; |
| } |
| |
| } |