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.wicket.util.string;
018:
019: import java.util.ArrayList;
020: import java.util.Collection;
021: import java.util.Collections;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.StringTokenizer;
025:
026: /**
027: * A typesafe, mutable list of strings supporting a variety of convenient
028: * operations as well as expected operations from List such as add(), size(),
029: * remove(), iterator(), get(int index) and toArray(). Instances of the class
030: * are not threadsafe.
031: * <p>
032: * StringList objects can be constructed empty or they can be created using any
033: * of several static factory methods:
034: * <ul>
035: * <li>valueOf(String[])
036: * <li>valueOf(String)
037: * <li>valueOf(Collection)
038: * <li>valueOf(Object[])
039: * </ul>
040: * In the case of the Collection and Object[] factory methods, each Object in
041: * the collection or array is converted to a String via toString() before being
042: * added to the StringList.
043: * <p>
044: * The tokenize() factory methods allow easy creation of StringLists via
045: * StringTokenizer. The repeat() static factory method creates a StringList that
046: * repeats a given String a given number of times.
047: * <p>
048: * The prepend() method adds a String to the beginning of the StringList. The
049: * removeLast() method pops a String off the end of the list. The sort() method
050: * sorts strings in the List using Collections.sort(). The class also inherits
051: * useful methods from AbstractStringList that include join() methods ala Perl
052: * and a toString() method which joins the list of strings with comma separators
053: * for easy viewing.
054: *
055: * @author Jonathan Locke
056: */
057: public final class StringList extends AbstractStringList {
058: private static final long serialVersionUID = 1L;
059:
060: // The underlying list of strings
061: private final List strings;
062:
063: // The total length of all strings in the list
064: private int totalLength;
065:
066: /**
067: * Returns a list of a string repeated a given number of times.
068: *
069: * @param count
070: * The number of times to repeat the string
071: * @param string
072: * The string to repeat
073: * @return The list of strings
074: */
075: public static StringList repeat(final int count, final String string) {
076: final StringList list = new StringList(count);
077:
078: for (int i = 0; i < count; i++) {
079: list.add(string);
080: }
081:
082: return list;
083: }
084:
085: /**
086: * Extracts tokens from a comma and space delimited string.
087: *
088: * @param string
089: * The string
090: * @return The string tokens as a list
091: */
092: public static StringList tokenize(final String string) {
093: return tokenize(string, ", ");
094: }
095:
096: /**
097: * Extracts tokens from a delimited string.
098: *
099: * @param string
100: * The string
101: * @param delimiters
102: * The delimiters
103: * @return The string tokens as a list
104: */
105: public static StringList tokenize(final String string,
106: final String delimiters) {
107: final StringTokenizer tokenizer = new StringTokenizer(string,
108: delimiters);
109: final StringList strings = new StringList();
110:
111: while (tokenizer.hasMoreTokens()) {
112: strings.add(tokenizer.nextToken());
113: }
114:
115: return strings;
116: }
117:
118: /**
119: * Converts a collection of objects into a list of string values by using
120: * the conversion methods of the StringValue class.
121: *
122: * @param collection
123: * The collection to add as strings
124: * @return The list
125: */
126: public static StringList valueOf(final Collection collection) {
127: if (collection != null) {
128: final StringList strings = new StringList(collection.size());
129:
130: for (final Iterator iterator = collection.iterator(); iterator
131: .hasNext();) {
132: strings.add(StringValue.valueOf(iterator.next()));
133: }
134:
135: return strings;
136: } else {
137: return new StringList();
138: }
139: }
140:
141: /**
142: * Converts an array of objects into a list of strings by using the object
143: * to string conversion method of the StringValue class.
144: *
145: * @param objects
146: * The objects to convert
147: * @return The list of strings
148: */
149: public static StringList valueOf(final Object[] objects) {
150: // check for null parameter
151: int length = (objects == null) ? 0 : objects.length;
152: final StringList strings = new StringList(length);
153:
154: for (int i = 0; i < length; i++) {
155: strings.add(StringValue.valueOf(objects[i]));
156: }
157:
158: return strings;
159: }
160:
161: /**
162: * Returns a string list with just one string in it.
163: *
164: * @param string
165: * The string
166: * @return The list of one string
167: */
168: public static StringList valueOf(final String string) {
169: final StringList strings = new StringList();
170:
171: if (string != null) {
172: strings.add(string);
173: }
174:
175: return strings;
176: }
177:
178: /**
179: * Converts a string array to a string list.
180: *
181: * @param array
182: * The array
183: * @return The list
184: */
185: public static StringList valueOf(final String[] array) {
186: int length = (array == null) ? 0 : array.length;
187: final StringList strings = new StringList(length);
188:
189: for (int i = 0; i < length; i++) {
190: strings.add(array[i]);
191: }
192:
193: return strings;
194: }
195:
196: /**
197: * Constructor.
198: */
199: public StringList() {
200: this .strings = new ArrayList();
201: }
202:
203: /**
204: * Constructor.
205: *
206: * @param size
207: * Number of elements to preallocate
208: */
209: public StringList(final int size) {
210: this .strings = new ArrayList(size);
211: }
212:
213: /**
214: * Adds a string to the back of this list.
215: *
216: * @param string
217: * String to add
218: */
219: public void add(final String string) {
220: // Add to list
221: add(size(), string);
222: }
223:
224: /**
225: * Adds the string to the stringlist at position pos.
226: *
227: * @param pos
228: * the position to add the string at
229: * @param string
230: * the string to add.
231: */
232: public void add(final int pos, final String string) {
233: strings.add(pos, string == null ? "" : string);
234:
235: // Increase total length
236: totalLength += string == null ? 0 : string.length();
237: }
238:
239: /**
240: * Adds a string value to this list as a string.
241: *
242: * @param value
243: * The value to add
244: */
245: public void add(final StringValue value) {
246: add(value.toString());
247: }
248:
249: /**
250: * @param string
251: * The string to look for
252: * @return True if the list contains the string
253: */
254: public boolean contains(final String string) {
255: return strings.contains(string);
256: }
257:
258: /**
259: * Gets the string at the given index.
260: *
261: * @param index
262: * The index
263: * @return The string at the index
264: * @throws IndexOutOfBoundsException
265: */
266: public String get(final int index) {
267: return (String) strings.get(index);
268: }
269:
270: /**
271: * @return List value (not a copy of this list)
272: */
273: public List getList() {
274: return strings;
275: }
276:
277: /**
278: * Returns a typesafe iterator over this collection of strings.
279: *
280: * @return Typesafe string iterator
281: */
282: public IStringIterator iterator() {
283: return new IStringIterator() {
284: private final Iterator iterator = strings.iterator();
285:
286: public boolean hasNext() {
287: return iterator.hasNext();
288: }
289:
290: public String next() {
291: return (String) iterator.next();
292: }
293: };
294: }
295:
296: /**
297: * Adds the given string to the front of the list.
298: *
299: * @param string
300: * The string to add
301: */
302: public void prepend(final String string) {
303: add(0, string);
304: }
305:
306: /**
307: * Removes the string at the given index.
308: *
309: * @param index
310: * The index
311: */
312: public void remove(final int index) {
313: String string = (String) strings.remove(index);
314: totalLength = totalLength - string.length();
315: }
316:
317: /**
318: * Removes the last string in this list.
319: */
320: public void removeLast() {
321: remove(size() - 1);
322: }
323:
324: /**
325: * @return The number of strings in this list.
326: */
327: public int size() {
328: return strings.size();
329: }
330:
331: /**
332: * Sorts this string list alphabetically.
333: */
334: public void sort() {
335: Collections.sort(strings);
336: }
337:
338: /**
339: * Converts this string list to a string array.
340: *
341: * @return The string array
342: */
343: public String[] toArray() {
344: return (String[]) strings.toArray(new String[size()]);
345: }
346:
347: /**
348: * @return The total length of all strings in this list.
349: */
350: public int totalLength() {
351: return totalLength;
352: }
353: }
|