http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/809d64d7/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/PreprocessorUtils.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/PreprocessorUtils.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/PreprocessorUtils.java deleted file mode 100644 index a1872c9..0000000 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/PreprocessorUtils.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional information regarding - * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. You may obtain a - * copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ -package org.apache.geode.management.internal.cli.parser.preprocessor; - - -import java.util.regex.Pattern; - -import org.apache.commons.lang.StringUtils; - -import org.apache.geode.internal.lang.SystemUtils; -import org.apache.geode.management.internal.cli.parser.SyntaxConstants; - -/** - * The methods in this class will be used by the {@link Preprocessor} class to perform various - * trivial operations - * - * @since GemFire 7.0 - */ -public class PreprocessorUtils { - - public static TrimmedInput simpleTrim(String input) { - if (input != null) { - // First remove the trailing white spaces, we do not need those - if (!containsOnlyWhiteSpaces(input)) { - input = StringUtils.stripEnd(input, null); - } - String output = input.trim(); - return new TrimmedInput(output, input.length() - output.length()); - } else { - return null; - } - } - - /** - * - * This function will trim the given input string. It will not only remove the spaces and tabs at - * the end but also compress multiple spaces and tabs to a single space - * - * @param input The input string on which the trim operation needs to be performed - * @return String - */ - public static TrimmedInput trim(final String input) { - return trim(input, true); - } - - /** - * - * This function will trim the given input string. It will not only remove the spaces and tabs at - * the end but also compress multiple spaces and tabs to a single space - * - * @param input The input string on which the trim operation needs to be performed - * @param retainLineSeparator whether to retain the line separator. - * - * @return String - */ - public static TrimmedInput trim(final String input, final boolean retainLineSeparator) { - if (input != null) { - String inputCopy = input; - StringBuffer output = new StringBuffer(); - // First remove the trailing white spaces, we do not need those - inputCopy = StringUtils.stripEnd(inputCopy, null); - // As this parser is for optionParsing, we also need to remove - // the trailing optionSpecifiers provided it has previous - // options. Remove the trailing LONG_OPTION_SPECIFIERs - // in a loop. It is necessary to check for previous options for - // the case of non-mandatory arguments. - // "^(.*)(\\s-+)$" - something that ends with a space followed by a series of hyphens. - while (Pattern.matches("^(.*)(\\s-+)$", inputCopy)) { - inputCopy = StringUtils.removeEnd(inputCopy, SyntaxConstants.SHORT_OPTION_SPECIFIER); - - // Again we need to trim the trailing white spaces - // As we are in a loop - inputCopy = StringUtils.stripEnd(inputCopy, null); - } - // Here we made use of the String class function trim to remove the - // space and tabs if any at the - // beginning and the end of the string - int noOfSpacesRemoved = 0; - { - int length = inputCopy.length(); - inputCopy = inputCopy.trim(); - noOfSpacesRemoved += length - inputCopy.length(); - } - // Now we need to compress the multiple spaces and tabs to single space - // and tabs but we also need to ignore the white spaces inside the - // quotes and parentheses - - StringBuffer buffer = new StringBuffer(); - - boolean startWhiteSpace = false; - for (int i = 0; i < inputCopy.length(); i++) { - char ch = inputCopy.charAt(i); - buffer.append(ch); - if (PreprocessorUtils.isWhitespace(ch)) { - if (PreprocessorUtils.isSyntaxValid(buffer.toString())) { - if (startWhiteSpace) { - noOfSpacesRemoved++; - } else { - startWhiteSpace = true; - if (ch == '\n') { - if (retainLineSeparator) { - output.append("\n"); - } - } else { - output.append(" "); - } - } - buffer.delete(0, buffer.length()); - } else { - output.append(ch); - } - } else { - startWhiteSpace = false; - output.append(ch); - } - } - return new TrimmedInput(output.toString(), noOfSpacesRemoved); - } else { - return null; - } - } - - /** - * This function just does the simple job of removing white spaces from the given input string - * - * @param input The input String from which the spaces need to be removed - * @return String - */ - public static String removeWhiteSpaces(String input) { - if (input != null) { - input = trim(input).getString(); - StringBuffer output = new StringBuffer(); - for (int i = 0; i < input.length(); i++) { - char ch = input.charAt(i); - if (PreprocessorUtils.isWhitespace(ch)) { - continue; - } else { - output.append(ch); - } - } - return output.toString(); - } else { - return null; - } - } - - /** - * - * This function will check for the validity of the input provided. - * - * For e.g; '" input"' is valid but '" input' is not a valid input same is the case with input - * like a JSON string - * - * @param input The input string which needs to be checked for proper syntax - * @return Boolean - */ - public static Boolean isSyntaxValid(String input) { - if (input != null) { - // We will need two different stacks one for double quotation - // and the other one for checking brackets - Stack<Character> stack = new Stack<Character>(); - if (input.length() > 0) { - for (int i = 0; i < input.length(); i++) { - char ch = input.charAt(i); - if ('\\' == ch) { - // It means that this is an escape sequence - // So skip the next character as well - i++; - continue; - } - if (isValueEnclosingChar(ch)) { - // First check whether the enclosing character - // is a double quotation. - if (EnclosingCharacters.DOUBLE_QUOTATION == ch) { - Character popped = stack.pop(); - if (popped == EnclosingCharacters.DOUBLE_QUOTATION) { - // Everything is normal - } else { - // We just push both the characters onto the stack - if (popped != null) { - stack.push(popped); - } - stack.push(ch); - } - } else if (EnclosingCharacters.SINGLE_QUOTATION == ch) { - Character popped = stack.pop(); - if (popped == EnclosingCharacters.SINGLE_QUOTATION) { - // Everything is normal - } else { - // We just push both the characters onto the stack - if (popped != null) { - stack.push(popped); - } - stack.push(ch); - } - } else { - if (isOpeningBracket(ch)) { - // If this a opening bracket then just push it onto - // the stack - stack.push(ch); - } else { - // This means that it is a closing bracket. - // Now pop a character form the stack and check - // whether both - // the brackets match each other - Character popped = stack.pop(); - if (matches(popped, ch)) { - // Everything is normal - } else { - return false; - } - } - } - } - } - } - if (stack.isEmpty()) { - return true; - } else { - return false; - } - } else { - return false; - } - } - - private static boolean matches(Character popped, char ch) { - if (popped != null) { - outer: { - if (isOpeningBracket(popped)) { - if (EnclosingCharacters.OPENING_SQUARE_BRACKET == popped) { - if (EnclosingCharacters.CLOSING_SQUARE_BRACKET == ch) { - return true; - } else { - break outer; - } - } - if (EnclosingCharacters.OPENING_CIRCULAR_BRACKET == popped) { - if (EnclosingCharacters.CLOSING_CIRCULAR_BRACKET == ch) { - return true; - } else { - break outer; - } - } - if (EnclosingCharacters.OPENING_CURLY_BRACE == popped) { - if (EnclosingCharacters.CLOSING_CURLY_BRACE == ch) { - return true; - } else { - break outer; - } - } - } - } - return false; - } else { - return false; - } - } - - // Not used at present - @SuppressWarnings("unused") - private static boolean isClosingBracket(char ch) { - if (EnclosingCharacters.CLOSING_SQUARE_BRACKET == ch - || EnclosingCharacters.CLOSING_CIRCULAR_BRACKET == ch - || EnclosingCharacters.CLOSING_CURLY_BRACE == ch) { - return true; - } else { - return false; - } - } - - private static boolean isOpeningBracket(char ch) { - if (EnclosingCharacters.OPENING_SQUARE_BRACKET == ch - || EnclosingCharacters.OPENING_CIRCULAR_BRACKET == ch - || EnclosingCharacters.OPENING_CURLY_BRACE == ch) { - return true; - } else { - return false; - } - } - - private static boolean isValueEnclosingChar(char ch) { - if (EnclosingCharacters.OPENING_SQUARE_BRACKET == ch - || EnclosingCharacters.CLOSING_SQUARE_BRACKET == ch - || EnclosingCharacters.OPENING_CIRCULAR_BRACKET == ch - || EnclosingCharacters.CLOSING_CIRCULAR_BRACKET == ch - || EnclosingCharacters.OPENING_CURLY_BRACE == ch - || EnclosingCharacters.CLOSING_CURLY_BRACE == ch - || EnclosingCharacters.DOUBLE_QUOTATION == ch - || EnclosingCharacters.SINGLE_QUOTATION == ch) { - return true; - } - return false; - } - - public static boolean containsOnlyWhiteSpaces(String input) { - if (input != null) { - for (int i = 0; i < input.length(); i++) { - if (!PreprocessorUtils.isWhitespace(input.charAt(i))) { - return false; - } - } - return true; - } else { - return false; - } - } - - public static boolean isWhitespace(char ch) { - if (ch == ' ' || ch == '\t' || ch == '\n' || (ch == '\r' && SystemUtils.isWindows())) { - return true; - } - return false; - } -}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/809d64d7/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/Stack.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/Stack.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/Stack.java deleted file mode 100644 index ae47723..0000000 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/Stack.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional information regarding - * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. You may obtain a - * copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ -package org.apache.geode.management.internal.cli.parser.preprocessor; - -import java.util.ArrayList; -import java.util.List; - -/** - * Basic Stack implementation, used by {@link PreprocessorUtils#isSyntaxValid(String)} for detecting - * valid syntax - * - * - * @param <T> - */ -public class Stack<T> { - private List<T> list = new ArrayList<T>(); - - public void push(T object) { - list.add(object); - } - - public T pop() { - if (list.size() > 0) { - int length = list.size(); - T object = list.get(length - 1); - list.remove(length - 1); - return object; - } else { - return null; - } - } - - public Boolean isEmpty() { - if (list.size() == 0) { - return true; - } else { - return false; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/809d64d7/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/TrimmedInput.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/TrimmedInput.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/TrimmedInput.java deleted file mode 100644 index 8740f00..0000000 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/TrimmedInput.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more contributor license - * agreements. See the NOTICE file distributed with this work for additional information regarding - * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. You may obtain a - * copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ -package org.apache.geode.management.internal.cli.parser.preprocessor; - -/** - * Used for trimming input before Pre-processing - * - * @since GemFire 7.0 - * - */ -public class TrimmedInput { - private final int noOfSpacesRemoved; - private final String string; - - public TrimmedInput(String string, int noOfSpacesRemoved) { - this.string = string; - this.noOfSpacesRemoved = noOfSpacesRemoved; - } - - public String getString() { - return string; - } - - public int getNoOfSpacesRemoved() { - return noOfSpacesRemoved; - } - - @Override - public String toString() { - return string; - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/809d64d7/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java index c182116..e64338b 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java @@ -14,38 +14,8 @@ */ package org.apache.geode.management.internal.cli.shell; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintStream; -import java.net.URL; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Scanner; -import java.util.Set; -import java.util.TreeMap; -import java.util.logging.Level; -import java.util.logging.LogManager; -import java.util.logging.Logger; - import jline.Terminal; import jline.console.ConsoleReader; -import org.springframework.shell.core.AbstractShell; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.ExecutionStrategy; -import org.springframework.shell.core.ExitShellRequest; -import org.springframework.shell.core.JLineLogHandler; -import org.springframework.shell.core.JLineShell; -import org.springframework.shell.core.Parser; -import org.springframework.shell.event.ShellStatus.Status; - import org.apache.geode.internal.Banner; import org.apache.geode.internal.GemFireVersion; import org.apache.geode.internal.lang.ClassUtils; @@ -59,7 +29,6 @@ import org.apache.geode.management.internal.cli.CommandManager; import org.apache.geode.management.internal.cli.GfshParser; import org.apache.geode.management.internal.cli.LogWrapper; import org.apache.geode.management.internal.cli.i18n.CliStrings; -import org.apache.geode.management.internal.cli.parser.SyntaxConstants; import org.apache.geode.management.internal.cli.result.CommandResult; import org.apache.geode.management.internal.cli.result.CompositeResultData; import org.apache.geode.management.internal.cli.result.CompositeResultData.SectionResultData; @@ -70,6 +39,34 @@ import org.apache.geode.management.internal.cli.shell.jline.GfshHistory; import org.apache.geode.management.internal.cli.shell.jline.GfshUnsupportedTerminal; import org.apache.geode.management.internal.cli.shell.unsafe.GfshSignalHandler; import org.apache.geode.management.internal.cli.util.CommentSkipHelper; +import org.springframework.shell.core.AbstractShell; +import org.springframework.shell.core.CommandMarker; +import org.springframework.shell.core.Converter; +import org.springframework.shell.core.ExecutionStrategy; +import org.springframework.shell.core.ExitShellRequest; +import org.springframework.shell.core.JLineLogHandler; +import org.springframework.shell.core.JLineShell; +import org.springframework.shell.core.Parser; +import org.springframework.shell.event.ShellStatus.Status; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintStream; +import java.net.URL; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.TreeMap; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; /** * Extends an interactive shell provided by @@ -101,13 +98,8 @@ public class Gfsh extends JLineShell { public static final String LINE_INDENT = " "; public static final String LINE_SEPARATOR = System.getProperty("line.separator"); - - private static final String DEFAULT_SECONDARY_PROMPT = ">"; - // Default Window dimensions public static final int DEFAULT_WIDTH = 100; - private static final int DEFAULT_HEIGHT = 100; - public static final String ENV_APP_NAME = "APP_NAME"; public static final String ENV_APP_CONTEXT_PATH = "APP_CONTEXT_PATH"; public static final String ENV_APP_FETCH_SIZE = "APP_FETCH_SIZE"; @@ -119,7 +111,6 @@ public class Gfsh extends JLineShell { public static final String ENV_APP_LOG_FILE = "APP_LOG_FILE"; public static final String ENV_APP_PWD = "APP_PWD"; public static final String ENV_APP_RESULT_VIEWER = "APP_RESULT_VIEWER"; - // Environment Properties taken from the OS public static final String ENV_SYS_USER = "SYS_USER"; public static final String ENV_SYS_USER_HOME = "SYS_USER_HOME"; @@ -129,7 +120,6 @@ public class Gfsh extends JLineShell { public static final String ENV_SYS_OS = "SYS_OS"; public static final String ENV_SYS_OS_LINE_SEPARATOR = "SYS_OS_LINE_SEPARATOR"; public static final String ENV_SYS_GEMFIRE_DIR = "SYS_GEMFIRE_DIR"; - // TODO merge find a better place for these // SSL Configuration properties. keystore/truststore type is not include public static final String SSL_KEYSTORE = "javax.net.ssl.keyStore"; @@ -138,41 +128,41 @@ public class Gfsh extends JLineShell { public static final String SSL_TRUSTSTORE_PASSWORD = "javax.net.ssl.trustStorePassword"; public static final String SSL_ENABLED_CIPHERS = "javax.rmi.ssl.client.enabledCipherSuites"; public static final String SSL_ENABLED_PROTOCOLS = "javax.rmi.ssl.client.enabledProtocols"; + private static final String DEFAULT_SECONDARY_PROMPT = ">"; + private static final int DEFAULT_HEIGHT = 100; + private static final Object INSTANCE_LOCK = new Object(); + //////////////////////// Fields for TestableShell Start ////////////////////// + public static boolean SUPPORT_MUTLIPLESHELL = false; + // private static final String ANIMATION_SLOT = "A"; //see 46072 protected static PrintStream gfshout = System.out; protected static PrintStream gfsherr = System.err; - - // private static final String ANIMATION_SLOT = "A"; //see 46072 - + protected static ThreadLocal<Gfsh> gfshThreadLocal = new ThreadLocal<Gfsh>(); private static Gfsh instance; - private static final Object INSTANCE_LOCK = new Object(); - + // This flag is used to restrict column trimming to table only types + private static ThreadLocal<Boolean> resultTypeTL = new ThreadLocal<Boolean>(); + private static String OS = System.getProperty("os.name").toLowerCase(); private final Map<String, String> env = new TreeMap<String, String>(); private final List<String> readonlyAppEnv = new ArrayList<String>(); - // Map to keep reference to actual user specified Command String // Should always have one value at the max private final Map<String, String> expandedPropCommandsMap = new HashMap<String, String>(); - private final CommandManager commandManager; private final ExecutionStrategy executionStrategy; private final GfshParser parser; - private OperationInvoker operationInvoker; - private int lastExecutionStatus; - private Thread runner; - private boolean debugON; private final LogWrapper gfshFileLogger; private final GfshConfig gfshConfig; private final GfshHistory gfshHistory; private final ANSIHandler ansiHandler; - private Terminal terminal; private final boolean isHeadlessMode; + private OperationInvoker operationInvoker; + private int lastExecutionStatus; + private Thread runner; + private boolean debugON; + private Terminal terminal; private boolean supressScriptCmdOutput; private boolean isScriptRunning; - private AbstractSignalNotificationHandler signalHandler; - // This flag is used to restrict column trimming to table only types - private static ThreadLocal<Boolean> resultTypeTL = new ThreadLocal<Boolean>(); protected Gfsh() throws ClassNotFoundException, IOException { this(null); @@ -253,22 +243,217 @@ public class Gfsh extends JLineShell { this.gfshFileLogger.warning(e.getMessage()); } - // For test code only - if (this.gfshConfig.isTestConfig()) { - instance = this; - } - this.isHeadlessMode = !launchShell; - if (this.isHeadlessMode) { - this.gfshFileLogger.config("Running in headless mode"); - // disable jline terminal - System.setProperty("jline.terminal", GfshUnsupportedTerminal.class.getName()); - env.put(ENV_APP_QUIET_EXECUTION, String.valueOf(true)); - // redirect Internal Java Loggers Now - // When run with shell, this is done on connection. See 'connect' command. - redirectInternalJavaLoggers(); - // AbstractShell.logger - we don't want it to log on screen - LogWrapper.getInstance().setParentFor(logger); + // For test code only + if (this.gfshConfig.isTestConfig()) { + instance = this; + } + this.isHeadlessMode = !launchShell; + if (this.isHeadlessMode) { + this.gfshFileLogger.config("Running in headless mode"); + // disable jline terminal + System.setProperty("jline.terminal", GfshUnsupportedTerminal.class.getName()); + env.put(ENV_APP_QUIET_EXECUTION, String.valueOf(true)); + // redirect Internal Java Loggers Now + // When run with shell, this is done on connection. See 'connect' command. + redirectInternalJavaLoggers(); + // AbstractShell.logger - we don't want it to log on screen + LogWrapper.getInstance().setParentFor(logger); + } + } + + public static Gfsh getInstance(boolean launchShell, String[] args, GfshConfig gfshConfig) + throws ClassNotFoundException, IOException { + if (instance == null) { + synchronized (INSTANCE_LOCK) { + if (instance == null) { + instance = new Gfsh(launchShell, args, gfshConfig); + instance.executeInitFileIfPresent(); + } + } + } + + return instance; + } + + public static boolean isInfoResult() { + if (resultTypeTL.get() == null) { + return false; + } + return resultTypeTL.get(); + } + + public static void println() { + gfshout.println(); + } + + public static <T> void println(T toPrint) { + gfshout.println(toPrint); + } + + public static <T> void print(T toPrint) { + gfshout.print(toPrint); + } + + public static <T> void printlnErr(T toPrint) { + gfsherr.println(toPrint); + } + + // See 46369 + private static String readLine(ConsoleReader reader, String prompt) throws IOException { + String earlierLine = reader.getCursorBuffer().toString(); + String readLine = null; + try { + readLine = reader.readLine(prompt); + } catch (IndexOutOfBoundsException e) { + if (earlierLine.length() == 0) { + reader.println(); + readLine = LINE_SEPARATOR; + reader.getCursorBuffer().cursor = 0; + } else { + readLine = readLine(reader, prompt); + } + } + return readLine; + } + + //////////////////// JLineShell Class Methods Start ////////////////////////// + //////////////////////// Implemented Methods //////////////////////////////// + + private static String removeBackslash(String result) { + if (result.endsWith(GfshParser.CONTINUATION_CHARACTER)) { + result = result.substring(0, result.length() - 1); + } + return result; + } + + public static void redirectInternalJavaLoggers() { + // Do we need to this on re-connect? + LogManager logManager = LogManager.getLogManager(); + + try { + Enumeration<String> loggerNames = logManager.getLoggerNames(); + + while (loggerNames.hasMoreElements()) { + String loggerName = loggerNames.nextElement(); + if (loggerName.startsWith("java.") || loggerName.startsWith("javax.")) { + // System.out.println(loggerName); + Logger javaLogger = logManager.getLogger(loggerName); + /* + * From Java Docs: It is also important to note that the Logger associated with the String + * name may be garbage collected at any time if there is no strong reference to the + * Logger. The caller of this method must check the return value for null in order to + * properly handle the case where the Logger has been garbage collected. + */ + if (javaLogger != null) { + LogWrapper.getInstance().setParentFor(javaLogger); + } + } + } + } catch (SecurityException e) { + // e.printStackTrace(); + LogWrapper.getInstance().warning(e.getMessage(), e); + } + } + + public static Gfsh getCurrentInstance() { + if (!SUPPORT_MUTLIPLESHELL) { + return instance; + } else { + return gfshThreadLocal.get(); + } + } + + //////////////////////// Overridden Behavior ///////////////////////////////// + + private static String extractKey(String input) { + return input.substring("${".length(), input.length() - "}".length()); + } + + public static ConsoleReader getConsoleReader() { + Gfsh gfsh = Gfsh.getCurrentInstance(); + return (gfsh == null ? null : gfsh.reader); + } + + /** + * Take a string and wrap it into multiple lines separated by CliConstants.LINE_SEPARATOR. Lines + * are separated based upon the terminal width, separated on word boundaries and may have extra + * spaces added to provide indentation. + * + * For example: if the terminal width were 5 and the string "123 456789 01234" were passed in with + * an indentation level of 2, then the returned string would be: + * + * <pre> + * 123 + * 45678 + * 9 + * 01234 + * </pre> + * + * @param string String to wrap (add breakpoints and indent) + * @param indentationLevel The number of indentation levels to use. + * @return The wrapped string. + */ + public static String wrapText(final String string, final int indentationLevel) { + Gfsh gfsh = getCurrentInstance(); + if (gfsh == null) { + return string; + } + + final int maxLineLength = gfsh.getTerminalWidth() - 1; + final StringBuffer stringBuf = new StringBuffer(); + int index = 0; + int startOfCurrentLine = 0; + while (index < string.length()) { + // Add the indentation + for (int i = 0; i < indentationLevel; i++) { + stringBuf.append(LINE_INDENT); + } + int currentLineLength = LINE_INDENT.length() * indentationLevel; + + // Find the end of a line: + // 1. If the end of string is reached + // 2. If the width of the terminal has been reached + // 3. If a newline character was found in the string + while (index < string.length() && currentLineLength < maxLineLength + && string.charAt(index) != '\n') { + index++; + currentLineLength++; + } + + // If the line was terminated with a newline character + if (index != string.length() && string.charAt(index) == '\n') { + stringBuf.append(string.substring(startOfCurrentLine, index)); + stringBuf.append(LINE_SEPARATOR); + index++; + startOfCurrentLine = index; + + // If the end of the string was reached or the last character just happened to be a space + // character + } else if (index == string.length() || string.charAt(index) == ' ') { + stringBuf.append(string.substring(startOfCurrentLine, index)); + if (index != string.length()) { + stringBuf.append(LINE_SEPARATOR); + index++; + } + + } else { + final int spaceCharIndex = string.lastIndexOf(" ", index); + + // If no spaces were found then there's no logical wayto split the string + if (spaceCharIndex == -1) { + stringBuf.append(string.substring(startOfCurrentLine, index)).append(LINE_SEPARATOR); + + // Else split the string cleanly between words + } else { + stringBuf.append(string.substring(startOfCurrentLine, spaceCharIndex)) + .append(LINE_SEPARATOR); + index = spaceCharIndex + 1; + } + } + + startOfCurrentLine = index; } + return stringBuf.toString(); } /** @@ -302,20 +487,6 @@ public class Gfsh extends JLineShell { env.put(ENV_APP_RESULT_VIEWER, String.valueOf(DEFAULT_APP_RESULT_VIEWER)); } - public static Gfsh getInstance(boolean launchShell, String[] args, GfshConfig gfshConfig) - throws ClassNotFoundException, IOException { - if (instance == null) { - synchronized (INSTANCE_LOCK) { - if (instance == null) { - instance = new Gfsh(launchShell, args, gfshConfig); - instance.executeInitFileIfPresent(); - } - } - } - - return instance; - } - public AbstractSignalNotificationHandler getSignalHandler() { return signalHandler; } @@ -384,8 +555,6 @@ public class Gfsh extends JLineShell { } - //////////////////// JLineShell Class Methods Start ////////////////////////// - //////////////////////// Implemented Methods //////////////////////////////// /** * See findResources in {@link AbstractShell} */ @@ -412,11 +581,10 @@ public class Gfsh extends JLineShell { * @return Parser used by Gfsh */ @Override - protected Parser getParser() { + public Parser getParser() { return parser; } - //////////////////////// Overridden Behavior ///////////////////////////////// /** * Executes the given command string. We have over-ridden the behavior to extend the original * implementation to store the 'last command execution status'. @@ -477,6 +645,15 @@ public class Gfsh extends JLineShell { commandManager.add(converter); } + // causes instability on MacOS See #46072 + // public void flashMessage(String message) { + // if (reader != null) { + // flash(Level.FINE, message, ANIMATION_SLOT); + // } + // } + /////// Save multiple-line commands as single line in history - ends ///////// + ///////////////////// JLineShell Class Methods End ////////////////////////// + @Override public void printBannerAndWelcome() { printAsInfo(getBanner()); @@ -584,14 +761,6 @@ public class Gfsh extends JLineShell { return false; } - public static boolean isInfoResult() { - if (resultTypeTL.get() == null) - return false; - return resultTypeTL.get(); - } - - private static String OS = System.getProperty("os.name").toLowerCase(); - private boolean isUnix() { return !(OS.indexOf("win") >= 0); } @@ -631,15 +800,6 @@ public class Gfsh extends JLineShell { return getVersion(); } - // causes instability on MacOS See #46072 - // public void flashMessage(String message) { - // if (reader != null) { - // flash(Level.FINE, message, ANIMATION_SLOT); - // } - // } - /////// Save multiple-line commands as single line in history - ends ///////// - ///////////////////// JLineShell Class Methods End ////////////////////////// - public int getTerminalHeight() { return terminal != null ? terminal.getHeight() : DEFAULT_HEIGHT; } @@ -658,22 +818,6 @@ public class Gfsh extends JLineShell { return DEFAULT_WIDTH; } - public static void println() { - gfshout.println(); - } - - public static <T> void println(T toPrint) { - gfshout.println(toPrint); - } - - public static <T> void print(T toPrint) { - gfshout.print(toPrint); - } - - public static <T> void printlnErr(T toPrint) { - gfsherr.println(toPrint); - } - /** * @return the lastExecutionStatus */ @@ -801,7 +945,7 @@ public class Gfsh extends JLineShell { linesBuffer.append(lineWithoutComments); linesBufferString = linesBuffer.toString(); // NOTE: Similar code is in promptLoop() - if (!linesBufferString.endsWith(SyntaxConstants.CONTINUATION_CHARACTER)) { // see 45893 + if (!linesBufferString.endsWith(GfshParser.CONTINUATION_CHARACTER)) { // see 45893 // String command = null; @@ -855,6 +999,9 @@ public class Gfsh extends JLineShell { return result; } + ///////////////// Providing Multiple-line support ends ////////////////////// + + /////////////// For setting shell environment properties END ///////////////// /////////////// For setting shell environment properties START /////////////// public String setEnvProperty(String propertyName, String propertyValue) { @@ -877,6 +1024,7 @@ public class Gfsh extends JLineShell { map.putAll(env); return map; } + //////////////////////// OperationInvoker code END ////////////////////////// @Override public void setPromptPath(String currentContext) { @@ -889,6 +1037,7 @@ public class Gfsh extends JLineShell { // System.out.println(env.get(CliConstants.ENV_APP_QUIET_EXECUTION)); return Boolean.parseBoolean(env.get(ENV_APP_QUIET_EXECUTION)); } + //////////////////////// Fields for TestableShell End //////////////////////// ////////////////// Providing Multiple-line support starts /////////////////// @Override @@ -899,7 +1048,7 @@ public class Gfsh extends JLineShell { gfshHistory.setAutoFlush(false); // NOTE: Similar code is in executeScript() while (exitShellRequest == null && (line = readLine(reader, prompt)) != null) { - if (!line.endsWith(SyntaxConstants.CONTINUATION_CHARACTER)) { // see 45893 + if (!line.endsWith(GfshParser.CONTINUATION_CHARACTER)) { // see 45893 List<String> commandList = MultiCommandHelper.getMultipleCommands(line); for (String cmdLet : commandList) { String trimmedCommand = cmdLet.trim(); @@ -927,37 +1076,9 @@ public class Gfsh extends JLineShell { setShellStatus(Status.SHUTTING_DOWN); } - // See 46369 - private static String readLine(ConsoleReader reader, String prompt) throws IOException { - String earlierLine = reader.getCursorBuffer().toString(); - String readLine = null; - try { - readLine = reader.readLine(prompt); - } catch (IndexOutOfBoundsException e) { - if (earlierLine.length() == 0) { - reader.println(); - readLine = LINE_SEPARATOR; - reader.getCursorBuffer().cursor = 0; - } else { - readLine = readLine(reader, prompt); - } - } - return readLine; - } - - private static String removeBackslash(String result) { - if (result.endsWith(SyntaxConstants.CONTINUATION_CHARACTER)) { - result = result.substring(0, result.length() - 1); - } - return result; - } - String getDefaultSecondaryPrompt() { return ansiHandler.decorateString(DEFAULT_SECONDARY_PROMPT, ANSIStyle.YELLOW); } - ///////////////// Providing Multiple-line support ends ////////////////////// - - /////////////// For setting shell environment properties END ///////////////// /////////////////////// OperationInvoker code START ////////////////////////// public boolean isConnectedAndReady() { @@ -977,66 +1098,11 @@ public class Gfsh extends JLineShell { public void setOperationInvoker(final OperationInvoker operationInvoker) { this.operationInvoker = operationInvoker; } - //////////////////////// OperationInvoker code END ////////////////////////// - - //////////////////////// Fields for TestableShell Start ////////////////////// - public static boolean SUPPORT_MUTLIPLESHELL = false; - protected static ThreadLocal<Gfsh> gfshThreadLocal = new ThreadLocal<Gfsh>(); - //////////////////////// Fields for TestableShell End //////////////////////// - - public static void redirectInternalJavaLoggers() { - // Do we need to this on re-connect? - LogManager logManager = LogManager.getLogManager(); - - try { - Enumeration<String> loggerNames = logManager.getLoggerNames(); - - while (loggerNames.hasMoreElements()) { - String loggerName = loggerNames.nextElement(); - if (loggerName.startsWith("java.") || loggerName.startsWith("javax.")) { - // System.out.println(loggerName); - Logger javaLogger = logManager.getLogger(loggerName); - /* - * From Java Docs: It is also important to note that the Logger associated with the String - * name may be garbage collected at any time if there is no strong reference to the - * Logger. The caller of this method must check the return value for null in order to - * properly handle the case where the Logger has been garbage collected. - */ - if (javaLogger != null) { - LogWrapper.getInstance().setParentFor(javaLogger); - } - } - } - } catch (SecurityException e) { - // e.printStackTrace(); - LogWrapper.getInstance().warning(e.getMessage(), e); - } - } - - public static Gfsh getCurrentInstance() { - if (!SUPPORT_MUTLIPLESHELL) { - return instance; - } else { - return gfshThreadLocal.get(); - } - } - - public String obtainHelp(String userInput, Set<String> requiredCommandNames) { - return parser.obtainHelp(userInput, requiredCommandNames); - } - - public List<String> obtainHelpCommandNames(String userInput) { - return parser.obtainHelpCommandNames(userInput); - } public GfshConfig getGfshConfig() { return this.gfshConfig; } - public List<String> getCommandNames(String matchingWith) { - return parser.getCommandNames(matchingWith); - } - @Override protected String getHistoryFileName() { return gfshConfig.getHistoryFileName(); @@ -1078,7 +1144,7 @@ public class Gfsh extends JLineShell { // contextPath = "." + CliConstants.DEFAULT_APP_CONTEXT_PATH; } - defaultPrompt = MessageFormat.format(defaultPrompt, new Object[] {clusterString, contextPath}); + defaultPrompt = MessageFormat.format(defaultPrompt, clusterString, contextPath); return ansiHandler.decorateString(defaultPrompt, ANSIStyle.YELLOW); } @@ -1122,97 +1188,6 @@ public class Gfsh extends JLineShell { return output; } - private static String extractKey(String input) { - return input.substring("${".length(), input.length() - "}".length()); - } - - public static ConsoleReader getConsoleReader() { - Gfsh gfsh = Gfsh.getCurrentInstance(); - return (gfsh == null ? null : gfsh.reader); - } - - /** - * Take a string and wrap it into multiple lines separated by CliConstants.LINE_SEPARATOR. Lines - * are separated based upon the terminal width, separated on word boundaries and may have extra - * spaces added to provide indentation. - * - * For example: if the terminal width were 5 and the string "123 456789 01234" were passed in with - * an indentation level of 2, then the returned string would be: - * - * <pre> - * 123 - * 45678 - * 9 - * 01234 - * </pre> - * - * @param string String to wrap (add breakpoints and indent) - * @param indentationLevel The number of indentation levels to use. - * @return The wrapped string. - */ - public static String wrapText(final String string, final int indentationLevel) { - Gfsh gfsh = getCurrentInstance(); - if (gfsh == null) { - return string; - } - - final int maxLineLength = gfsh.getTerminalWidth() - 1; - final StringBuffer stringBuf = new StringBuffer(); - int index = 0; - int startOfCurrentLine = 0; - while (index < string.length()) { - // Add the indentation - for (int i = 0; i < indentationLevel; i++) { - stringBuf.append(LINE_INDENT); - } - int currentLineLength = LINE_INDENT.length() * indentationLevel; - - // Find the end of a line: - // 1. If the end of string is reached - // 2. If the width of the terminal has been reached - // 3. If a newline character was found in the string - while (index < string.length() && currentLineLength < maxLineLength - && string.charAt(index) != '\n') { - index++; - currentLineLength++; - } - - // If the line was terminated with a newline character - if (index != string.length() && string.charAt(index) == '\n') { - stringBuf.append(string.substring(startOfCurrentLine, index)); - stringBuf.append(LINE_SEPARATOR); - index++; - startOfCurrentLine = index; - - // If the end of the string was reached or the last character just happened to be a space - // character - } else if (index == string.length() || string.charAt(index) == ' ') { - stringBuf.append(string.substring(startOfCurrentLine, index)); - if (index != string.length()) { - stringBuf.append(LINE_SEPARATOR); - index++; - } - - } else { - final int spaceCharIndex = string.lastIndexOf(" ", index); - - // If no spaces were found then there's no logical wayto split the string - if (spaceCharIndex == -1) { - stringBuf.append(string.substring(startOfCurrentLine, index)).append(LINE_SEPARATOR); - - // Else split the string cleanly between words - } else { - stringBuf.append(string.substring(startOfCurrentLine, spaceCharIndex)) - .append(LINE_SEPARATOR); - index = spaceCharIndex + 1; - } - } - - startOfCurrentLine = index; - } - return stringBuf.toString(); - } - // // for testing only // public static void main(String[] args) { // try { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/809d64d7/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/MultiCommandHelper.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/MultiCommandHelper.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/MultiCommandHelper.java index 89f93d5..9eafff5 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/MultiCommandHelper.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/MultiCommandHelper.java @@ -14,22 +14,18 @@ */ package org.apache.geode.management.internal.cli.shell; +import org.apache.geode.management.internal.cli.GfshParser; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.geode.management.internal.cli.parser.SyntaxConstants; - -/** - * - * - */ public class MultiCommandHelper { public static List<String> getMultipleCommands(String input) { Map<Integer, List<String>> listMap = new HashMap<Integer, List<String>>(); - String as[] = input.split(SyntaxConstants.COMMAND_DELIMITER); + String as[] = input.split(GfshParser.COMMAND_DELIMITER); int splitCount = 0; for (String a : as) { if (a.endsWith("\\")) { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/809d64d7/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/jline/GfshHistory.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/jline/GfshHistory.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/jline/GfshHistory.java index dc4a42f..d0113af 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/jline/GfshHistory.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/jline/GfshHistory.java @@ -14,13 +14,11 @@ */ package org.apache.geode.management.internal.cli.shell.jline; +import jline.console.history.MemoryHistory; + import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.geode.management.internal.cli.parser.preprocessor.PreprocessorUtils; - -import jline.console.history.MemoryHistory; - /** * Overrides jline.History to add History without newline characters. * @@ -35,6 +33,13 @@ public class GfshHistory extends MemoryHistory { // let the history from history file get added initially private boolean autoFlush = true; + public static String redact(String buffer) { + String trimmed = buffer.trim(); + Matcher matcher = passwordRe.matcher(trimmed); + String sanitized = matcher.replaceAll("$1*****"); + return sanitized; + } + public void addToHistory(String buffer) { if (isAutoFlush()) { super.add(redact(buffer)); @@ -48,12 +53,4 @@ public class GfshHistory extends MemoryHistory { public void setAutoFlush(boolean autoFlush) { this.autoFlush = autoFlush; } - - public static String redact(String buffer) { - String trimmed = PreprocessorUtils.trim(buffer, false).getString(); - - Matcher matcher = passwordRe.matcher(trimmed); - String sanitized = matcher.replaceAll("$1*****"); - return sanitized; - } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/809d64d7/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/CommandStringBuilder.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/CommandStringBuilder.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/CommandStringBuilder.java index 16efda5..5dc5584 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/CommandStringBuilder.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/util/CommandStringBuilder.java @@ -17,7 +17,6 @@ package org.apache.geode.management.internal.cli.util; import org.apache.geode.internal.lang.StringUtils; import org.apache.geode.internal.lang.SystemUtils; import org.apache.geode.management.internal.cli.GfshParser; -import org.apache.geode.management.internal.cli.parser.SyntaxConstants; /** @@ -27,10 +26,10 @@ import org.apache.geode.management.internal.cli.parser.SyntaxConstants; * @since GemFire 7.0 */ public class CommandStringBuilder { - private final String OPTION_MARKER = SyntaxConstants.LONG_OPTION_SPECIFIER; - private final String EQUAL_TO = SyntaxConstants.OPTION_VALUE_SPECIFIER; - private final String ARG_SEPARATOR = SyntaxConstants.OPTION_SEPARATOR; - private final String OPTION_SEPARATOR = SyntaxConstants.OPTION_SEPARATOR; + private final String OPTION_MARKER = GfshParser.LONG_OPTION_SPECIFIER; + private final String EQUAL_TO = GfshParser.OPTION_VALUE_SPECIFIER; + private final String ARG_SEPARATOR = GfshParser.OPTION_SEPARATOR; + private final String OPTION_SEPARATOR = GfshParser.OPTION_SEPARATOR; private final String SINGLE_SPACE = " "; private final StringBuffer buffer; @@ -40,6 +39,15 @@ public class CommandStringBuilder { buffer = new StringBuffer(command); } + private static String getLineSeparator() { + // Until TestableGfsh issue #46388 is resolved + if (SystemUtils.isWindows()) { + return "\r"; + } else { + return GfshParser.LINE_SEPARATOR; + } + } + public CommandStringBuilder addArgument(String argument) { if (hasOptions) { throw new IllegalStateException( @@ -77,20 +85,11 @@ public class CommandStringBuilder { public CommandStringBuilder addNewLine() { buffer.append(SINGLE_SPACE); // add a space before continuation char - buffer.append(SyntaxConstants.CONTINUATION_CHARACTER); + buffer.append(GfshParser.CONTINUATION_CHARACTER); buffer.append(getLineSeparator()); return this; } - private static String getLineSeparator() { - // Until TestableGfsh issue #46388 is resolved - if (SystemUtils.isWindows()) { - return "\r"; - } else { - return GfshParser.LINE_SEPARATOR; - } - } - public String getCommandString() { return buffer.toString(); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/809d64d7/geode-core/src/test/java/org/apache/geode/management/internal/cli/CommandManagerJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/CommandManagerJUnitTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/CommandManagerJUnitTest.java index 503ffb2..b7e73c8 100644 --- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/CommandManagerJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/CommandManagerJUnitTest.java @@ -14,27 +14,17 @@ */ package org.apache.geode.management.internal.cli; -import static org.junit.Assert.*; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertTrue; import org.apache.geode.management.cli.CliMetaData; import org.apache.geode.management.cli.ConverterHint; import org.apache.geode.management.cli.Result; -import org.apache.geode.management.internal.cli.annotation.CliArgument; -import org.apache.geode.management.internal.cli.parser.Argument; -import org.apache.geode.management.internal.cli.parser.AvailabilityTarget; -import org.apache.geode.management.internal.cli.parser.CommandTarget; -import org.apache.geode.management.internal.cli.parser.Option; import org.apache.geode.management.internal.security.ResourceOperation; import org.apache.geode.security.ResourcePermission.Operation; import org.apache.geode.security.ResourcePermission.Resource; import org.apache.geode.test.junit.categories.UnitTest; - import org.junit.After; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -46,6 +36,8 @@ import org.springframework.shell.core.annotation.CliAvailabilityIndicator; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; +import java.util.List; + /** * CommandManagerTest - Includes tests to check the CommandManager functions */ @@ -106,7 +98,7 @@ public class CommandManagerJUnitTest { public void testCommandManagerLoadCommands() throws Exception { CommandManager commandManager = CommandManager.getInstance(true); assertNotNull(commandManager); - assertNotSame(0, commandManager.getCommands().size()); + assertNotSame(0, commandManager.getCommandMarkers().size()); } /** @@ -119,106 +111,6 @@ public class CommandManagerJUnitTest { } /** - * tests createOption method for creating option - */ - @Test - public void testCommandManagerCreateOption() throws Exception { - CommandManager commandManager = CommandManager.getInstance(true); - assertNotNull(commandManager); - - Method method = Commands.class.getMethod(COMMAND1_NAME, String.class, String.class, - String.class, String.class, String.class); - - Annotation[][] annotations = method.getParameterAnnotations(); - Class<?>[] parameterTypes = method.getParameterTypes(); - List<String> optionNames = new ArrayList<String>(); - optionNames.add(OPTION1_NAME); - optionNames.add(OPTION2_NAME); - optionNames.add(OPTION3_NAME); - - int parameterNo = 0; - for (int i = 0; i < annotations.length; i++) { - Annotation[] annotation = annotations[i]; - for (Annotation ann : annotation) { - if (ann instanceof CliOption) { - Option createdOption = - commandManager.createOption((CliOption) ann, parameterTypes[i], parameterNo); - assertTrue(optionNames.contains(createdOption.getLongOption())); - assertEquals(((CliOption) ann).help(), createdOption.getHelp()); - if (((CliOption) ann).specifiedDefaultValue() != null - && ((CliOption) ann).specifiedDefaultValue().length() > 0) { - assertEquals(((CliOption) ann).specifiedDefaultValue().trim(), - createdOption.getSpecifiedDefaultValue().trim()); - } - if (((CliOption) ann).unspecifiedDefaultValue() != null - && ((CliOption) ann).unspecifiedDefaultValue().length() > 0) { - assertEquals(((CliOption) ann).specifiedDefaultValue().trim(), - createdOption.getSpecifiedDefaultValue().trim()); - } - - } - } - } - } - - /** - * tests createArgument method for creating argument - */ - @Test - public void testCommandManagerCreateArgument() throws Exception { - CommandManager commandManager = CommandManager.getInstance(true); - assertNotNull(commandManager); - - Method method = Commands.class.getMethod(COMMAND1_NAME, String.class, String.class, - String.class, String.class, String.class); - - Annotation[][] annotations = method.getParameterAnnotations(); - Class<?>[] parameterTypes = method.getParameterTypes(); - List<String> argumentList = new ArrayList<String>(); - argumentList.add(ARGUMENT1_NAME); - argumentList.add(ARGUMENT2_NAME); - - int parameterNo = 0; - for (int i = 0; i < annotations.length; i++) { - Annotation[] annotation = annotations[i]; - for (Annotation ann : annotation) { - if (ann instanceof CliArgument) { - Argument arg = - commandManager.createArgument((CliArgument) ann, parameterTypes[i], parameterNo); - assertEquals(true, argumentList.contains(arg.getArgumentName())); - assertEquals(((CliArgument) ann).mandatory(), arg.isRequired()); - assertEquals(((CliArgument) ann).name().trim(), arg.getArgumentName().trim()); - assertEquals(((CliArgument) ann).argumentContext().trim(), arg.getContext().trim()); - assertEquals(((CliArgument) ann).help().trim(), arg.getHelp().trim()); - } - } - } - } - - /** - * tests availabilityIndicator for a method - */ - @Test - public void testCommandManagerAvailabilityIndicator() throws Exception { - CommandManager commandManager = CommandManager.getInstance(true); - assertNotNull(commandManager); - commandManager.add(Commands.class.newInstance()); - Map<String, CommandTarget> commands = commandManager.getCommands(); - for (String commandName : commands.keySet()) { - if (commandName.equals(COMMAND1_NAME)) { - CommandTarget commandTarget = commands.get(commandName); - AvailabilityTarget availabilityIndicator = commandTarget.getAvailabilityIndicator(); - if (availabilityIndicator == null) { - availabilityIndicator = commandManager.getAvailabilityIndicator(COMMAND1_NAME); - commandTarget.setAvailabilityIndicator(availabilityIndicator); - } - assertEquals(true, commandTarget.isAvailable()); - break; - } - } - } - - /** * Tests {@link CommandManager#loadPluginCommands()}. * * @since GemFire 8.1 @@ -230,9 +122,9 @@ public class CommandManagerJUnitTest { // see META-INF/services/org.springframework.shell.core.CommandMarker service loader file. assertTrue("Should find listed plugin.", - commandManager.getCommands().containsKey("mock plugin command")); + commandManager.getCommandMarkers().contains("mock plugin command")); assertTrue("Should not find unlisted plugin.", - !commandManager.getCommands().containsKey("mock plugin command unlisted")); + !commandManager.getCommandMarkers().contains("mock plugin command unlisted")); } /** @@ -244,9 +136,9 @@ public class CommandManagerJUnitTest { @CliMetaData(shellOnly = true, relatedTopic = {"relatedTopicOfCommand1"}) @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ) public static String command1( - @CliArgument(name = ARGUMENT1_NAME, argumentContext = ARGUMENT1_CONTEXT, + @CliOption(key = ARGUMENT1_NAME, optionContext = ARGUMENT1_CONTEXT, help = ARGUMENT1_HELP, mandatory = true) String argument1, - @CliArgument(name = ARGUMENT2_NAME, argumentContext = ARGUMENT2_CONTEXT, + @CliOption(key = ARGUMENT2_NAME, optionContext = ARGUMENT2_CONTEXT, help = ARGUMENT2_HELP, mandatory = false, unspecifiedDefaultValue = ARGUMENT2_UNSPECIFIED_DEFAULT_VALUE, systemProvided = false) String argument2, @@ -282,8 +174,8 @@ public class CommandManagerJUnitTest { @CliCommand(value = {"testMultiWordArg"}) @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ) - public static Result testMultiWordArg(@CliArgument(name = "arg1") String arg1, - @CliArgument(name = "arg2") String arg2) { + public static Result testMultiWordArg(@CliOption(key = "arg1") String arg1, + @CliOption(key = "arg2") String arg2) { return null; } @@ -300,10 +192,7 @@ public class CommandManagerJUnitTest { @Override public boolean supports(Class<?> type, String optionContext) { - if (type.isAssignableFrom(String.class)) { - return true; - } - return false; + return type.isAssignableFrom(String.class); } @Override http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/809d64d7/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java index f3e3bd8..0122434 100644 --- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java +++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/GfshParserIntegrationTest.java @@ -14,30 +14,40 @@ */ package org.apache.geode.management.internal.cli; -import static org.assertj.core.api.Assertions.*; - -import java.util.Arrays; -import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import org.apache.geode.management.internal.cli.i18n.CliStrings; +import org.apache.geode.test.junit.categories.IntegrationTest; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; +import org.springframework.shell.core.Completion; import org.springframework.shell.event.ParseResult; -import org.apache.geode.test.junit.categories.IntegrationTest; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; @Category(IntegrationTest.class) public class GfshParserIntegrationTest { private CommandManager commandManager; private GfshParser parser; + private List<Completion> candidates; + private String buffer; + private int cursor; @Before public void setUp() throws Exception { CommandManager.clearInstance(); this.commandManager = CommandManager.getInstance(true); this.parser = new GfshParser(commandManager); + this.candidates = new ArrayList<>(); } @After @@ -47,6 +57,7 @@ public class GfshParserIntegrationTest { private Map<String, String> params(String input, String commandName, String commandMethod) { ParseResult parseResult = parser.parse(input); + GfshParseResult gfshParseResult = (GfshParseResult) parseResult; Map<String, String> params = gfshParseResult.getParamValueStrings(); for (String param : params.keySet()) { @@ -55,12 +66,36 @@ public class GfshParserIntegrationTest { assertThat(gfshParseResult.getMethod().getName()).isEqualTo(commandMethod); assertThat(gfshParseResult.getUserInput()).isEqualTo(input.trim()); - assertThat(gfshParseResult.getCommandName()).isEqualTo(commandName); return params; } @Test + public void getSimpleParserInputTest() { + buffer = "start locator --J=\"-Dgemfire.http-service-port=8080\" --name=loc1"; + assertEquals("start locator --J \"-Dgemfire.http-service-port=8080\" --name loc1", + GfshParser.convertToSimpleParserInput(buffer)); + + buffer = "start locator --J=-Dgemfire.http-service-port=8080 --name=loc1 --J=-Ddummythinghere"; + assertEquals( + "start locator --J \"-Dgemfire.http-service-port=8080,-Ddummythinghere\" --name loc1", + GfshParser.convertToSimpleParserInput(buffer)); + + buffer = "start locator --"; + assertEquals("start locator --", GfshParser.convertToSimpleParserInput(buffer)); + + buffer = + "start locator --J=-Dgemfire.http-service-port=8080 --name=loc1 --J=-Ddummythinghere --"; + assertEquals( + "start locator --J \"-Dgemfire.http-service-port=8080,-Ddummythinghere\" --name loc1 --", + GfshParser.convertToSimpleParserInput(buffer)); + + buffer = "start server --name=name1 --locators=localhost --J=-Dfoo=bar"; + assertEquals("start server --name name1 --locators localhost --J \"-Dfoo=bar\"", + GfshParser.convertToSimpleParserInput(buffer)); + } + + @Test public void optionStartsWithHyphenWithoutQuotes() throws Exception { String input = "rebalance --exclude-region=/GemfireDataCommandsDUnitTestRegion2 --simulate=true --time-out=-1"; @@ -68,7 +103,7 @@ public class GfshParserIntegrationTest { assertThat(params.get("exclude-region")).isEqualTo("/GemfireDataCommandsDUnitTestRegion2"); assertThat(params.get("simulate")).isEqualTo("true"); - assertThat(params.get("time-out")).isEqualTo("\"-1\""); + assertThat(params.get("time-out")).isEqualTo("-1"); } @Test @@ -79,7 +114,7 @@ public class GfshParserIntegrationTest { assertThat(params.get("exclude-region")).isEqualTo("/GemfireDataCommandsDUnitTestRegion2"); assertThat(params.get("simulate")).isEqualTo("true"); - assertThat(params.get("time-out")).isEqualTo("\"-1\""); + assertThat(params.get("time-out")).isEqualTo("-1"); } @Test @@ -106,7 +141,7 @@ public class GfshParserIntegrationTest { Map<String, String> params = params(input, "start locator", "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")).isEqualTo("\"-Dgemfire.http-service-port=8080\""); + assertThat(params.get("J")).isEqualTo("-Dgemfire.http-service-port=8080"); } @Test @@ -115,7 +150,7 @@ public class GfshParserIntegrationTest { Map<String, String> params = params(input, "start locator", "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")).isEqualTo("\"-Dgemfire.http-service-port= 8080\""); + assertThat(params.get("J")).isEqualTo("-Dgemfire.http-service-port= 8080"); } @Test @@ -124,7 +159,7 @@ public class GfshParserIntegrationTest { Map<String, String> params = params(input, "start locator", "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")).isEqualTo("\"-Dgemfire.http-service-port=8080\""); + assertThat(params.get("J")).isEqualTo("-Dgemfire.http-service-port=8080"); } @Test @@ -135,7 +170,7 @@ public class GfshParserIntegrationTest { assertThat(params.get("name")).isEqualTo("loc1"); assertThat(params.get("J")) - .isEqualTo("\"-Dgemfire.http-service-port=8080\",\"-Ddummythinghere\""); + .isEqualTo("-Dgemfire.http-service-port=8080,-Ddummythinghere"); } @Test @@ -146,7 +181,7 @@ public class GfshParserIntegrationTest { assertThat(params.get("name")).isEqualTo("loc1"); assertThat(params.get("J")) - .isEqualTo("\"-Dgemfire.http-service-port=8080\",\"-Ddummythinghere\""); + .isEqualTo("-Dgemfire.http-service-port=8080,-Ddummythinghere"); } @Test @@ -156,7 +191,267 @@ public class GfshParserIntegrationTest { Map<String, String> params = params(input, "start locator", "startLocator"); assertThat(params.get("name")).isEqualTo("loc1"); - assertThat(params.get("J")).isEqualTo("\"-Dgemfire.http-service-port=8080\""); + assertThat(params.get("J")).isEqualTo("-Dgemfire.http-service-port=8080"); + } + + @Test + public void testCompleteWithRequiredOption() throws Exception { + candidates = new ArrayList<>(); + buffer = "start server"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(1, candidates.size()); + assertEquals("start server --name", getCompleted(buffer, cursor, candidates.get(0))); + } + + @Test + public void testCompleteWithRequiredOption1() throws Exception { + candidates = new ArrayList<>(); + buffer = "start server "; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(1, candidates.size()); + assertEquals("start server --name", getCompleted(buffer, cursor, candidates.get(0))); + } + + @Test + public void testCompleteCommand() throws Exception { + buffer = "start ser"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(1, candidates.size()); + assertEquals("start server", getCompleted(buffer, cursor, candidates.get(0))); + } + + @Test + public void testCompleteCommand2() throws Exception { + buffer = "start server --name=jinmei --loc"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(3, candidates.size()); + assertTrue(candidates.contains(new Completion("--locators"))); + } + + @Test + public void testComplete1() throws Exception { + buffer = "start "; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(0, cursor); + assertEquals(8, candidates.size()); + assertTrue(candidates.contains(new Completion("start server"))); + } + + @Test + public void testComplete2() throws Exception { + buffer = "start"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(0, cursor); + assertEquals(8, candidates.size()); + assertTrue(candidates.contains(new Completion("start server"))); + } + + @Test + public void testComplete8() throws Exception { + buffer = "start server --name=name1 --se"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals("start server --name=name1 ".length(), cursor); + assertEquals(3, candidates.size()); + assertTrue(candidates.contains(new Completion("--server-port"))); + } + + @Test + public void testComplete8WithExtraSpace() throws Exception { + buffer = "start server --name=name1 --se"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals("start server --name=name1 ".length(), cursor); + assertEquals(3, candidates.size()); + assertTrue(candidates.contains(new Completion("--server-port"))); + } + + @Test + public void testComplete3() throws Exception { + buffer = "start server --name=name1 --"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(26, cursor); + assertEquals(50, candidates.size()); + assertTrue(candidates.contains(new Completion("--properties-file"))); + } + + @Test + public void testComplete4() throws Exception { + buffer = "start server --name=name1 "; + // if there is no more required options, the parser won't display more options unless you typed -- + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals("start server --name=name1 ".length(), cursor); + assertEquals(50, candidates.size()); + assertTrue(candidates.contains(new Completion("--properties-file"))); + + } + + @Test + public void testCompleteJ4() throws Exception { + buffer = "start server --name=name1 --J="; + // if there is no more required options, the parser won't display more options unless you typed -- + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals("start server --name=name1 --J=".length(), cursor); + assertEquals(0, candidates.size()); + } + + @Test + public void testComplete5() throws Exception { + buffer = "start server --name=name1"; + // if there is no more required options, the parser won't display more options unless you typed -- + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(buffer.length(), cursor); + assertEquals(50, candidates.size()); + assertTrue(candidates.contains(new Completion("--properties-file"))); + } + + @Test + public void testComplete6() throws Exception { + buffer = "start server --name=name1 --J"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(buffer.length(), cursor); + assertEquals(0, candidates.size()); + } + + @Test + public void testComplete9() throws Exception { + buffer = "start server --name=name1 --J=-Dfoo.bar --"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(49, candidates.size()); + } + + @Test + public void testComplete10() throws Exception { + buffer = "start server --name=name1 --J=-Dme=her --J=-Dfoo=bar --l"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals("start server --name=name1 --J=-Dme=her --J=-Dfoo=bar ".length(), cursor); + assertEquals(4, candidates.size()); + assertTrue(candidates.contains(new Completion("--locators"))); + } + + @Test + public void testMultiJComplete() throws Exception { + buffer = "start server --name=name1 --J=-Dtest=test1 --J=-Dfoo=bar"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(buffer.length(), cursor); + assertEquals(49, candidates.size()); + assertTrue(candidates.contains(new Completion("--properties-file"))); + } + + @Test + public void testMultiJComplete2() throws Exception { + buffer = "start server --J=-Dtest=test1 --J=-Dfoo=bar --name=name1"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(buffer.length(), cursor); + assertEquals(49, candidates.size()); + assertTrue(candidates.contains(new Completion("--properties-file"))); + } + + @Test + public void testJComplete3() throws Exception { + buffer = "start server --name=name1 --locators=localhost --J=-Dfoo=bar"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals(buffer.length(), cursor); + assertEquals(48, candidates.size()); + } + + @Test + public void testJComplete4() throws Exception { + buffer = "start server --name=name1 --locators=localhost --J=-Dfoo=bar --"; + cursor = parser.completeAdvanced(buffer, 0, candidates); + assertEquals("start server --name=name1 --locators=localhost --J=-Dfoo=bar ".length(), cursor); + assertEquals(48, candidates.size()); + } + + @Test + public void testObtainHelp1() throws Exception { + Set<String> allowedCommands = new HashSet<>(); + allowedCommands.add(CliStrings.ENCRYPT); + allowedCommands.add(CliStrings.RUN); + allowedCommands.add(CliStrings.START_PULSE); + allowedCommands.add(CliStrings.START_JCONSOLE); + allowedCommands.add(CliStrings.START_JVISUALVM); + allowedCommands.add(CliStrings.START_LOCATOR); + allowedCommands.add(CliStrings.START_MANAGER); + allowedCommands.add(CliStrings.START_SERVER); + allowedCommands.add(CliStrings.START_VSD); + allowedCommands.add(CliStrings.STATUS_LOCATOR); + allowedCommands.add(CliStrings.STATUS_SERVER); + allowedCommands.add(CliStrings.STOP_LOCATOR); + allowedCommands.add(CliStrings.STOP_SERVER); + allowedCommands.add(CliStrings.VERSION); + allowedCommands.add(CliStrings.COMPACT_OFFLINE_DISK_STORE); + allowedCommands.add(CliStrings.DESCRIBE_OFFLINE_DISK_STORE); + allowedCommands.add(CliStrings.EXPORT_OFFLINE_DISK_STORE); + allowedCommands.add(CliStrings.VALIDATE_DISK_STORE); + allowedCommands.add(CliStrings.PDX_DELETE_FIELD); + allowedCommands.add(CliStrings.PDX_RENAME); + + String helpString = "compact offline-disk-store\n" + + "Compact an offline disk store. If the disk store is large, additional memory may need to be allocated to the process using the --J=-Xmx??? parameter.\n" + + "describe offline-disk-store\n" + + "Display information about an offline disk store.\n" + + "encrypt password\n" + + "Encrypt a password for use in data source configuration.\n" + + "export offline-disk-store\n" + + "Export region data from an offline disk store into Geode snapshot files.\n" + + "pdx rename\n" + + "Renames PDX types in an offline disk store. \n" + + " Any pdx types that are renamed will be listed in the output. \n" + + " If no renames are done or the disk-store is online then this command will fail.\n" + + "run\n" + + "Execute a set of GFSH commands. Commands that normally prompt for additional input will instead use default values.\n" + + "start jconsole\n" + + "Start the JDK's JConsole tool in a separate process. JConsole will be launched, but connecting to Geode must be done manually.\n" + + "start jvisualvm\n" + + "Start the JDK's Java VisualVM (jvisualvm) tool in a separate process. Java VisualVM will be launched, but connecting to Geode must be done manually.\n" + + "start locator\n" + + "Start a Locator.\n" + + "start pulse\n" + + "Open a new window in the default Web browser with the URL for the Pulse application.\n" + + "start server\n" + + "Start a Geode Cache Server.\n" + + "start vsd\n" + + "Start VSD in a separate process.\n" + + "status locator\n" + + "Display the status of a Locator. Possible statuses are: started, online, offline or not responding.\n" + + "status server\n" + + "Display the status of a Geode Cache Server.\n" + + "stop locator\n" + + "Stop a Locator.\n" + + "stop server\n" + + "Stop a Geode Cache Server.\n" + + "validate offline-disk-store\n" + + "Scan the contents of a disk store to verify that it has no errors.\n" + + "version\n" + + "Display product version information.\n\n"; + assertEquals(helpString, ""); + } + + @Test + public void testObtainHelp2() { + String command = CliStrings.START_PULSE; + String helpString = "NAME\n" + + "start pulse\n" + + "IS AVAILABLE\n" + + "true\n" + + "SYNOPSIS\n" + + "Open a new window in the default Web browser with the URL for the Pulse application.\n" + + "SYNTAX\n" + + "start pulse [--url=value]\n" + + "PARAMETERS\n" + + "url\n" + + "URL of the Pulse Web application.\n" + + "Required: false\n" + + "Default (if the parameter is not specified): http://localhost:7070/pulse\n"; + assertEquals(helpString, ""); + } + + @Test + public void testGetHelp() { + parser.obtainHelp(CliStrings.CREATE_DISK_STORE); + } + + private String getCompleted(String buffer, int cursor, Completion completed) { + return buffer.substring(0, cursor) + completed.getValue(); } }
