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
019     *  delimiter.  A fast, simple version of
020     *  {@link java.util.StringTokenizer}.
021     *
022     *  @author Howard Lewis Ship
023     * 
024     **/
025    
026    public class StringSplitter
027    {
028        private char delimiter;
029    
030        public StringSplitter(char delimiter)
031        {
032            this.delimiter = delimiter;
033        }
034    
035        public char getDelimiter()
036        {
037            return delimiter;
038        }
039    
040        /**
041         *  Splits a string on the delimter into an array of String
042         *  tokens.  The delimiters are not included in the tokens.  Null
043         *  tokens (caused by two consecutive delimiter) are reduced to an
044         *  empty string. Leading delimiters are ignored.
045         *
046         **/
047    
048        public String[] splitToArray(String value)
049        {
050            char[] buffer;
051            int i;
052            String[] result;
053            int resultCount = 0;
054            int start;
055            int length;
056            String token;
057            String[] newResult;
058            boolean first = true;
059    
060            buffer = value.toCharArray();
061    
062            result = new String[3];
063    
064            start = 0;
065            length = 0;
066    
067            for (i = 0; i < buffer.length; i++)
068            {
069                if (buffer[i] != delimiter)
070                {
071                    length++;
072                    continue;
073                }
074    
075                // This is used to ignore leading delimiter(s).
076    
077                if (length > 0 || !first)
078                {
079                    token = new String(buffer, start, length);
080    
081                    if (resultCount == result.length)
082                    {
083                        newResult = new String[result.length * 2];
084    
085                        System.arraycopy(result, 0, newResult, 0, result.length);
086    
087                        result = newResult;
088                    }
089    
090                    result[resultCount++] = token;
091    
092                    first = false;
093                }
094    
095                start = i + 1;
096                length = 0;
097            }
098    
099            // Special case:  if the string contains no delimiters
100            // then it isn't really split.  Wrap the input string
101            // in an array and return.  This is a little optimization
102            // to prevent a new String instance from being
103            // created unnecessarily.
104    
105            if (start == 0 && length == buffer.length)
106            {
107                result = new String[1];
108                result[0] = value;
109                return result;
110            }
111    
112            // If the string is all delimiters, then this
113            // will result in a single empty token.
114    
115            token = new String(buffer, start, length);
116    
117            newResult = new String[resultCount + 1];
118            System.arraycopy(result, 0, newResult, 0, resultCount);
119            newResult[resultCount] = token;
120    
121            return newResult;
122        }
123    }