/*-------------------------------------------------------------------------- * Copyright 2008 utgenome.org * * 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. *--------------------------------------------------------------------------*/ //-------------------------------------- // utgb-shell Project // // UTGBShell.java // Since: Jan 8, 2008 // // $URL$ // $Author$ //-------------------------------------- package org.utgenome.shell; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Modifier; import java.util.List; import java.util.Set; import java.util.TreeMap; import org.xerial.core.XerialException; import org.xerial.util.FileResource; import org.xerial.util.ResourceFilter; import org.xerial.util.StringUtil; import org.xerial.util.bean.BeanUtil; import org.xerial.util.io.VirtualFile; import org.xerial.util.log.LogLevel; import org.xerial.util.log.Logger; import org.xerial.util.log.SimpleLogWriter; import org.xerial.util.opt.Argument; import org.xerial.util.opt.Option; import org.xerial.util.opt.OptionParser; import org.xerial.util.opt.OptionParserException; /** * A command line client entry point * * @author leo * */ public class UTGBShell { private static Logger _logger = Logger.getLogger(UTGBShell.class); private static TreeMap subCommandTable = new TreeMap(); /** * search sub commands from the this package (org.utgenome.shell) */ static void searchSubCommands() { String shellPackage = UTGBShell.class.getPackage().getName(); List classFileList = FileResource.listResources(shellPackage, new ResourceFilter() { public boolean accept(String resourcePath) { return resourcePath.endsWith(".class"); } }); for (VirtualFile vf : classFileList) { String logicalPath = vf.getLogicalPath(); int dot = logicalPath.lastIndexOf("."); if (dot <= 0) continue; String className = shellPackage + "." + logicalPath.substring(0, dot).replaceAll("/", "."); try { Class c = Class.forName(className, false, UTGBShell.class.getClassLoader()); if (!Modifier.isAbstract(c.getModifiers()) && UTGBShellCommand.class.isAssignableFrom(c)) { // found a sub command class UTGBShellCommand subCommand = (UTGBShellCommand) c.newInstance(); if (subCommand == null) continue; subCommandTable.put(subCommand.name(), subCommand); } } catch (ClassNotFoundException e) { continue; } catch (InstantiationException e) { _logger.error(e); } catch (IllegalAccessException e) { _logger.error(e); } } } static { // search the all available sub commands searchSubCommands(); // System.setProperty("com.apple.eawt.CocoaComponent.CompatibilityMode", "false"); } public static class UTGBShellOption { @Option(symbol = "h", longName = "help", description = "display help message") private boolean displayHelp = false; @Option(symbol = "v", longName = "version", description = "display version") private boolean displayVersion = false; @Argument(index = 0, required = false) private String subCommand = null; @Option(symbol = "l", longName = "loglevel", description = "set log level: TRACE, DEBUG, INFO(default), WARN, ERROR, FATAL") private LogLevel logLevel = null; @Option(symbol = "d", longName = "projectDir") public String projectDir = new File("").getAbsolutePath(); @Option(symbol = "e", longName = "env", varName = "test|development|production", description = "running mode (default: development)") public String environment = "development"; } public static Set getSubCommandNameSet() { return subCommandTable.keySet(); } public static void main(String[] args) { UTGBShellOption opt = new UTGBShellOption(); OptionParser optionParser = new OptionParser(opt); optionParser.setIgnoreUnknownOption(true); try { optionParser.parse(args); String[] subCommandArgumetns = optionParser.getUnusedArguments(); if (opt.logLevel != null) Logger.getRootLogger().setLogLevel(opt.logLevel); Logger.getRootLogger().setLogWriter(new SimpleLogWriter(System.err)); if (opt.subCommand != null) { // go to sub command processing UTGBShellCommand subCommand = subCommandTable.get(opt.subCommand); if (subCommand != null) { // Use the specified option holder for binding command-line parameters. If no option holder is // given, use the sub command instance itself. Object optionHolder = subCommand.getOptionHolder(); if (optionHolder == null) optionHolder = subCommand; OptionParser subCommandParser = new OptionParser(optionHolder); subCommandParser.setIgnoreUnknownOption(true); try { subCommandParser.parse(subCommandArgumetns); if (opt.displayHelp) { String helpFile = String.format("help-%s.txt", subCommand.name()); System.out.println(loadUsage(helpFile)); subCommandParser.printUsage(); return; } else { // copy the rest of the command line arguments subCommand.execute(opt, subCommandArgumetns); return; } } catch (OptionParserException e) { System.err.println(e.getMessage()); return; } } else { System.err.println("unknown subcommand: " + opt.subCommand); } } else { if (opt.displayHelp) { // display help message System.out.println(getProgramInfo()); BufferedReader helpReader = FileResource.open(UTGBShell.class, "help-message.txt"); String line; while ((line = helpReader.readLine()) != null) System.out.println(line); // list command line options optionParser.printUsage(); // list all sub commands System.out.println("[sub commands]"); for (String subCommandName : subCommandTable.keySet()) { UTGBShellCommand sc = subCommandTable.get(subCommandName); System.out.format(" %-10s\t%s", subCommandName, sc.getOneLinerDescription()); System.out.println(); } return; } if (opt.displayVersion) { System.out.println(getProgramInfo()); return; } } // display a short help message System.out.println(getProgramInfo()); System.out.println("type --help for a list of the available sub commands."); } catch (Exception e) { System.err.println(e.getMessage()); } catch (Error e) { e.printStackTrace(System.err); } } public static String loadUsage(String helpFileName) { // display help messages StringBuilder out = new StringBuilder(); try { BufferedReader reader = FileResource.open(Create.class, helpFileName); String line; while ((line = reader.readLine()) != null) { out.append(line); out.append(StringUtil.NEW_LINE); } return out.toString(); } catch (IOException e) { _logger.warn(String.format("%s is not found in the org.utgenome.shell package", helpFileName)); return ""; } } public static String getProgramInfo() { return "UTGB Shell: version " + getVersion() + " (" + getRevision() + ")"; } public static String getRevision() { return getPom().getRevision(); } private static POM getPom() { POM pom = new POM(); // read the pom.xml file and extract the version information try { // load the pom.xml file copied as a resource InputStream pomIn = UTGBShell.class.getResourceAsStream("/META-INF/maven/org.utgenome/utgb-shell/pom.xml"); if (pomIn != null) { BufferedReader pomReader = new BufferedReader(new InputStreamReader(pomIn)); if (pomReader != null) BeanUtil.populateBeanWithXML(pom, pomReader); } } catch (XerialException e) { _logger.debug(e); } return pom; } public static String getVersion() { return getPom().getVersion(); } }