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
015package 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
026public 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}