/** * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.component.tool; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.opengamma.component.factory.RemoteComponentFactory; import com.opengamma.financial.tool.ToolContext; import com.opengamma.util.ArgumentChecker; import com.opengamma.util.LogUtils; import com.opengamma.util.StartupUtils; /** * Abstract base class for tools which operate on components obtained through an OpenGamma component server. */ public abstract class AbstractDualComponentTool { private static final Logger s_logger = LoggerFactory.getLogger(AbstractTool.class); /** * Default logback file. */ public static final String TOOL_LOGBACK_XML = "tool-logback.xml"; /** Help command line option. */ private static final String HELP_OPTION = "h"; /** Component server URI command line option. */ private static final String SRC_COMPONENT_SERVER_URI_OPTION = "src"; /** Component server URI command line option. */ private static final String DEST_COMPONENT_SERVER_URI_OPTION = "dest"; /** Logging command line option. */ private static final String LOGBACK_RESOURCE_OPTION = "l"; static { StartupUtils.init(); } /** * The command line. */ private CommandLine _commandLine; /** * The remote source component factory. */ private RemoteComponentFactory _srcRemoteComponentFactory; /** * The remote destination component factory. */ private RemoteComponentFactory _destRemoteComponentFactory; /** * Initializes the tool statically. * * @param logbackResource the logback resource location, not null * @return true if successful */ public static final boolean init(String logbackResource) { return LogUtils.configureLogger(logbackResource); } /** * Creates an instance. */ protected AbstractDualComponentTool() { } //------------------------------------------------------------------------- /** * Initializes and runs the tool from standard command-line arguments. * <p> * The base class defined three options:<br /> * c/component server URI - the component server URI, mandatory<br /> * l/logback - the logback configuration, default tool-logback.xml<br /> * h/help - prints the help tool<br /> * * @param args the command-line arguments, not null * @return true if successful, false otherwise */ public boolean initAndRun(String[] args) { return initAndRun(args, null); } /** * Initializes and runs the tool from standard command-line arguments. * <p> * The base class defined three options:<br /> * c/component server URI - the component server URI, mandatory<br /> * l/logback - the logback configuration, default tool-logback.xml<br /> * h/help - prints the help tool<br /> * * @param args the command-line arguments, not null * @param defaultLogbackResource the default logback resource, null to use tool-logback.xml as the default * @return true if successful, false otherwise */ public boolean initAndRun(String[] args, String defaultLogbackResource) { ArgumentChecker.notNull(args, "args"); Options options = createOptions(); CommandLineParser parser = new PosixParser(); CommandLine line; try { line = parser.parse(options, args); } catch (ParseException e) { usage(options); return false; } _commandLine = line; if (line.hasOption(HELP_OPTION)) { usage(options); return true; } String logbackResource = line.getOptionValue(LOGBACK_RESOURCE_OPTION); logbackResource = StringUtils.defaultIfEmpty(logbackResource, TOOL_LOGBACK_XML); String srcComponentServerUri = line.getOptionValue(SRC_COMPONENT_SERVER_URI_OPTION); String destComponentServerUri = line.getOptionValue(DEST_COMPONENT_SERVER_URI_OPTION); return init(logbackResource) && run(srcComponentServerUri, destComponentServerUri); } /** * Runs the tool. * <p> * This starts the tool context and calls {@link #run(ToolContext)}. This will catch exceptions and print a stack trace. * * @param srcComponentServerUri the config resource location, not null * @param destComponentServerUri the config resource location, not null * @return true if successful */ public final boolean run(String srcComponentServerUri, String destComponentServerUri) { try { ArgumentChecker.notNull(srcComponentServerUri, "srcComponentServerUri"); ArgumentChecker.notNull(destComponentServerUri, "destComponentServerUri"); s_logger.info("Starting " + getClass().getSimpleName()); srcComponentServerUri = resolveComponentServerUri(srcComponentServerUri); RemoteComponentFactory srcRemoteComponentFactory = new RemoteComponentFactory(srcComponentServerUri); destComponentServerUri = resolveComponentServerUri(destComponentServerUri); RemoteComponentFactory destRemoteComponentFactory = new RemoteComponentFactory(destComponentServerUri); s_logger.info("Running " + getClass().getSimpleName()); run(srcRemoteComponentFactory, destRemoteComponentFactory); s_logger.info("Finished " + getClass().getSimpleName()); return true; } catch (Exception ex) { ex.printStackTrace(); return false; } } /** * Runs the tool, calling {@code doRun}. * <p> * This will catch unhandled exceptions, and will convert checked exceptions to unchecked. * * @param srcRemoteComponentFactory the remote component factory, not null * @param destRemoteComponentFactory the remote component factory, not null * @throws RuntimeException if an error occurs */ public final void run(RemoteComponentFactory srcRemoteComponentFactory, RemoteComponentFactory destRemoteComponentFactory) { _srcRemoteComponentFactory = srcRemoteComponentFactory; _destRemoteComponentFactory = destRemoteComponentFactory; try { doRun(); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { throw new RuntimeException(ex); } } //------------------------------------------------------------------------- /** * Override in subclasses to implement the tool. * * @throws Exception if an error occurs */ protected abstract void doRun() throws Exception; //------------------------------------------------------------------------- /** * Gets the source remote component factory. * * @return the source remote component factory, not null during {@code doRun} */ protected RemoteComponentFactory getSourceRemoteComponentFactory() { return _srcRemoteComponentFactory; } /** * Gets the destination remote component factory. * * @return the destination remote component factory, not null during {@code doRun} */ protected RemoteComponentFactory getDestinationRemoteComponentFactory() { return _destRemoteComponentFactory; } /** * Gets the parsed command line. * * @return the parsed command line, not null after parsing */ protected CommandLine getCommandLine() { return _commandLine; } //------------------------------------------------------------------------- /** * Creates the command line options. * <p> * Subclasses may override this and add their own parameters. The base class defined the options h/help, c/config, l/logback. * * @return the set of command line options, not null */ protected Options createOptions() { Options options = new Options(); options.addOption(createHelpOption()); options.addOption(createSourceComponentServerOption()); options.addOption(createDestinationComponentServerOption()); options.addOption(createLogbackOption()); return options; } private static Option createHelpOption() { return new Option(HELP_OPTION, "help", false, "prints this message"); } private static Option createSourceComponentServerOption() { Option option = new Option(SRC_COMPONENT_SERVER_URI_OPTION, "source-component-server", true, "the source component server, host[:port]"); option.setArgName("source component server"); option.setRequired(true); return option; } private static Option createDestinationComponentServerOption() { Option option = new Option(DEST_COMPONENT_SERVER_URI_OPTION, "destination-component-server", true, "the destination component server, host[:port]"); option.setArgName("source component server"); option.setRequired(true); return option; } private static Option createLogbackOption() { Option option = new Option(LOGBACK_RESOURCE_OPTION, "logback", true, "the logback configuration resource"); option.setArgName("resource"); option.setRequired(false); return option; } protected Class<?> getEntryPointClass() { return getClass(); } private void usage(Options options) { HelpFormatter formatter = new HelpFormatter(); formatter.setWidth(120); formatter.printHelp("java " + getEntryPointClass().getName(), options, true); } //------------------------------------------------------------------------- private String resolveComponentServerUri(String componentServerUri) { componentServerUri = componentServerUri.trim(); if (componentServerUri.contains("/")) { // Assume it's the full URI return componentServerUri; } else { // Assume it's host[:port] return "http://" + componentServerUri + "/jax"; } } }