001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.util;
016    
017    /**
018     * Used to split a string into substrings based on a single character delimiter.
019     * A fast, simple version of {@link java.util.StringTokenizer}.
020     * 
021     * @author Howard Lewis Ship
022     */
023    
024    public class StringSplitter
025    {
026    
027        private char _delimiter;
028    
029        public StringSplitter(char delimiter)
030        {
031            this._delimiter = delimiter;
032        }
033    
034        public char getDelimiter()
035        {
036            return _delimiter;
037        }
038    
039        /**
040         * Splits a string on the delimter into an array of String tokens. The
041         * delimiters are not included in the tokens. Null tokens (caused by two
042         * consecutive delimiter) are reduced to an empty string. Leading delimiters
043         * are ignored.
044         */
045    
046        public String[] splitToArray(String value)
047        {
048            char[] buffer;
049            int i;
050            String[] result;
051            int resultCount = 0;
052            int start;
053            int length;
054            String token;
055            String[] newResult;
056            boolean first = true;
057    
058            buffer = value.toCharArray();
059    
060            result = new String[3];
061    
062            start = 0;
063            length = 0;
064    
065            for(i = 0; i < buffer.length; i++)
066            {
067                if (buffer[i] != _delimiter)
068                {
069                    length++;
070                    continue;
071                }
072    
073                // This is used to ignore leading delimiter(s).
074    
075                if (length > 0 || !first)
076                {
077                    token = new String(buffer, start, length);
078    
079                    if (resultCount == result.length)
080                    {
081                        newResult = new String[result.length * 2];
082    
083                        System.arraycopy(result, 0, newResult, 0, result.length);
084    
085                        result = newResult;
086                    }
087    
088                    result[resultCount++] = token;
089    
090                    first = false;
091                }
092    
093                start = i + 1;
094                length = 0;
095            }
096    
097            // Special case: if the string contains no delimiters
098            // then it isn't really split. Wrap the input string
099            // in an array and return. This is a little optimization
100            // to prevent a new String instance from being
101            // created unnecessarily.
102    
103            if (start == 0 && length == buffer.length)
104            {
105                result = new String[1];
106                result[0] = value;
107                return result;
108            }
109    
110            // If the string is all delimiters, then this
111            // will result in a single empty token.
112    
113            token = new String(buffer, start, length);
114    
115            newResult = new String[resultCount + 1];
116            System.arraycopy(result, 0, newResult, 0, resultCount);
117            newResult[resultCount] = token;
118    
119            return newResult;
120        }
121    }