/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.wicket.util.string;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* An abstract base class for string list implementations. Besides having an implementation for
* IStringSequence (iterator(), get(int index) and size()), an AbstractStringList can be converted
* to a String array or a List of Strings.
* <p>
* The total length of all Strings in the list can be determined by calling totalLength().
* <p>
* Strings or a subset of Strings in the list can be formatted using three join() methods:
* <p>
* <ul>
* <li>join(String) Joins strings together using a given separator
* <li>join() Joins Strings using comma as a separator
* <li>join(int first, int last, String) Joins a sublist of strings using a given separator
* </ul>
*
* @author Jonathan Locke
*/
public abstract class AbstractStringList implements IStringSequence, Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* @return String iterator
* @see org.apache.wicket.util.string.IStringSequence#iterator()
*/
@Override
public abstract IStringIterator iterator();
/**
* @return Number of strings in this string list
* @see org.apache.wicket.util.string.IStringSequence#size()
*/
@Override
public abstract int size();
/**
* @param index
* The index into this string list
* @return The string at the given index
* @see org.apache.wicket.util.string.IStringSequence#get(int)
*/
@Override
public abstract String get(int index);
/**
* Returns this String sequence as an array of Strings. Subclasses may provide a more efficient
* implementation than the one provided here.
*
* @return An array containing exactly this sequence of Strings
*/
public String[] toArray()
{
// Get number of Strings
final int size = size();
// Allocate array
final String[] strings = new String[size];
// Copy string references
for (int i = 0; i < size; i++)
{
strings[i] = get(i);
}
return strings;
}
/**
* Returns this String sequence as an array of Strings. Subclasses may provide a more efficient
* implementation than the one provided here.
*
* @return An array containing exactly this sequence of Strings
*/
public final List<String> toList()
{
// Get number of Strings
final int size = size();
// Allocate list of exactly the right size
final List<String> strings = new ArrayList<>(size);
// Add strings to list
for (int i = 0; i < size; i++)
{
strings.add(get(i));
}
return strings;
}
/**
* @return The total length of all Strings in this sequence.
*/
public int totalLength()
{
// Get number of Strings
final int size = size();
// Add strings to list
int totalLength = 0;
for (int i = 0; i < size; i++)
{
totalLength += get(i).length();
}
return totalLength;
}
/**
* Joins this sequence of strings using a comma separator. For example, if this sequence
* contains [1 2 3], the result of calling this method will be "1, 2, 3".
*
* @return The joined String
*/
public final String join()
{
return join(", ");
}
/**
* Joins this sequence of strings using a separator
*
* @param separator
* The separator to use
* @return The joined String
*/
public final String join(final String separator)
{
return join(0, size(), separator);
}
/**
* Joins this sequence of strings from first index to last using a separator
*
* @param first
* The first index to use, inclusive
* @param last
* The last index to use, exclusive
* @param separator
* The separator to use
* @return The joined String
*/
public final String join(final int first, final int last, final String separator)
{
// Allocate buffer of exactly the right length
final int length = totalLength() + (separator.length() * (Math.max(0, last - first - 1)));
final AppendingStringBuffer buf = new AppendingStringBuffer(length);
// Loop through indexes requested
for (int i = first; i < last; i++)
{
// Add next string
buf.append(get(i));
// Add separator?
if (i != (last - 1))
{
buf.append(separator);
}
}
return buf.toString();
}
/**
* Converts this object to a string representation
*
* @return String version of this object
*/
@Override
public String toString()
{
return "[" + join() + "]";
}
}