/** * SPINdle (version 2.2.2) * Copyright (C) 2009-2012 NICTA Ltd. * * This file is part of SPINdle project. * * SPINdle 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. * * SPINdle 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 SPINdle. If not, see <http://www.gnu.org/licenses/>. * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory */ package spindle.console.impl; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import com.app.utils.FileManager; import com.app.utils.TextUtilities; import spindle.console.Command; import spindle.console.CommandOption; import spindle.console.Commands; import spindle.console.ConsoleException; import spindle.core.dom.Conclusion; import spindle.core.dom.Theory; import spindle.sys.AppConst; import spindle.sys.ConfigurationException; import spindle.sys.Messages; import spindle.sys.message.ErrorMessage; /** * Base class for command supported in console * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory * @since version 2.0.0 * @since 2011.07.27 * @version Last modified 2012.07.30 */ public abstract class CommandBase implements Command, Comparable<Object> { protected static String LINE_SEPARATOR = FileManager.LINE_SEPARATOR; private static final int TEXT_WIDTH = Commands.TEXT_WIDTH; private String name = null; private String description = null; private boolean isMiscellaneous = false; private boolean isUserCommand = true; private Set<CommandOption> options = null; private Map<String, String> optionsMap = null; private String usage = null; private String cmdStr = null; protected PrintStream out = null; public CommandBase(final String name, final String description, final String usage) { this(name, description, usage, false, true); } public CommandBase(final String name, final String description, final String usage, final boolean isMiscellaneous) { this(name, description, usage, isMiscellaneous, true); } public CommandBase(final String name, final String description, final String usage, final boolean isMiscellaneous, final boolean isUserCommand) { if (null == name || "".equals(name.trim())) throw new IllegalArgumentException(Messages.getErrorMessage(ErrorMessage.CONSOLE_NULL_COMMAND_NAME)); this.name = name.trim(); this.isUserCommand = isUserCommand; this.isMiscellaneous = isMiscellaneous; setDescription(description); setUsage(usage); options = new TreeSet<CommandOption>(); optionsMap = new HashMap<String, String>(); setPrintStream(System.out); } @Override public String getName() { return name; } @Override public boolean isUserCommand() { return isUserCommand; } @Override public boolean isMiscellaneous() { return isMiscellaneous; } @Override public void setDescription(String description) { this.description = (null == description) ? "" : description.trim(); } @Override public String getDescription() { return description; } @Override public void setUsage(String usage) { this.usage = usage; } @Override public String getUsage() { if (null == cmdStr) { StringBuilder sb = new StringBuilder(); sb.append("Command: ").append(name).append(LINE_SEPARATOR); if (!"".equals(usage)) { int c = 0; sb.append(LINE_SEPARATOR).append("Usage: "); for (String s : usage.split("\n")) { if (c++ > 0) sb.append(" "); sb.append(s.trim()).append(LINE_SEPARATOR); } } if (!"".equals(description)) { sb.append(LINE_SEPARATOR)// .append("Description").append(LINE_SEPARATOR).append("-----------")// .append(LINE_SEPARATOR).append(TextUtilities.trimTextWithWidth(description, TEXT_WIDTH)).append(LINE_SEPARATOR); } if (options.size() > 0) { List<List<String>> optionTextList = new ArrayList<List<String>>(); int maxArgsLen = 0, l = 0; for (CommandOption option : options) { if (!"".equals(option.getName())) { List<String> optionText = new ArrayList<String>(); optionText.add(""); optionText.add(option.getOptionWithArgs()); optionText.add(option.getDescription()); optionTextList.add(optionText); l = option.getOptionWithArgs().length(); if (l > maxArgsLen) maxArgsLen = l; } } if (optionTextList.size() > 0) { String[][] text = new String[optionTextList.size()][3]; for (int i = 0; i < optionTextList.size(); i++) { optionTextList.get(i).toArray(text[i]); } String[] header = { "", "", "" }; int[] sep = { 0, Commands.COMMAND_ARGS_DESCRIPTION_SEP }; int descriptionWidth = TEXT_WIDTH - AppConst.IDENTATOR.length() - maxArgsLen; for (int s : sep) descriptionWidth -= s; int[] columnWidth = { AppConst.IDENTATOR.length(), maxArgsLen, descriptionWidth }; sb.append(LINE_SEPARATOR).append("Option(s)").append(LINE_SEPARATOR).append("---------").append(LINE_SEPARATOR); sb.append(TextUtilities.generateColumnText(header, text, columnWidth, sep, "", "")); sb.append(LINE_SEPARATOR); } } cmdStr = sb.toString(); } return cmdStr; } @Override public Set<CommandOption> getOptions() { return options; } @Override public int compareTo(Object o) { if (this == o) return 0; if (o instanceof CommandBase) { CommandBase cmd = (CommandBase) o; int c = (name.compareTo(cmd.name)); if (c != 0) return c; if (options.size() != cmd.options.size()) return options.size() - cmd.options.size(); for (CommandOption commandOption : options) { if (!cmd.options.contains(commandOption)) return Integer.MAX_VALUE; } return 0; } return toString().compareTo(o.toString()); } protected void addOption(CommandOption option) { options.add(option); if ("".equals(option.getName())) return; String name = option.getName(); String shortcut = (name.length() > Commands.SHORT_CUT_CHARACTORS_LENGTH) ? name.substring(0, Commands.SHORT_CUT_CHARACTORS_LENGTH) : name; optionsMap.put(name, name); optionsMap.put(shortcut, name); } public String getOptionName(String name) { return optionsMap.get(name); } public String toString() { StringBuilder sb = new StringBuilder(); sb.append(name); if (options.size() == 0) { sb.append("\t").append(description); } else { int maxLen = 0; for (CommandOption option : options) { if (!"".equals(option.getName()) && option.getName().length() > maxLen) maxLen = option.getName().length(); } for (CommandOption option : options) { if (!"".equals(option.getName())) { sb.append(LINE_SEPARATOR).append(AppConst.IDENTATOR).append(option.getName()).append(" \t").append(option.getDescription()); } } } return sb.toString(); } public void setPrintStream(final PrintStream out) { if (null != out) this.out = out; } protected void printConsoleMessage(String messageTag) { printConsoleMessage(messageTag, null, true); } protected void printConsoleMessage(String messageTag, Object[] args) { printConsoleMessage(messageTag, args, true); } protected void printConsoleMessage(String messageTag, Object[] args, boolean withLineBreak) { if (null == out) return; if (withLineBreak) out.println(Messages.getSystemMessage(messageTag, args)); else out.print(Messages.getSystemMessage(messageTag, args)); } public abstract Object execute(Theory theory, List<Conclusion> conclusions, List<String> args) // throws ConfigurationException, ConsoleException; public abstract Object execute(String option, Theory theory, List<Conclusion> conclusions, List<String> args) // throws ConfigurationException, ConsoleException; }