/** * Copyright (C) 2012-2013 Selventa, Inc. * * This file is part of the OpenBEL Framework. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The OpenBEL Framework is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the OpenBEL Framework. If not, see <http://www.gnu.org/licenses/>. * * Additional Terms under LGPL v3: * * This license does not authorize you and you are prohibited from using the * name, trademarks, service marks, logos or similar indicia of Selventa, Inc., * or, in the discretion of other licensors or authors of the program, the * name, trademarks, service marks, logos or similar indicia of such authors or * licensors, in any marketing or advertising materials relating to your * distribution of the program or any covered product. This restriction does * not waive or limit your obligation to keep intact all copyright notices set * forth in the program as delivered to you. * * If you distribute the program in whole or in part, or any modified version * of the program, and you assume contractual liability to the recipient with * respect to the program or modified version, then you will indemnify the * authors and licensors of the program for any liabilities that these * contractual assumptions directly impose on those licensors and authors. */ package org.openbel.framework.tools.kamstore; import static java.lang.String.format; import static java.util.Arrays.copyOfRange; import static org.apache.commons.lang.StringUtils.join; import static org.openbel.framework.common.BELUtilities.constrainedHashMap; import static org.openbel.framework.common.Strings.SYSTEM_CONFIG_PATH; import static org.openbel.framework.common.cfg.SystemConfiguration.getSystemConfiguration; import static org.openbel.framework.common.enums.ExitCode.GENERAL_FAILURE; import static org.openbel.framework.core.StandardOptions.ARG_SYSCFG; import static org.openbel.framework.core.StandardOptions.LONG_OPT_DEBUG; import static org.openbel.framework.core.StandardOptions.LONG_OPT_SYSCFG; import static org.openbel.framework.core.StandardOptions.SHORT_OPT_VERBOSE; import static org.openbel.framework.core.StandardOptions.SHRT_OPT_SYSCFG; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import java.util.EnumMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.commons.cli.Option; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.openbel.framework.api.KAMStore; import org.openbel.framework.api.KAMStoreException; import org.openbel.framework.api.KAMStoreImpl; import org.openbel.framework.api.Kam; import org.openbel.framework.api.internal.KAMCatalogDao; import org.openbel.framework.api.internal.KAMCatalogDao.KamInfo; import org.openbel.framework.api.internal.KamDbObject; import org.openbel.framework.common.BELUtilities; import org.openbel.framework.common.InvalidArgument; import org.openbel.framework.common.SimpleOutput; import org.openbel.framework.common.cfg.SystemConfiguration; import org.openbel.framework.common.enums.ExitCode; import org.openbel.framework.compiler.kam.KAMStoreSchemaService; import org.openbel.framework.compiler.kam.KAMStoreSchemaServiceImpl; import org.openbel.framework.core.CommandLineApplication; import org.openbel.framework.core.df.DBConnection; import org.openbel.framework.core.df.DatabaseService; import org.openbel.framework.core.df.DatabaseServiceImpl; import org.openbel.framework.tools.pkam.DefaultPKAMSerializationService; import org.openbel.framework.tools.pkam.PKAMSerializationFailure; import org.openbel.framework.tools.pkam.PKAMSerializationService; import org.openbel.framework.tools.rdf.RDFExporter; import org.openbel.framework.tools.xgmml.XGMMLExporter; public final class KamManager extends CommandLineApplication { private static final String KAM_MANAGER_NAME = "Kam Manager"; private static final String KAM_MANAGER_DESC = "Provides utilities to manage the KAM store"; private static final String LONG_OPT_NO_PRESERVE = "no-preserve"; private static final String USAGE_NO_PRESERVE = " [-f | --force | --no-preserve]"; private static final String USAGE_PORTABLE_KAM_TYPE = " [{-t | --type} {kam | KAM}]"; private static final String USAGE_TYPE = " [{-t | --type} {kam | KAM | rdf | RDF | xgmml | XGMML}]"; private static final String KAM_EXTENSION = ".kam"; private static final String XGMML_EXTENSION = ".xgmml"; private static final String N3_EXTENSION = ".n3"; // The name of the program that invoked main() private final String kamManager; // The command option passed to the program private Command command; private String commandStr; // Flags specified by command line options private boolean help, verbose, quiet, debug; // OpenBEL Framework system configuration to use, either default or from a specified // configuration file. private final SystemConfiguration sysconfig; // Objects used by the various commands. They are initialized in setUp() and // destroyed in teardown(). private DatabaseService dbservice; private DBConnection dbConnection; private KAMStore kAMStore; private KAMStoreSchemaService kamSchemaService; private PKAMSerializationService pkamService; private KAMCatalogDao kamCatalogDao; /** * Static main method to launch the KAM Manager tool. * * @param args {@link String String[]} the command-line arguments */ public static void main(String[] args) throws Exception { KamManager app = new KamManager(args); app.run(); } private static String[] withoutKamManagerName(final String[] args) { final int length = args.length; if (length >= 1 && ( "KamManager.sh".equals(args[0]) || "KamManager.cmd".equals(args[0]))) { return copyOfRange(args, 1, length); } return args; } public KamManager(String[] args) { super(withoutKamManagerName(args), false); if ("KamManager.sh".equals(args[0]) || "KamManager.cmd".equals(args[0])) { kamManager = args[0]; } else { kamManager = "KamManager"; } final SimpleOutput reportable = new SimpleOutput(); reportable.setErrorStream(System.err); reportable.setOutputStream(System.out); setReportable(reportable); printApplicationInfo(); initializeSystemConfiguration(); sysconfig = getSystemConfiguration(); // Determine the command that the user wants to use determineCommand(); } private void setUp() throws SQLException, IOException { // Setup a database connector to the KAM Store. dbservice = new DatabaseServiceImpl(); if (verbose || debug) { reportable.output("Using KAM Store URL: " + sysconfig.getKamURL()); reportable .output("Using KAM Store User: " + sysconfig.getKamUser()); } dbConnection = dbservice.dbConnection( sysconfig.getKamURL(), sysconfig.getKamUser(), sysconfig.getKamPassword()); // Connect to the KAM Store. This establishes a connection to the // KAM store database and sets up the system to read and process // KAMs. kAMStore = new KAMStoreImpl(dbConnection); // Set up the KAM Store schemas kamSchemaService = new KAMStoreSchemaServiceImpl(dbservice); // Load the KAM catalog schema, if it doesn't exist (see #88). kamSchemaService.setupKAMCatalogSchema(); if (command == Command.SET_DESCRIPTION || command == Command.RENAME) { kamCatalogDao = new KAMCatalogDao(dbConnection, syscfg.getKamCatalogSchema(), syscfg.getKamSchemaPrefix()); } if (command == Command.IMPORT || command == Command.EXPORT) { pkamService = new DefaultPKAMSerializationService( dbservice, kamSchemaService); } } private void teardown() { // Tears down the KAM store. This removes any cached data and queries if (kAMStore != null) { kAMStore.teardown(); } // Close the DBConnection if (dbConnection != null) { try { final Connection conn = dbConnection.getConnection(); if (conn != null) { conn.close(); } } catch (SQLException e) { // Do nothing. } } dbservice = null; dbConnection = null; kAMStore = null; kamSchemaService = null; pkamService = null; kamCatalogDao = null; } public void run() { // Determine the values of the common options (the constructor has already initialized // some of the options: syscfg (from -s/--system-config-file), command and commandStr // (from one of the command options), and kamManager (which is always the first // argument). verbose = hasOption(SHORT_OPT_VERBOSE); quiet = !verbose && hasOption("q"); // --verbose supersedes --quiet if both are provided debug = hasOption(LONG_OPT_DEBUG); final String[] extraArgs = getExtraneousArguments().toArray(new String[0]); if (help || command == Command.HELP) { // The help command requires no extra arguments, although this is not // enforced since the user seems to be looking for usage help. printHelp(true); } else if (command == Command.IMPORT) { // The import command requires one or two extra arguments: // the KAM file to import and, optionally, the new KAM name. checkExtraArguments(extraArgs, 1, 2); final String pkamPath = extraArgs[0]; // check that the indicated PKAM file exists final File pkamFile = new File(pkamPath); if (!pkamFile.exists()) { reportable.error("KAM file does not exist - " + pkamFile.getAbsolutePath()); bail(ExitCode.GENERAL_FAILURE); } final String kamName = (extraArgs.length > 1 ? extraArgs[1] : null); ExportFormat exportFormat = determineType(); if (exportFormat == null) { exportFormat = inferType(pkamFile); } if (exportFormat == null) { // Assume the default format: portable KAM exportFormat = ExportFormat.PORTABLE_KAM; } final boolean noPreserve = isNoPreserve(); runImportCommand(kamName, pkamFile, exportFormat, noPreserve); if (!quiet) { reportable.output(format("Imported %s file from '%s'.", exportFormat.toString(), pkamPath)); } } else if (command == Command.EXPORT) { // The export command uses two extra arguments: // the name of the KAM to export and an output file name (which can be // a default value if it is not specified). checkExtraArguments(extraArgs, 1, 2); ExportFormat exportFormat = determineType(); if (exportFormat == null) { // Assume the default format: portable KAM exportFormat = ExportFormat.PORTABLE_KAM; } final String kamName = extraArgs[0]; final String outputFilename = (extraArgs.length > 1 ? extraArgs[1] : null); final boolean noPreserve = isNoPreserve(); runExportCommand(kamName, outputFilename, exportFormat, noPreserve); } else if (command == Command.SUMMARIZE) { // The summarize command requires one extra argument: // the name of the KAM to summarize. checkExtraArguments(extraArgs, 1); final String outputFilename = determineOutputFileName(); final String kamName = extraArgs[0]; final boolean noPreserve = isNoPreserve(); runSummarizeCommand(kamName, outputFilename, noPreserve); } else if (command == Command.DELETE) { // The delete command requires one extra argument: // the name of the KAM to delete. checkExtraArguments(extraArgs, 1); final String kamName = extraArgs[0]; runDeleteCommand(kamName); } else if (command == Command.LIST) { // The list command requires zero extra arguments. checkExtraArguments(extraArgs, 0); runListCommand(); } else if (command == Command.SET_DESCRIPTION) { // The set-description command requires two extra arguments: // the name of the KAM and the new description. checkExtraArguments(extraArgs, 2); final String kamName = extraArgs[0]; final String newDescription = extraArgs[1]; runSetDescriptionCommand(kamName, newDescription); } else if (command == Command.RENAME) { // The rename command requires two extra arguments: // the old KAM name and the new KAM name. checkExtraArguments(extraArgs, 2); final String oldKamName = extraArgs[0]; final String newKamName = extraArgs[1]; final boolean noPreserve = isNoPreserve(); runRenameCommand(oldKamName, newKamName, noPreserve); } } private void checkExtraArguments(final String[] extraArgs, final int expectedNumber) { final int extraArgsSize = extraArgs.length; if (extraArgsSize != expectedNumber) { fatal(format( "`%s --%s` expects %s argument%s but received %s.", kamManager, commandStr, (expectedNumber != 0 ? Integer.toString(expectedNumber) : "no"), (expectedNumber != 1 ? "s" : ""), (extraArgsSize == 0 ? "none" : format("%d: '%s'", extraArgsSize, join(extraArgs, "', '"))))); } } private void checkExtraArguments(final String[] extraArgs, final int minNumber, final int maxNumber) { final int extraArgsSize = extraArgs.length; if (extraArgsSize < minNumber) { fatal(format( "`%s --%s` expects at least %d argument%s but received %s.", kamManager, commandStr, minNumber, (minNumber != 1 ? "s" : ""), (extraArgsSize == 0 ? "none" : format("%d: '%s'", extraArgsSize, join(extraArgs, "', '"))))); } else if (extraArgsSize > maxNumber) { fatal(format( "`%s --%s` expects no more than %d argument%s but received %s.", kamManager, commandStr, maxNumber, (maxNumber != 1 ? "s" : ""), (extraArgsSize == 0 ? "none" : format("%d: '%s'", extraArgsSize, join(extraArgs, "', '"))))); } } /* * The following methods determine values for certain command line options: */ /** * Initializes the member variables command, commandStr, and help, according to the command * option specified by the user in the command line. */ private void determineCommand() { command = null; commandStr = null; boolean tooManyCommands = false; for (Command c : Command.values()) { final String alias = c.getAlias(); if (hasOption(alias)) { if (c == Command.HELP) { // `--help` can be a command or just a long option for another command. help = true; } else if (command == null) { // Found a command option command = c; commandStr = alias; } else { tooManyCommands = true; } } } if (tooManyCommands) { command = null; commandStr = null; if (!help) { reportable.error(format( "You must specify only one command (%s).%n", showCommandAliases())); printHelp(true); } } if (help && command == null) { // `--help` is considered as the command if no other command is provided. command = Command.HELP; commandStr = command.getAlias(); } else if (command == null) { // Print usage if no commands were specified printUsage(); reportable.error("\n"); reportable .error("No command option given. Please specify one of: " + showCommandAliases()); end(); } } /** * Converts the -t/--type argument to an ExportFormat. * @return */ private ExportFormat determineType() { ExportFormat exportFormat = null; if (hasOption("t")) { final String value = getOptionValue("t"); exportFormat = ExportFormat.getFormatByLabel(value); if (exportFormat == null) { reportable.error(format( "The KAM file format '%s' is not valid.%n", value)); printHelp(true); } } return exportFormat; } /** * If {@link #determineType} returns {@code null} then this function may be able to determine * an appropriate type of KAM file from its file extension. * @param file * @return */ private static ExportFormat inferType(final File file) { final int index = file.getName().lastIndexOf("."); if (index == -1) { return null; } final String extension = file.getName().substring(index); if (extension.equals(KAM_EXTENSION)) { return ExportFormat.PORTABLE_KAM; } else if (extension.equals(XGMML_EXTENSION)) { return ExportFormat.XGMML; } else if (extension.equals(N3_EXTENSION)) { return ExportFormat.RDF; } else { return null; } } /** * Gets the -o/--output-file option. * @return */ private String determineOutputFileName() { return (hasOption("o") ? getOptionValue("o") : null); } /** * Determines whether -f/--force/--no-preserve was specified on the command line. * @return */ private boolean isNoPreserve() { return hasOption("f") || hasOption(LONG_OPT_NO_PRESERVE); } /* * The following methods are responsible for performing one of the commands. They all: * <ol> * <li>throw no exceptions, and therefore report their own error messages</li> * <li>take the values of the related command line options as method arguments (except for common options)</li> * <li>may utilize the services provided by those objects initialized in {@link setUp} and destroyed in {@link teardown}, and</li> * <li>call {@link setUp} and {@link teardown} before and after performing the command.</li> * </ol> */ private void runImportCommand(final String kamName, final File pkamFile, final ExportFormat exportFormat, final boolean noPreserve) { if (exportFormat != ExportFormat.PORTABLE_KAM) { fatal(format( "`%s --%s` only supports the portable KAM file format.", kamManager, commandStr)); } final String pkamPath = pkamFile.getAbsolutePath(); try { setUp(); // find KAM by name and see if validate preserve option if (kamName != null) { List<KamInfo> kamInfos = kAMStore.getCatalog(); for (KamInfo kamInfo : kamInfos) { if (kamName.equals(kamInfo.getName()) && !noPreserve) { teardown(); fatal("KAM cannot be overridden, specify --" + LONG_OPT_NO_PRESERVE + " to override"); } } } pkamService.deserializeKAM(kamName, pkamPath, noPreserve); } catch (KAMStoreException e) { teardown(); bailOnException(e); } catch (PKAMSerializationFailure e) { teardown(); bailOnException(e); } catch (IllegalStateException e) { // FIXME Hack to catch noPreserve check error thrown from DefaultPKAMSerializationService teardown(); fatal("KAM cannot be overridden, specify --" + LONG_OPT_NO_PRESERVE + " to override"); } catch (SQLException e) { teardown(); bailOnException(e); } catch (IOException e) { teardown(); bailOnException(e); } finally { teardown(); } } private void runExportCommand(final String kamName, String outputFilename, final ExportFormat exportFormat, final boolean noPreserve) { if (kamName == null) { return; } final Kam kam; try { setUp(); kam = kAMStore.getKam(kamName); if (kam == null) { fatal(format("No KAM named \"%s\" exists in the catalog", kamName)); } // establish a default if output path is not set if (outputFilename == null) { outputFilename = kam.getKamInfo().getName() + defaultExtension(exportFormat); } if (!noPreserve && new File(outputFilename).exists()) { teardown(); fatal("File '" + outputFilename + "' exists, specify --" + LONG_OPT_NO_PRESERVE + " to override."); } final String formatString; if (exportFormat == ExportFormat.XGMML) { formatString = "XGMML"; XGMMLExporter.exportKam(kam, kAMStore, outputFilename); } else if (exportFormat == ExportFormat.RDF) { formatString = "RDF"; RDFExporter.exportRdf(kam, kAMStore.getKamInfo(kamName), kAMStore, outputFilename); } else if (exportFormat == ExportFormat.PORTABLE_KAM) { formatString = "portable"; pkamService.serializeKAM(kamName, outputFilename); } else { throw new UnsupportedOperationException(exportFormat.toString() + " is not supported."); } if (!quiet) { reportable.output(format( "Exported '%s' KAM to %s format in '%s'.", kam.getKamInfo().getName(), formatString, outputFilename)); } } catch (PKAMSerializationFailure e) { reportable.error(e.getUserFacingMessage()); } catch (KAMStoreException e) { teardown(); bailOnException(e); } catch (IOException e) { teardown(); bailOnException(e); } catch (InvalidArgument e) { teardown(); bailOnException(e); } catch (SQLException e) { teardown(); bailOnException(e); } finally { teardown(); } } private static String defaultExtension(final ExportFormat type) { switch (type) { case PORTABLE_KAM: return KAM_EXTENSION; case XGMML: return XGMML_EXTENSION; case RDF: return N3_EXTENSION; } throw new UnsupportedOperationException(type.toString() + " is not supported."); } private void runSummarizeCommand(final String kamName, final String outputFilename, final boolean noPreserve) { KamSummaryXHTMLWriter xhtmlWriter = null; try { setUp(); xhtmlWriter = createOutputFileWriter(outputFilename, noPreserve); Kam kam; if (kamName != null) { // Look up the requested KAM and summarize. kam = kAMStore.getKam(kamName); if (kam == null) { fatal(format("No KAM named \"%s\" exists in the catalog", kamName)); } KamSummarizer summarizer = new KamSummarizer(reportable); KamSummary summary = KamSummarizer.summarizeKam(kAMStore, kam); summarizer.printKamSummary(kAMStore, summary); if (xhtmlWriter != null) { xhtmlWriter.write(summary); } } } catch (KAMStoreException e) { teardown(); bailOnException(e); } catch (IOException e) { teardown(); bailOnException(e); } catch (InvalidArgument e) { teardown(); bailOnException(e); } catch (SQLException e) { teardown(); bailOnException(e); } finally { teardown(); if (xhtmlWriter != null) { try { xhtmlWriter.close(); } catch (IOException e) { teardown(); bailOnException(e); } } } } private KamSummaryXHTMLWriter createOutputFileWriter(String outputFilename, final boolean noPreserve) throws IOException { FileWriter writer = null; KamSummaryXHTMLWriter xhtmlWriter = null; if (verbose || debug) { reportable.output("Creating output file: " + outputFilename); } if (!StringUtils.isBlank(outputFilename)) { File outputFile = new File(outputFilename); if (!outputFile.exists() || noPreserve) { writer = new FileWriter(outputFile); xhtmlWriter = new KamSummaryXHTMLWriter(writer); xhtmlWriter.open(); } else { reportable .warning(format( "Output file already exist: %s, specify --%s option to overwrite.", outputFilename, LONG_OPT_NO_PRESERVE)); } } return xhtmlWriter; } private void runDeleteCommand(final String kamName) { try { setUp(); KamInfo kamInfo = kAMStore.getKamInfo(kamName); if (kamInfo != null) { deleteKam(kamInfo, quiet); } else { reportable.warning("No KAM named '" + kamName + "' exists in the catalog."); } } catch (SQLException e) { teardown(); bailOnException(e); } catch (IOException e) { teardown(); bailOnException(e); } catch (KAMStoreException e) { teardown(); bailOnException(e); } finally { teardown(); } } private void deleteKam(final KamInfo kamInfo, final boolean quiet) throws SQLException, IOException { final String kamName = kamInfo.getName(); kamSchemaService.deleteFromKAMCatalog(kamName); final String schemaName = kamInfo.getSchemaName(); boolean deletedSchema = kamSchemaService.deleteKAMStoreSchema(dbConnection, schemaName); if (deletedSchema && !quiet) { reportable.output("The KAM named '" + kamName + "' has been removed."); } else if (!deletedSchema) { reportable .warning("The KAM data was truncated, but the database schema '" + schemaName + "' still exists. The schema deletion must be handled separately in dba-managed configurations."); } } private void runListCommand() { try { setUp(); final List<KamInfo> kamInfos = kAMStore.getCatalog(); // Get a list of all the KAMs available in the KAM store reportable.output("Available KAMs:"); reportable.output("\tName\tLast Compiled\tSchema Name"); reportable.output("\t------\t-------------\t-----------"); for (KamInfo kamInfo : kamInfos) { KamDbObject kamDb = kamInfo.getKamDbObject(); reportable.output(format("\t%s\t%s\t%s", kamDb.getName(), kamDb.getLastCompiled(), kamDb.getSchemaName())); } reportable.output("\n"); } catch (KAMStoreException e) { teardown(); bailOnException(e); } catch (SQLException e) { teardown(); bailOnException(e); } catch (IOException e) { teardown(); bailOnException(e); } finally { teardown(); } } private void runSetDescriptionCommand(final String kamName, final String newDescription) { try { setUp(); final KamInfo kamInfo = kAMStore.getKamInfo(kamName); if (kamInfo != null) { if (!BELUtilities.equals(kamInfo.getDescription(), newDescription)) { final KamDbObject updated = new KamDbObject(kamInfo.getId(), kamInfo.getName(), newDescription, kamInfo.getLastCompiled(), kamInfo.getSchemaName()); kamCatalogDao.saveToCatalog(updated); } } else { reportable.warning("No KAM named '" + kamName + "' exists in the catalog."); } } catch (SQLException e) { teardown(); bailOnException(e); } catch (KAMStoreException e) { teardown(); bailOnException(e); } catch (IOException e) { teardown(); bailOnException(e); } finally { teardown(); } } private void runRenameCommand(final String oldKamName, final String newKamName, final boolean noPreserve) { if (BELUtilities.equals(oldKamName, newKamName)) { return; } try { setUp(); final KamInfo kamInfo = kAMStore.getKamInfo(oldKamName); if (kamInfo != null) { final KamInfo kamInfo2 = kAMStore.getKamInfo(newKamName); if (kamInfo2 != null) { if (noPreserve) { deleteKam(kamInfo2, true); } else { teardown(); fatal(format( "A KAM named '%s' already exists in the KAM store. Specify --%s to override.", newKamName, LONG_OPT_NO_PRESERVE)); } } final KamDbObject updated = new KamDbObject(kamInfo.getId(), newKamName, kamInfo.getDescription(), kamInfo.getLastCompiled(), kamInfo.getSchemaName()); kamCatalogDao.saveToCatalog(updated); } else { reportable.warning("No KAM named '" + oldKamName + "' exists in the catalog."); } } catch (SQLException e) { teardown(); bailOnException(e); } catch (KAMStoreException e) { teardown(); bailOnException(e); } catch (IOException e) { teardown(); bailOnException(e); } finally { teardown(); } } /* * The following are utility methods used for usage and error messages: */ private static String showCommandAliases() { final Command[] commands = Command.values(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < commands.length; ++i) { if (i != 0) { sb.append(", "); if (i == commands.length - 1) { sb.append("or "); } } sb.append("`--"); sb.append(commands[i].getAlias()); sb.append("`"); } return sb.toString(); } private void bailOnException(final Exception e) { final Throwable cause = ExceptionUtils.getRootCause(e); reportable.error("Unable to run " + KAM_MANAGER_NAME); reportable.error("Reason: " + (cause == null ? e.getMessage() : cause.getMessage())); if (debug) { e.printStackTrace(reportable.errorStream()); } bail(GENERAL_FAILURE); } /* * The following are overrides of {@link org.openbel.framework.clf.CommandLineApplication CommandLineApplication}'s methods: */ @Override public String getApplicationName() { return KAM_MANAGER_NAME; } @Override public String getApplicationShortName() { return KAM_MANAGER_NAME; } @Override public String getApplicationDescription() { return KAM_MANAGER_DESC; } @Override public String getUsage() { final StringBuilder bldr = new StringBuilder(); if (command == null || command == Command.HELP) { bldr.append(" {"); final Command[] commands = Command.values(); for (int i = 0; i < commands.length; ++i) { if (commands[i] != Command.HELP) { if (i != 0) { bldr.append(" | "); } bldr.append("--").append(commands[i].getAlias()); } } bldr.append("}"); } else { bldr.append(" --").append(commandStr); if (command == Command.IMPORT) { bldr.append(" <exported KAM file> [<new KAM name>]") .append(USAGE_NO_PRESERVE) .append(USAGE_PORTABLE_KAM_TYPE); } else if (command == Command.EXPORT) { bldr.append(" <KAM name> [<output file name>]") .append(USAGE_NO_PRESERVE).append(USAGE_TYPE); } else if (command == Command.SUMMARIZE || command == Command.DELETE) { bldr.append(" <KAM name>"); } else if (command == Command.SET_DESCRIPTION) { bldr.append(" <KAM name> <new description>"); } else if (command == Command.RENAME) { bldr.append(" <old KAM name> <new KAM name>").append( USAGE_NO_PRESERVE); } } bldr.append(" [-h | --help] [-v | --verbose] [-q | --quiet] [--debug] [{-s | --system-config-file} <OpenBEL Framework configuration file>]"); return bldr.toString(); } private static EnumMap<Command, String> commandToUsageHelp = new EnumMap<Command, String>(Command.class); static { commandToUsageHelp.put(Command.DELETE, "Deletes a KAM from the KAM store."); commandToUsageHelp.put(Command.EXPORT, "Exports a KAM to a file."); commandToUsageHelp.put(Command.IMPORT, "Imports a KAM from a file to a KAM store."); commandToUsageHelp.put(Command.LIST, "Lists the KAMs in a KAM store."); commandToUsageHelp.put(Command.RENAME, "Changes the name of a KAM."); commandToUsageHelp.put(Command.SET_DESCRIPTION, "Changes the description of a KAM."); commandToUsageHelp.put(Command.SUMMARIZE, "Prints summary information for a KAM."); } @Override public List<Option> getCommandLineOptions() { List<Option> options = new LinkedList<Option>(); // Add the long options that serve as the commands for (Command c : Command.values()) { if (c != Command.HELP) { options.add(new Option(null, c.getAlias(), false, "The " + c.getAlias() + " command. " + commandToUsageHelp.get(c))); } } // -f/--force/--no-preserve used for the import, export, and rename commands final String noPreserveHelp = "Optional. Used with the summarize or export commands, if a file with the same name " + "as the output file already exists then it will be overwritten. " + "If used with the import command, if a KAM with the same name as " + "being imported already exists in the KAM store, it will be " + "overwritten. If used with the rename command, if the new name for a KAM " + "is also the name of another KAM in the KAM store, then that KAM " + "will be overwritten.\n" + "The default is always to preserve the existing file or KAM and " + "generate a warning."; options.add(new Option("f", "force", false, "Identical to --no-preserve.")); options.add(new Option(null, LONG_OPT_NO_PRESERVE, false, noPreserveHelp)); // -o/--output-file used to set the file to output XHTML output (for the // summarize command, for example) final String outputFileHelp = "Optional. If present, it indicates the name of the output file " + "to write the summary to. The file will be written as XHTML."; options.add(new Option("o", "output-file", true, outputFileHelp)); // -t/--type used for the import and export commands final String typeHelp = "With the import command, this option specifies the format of the imported KAM file. " + "By default, " + getApplicationShortName() + " infers the format of the KAM file by " + "its extension (" + KAM_EXTENSION + ", " + XGMML_EXTENSION + ", or " + N3_EXTENSION + ").\n" + "With the export command, this option specifies the type of export file to generate. " + "If XGMML the KAM will be exported in XGMML format. If RDF " + "the KAM will be exported as an RDF using N3 format. If KAM " + "is specified, the KAM will be exported in a portable binary " + "format that can be subsequently imported to another KAM store " + "using the " + getApplicationShortName() + " import command. The default is to export to " + "a portable KAM format."; options.add(new Option("t", "type", true, typeHelp)); // Add the options common to all commands: options.add(new Option( "q", "quiet", false, "Enables quiet mode. This mode outputs very little additional information " + "as the application runs.\n" + "The default is to disable quiet mode.")); final Option sOpt = new Option(SHRT_OPT_SYSCFG, LONG_OPT_SYSCFG, true, SYSTEM_CONFIG_PATH); sOpt.setArgName(ARG_SYSCFG); options.add(sOpt); // The base class CommandLineApplication will add the --debug, -h/--help, // and -v/--verbose options. return options; } /* * The following are the Command and ExportFormat enums: */ private static enum Command { IMPORT("import"), EXPORT("export"), SUMMARIZE("summarize"), DELETE("delete"), LIST("list"), SET_DESCRIPTION("set-description"), RENAME("rename"), HELP("help"); private static final Map<String, Command> aliasToCommand; static { aliasToCommand = constrainedHashMap(values().length); for (Command command : values()) { aliasToCommand.put(command.alias, command); } } private String alias; private Command(String alias) { this.alias = alias; } public String getAlias() { return alias; } } /** * ExportFormat represents the supported export formats. */ public static enum ExportFormat { XGMML("xgmml", "XGMML"), RDF("rdf", "RDF"), PORTABLE_KAM("kam", "KAM"); private static final Map<String, ExportFormat> STRINGTOENUM; static { STRINGTOENUM = constrainedHashMap(values().length); for (ExportFormat exportFormat : values()) { for (String label : exportFormat.labels) { STRINGTOENUM.put(label, exportFormat); } } } private final String[] labels; private ExportFormat(final String... labels) { this.labels = labels; } @Override public String toString() { switch (this) { case XGMML: return "XGMML"; case RDF: return "RDF"; case PORTABLE_KAM: return "Portable KAM"; default: throw new UnsupportedOperationException( "ExportFormat." + name() + ".toString() is not supported."); } } public static ExportFormat getFormatByLabel(final String label) { return STRINGTOENUM.get(label); } } }