001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.util; 018 019import java.util.ArrayList; 020import java.util.List; 021 022/** 023 * Utility class for parsing quoted string which is intended for parameters, separated by comma. 024 */ 025public final class StringQuoteHelper { 026 027 private StringQuoteHelper() { 028 } 029 030 /** 031 * Returns the text wrapped double quotes 032 */ 033 public static String doubleQuote(String text) { 034 return quote(text, "\""); 035 } 036 037 /** 038 * Returns the text wrapped single quotes 039 */ 040 public static String singleQuote(String text) { 041 return quote(text, "'"); 042 } 043 044 /** 045 * Wraps the text in the given quote text 046 * 047 * @param text the text to wrap in quotes 048 * @param quote the quote text added to the prefix and postfix of the text 049 * 050 * @return the text wrapped in the given quotes 051 */ 052 public static String quote(String text, String quote) { 053 return quote + text + quote; 054 } 055 056 057 /** 058 * Splits the input safely honoring if values is enclosed in quotes. 059 * <p/> 060 * Though this method does not support double quoting values. A quoted value 061 * must start with the same start and ending quote, which is either a single 062 * quote or double quote value. 063 * <p/> 064 * Will <i>trim</i> each splitted value by default. 065 * 066 * @param input the input 067 * @param separator the separator char to split the input, for example a comma. 068 * @return the input splitted, or <tt>null</tt> if the input is null. 069 */ 070 public static String[] splitSafeQuote(String input, char separator) { 071 return splitSafeQuote(input, separator, true); 072 } 073 074 /** 075 * Splits the input safely honoring if values is enclosed in quotes. 076 * <p/> 077 * Though this method does not support double quoting values. A quoted value 078 * must start with the same start and ending quote, which is either a single 079 * quote or double quote value. 080 * \ 081 * @param input the input 082 * @param separator the separator char to split the input, for example a comma. 083 * @param trim whether to trim each splitted value 084 * @return the input splitted, or <tt>null</tt> if the input is null. 085 */ 086 public static String[] splitSafeQuote(String input, char separator, boolean trim) { 087 if (input == null) { 088 return null; 089 } 090 091 if (input.indexOf(separator) == -1) { 092 // no separator in data, so return single string with input as is 093 return new String[]{trim ? input.trim() : input}; 094 } 095 096 List<String> answer = new ArrayList<String>(); 097 StringBuilder sb = new StringBuilder(); 098 099 boolean singleQuoted = false; 100 boolean doubleQuoted = false; 101 boolean skipLeadingWhitespace = true; 102 103 for (int i = 0; i < input.length(); i++) { 104 char ch = input.charAt(i); 105 char prev = i > 0 ? input.charAt(i - 1) : 0; 106 boolean isQuoting = singleQuoted || doubleQuoted; 107 108 if (!doubleQuoted && ch == '\'') { 109 if (singleQuoted && prev == ch && sb.length() == 0) { 110 // its an empty quote so add empty text 111 answer.add(""); 112 } 113 // special logic needed if this quote is the end 114 if (i == input.length() - 1) { 115 if (singleQuoted && sb.length() > 0) { 116 String text = sb.toString(); 117 // do not trim a quoted string 118 answer.add(text); 119 sb.setLength(0); 120 } 121 } 122 singleQuoted = !singleQuoted; 123 continue; 124 } else if (!singleQuoted && ch == '"') { 125 if (doubleQuoted && prev == ch && sb.length() == 0) { 126 // its an empty quote so add empty text 127 answer.add(""); 128 } 129 // special logic needed if this quote is the end 130 if (i == input.length() - 1) { 131 if (doubleQuoted && sb.length() > 0) { 132 String text = sb.toString(); 133 // do not trim a quoted string 134 answer.add(text); 135 sb.setLength(0); 136 } 137 } 138 doubleQuoted = !doubleQuoted; 139 continue; 140 } else if (!isQuoting && ch == ' ') { 141 if (skipLeadingWhitespace) { 142 continue; 143 } 144 } else if (!isQuoting && ch == separator) { 145 // add as answer if we are not in a quote 146 if (sb.length() > 0) { 147 String text = sb.toString(); 148 if (trim) { 149 text = text.trim(); 150 } 151 answer.add(text); 152 sb.setLength(0); 153 } 154 // we should avoid adding the separator 155 continue; 156 } 157 158 sb.append(ch); 159 } 160 161 // any leftover 162 if (sb.length() > 0) { 163 String text = sb.toString(); 164 if (trim) { 165 text = text.trim(); 166 } 167 answer.add(text); 168 } 169 170 return answer.toArray(new String[answer.size()]); 171 } 172 173}