http://git-wip-us.apache.org/repos/asf/geode/blob/1fc0f0ca/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/Preprocessor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/Preprocessor.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/Preprocessor.java deleted file mode 100644 index 0dd875a..0000000 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/parser/preprocessor/Preprocessor.java +++ /dev/null @@ -1,151 +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; - -import org.apache.geode.management.internal.cli.parser.SyntaxConstants; - -/** - * - * <code><br></code> This Class will serve the same purpose as pre-processors do during compilation - * of a program. - * - * It will act as pre-processor for jopt. - * - * It will split the user input into an array of strings as per the specifications of the command - * for e.g; Different command might require different value separators, different value specifiers - * and many more customizations - * - * @since GemFire 7.0 - * - */ -public class Preprocessor { - private static final String VALUE_SPECIFIER = SyntaxConstants.OPTION_VALUE_SPECIFIER; - private static final String ARGUMENT_SEPARATOR = SyntaxConstants.ARGUMENT_SEPARATOR; - private static final String OPTION_SEPARATOR = SyntaxConstants.OPTION_SEPARATOR; - private static final String LONG_OPTION_SPECIFIER = SyntaxConstants.LONG_OPTION_SPECIFIER; - private static final String OPTION_DELIMITER = OPTION_SEPARATOR + LONG_OPTION_SPECIFIER; - - public static String[] split(final String input) { - if (input == null) { - return null; - } - - final String trimInput = PreprocessorUtils.trim(input).getString(); - final int length = trimInput.length(); - final List<String> returnStrings = new ArrayList<String>(); - - int index = 0; // Current location of the character(s) in the string being examined - int startOfString = 0; // Starting index of the string we're currently parsing and preparing to - // save - - // If this first string doesn't start with the long option specifier, then there are arguments. - // Process the arguments first. - if (!trimInput.regionMatches(index, LONG_OPTION_SPECIFIER, 0, LONG_OPTION_SPECIFIER.length())) { - // Until we find the first occurrence of Option Delimiter (" --") - while (index < length - && !trimInput.regionMatches(index, OPTION_DELIMITER, 0, OPTION_DELIMITER.length())) { - // Anything inside single or double quotes gets ignored - if (trimInput.charAt(index) == '\'' || trimInput.charAt(index) == '\"') { - char charToLookFor = trimInput.charAt(index++); - // Look for the next single or double quote. Those preceded by a '\' character are - // ignored. - while (index < length && (trimInput.charAt(index) != charToLookFor - || trimInput.charAt(index - 1) == '\\')) { - index++; - } - } - - index++; - // 1. There are only arguments & we've reached the end OR - // 2. We are at index where option (" --") has started OR - // 3. One argument has finished & we are now at the next argument - check for Argument - // Separator (" ") - if (index >= length - || trimInput.regionMatches(index, OPTION_DELIMITER, 0, OPTION_DELIMITER.length()) - || trimInput.regionMatches(index, ARGUMENT_SEPARATOR, 0, ARGUMENT_SEPARATOR.length())) { - String stringToAdd = - trimInput.substring(startOfString, (index > length ? length : index)).trim(); - returnStrings.add(stringToAdd); - - if (trimInput.regionMatches(index, ARGUMENT_SEPARATOR, 0, ARGUMENT_SEPARATOR.length())) { - index += ARGUMENT_SEPARATOR.length(); - } - startOfString = index; - } - } - index += OPTION_SEPARATOR.length(); - } - - // Process the options - startOfString = index; - while (index < length) { - // Until we find the first occurrence of Option Separator (" ") or Value Specifier ("=") - while (index < length - && !trimInput.regionMatches(index, OPTION_SEPARATOR, 0, OPTION_SEPARATOR.length()) - && !trimInput.regionMatches(index, VALUE_SPECIFIER, 0, VALUE_SPECIFIER.length())) { - index++; - } - - if (startOfString != index) { - returnStrings.add(trimInput.substring(startOfString, index)); - startOfString = index + 1; - } - - // If value part (starting with "=") has started - if (trimInput.regionMatches(index++, VALUE_SPECIFIER, 0, VALUE_SPECIFIER.length())) { - startOfString = index; - - // Keep going over chars until we find the option separator ("--") - while (index < length - && !trimInput.regionMatches(index, OPTION_SEPARATOR, 0, OPTION_SEPARATOR.length())) { - // Anything inside single or double quotes gets ignored - if (index < length - && (trimInput.charAt(index) == '\'' || trimInput.charAt(index) == '\"')) { - char charToLookFor = trimInput.charAt(index++); - // Look for the next single or double quote. Those preceded by a '\' character are - // ignored. - while (index < length && (trimInput.charAt(index) != charToLookFor - || trimInput.charAt(index - 1) == '\\')) { - index++; - } - } - index++; - } - - // 1. We are done & at the end OR - // 2. There is another word which matches ("--") - if (index >= length - || trimInput.regionMatches(index, OPTION_SEPARATOR, 0, OPTION_SEPARATOR.length())) { - if (startOfString == index) { - // This place-holder value indicates to OptionParser that an option - // was specified without a value. - returnStrings.add("__NULL__"); - } else { - String stringToAdd = - trimInput.substring(startOfString, (index > length ? length : index)); - returnStrings.add(stringToAdd); - } - startOfString = index + 1; - } - index++; - } - } - - return returnStrings.toArray(new String[0]); - } -}
http://git-wip-us.apache.org/repos/asf/geode/blob/1fc0f0ca/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/geode/blob/1fc0f0ca/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/geode/blob/1fc0f0ca/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/geode/blob/1fc0f0ca/geode-core/src/main/java/org/apache/geode/management/internal/cli/remote/CommandProcessor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/remote/CommandProcessor.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/remote/CommandProcessor.java index c346eaf..c2c6e14 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/remote/CommandProcessor.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/remote/CommandProcessor.java @@ -14,27 +14,25 @@ */ package org.apache.geode.management.internal.cli.remote; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.Properties; - import org.apache.geode.internal.security.IntegratedSecurityService; import org.apache.geode.internal.security.SecurityService; import org.apache.geode.management.cli.CommandProcessingException; import org.apache.geode.management.cli.CommandStatement; import org.apache.geode.management.cli.Result; -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.result.ResultBuilder; import org.apache.geode.management.internal.cli.util.CommentSkipHelper; import org.apache.geode.management.internal.security.ResourceOperation; import org.apache.geode.security.NotAuthorizedException; - import org.springframework.shell.core.Parser; import org.springframework.shell.event.ParseResult; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.Properties; + /** * * @@ -42,8 +40,7 @@ import org.springframework.shell.event.ParseResult; */ public class CommandProcessor { protected RemoteExecutionStrategy executionStrategy; - protected Parser parser; - private CommandManager commandManager; + private GfshParser gfshParser; private int lastExecutionStatus; private LogWrapper logWrapper; @@ -59,9 +56,8 @@ public class CommandProcessor { } public CommandProcessor(Properties cacheProperties) throws ClassNotFoundException, IOException { - this.commandManager = CommandManager.getInstance(cacheProperties); + this.gfshParser = new GfshParser(cacheProperties); this.executionStrategy = new RemoteExecutionStrategy(); - this.parser = new GfshParser(commandManager); this.logWrapper = LogWrapper.getInstance(); } @@ -73,7 +69,7 @@ public class CommandProcessor { protected Parser getParser() { synchronized (LOCK) { - return parser; + return gfshParser; } } @@ -178,9 +174,8 @@ public class CommandProcessor { public void stop() { synchronized (LOCK) { - this.commandManager = null; + this.gfshParser = null; this.executionStrategy = null; - this.parser = null; this.isStopped = true; } } http://git-wip-us.apache.org/repos/asf/geode/blob/1fc0f0ca/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 bcf1b41..78921c5 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 @@ -26,11 +26,9 @@ import org.apache.geode.internal.util.SunAPINotFoundException; import org.apache.geode.management.cli.CommandProcessingException; import org.apache.geode.management.cli.Result; import org.apache.geode.management.internal.cli.CliUtil; -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; @@ -42,8 +40,6 @@ import org.apache.geode.management.internal.cli.shell.jline.GfshUnsupportedTermi 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; @@ -65,7 +61,6 @@ 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; @@ -84,7 +79,7 @@ import java.util.logging.Logger; * <p /> * Additionally, this class is used to maintain GemFire SHell (gfsh) specific information like: * environment TODO - * + * * * @since GemFire 7.0 */ @@ -101,13 +96,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 +109,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"; @@ -138,41 +127,39 @@ 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(); + 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); @@ -180,7 +167,7 @@ public class Gfsh extends JLineShell { /** * Create a GemFire shell with console using the specified arguments. - * + * * @param args arguments to be used to create a GemFire shell instance * @throws IOException * @throws ClassNotFoundException @@ -192,7 +179,7 @@ public class Gfsh extends JLineShell { /** * Create a GemFire shell using the specified arguments. Console for user inputs is made available * if <code>launchShell</code> is set to <code>true</code>. - * + * * @param launchShell whether to make Console available * @param args arguments to be used to create a GemFire shell instance or execute command * @throws IOException @@ -219,14 +206,11 @@ public class Gfsh extends JLineShell { // 4. Customized History implementation this.gfshHistory = new GfshHistory(); - // 5. Create CommandManager & load Commands & Converters - this.commandManager = CommandManager.getInstance(); - // 6. Set System Environment here initializeEnvironment(); // 7. Create Roo/SpringShell framework objects this.executionStrategy = new GfshExecutionStrategy(this); - this.parser = new GfshParser(commandManager); + this.parser = new GfshParser(); // 8. Set max History file size setHistorySize(gfshConfig.getHistorySize()); @@ -271,6 +255,195 @@ public class Gfsh extends JLineShell { } } + 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; + } + + 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) { + LogWrapper.getInstance().warning(e.getMessage(), e); + } + } + + public static Gfsh getCurrentInstance() { + if (!SUPPORT_MUTLIPLESHELL) { + return instance; + } else { + return gfshThreadLocal.get(); + } + } + + 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, + final int terminalWidth) { + if (terminalWidth <= 1) { + return string; + } + + final int maxLineLength = terminalWidth - 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(); + } + /** * Initializes default environment variables to default values */ @@ -302,20 +475,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 +543,6 @@ public class Gfsh extends JLineShell { } - //////////////////// JLineShell Class Methods Start ////////////////////////// - //////////////////////// Implemented Methods //////////////////////////////// /** * See findResources in {@link AbstractShell} */ @@ -397,7 +554,7 @@ public class Gfsh extends JLineShell { /** * Returns the {@link ExecutionStrategy} implementation used by this implementation of * {@link AbstractShell}. {@link Gfsh} uses {@link GfshExecutionStrategy}. - * + * * @return ExecutionStrategy used by Gfsh */ @Override @@ -408,19 +565,22 @@ public class Gfsh extends JLineShell { /** * Returns the {@link Parser} implementation used by this implementation of * {@link AbstractShell}.{@link Gfsh} uses {@link GfshParser}. - * + * * @return Parser used by Gfsh */ @Override - protected Parser getParser() { + public Parser getParser() { + return parser; + } + + public GfshParser getGfshParser() { 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'. - * + * * @param line command string to be executed * @return true if execution is successful; false otherwise */ @@ -469,14 +629,6 @@ public class Gfsh extends JLineShell { return reader.readLine(textToPrompt, mask); } - public void add(final CommandMarker command) { - commandManager.add(command); - } - - public void add(final Converter<?> converter) { - commandManager.add(converter); - } - @Override public void printBannerAndWelcome() { printAsInfo(getBanner()); @@ -584,14 +736,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); } @@ -604,7 +748,6 @@ public class Gfsh extends JLineShell { } } - /////// Save multiple-line commands as single line in history - starts /////// @Override protected ConsoleReader createConsoleReader() { ConsoleReader consoleReader = super.createConsoleReader(); @@ -631,15 +774,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 +792,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 */ @@ -684,7 +802,7 @@ public class Gfsh extends JLineShell { /** * Set the last command execution status - * + * * @param lastExecutionStatus last command execution status */ public void setLastExecutionStatus(int lastExecutionStatus) { @@ -801,7 +919,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; List<String> commandList = MultiCommandHelper.getMultipleCommands(linesBufferString); @@ -855,7 +973,7 @@ public class Gfsh extends JLineShell { return result; } - /////////////// For setting shell environment properties START /////////////// + public String setEnvProperty(String propertyName, String propertyValue) { if (propertyName == null || propertyValue == null) { throw new IllegalArgumentException( @@ -885,11 +1003,9 @@ public class Gfsh extends JLineShell { } public boolean isQuietMode() { - // System.out.println(env.get(CliConstants.ENV_APP_QUIET_EXECUTION)); return Boolean.parseBoolean(env.get(ENV_APP_QUIET_EXECUTION)); } - ////////////////// Providing Multiple-line support starts /////////////////// @Override public void promptLoop() { String line = null; @@ -898,7 +1014,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(); @@ -926,39 +1042,10 @@ 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() { return operationInvoker != null && operationInvoker.isConnected() && operationInvoker.isReady(); } @@ -976,66 +1063,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(); @@ -1077,7 +1109,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); } @@ -1120,114 +1152,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 { - // Gfsh gfsh = new Gfsh(); - // String expandProperties = gfsh.expandProperties("execute function - // --id=group-with-arguments-with-result-collector - // --result-collector=management.operations.ops.FunctionOperations$CustomResultCollector - // --arguments=group-with-arguments-with-result-collector --group=managed1"); - //// String expandProperties = gfsh.expandProperties("My name is ${NAME}"); - // System.out.println(expandProperties); - // } catch (ClassNotFoundException e) { - // e.printStackTrace(); - // } catch (IOException e) { - // e.printStackTrace(); - // } - // } } http://git-wip-us.apache.org/repos/asf/geode/blob/1fc0f0ca/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/GfshExecutionStrategy.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/GfshExecutionStrategy.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/GfshExecutionStrategy.java index d74f5d6..7c80e0d 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/GfshExecutionStrategy.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/GfshExecutionStrategy.java @@ -72,12 +72,11 @@ public class GfshExecutionStrategy implements ExecutionStrategy { */ @Override public Object execute(ParseResult parseResult) { - Object result = null; + Result result = null; Method method = parseResult.getMethod(); try { // Check if it's a multi-step command - Method reflectmethod = parseResult.getMethod(); - MultiStepCommand cmd = reflectmethod.getAnnotation(MultiStepCommand.class); + MultiStepCommand cmd = method.getAnnotation(MultiStepCommand.class); if (cmd != null) { return execCLISteps(logWrapper, shell, parseResult); } http://git-wip-us.apache.org/repos/asf/geode/blob/1fc0f0ca/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/geode/blob/1fc0f0ca/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/geode/blob/1fc0f0ca/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..4410fea 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,14 +39,13 @@ public class CommandStringBuilder { buffer = new StringBuffer(command); } - public CommandStringBuilder addArgument(String argument) { - if (hasOptions) { - throw new IllegalStateException( - "Arguments can't be specified after options. Built String is: " + buffer.toString()); + private static String getLineSeparator() { + // Until TestableGfsh issue #46388 is resolved + if (SystemUtils.isWindows()) { + return "\r"; + } else { + return GfshParser.LINE_SEPARATOR; } - buffer.append(ARG_SEPARATOR); - buffer.append(argument); - return this; } public CommandStringBuilder addOption(String option, String value) { @@ -77,20 +75,10 @@ public class CommandStringBuilder { public CommandStringBuilder addNewLine() { buffer.append(SINGLE_SPACE); // add a space before continuation char - buffer.append(SyntaxConstants.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/geode/blob/1fc0f0ca/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/DataCommandsController.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/DataCommandsController.java b/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/DataCommandsController.java index cfe6089..3a8ed82 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/DataCommandsController.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/DataCommandsController.java @@ -14,8 +14,6 @@ */ package org.apache.geode.management.internal.web.controllers; -import java.util.concurrent.Callable; - import org.apache.geode.internal.lang.StringUtils; import org.apache.geode.management.internal.cli.i18n.CliStrings; import org.apache.geode.management.internal.cli.util.CommandStringBuilder; @@ -28,6 +26,8 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.WebRequest; +import java.util.concurrent.Callable; + /** * The DataCommandsController class implements GemFire Management REST API web service endpoints for * the Gfsh Data Commands. @@ -115,7 +115,7 @@ public class DataCommandsController extends AbstractCommandsController { command.addOption(CliStrings.REMOVE__REGION, decode(regionNamePath)); command.addOption(CliStrings.REMOVE__ALL, String.valueOf(allKeys)); - if (hasValue(key)) { + if (key != null) { command.addOption(CliStrings.REMOVE__KEY, key); } http://git-wip-us.apache.org/repos/asf/geode/blob/1fc0f0ca/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/ExportLogController.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/ExportLogController.java b/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/ExportLogController.java index 527e059..604bdee 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/ExportLogController.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/ExportLogController.java @@ -94,7 +94,7 @@ public class ExportLogController extends AbstractCommandsController { } ResponseEntity<InputStreamResource> getResponse(String result) { - // the result is json string from CommandResul + // the result is json string from CommandResult Result commandResult = ResultBuilder.fromJson(result); if (commandResult.getStatus().equals(Result.Status.OK)) { return getOKResponse(commandResult); http://git-wip-us.apache.org/repos/asf/geode/blob/1fc0f0ca/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..3189f9f 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,28 +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.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; +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.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.springframework.shell.core.CommandMarker; @@ -46,6 +35,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 */ @@ -94,9 +85,11 @@ public class CommandManagerJUnitTest { private static final String OPTION3_UNSPECIFIED_DEFAULT_VALUE = "{unspecified default value for option3}"; - @After - public void tearDown() { - CommandManager.clearInstance(); + private CommandManager commandManager; + + @Before + public void before() { + commandManager = new CommandManager(); } /** @@ -104,9 +97,9 @@ public class CommandManagerJUnitTest { */ @Test public void testCommandManagerLoadCommands() throws Exception { - CommandManager commandManager = CommandManager.getInstance(true); assertNotNull(commandManager); - assertNotSame(0, commandManager.getCommands().size()); + assertThat(commandManager.getCommandMarkers().size()).isGreaterThan(0); + assertThat(commandManager.getConverters().size()).isGreaterThan(0); } /** @@ -114,125 +107,23 @@ public class CommandManagerJUnitTest { */ @Test public void testCommandManagerInstance() throws Exception { - CommandManager commandManager = CommandManager.getInstance(true); assertNotNull(commandManager); } /** - * 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 */ @Test public void testCommandManagerLoadPluginCommands() throws Exception { - CommandManager commandManager = CommandManager.getInstance(true); assertNotNull(commandManager); // see META-INF/services/org.springframework.shell.core.CommandMarker service loader file. assertTrue("Should find listed plugin.", - commandManager.getCommands().containsKey("mock plugin command")); + commandManager.getHelper().getCommands().contains("mock plugin command")); assertTrue("Should not find unlisted plugin.", - !commandManager.getCommands().containsKey("mock plugin command unlisted")); + !commandManager.getHelper().getCommands().contains("mock plugin command unlisted")); } /** @@ -244,11 +135,10 @@ 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, - help = ARGUMENT1_HELP, mandatory = true) String argument1, - @CliArgument(name = ARGUMENT2_NAME, argumentContext = ARGUMENT2_CONTEXT, - help = ARGUMENT2_HELP, mandatory = false, - unspecifiedDefaultValue = ARGUMENT2_UNSPECIFIED_DEFAULT_VALUE, + @CliOption(key = ARGUMENT1_NAME, optionContext = ARGUMENT1_CONTEXT, help = ARGUMENT1_HELP, + mandatory = true) String argument1, + @CliOption(key = ARGUMENT2_NAME, optionContext = ARGUMENT2_CONTEXT, help = ARGUMENT2_HELP, + mandatory = false, unspecifiedDefaultValue = ARGUMENT2_UNSPECIFIED_DEFAULT_VALUE, systemProvided = false) String argument2, @CliOption(key = {OPTION1_NAME, OPTION1_SYNONYM}, help = OPTION1_HELP, mandatory = true, optionContext = OPTION1_CONTEXT, @@ -272,18 +162,16 @@ public class CommandManagerJUnitTest { @CliCommand(value = {"testParamConcat"}) @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ) public static Result testParamConcat(@CliOption(key = {"string"}) String string, - @CliOption(key = {"stringArray"}) @CliMetaData(valueSeparator = ",") String[] stringArray, - @CliOption(key = {"stringList"}, optionContext = ConverterHint.STRING_LIST) @CliMetaData( - valueSeparator = ",") List<String> stringList, + @CliOption(key = {"stringArray"}) String[] stringArray, @CliOption(key = {"integer"}) Integer integer, - @CliOption(key = {"colonArray"}) @CliMetaData(valueSeparator = ":") String[] colonArray) { + @CliOption(key = {"colonArray"}) String[] colonArray) { return null; } @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 +188,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
