/* * 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]); } }