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 */ 017package org.apache.wicket.util.string; 018 019import java.io.Serializable; 020import java.util.ArrayList; 021import java.util.List; 022 023/** 024 * An abstract base class for string list implementations. Besides having an implementation for 025 * IStringSequence (iterator(), get(int index) and size()), an AbstractStringList can be converted 026 * to a String array or a List of Strings. 027 * <p> 028 * The total length of all Strings in the list can be determined by calling totalLength(). 029 * <p> 030 * Strings or a subset of Strings in the list can be formatted using three join() methods: 031 * <p> 032 * <ul> 033 * <li>join(String) Joins strings together using a given separator 034 * <li>join() Joins Strings using comma as a separator 035 * <li>join(int first, int last, String) Joins a sublist of strings using a given separator 036 * </ul> 037 * 038 * @author Jonathan Locke 039 */ 040public abstract class AbstractStringList implements IStringSequence, Serializable 041{ 042 /** 043 * 044 */ 045 private static final long serialVersionUID = 1L; 046 047 /** 048 * @return String iterator 049 * @see org.apache.wicket.util.string.IStringSequence#iterator() 050 */ 051 @Override 052 public abstract IStringIterator iterator(); 053 054 /** 055 * @return Number of strings in this string list 056 * @see org.apache.wicket.util.string.IStringSequence#size() 057 */ 058 @Override 059 public abstract int size(); 060 061 /** 062 * @param index 063 * The index into this string list 064 * @return The string at the given index 065 * @see org.apache.wicket.util.string.IStringSequence#get(int) 066 */ 067 @Override 068 public abstract String get(int index); 069 070 /** 071 * Returns this String sequence as an array of Strings. Subclasses may provide a more efficient 072 * implementation than the one provided here. 073 * 074 * @return An array containing exactly this sequence of Strings 075 */ 076 public String[] toArray() 077 { 078 // Get number of Strings 079 final int size = size(); 080 081 // Allocate array 082 final String[] strings = new String[size]; 083 084 // Copy string references 085 for (int i = 0; i < size; i++) 086 { 087 strings[i] = get(i); 088 } 089 090 return strings; 091 } 092 093 /** 094 * Returns this String sequence as an array of Strings. Subclasses may provide a more efficient 095 * implementation than the one provided here. 096 * 097 * @return An array containing exactly this sequence of Strings 098 */ 099 public final List<String> toList() 100 { 101 // Get number of Strings 102 final int size = size(); 103 104 // Allocate list of exactly the right size 105 final List<String> strings = new ArrayList<>(size); 106 107 // Add strings to list 108 for (int i = 0; i < size; i++) 109 { 110 strings.add(get(i)); 111 } 112 113 return strings; 114 } 115 116 /** 117 * @return The total length of all Strings in this sequence. 118 */ 119 public int totalLength() 120 { 121 // Get number of Strings 122 final int size = size(); 123 124 // Add strings to list 125 int totalLength = 0; 126 127 for (int i = 0; i < size; i++) 128 { 129 totalLength += get(i).length(); 130 } 131 132 return totalLength; 133 } 134 135 /** 136 * Joins this sequence of strings using a comma separator. For example, if this sequence 137 * contains [1 2 3], the result of calling this method will be "1, 2, 3". 138 * 139 * @return The joined String 140 */ 141 public final String join() 142 { 143 return join(", "); 144 } 145 146 /** 147 * Joins this sequence of strings using a separator 148 * 149 * @param separator 150 * The separator to use 151 * @return The joined String 152 */ 153 public final String join(final String separator) 154 { 155 return join(0, size(), separator); 156 } 157 158 /** 159 * Joins this sequence of strings from first index to last using a separator 160 * 161 * @param first 162 * The first index to use, inclusive 163 * @param last 164 * The last index to use, exclusive 165 * @param separator 166 * The separator to use 167 * @return The joined String 168 */ 169 public final String join(final int first, final int last, final String separator) 170 { 171 // Allocate buffer of exactly the right length 172 final int length = totalLength() + (separator.length() * (Math.max(0, last - first - 1))); 173 final AppendingStringBuffer buf = new AppendingStringBuffer(length); 174 175 // Loop through indexes requested 176 for (int i = first; i < last; i++) 177 { 178 // Add next string 179 buf.append(get(i)); 180 181 // Add separator? 182 if (i != (last - 1)) 183 { 184 buf.append(separator); 185 } 186 } 187 188 return buf.toString(); 189 } 190 191 /** 192 * Converts this object to a string representation 193 * 194 * @return String version of this object 195 */ 196 @Override 197 public String toString() 198 { 199 return "[" + join() + "]"; 200 } 201}