1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.utgenome.shell;
26
27 import java.io.BufferedReader;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.lang.reflect.Modifier;
31 import java.util.List;
32 import java.util.Properties;
33 import java.util.Set;
34 import java.util.TreeMap;
35
36 import org.utgenome.shell.Create.OverwriteMode;
37 import org.xerial.util.FileResource;
38 import org.xerial.util.ResourceFilter;
39 import org.xerial.util.StringUtil;
40 import org.xerial.util.io.VirtualFile;
41 import org.xerial.util.log.LogLevel;
42 import org.xerial.util.log.Logger;
43 import org.xerial.util.log.SimpleLogWriter;
44 import org.xerial.util.opt.Argument;
45 import org.xerial.util.opt.Option;
46 import org.xerial.util.opt.OptionParser;
47 import org.xerial.util.opt.OptionParserException;
48
49
50
51
52
53
54
55 public class UTGBShell {
56
57 static {
58 }
59
60 private static Logger _logger = Logger.getLogger(UTGBShell.class);
61
62 private static TreeMap<String, UTGBShellCommand> subCommandTable = new TreeMap<String, UTGBShellCommand>();
63
64
65
66
67 static void findSubCommands() {
68 String shellPackage = UTGBShell.class.getPackage().getName();
69 List<VirtualFile> classFileList = FileResource.listResources(shellPackage, new ResourceFilter() {
70 public boolean accept(String resourcePath) {
71 return resourcePath.endsWith(".class");
72 }
73 });
74 for (VirtualFile vf : classFileList) {
75 String logicalPath = vf.getLogicalPath();
76 int dot = logicalPath.lastIndexOf(".");
77 if (dot <= 0)
78 continue;
79 String className = shellPackage + "." + logicalPath.substring(0, dot).replaceAll("/", ".");
80 try {
81 Class<?> c = Class.forName(className, false, UTGBShell.class.getClassLoader());
82 if (!Modifier.isAbstract(c.getModifiers()) && UTGBShellCommand.class.isAssignableFrom(c)) {
83
84 UTGBShellCommand subCommand = (UTGBShellCommand) c.newInstance();
85 if (subCommand == null)
86 continue;
87 subCommandTable.put(subCommand.name(), subCommand);
88 }
89 }
90 catch (ClassNotFoundException e) {
91 continue;
92 }
93 catch (InstantiationException e) {
94 _logger.error(e);
95 }
96 catch (IllegalAccessException e) {
97 _logger.error(e);
98 }
99 }
100 }
101
102 static {
103
104 findSubCommands();
105
106
107 }
108
109 public static class UTGBShellOption {
110
111 @Option(symbol = "h", longName = "help", description = "display help message")
112 private boolean displayHelp = false;
113
114 @Option(symbol = "v", longName = "version", description = "display version")
115 private boolean displayVersion = false;
116
117 @Argument(index = 0, required = false)
118 private String subCommand = null;
119
120 @Option(symbol = "l", longName = "loglevel", description = "set log level: TRACE, DEBUG, INFO(default), WARN, ERROR, FATAL")
121 private LogLevel logLevel = null;
122
123 @Option(symbol = "d", longName = "projectDir", description = "specify the project directory (default = current directory)")
124 public String projectDir = ".";
125
126 @Option(symbol = "e", longName = "env", varName = "test|development|production", description = "switch the configuration file (default: development)")
127 public String environment = "development";
128
129 @Option(symbol = "y", description = "(non-interactive mode) answer yes to all questions")
130 public boolean answerYes = false;
131
132 }
133
134 public static Set<String> getSubCommandNameSet() {
135 return subCommandTable.keySet();
136 }
137
138
139
140
141
142
143
144 public static void runCommand(String argLine) throws Exception {
145 runCommand(argLine.split("[\\s]+"));
146 }
147
148 public static void runCommand(UTGBShellOption opt, String argLine) throws Exception {
149 runCommand(opt, argLine.split("[\\s]+"));
150 }
151
152 public static void runCommand(UTGBShellOption opt, String[] args) throws Exception {
153
154 OptionParser optionParser = new OptionParser(opt);
155 optionParser.setIgnoreUnknownOption(true);
156
157 optionParser.parse(args);
158 String[] subCommandArgumetns = optionParser.getUnusedArguments();
159
160 if (opt.logLevel != null)
161 Logger.getRootLogger().setLogLevel(opt.logLevel);
162
163 Logger.getRootLogger().setLogWriter(new SimpleLogWriter(System.err));
164
165 if (opt.answerYes) {
166 ScaffoldGenerator.overwriteMode = OverwriteMode.YES_TO_ALL;
167 }
168
169 if (opt.subCommand != null) {
170
171 UTGBShellCommand subCommand = subCommandTable.get(opt.subCommand);
172
173 if (subCommand != null) {
174
175
176 Object optionHolder = subCommand.getOptionHolder();
177 if (optionHolder == null)
178 optionHolder = subCommand;
179
180 OptionParser subCommandParser = new OptionParser(optionHolder);
181 subCommandParser.setIgnoreUnknownOption(true);
182 try {
183 subCommandParser.parse(subCommandArgumetns);
184 if (opt.displayHelp) {
185 String helpFile = String.format("help-%s.txt", subCommand.name());
186 System.out.println(loadUsage(helpFile));
187 subCommandParser.printUsage();
188 return;
189 }
190 else {
191
192 subCommand.execute(opt, subCommandArgumetns);
193 return;
194 }
195 }
196 catch (OptionParserException e) {
197 System.err.println(e.getMessage());
198 return;
199 }
200
201 }
202 else {
203 System.err.println("unknown subcommand: " + opt.subCommand);
204 }
205 }
206 else {
207 if (opt.displayHelp) {
208
209 System.out.println(getProgramInfo());
210 BufferedReader helpReader = FileResource.open(UTGBShell.class, "help-message.txt");
211 String line;
212 while ((line = helpReader.readLine()) != null)
213 System.out.println(line);
214
215 optionParser.printUsage();
216
217 System.out.println("[sub commands]");
218 for (String subCommandName : subCommandTable.keySet()) {
219 UTGBShellCommand sc = subCommandTable.get(subCommandName);
220 System.out.format(" %-15s\t%s", subCommandName, sc.getOneLinerDescription());
221 System.out.println();
222 }
223 return;
224 }
225 if (opt.displayVersion) {
226 System.out.println(getProgramInfo());
227 return;
228 }
229 }
230
231
232 System.out.println(getProgramInfo());
233 System.out.println("type --help for a list of the available sub commands.");
234
235 }
236
237
238
239
240
241
242
243 public static void runCommand(String[] args) throws Exception {
244 runCommand(new UTGBShellOption(), args);
245 }
246
247
248
249
250
251
252
253
254
255 public static void main(String[] args) {
256 try {
257 runCommand(args);
258 }
259 catch (UTGBShellException e) {
260 System.err.println(e.getMessage());
261 System.exit(1);
262 }
263 catch (OptionParserException e) {
264 System.err.println(e.getMessage());
265 System.exit(1);
266 }
267 catch (Exception e) {
268 e.printStackTrace(System.err);
269 System.exit(1);
270 }
271 catch (Error e) {
272 e.printStackTrace(System.err);
273 System.exit(1);
274 }
275 }
276
277 public static String loadUsage(String helpFileName) {
278
279 StringBuilder out = new StringBuilder();
280 try {
281 BufferedReader reader = FileResource.open(Create.class, helpFileName);
282 String line;
283 if (reader == null)
284 return "";
285 while ((line = reader.readLine()) != null) {
286 out.append(line);
287 out.append(StringUtil.NEW_LINE);
288 }
289 return out.toString();
290 }
291 catch (IOException e) {
292 _logger.warn(String.format("%s is not found in the org.utgenome.shell package", helpFileName));
293 return "";
294 }
295 }
296
297 public static String getProgramInfo() {
298 return "UTGB Shell: version " + getVersion();
299 }
300
301 public static String getVersion() {
302 String version = "(unknown)";
303 try {
304
305 InputStream pomIn = UTGBShell.class.getResourceAsStream("/META-INF/maven/org.utgenome/utgb-core/pom.properties");
306 if (pomIn != null) {
307 Properties prop = new Properties();
308 prop.load(pomIn);
309 version = prop.getProperty("version", version);
310 }
311 }
312 catch (IOException e) {
313 _logger.debug(e);
314 }
315 return version;
316 }
317 }