/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.command.spi; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import de.rcenvironment.core.command.api.CommandExecutionService; import de.rcenvironment.core.command.common.CommandException; import de.rcenvironment.core.utils.common.StringUtils; import de.rcenvironment.core.utils.common.textstream.TextOutputReceiver; /** * Common base class for {@link TextOutputReceiver}s that display {@link CommandExecutionService} results in an interactive command shell. * Could be expanded with more common methods/features in the future. * * Subclasses must implement {@link #addOutput(String)}, and may optionally override {@link #onStart()} and {@link #onFinished()}. * * @author Robert Mischke */ public abstract class AbstractInteractiveCommandConsole implements TextOutputReceiver { private final CommandExecutionService commandExecutionService; private final Log log = LogFactory.getLog(getClass()); private String commandPrefix; public AbstractInteractiveCommandConsole(CommandExecutionService commandExecutionService) { // default: no command prefix this(commandExecutionService, ""); } public AbstractInteractiveCommandConsole(CommandExecutionService commandExecutionService, String commandPrefix) { this.commandExecutionService = commandExecutionService; this.commandPrefix = commandPrefix; } @Override public void onStart() { // empty default implementation; override as needed } @Override public abstract void addOutput(String line); @Override public void onFinished() { // empty default implementation; override as needed } @Override // note: made final to avoid accidental "custom" implementations; only make non-final if there is a good reason - misc_ro public final void onFatalError(Exception e) { if (e instanceof CommandException) { CommandException ce = (CommandException) e; switch (ce.getType()) { case SYNTAX_ERROR: // do not log anything // log.info(StringUtils.format("Syntax error in command \"%s\"; message=%s", ce.getCommandString(), ce.getMessage())); if (ce.getMessage() != null) { addOutput(StringUtils.format("Syntax error: %s", ce.getMessage())); addOutput(StringUtils.format("Use \"%shelp\" to see all available commands.", commandPrefix)); } else { addOutput(StringUtils.format("Syntax error. Use \"%shelp\" to see all available commands.", commandPrefix)); } break; case UNKNOWN_COMMAND: // do not log anything addOutput(StringUtils.format("Unknown command \"%s\". Use \"%shelp\" to see all available commands.", ce.getCommandString(), commandPrefix)); break; case EXECUTION_ERROR: log.warn(StringUtils.format("Error executing command \"%s\"; message=%s", ce.getCommandString(), ce.getMessage())); if (ce.getMessage() != null) { addOutput(StringUtils.format("Error executing command \"%s\": %s", ce.getCommandString(), ce.getMessage())); } else { addOutput(StringUtils.format("Error executing command \"%s\". " + "No message text available; check the log file for more information.", ce.getCommandString())); } break; case HELP_REQUESTED: // TODO backwards compatibility hack; pass prefix as parameter instead - misc_ro boolean useCommandPrefix = commandPrefix != null && !commandPrefix.isEmpty(); commandExecutionService.printHelpText(useCommandPrefix, ce.shouldPrintDeveloperHelp(), this); break; default: // should never happen log.error("Unhandled CommandException sub-type", e); addOutput("Internal error: Unhandled CommandException sub-type (" + e.toString() + ")"); } } else { log.info("Error during command execution", e); addOutput("Error during command execution (" + e.toString() + "); check log file for details"); } } }