package com.ontology2.bakemono; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; import org.springframework.beans.factory.BeanNotOfRequiredTypeException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainBase implements Runnable { private static Log logger = LogFactory.getLog(Main.class); private final ClassPathXmlApplicationContext context; public static class IncorrectUsageException extends Exception { public IncorrectUsageException(String message) { super(message); } } Map<String, TopLevelCommand> myCommands=new HashMap<String,TopLevelCommand>() {{ put("run",new RunATool()); put("list",new ListTools()); }}; final List<String> args; public MainBase(String[] arg0) { args= Lists.newArrayList(arg0); context=new ClassPathXmlApplicationContext(getApplicationContextPath().toArray(new String[] {})); } public List<String> getApplicationContextPath() { return Lists.newArrayList("com/ontology2/bakemono/applicationContext.xml"); } @Override public void run() { try { try { parseArguments(); cmd.run(); } catch(IncorrectUsageException ex) { usage(ex); return; } } catch(Exception ex) { logger.error("Uncaught exception in application",ex); }; } void parseArguments() throws Exception { if(args.isEmpty()) errorCausedByUser("you didn't specify any arguments"); cmd = myCommands.get(args.get(0)); if(cmd==null) errorCausedByUser("bakemono only supports the following commands: "+ Joiner.on(" ").join(myCommands.keySet())); if(args.size()<cmd.getMinimumArgumentCount()+1) errorCausedByUser("the "+args.get(0)+" command requires at least one argument, the name of a tool"); cmd.validateArguments(); } protected String toolName; protected Tool tool; protected List<String> toolArgs; TopLevelCommand cmd; String getToolName() { return this.toolName; } String getTool() { return this.toolName; } List<String> getToolArgs() { return toolArgs; } public static IncorrectUsageException errorCausedByUser(String error) throws IncorrectUsageException { throw new IncorrectUsageException(error); } private void usage(IncorrectUsageException ex) { System.out.println("User error: "+ex.getMessage()); } abstract class TopLevelCommand implements Runnable { int getMinimumArgumentCount() { return 0; } void validateArguments() throws Exception {}; }; public class RunATool extends TopLevelCommand { @Override public void run() { try { ToolRunner.run(tool, toolArgs.toArray(new String[0])); } catch(Exception ex) { logger.error("Uncaught exception in application",ex); }; } @Override public int getMinimumArgumentCount() { return 1; } void validateArguments() throws Exception { toolName=args.get(1); try { tool=context.getBean(toolName,Tool.class); } catch(NoSuchBeanDefinitionException |BeanNotOfRequiredTypeException x) { errorCausedByUser("you specified a tool ["+toolName+"] not supported by the bakemono system"); } toolArgs=Lists.newArrayList(Iterables.skip(args, 2)); } } class ListTools extends TopLevelCommand { @Override public void run() { System.out.println("Tools supported by this build of bakemono:"); System.out.println(); for(Map.Entry<String,Tool> i:context.getBeansOfType(Tool.class).entrySet()) { System.out.println(" "+i.getKey()); } } } }