1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.any23.cli;
19
20 import com.beust.jcommander.JCommander;
21 import com.beust.jcommander.Parameter;
22 import com.beust.jcommander.converters.FileConverter;
23 import org.apache.any23.Any23;
24 import org.apache.any23.plugin.Any23PluginManager;
25
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.PrintStream;
30 import java.util.Date;
31 import java.util.Iterator;
32 import java.util.Locale;
33 import java.util.Map;
34 import java.util.Properties;
35
36 import static java.lang.System.currentTimeMillis;
37 import static java.lang.System.exit;
38
39
40
41
42
43
44
45
46 public final class ToolRunner {
47
48 public static final File DEFAULT_PLUGIN_DIR = new File(new File(System.getProperty("user.home")), ".any23/plugins");
49
50 private static final PrintStream infoStream = System.err;
51
52 @Parameter(names = { "-h", "--help" }, description = "Display help information.")
53 private boolean printHelp;
54
55 @Parameter(names = { "-v", "--version" }, description = "Display version information.")
56 private boolean showVersion;
57
58 @Parameter(names = { "-X", "--verbose" }, description = "Produce execution verbose output.")
59 private boolean verbose;
60
61 @Parameter(names = {
62 "--plugins-dir" }, description = "The Any23 plugins directory.", converter = FileConverter.class)
63 private File pluginsDir = DEFAULT_PLUGIN_DIR;
64
65 public static void main(String[] args) throws Exception {
66 exit(new ToolRunner().execute(args));
67 }
68
69 public int execute(String... args) throws Exception {
70 return execute(false, args);
71 }
72
73 int execute(boolean concise, String... args) throws Exception {
74 JCommander commander = new JCommander(this);
75 commander.setProgramName(System.getProperty("app.name"));
76
77
78
79 final File pluginsDirOption;
80 try {
81 pluginsDirOption = parsePluginDirOption(args);
82 } catch (Exception e) {
83 System.err.println(e.getMessage());
84 return 1;
85 }
86 if (pluginsDirOption != null) {
87 pluginsDir = pluginsDirOption;
88 }
89
90
91 final Iterator<Tool> tools = getToolsInClasspath();
92 while (tools.hasNext()) {
93 Tool tool = tools.next();
94 commander.addCommand(tool);
95 }
96
97 commander.parse(args);
98
99 Map<String, JCommander> commands = commander.getCommands();
100 String parsedCommand = commander.getParsedCommand();
101
102 if (printHelp) {
103 commander.usage();
104 return 0;
105 }
106
107 if (showVersion) {
108 printVersionInfo();
109 return 0;
110 }
111
112 if (parsedCommand == null) {
113 infoStream.println("A command must be specified.");
114 commander.usage();
115 return 1;
116 }
117
118 long start = currentTimeMillis();
119 int exit = 0;
120
121 Throwable error = null;
122
123
124 infoStream.println();
125 infoStream.println("------------------------------------------------------------------------");
126 infoStream.printf(Locale.ROOT, "Apache Any23 :: %s%n", parsedCommand);
127 infoStream.println("------------------------------------------------------------------------");
128 infoStream.println();
129
130 try {
131 Tool tool = Tool.class.cast(commands.get(parsedCommand).getObjects().get(0));
132 if (tool instanceof BaseTool) {
133 ((BaseTool) tool).run(concise);
134 } else {
135 tool.run();
136 }
137 } catch (Throwable t) {
138 exit = 1;
139 error = t;
140 } finally {
141 infoStream.println();
142 infoStream.println("------------------------------------------------------------------------");
143 infoStream.printf(Locale.ROOT, "Apache Any23 %s%n", (exit != 0) ? "FAILURE" : "SUCCESS");
144
145 if (exit != 0) {
146 infoStream.println();
147
148 if (verbose) {
149 System.err.println("Execution terminated with errors:");
150 error.printStackTrace(infoStream);
151 } else {
152 infoStream.printf(Locale.ROOT, "Execution terminated with errors: %s%n", error.getMessage());
153 }
154
155 infoStream.println();
156 }
157
158 infoStream.printf(Locale.ROOT, "Total time: %ss%n", ((currentTimeMillis() - start) / 1000));
159 infoStream.printf(Locale.ROOT, "Finished at: %s%n", new Date());
160
161 final Runtime runtime = Runtime.getRuntime();
162 final int megaUnit = 1024 * 1024;
163 infoStream.printf(Locale.ROOT, "Final Memory: %sM/%sM%n",
164 (runtime.totalMemory() - runtime.freeMemory()) / megaUnit, runtime.totalMemory() / megaUnit);
165
166 infoStream.println("------------------------------------------------------------------------");
167 }
168
169 return exit;
170 }
171
172 Iterator<Tool> getToolsInClasspath() throws IOException {
173 final Any23PluginManager pluginManager = Any23PluginManager.getInstance();
174 if (pluginsDir.exists() && pluginsDir.isDirectory()) {
175 pluginManager.loadJARDir(pluginsDir);
176 }
177 return pluginManager.getTools();
178 }
179
180 private static void printVersionInfo() {
181 Properties properties = new Properties();
182 InputStream input = ToolRunner.class.getClassLoader()
183 .getResourceAsStream("META-INF/maven/org.apache.any23/any23-core/pom.properties");
184
185 if (input != null) {
186 try {
187 properties.load(input);
188 } catch (IOException e) {
189
190 } finally {
191 try {
192 input.close();
193 } catch (IOException e) {
194
195 }
196 }
197 }
198
199 infoStream.printf(Locale.ROOT, "Apache Any23 %s%n", Any23.VERSION);
200 infoStream.printf(Locale.ROOT, "Java version: %s, vendor: %s%n", System.getProperty("java.version"),
201 System.getProperty("java.vendor"));
202 infoStream.printf(Locale.ROOT, "Java home: %s%n", System.getProperty("java.home"));
203 infoStream.printf(Locale.ROOT, "Default locale: %s_%s, platform encoding: %s%n",
204 System.getProperty("user.language"), System.getProperty("user.country"),
205 System.getProperty("sun.jnu.encoding"));
206 infoStream.printf(Locale.ROOT, "OS name: \"%s\", version: \"%s\", arch: \"%s\", family: \"%s\"%n",
207 System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch"),
208 getOsFamily());
209 }
210
211 private static final String getOsFamily() {
212 String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT);
213 String pathSep = System.getProperty("path.separator");
214
215 if (osName.contains("windows")) {
216 return "windows";
217 } else if (osName.contains("os/2")) {
218 return "os/2";
219 } else if (osName.contains("z/os") || osName.contains("os/390")) {
220 return "z/os";
221 } else if (osName.contains("os/400")) {
222 return "os/400";
223 } else if (";".equals(pathSep)) {
224 return "dos";
225 } else if (osName.contains("mac")) {
226 if (osName.endsWith("x")) {
227 return "mac";
228 }
229 return "unix";
230 } else if (osName.contains("nonstop_kernel")) {
231 return "tandem";
232 } else if (osName.contains("openvms")) {
233 return "openvms";
234 } else if (":".equals(pathSep)) {
235 return "unix";
236 }
237
238 return "undefined";
239 }
240
241 private static File parsePluginDirOption(String[] args) {
242 int optionIndex = -1;
243 for (int i = 0; i < args.length; i++) {
244 if ("--plugins-dir".equals(args[i])) {
245 optionIndex = i;
246 }
247 }
248 if (optionIndex == -1)
249 return null;
250
251 if (optionIndex == args.length - 1) {
252 throw new IllegalArgumentException("Missing argument for --plugins-dir option.");
253 }
254 final File pluginsDir = new File(args[optionIndex + 1]);
255 if (!pluginsDir.isDirectory()) {
256 throw new IllegalArgumentException("Expected a directory for --plugins-dir option value.");
257 }
258 return pluginsDir;
259 }
260
261 }