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     */
017    package org.apache.camel.util;
018    
019    import java.util.ArrayList;
020    import java.util.List;
021    
022    /**
023     * Utility class for parsing quoted string which is intended for parameters, separated by comma.
024     */
025    public final class StringQuoteHelper {
026    
027        private StringQuoteHelper() {
028        }
029    
030        /**
031         * Splits the input safely honoring if values is enclosed in quotes.
032         * <p/>
033         * Though this method does not support double quoting values. A quoted value
034         * must start with the same start and ending quote, which is either a single
035         * quote or double quote value.
036         * <p/>
037         * Will <i>trim</i> each splitted value by default.
038         *
039         * @param input    the input
040         * @param separator the separator char to split the input, for example a comma.
041         * @return the input splitted, or <tt>null</tt> if the input is null.
042         */
043        public static String[] splitSafeQuote(String input, char separator) {
044            return splitSafeQuote(input, separator, true);
045        }
046    
047        /**
048         * Splits the input safely honoring if values is enclosed in quotes.
049         * <p/>
050         * Though this method does not support double quoting values. A quoted value
051         * must start with the same start and ending quote, which is either a single
052         * quote or double quote value.
053         * \
054         * @param input    the input
055         * @param separator the separator char to split the input, for example a comma.
056         * @param trim      whether to trim each splitted value
057         * @return the input splitted, or <tt>null</tt> if the input is null.
058         */
059        public static String[] splitSafeQuote(String input, char separator, boolean trim) {
060            if (input == null) {
061                return null;
062            }
063    
064            List<String> answer = new ArrayList<String>();
065            StringBuilder sb = new StringBuilder();
066    
067            boolean singleQuoted = false;
068            boolean doubleQuoted = false;
069    
070            for (int i = 0; i < input.length(); i++) {
071                char ch = input.charAt(i);
072    
073                if (ch == '\'') {
074                    singleQuoted = !singleQuoted;
075                    continue;
076                } else if (ch == '"') {
077                    doubleQuoted = !doubleQuoted;
078                    continue;
079                } else if (ch == separator) {
080                    // add as answer if we are not in a quote
081                    if (!singleQuoted && !doubleQuoted && sb.length() > 0) {
082                        String text = sb.toString();
083                        if (trim) {
084                            text = text.trim();
085                        }
086                        answer.add(text);
087                        sb.setLength(0);
088                        continue;
089                    }
090                }
091    
092                sb.append(ch);
093            }
094    
095            // any leftover
096            if (sb.length() > 0) {
097                String text = sb.toString();
098                if (trim) {
099                    text = text.trim();
100                }
101                answer.add(text);
102            }
103    
104            return answer.toArray(new String[answer.size()]);
105        }
106    
107    }