1 /* Copyright (c) 2001-2015, The HSQL Development Group
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
alloc_from_user_code()5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of the HSQL Development Group nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32 package org.hsqldb.lib;
33
allocatestd::allocator34 import java.lang.reflect.Array;
35
36 /** Provides a collection of convenience methods for processing and
37 * creating objects with <code>String</code> value components.
38 *
39 * @author Campbell Burnet (boucherb@users dot sourceforge.net)
allocatestd::allocator40 * @author Fred Toussi (fredt@users dot sourceforge.net)
41 * @version 2.2.6
42 * @since 1.7.0
43 */
44 public class StringUtil {
45
46 /**
47 * If necessary, adds zeros to the beginning of a value so that the total
48 * length matches the given precision, otherwise trims the right digits.
49 * Then if maxSize is smaller than precision, trims the right digits to
50 * maxSize. Negative values are treated as positive
51 */
52 public static String toZeroPaddedString(long value, int precision,
53 int maxSize) {
54
55 StringBuffer sb = new StringBuffer();
56
57 if (value < 0) {
58 value = -value;
59 }
60
61 String s = Long.toString(value);
62
63 if (s.length() > precision) {
64 s = s.substring(precision);
65 }
66
67 for (int i = s.length(); i < precision; i++) {
68 sb.append('0');
69 }
70
71 sb.append(s);
72
73 if (maxSize < precision) {
74 sb.setLength(maxSize);
75 }
76
77 return sb.toString();
78 }
79
80 public static String toPaddedString(String source, int length, char pad,
81 boolean trailing) {
82
83 int len = source.length();
84
85 if (len >= length) {
86 return source;
87 }
88
89 StringBuffer sb = new StringBuffer(length);
90
91 if (trailing) {
92 sb.append(source);
93 }
94
95 for (int i = len; i < length; i++) {
96 sb.append(pad);
97 }
98
99 if (!trailing) {
100 sb.append(source);
101 }
102
103 return sb.toString();
104 }
105
106 public static String toPaddedString(String source, int length, String pad,
107 boolean trailing) {
108
109 int len = source.length();
110
111 if (len == length) {
112 return source;
113 }
114
115 if (len > length) {
116 if (trailing) {
117 return source.substring(0, length);
118 } else {
119 return source.substring(len - length, len);
120 }
121 }
122
123 StringBuffer sb = new StringBuffer(length);
124 int padLength = source.length();
125 int partLength = (length - padLength) % pad.length();
126
127 if (trailing) {
128 sb.append(source);
129 sb.append(pad.substring(pad.length() - partLength, pad.length()));
130 }
131
132 for (; padLength + pad.length() <= length; padLength += pad.length()) {
133 sb.append(pad);
134 }
135
136 if (!trailing) {
137 sb.append(pad.substring(0, partLength));
138 sb.append(source);
139 }
140
141 return sb.toString();
142 }
143
144 /**
145 * Returns a string with non alphanumeric chars converted to the
146 * substitute character. A digit first character is also converted.
147 * By sqlbob@users
148 * @param source string to convert
149 * @param substitute character to use
150 * @return converted string
151 */
152 public static String toLowerSubset(String source, char substitute) {
153
154 int len = source.length();
155 StringBuffer sb = new StringBuffer(len);
156 char ch;
157
158 for (int i = 0; i < len; i++) {
159 ch = source.charAt(i);
160
161 if (!Character.isLetterOrDigit(ch)) {
162 sb.append(substitute);
163 } else if ((i == 0) && Character.isDigit(ch)) {
164 sb.append(substitute);
165 } else {
166 sb.append(Character.toLowerCase(ch));
167 }
168 }
169
170 return sb.toString();
171 }
172
173 /**
174 * Builds a bracketed CSV list from the array
175 * @param array an array of Objects
176 * @return string
177 */
178 public static String arrayToString(Object array) {
179
180 int len = Array.getLength(array);
181 int last = len - 1;
182 StringBuffer sb = new StringBuffer(2 * (len + 1));
183
184 sb.append('{');
185
186 for (int i = 0; i < len; i++) {
187 sb.append(Array.get(array, i));
188
189 if (i != last) {
190 sb.append(',');
191 }
192 }
193
194 sb.append('}');
195
196 return sb.toString();
197 }
198
199 /**
200 * Builds a CSV list from the specified String[], separator string and
201 * quote string. <p>
202 *
203 * <ul>
204 * <li>All arguments are assumed to be non-null.
205 * <li>Separates each list element with the value of the
206 * <code>separator</code> argument.
207 * <li>Prepends and appends each element with the value of the
208 * <code>quote</code> argument.
209 * <li> No attempt is made to escape the quote character sequence if it is
210 * found internal to a list element.
211 * <ul>
212 * @return a CSV list
213 * @param separator the <code>String</code> to use as the list element separator
214 * @param quote the <code>String</code> with which to quote the list elements
215 * @param s array of <code>String</code> objects
216 */
217 public static String getList(String[] s, String separator, String quote) {
218
219 int len = s.length;
220 StringBuffer sb = new StringBuffer(len * 16);
221
222 for (int i = 0; i < len; i++) {
223 sb.append(quote);
224 sb.append(s[i]);
225 sb.append(quote);
226
227 if (i + 1 < len) {
228 sb.append(separator);
229 }
230 }
231
232 return sb.toString();
233 }
234
235 /**
236 * Builds a CSV list from the specified int[], <code>separator</code>
237 * <code>String</code> and <code>quote</code> <code>String</code>. <p>
238 *
239 * <ul>
240 * <li>All arguments are assumed to be non-null.
241 * <li>Separates each list element with the value of the
242 * <code>separator</code> argument.
243 * <li>Prepends and appends each element with the value of the
244 * <code>quote</code> argument.
245 * <ul>
246 * @return a CSV list
247 * @param s the array of int values
248 * @param separator the <code>String</code> to use as the separator
249 * @param quote the <code>String</code> with which to quote the list elements
250 */
251 public static String getList(int[] s, String separator, String quote) {
252
253 int len = s.length;
254 StringBuffer sb = new StringBuffer(len * 8);
255
256 for (int i = 0; i < len; i++) {
257 sb.append(quote);
258 sb.append(s[i]);
259 sb.append(quote);
260
261 if (i + 1 < len) {
262 sb.append(separator);
263 }
264 }
265
266 return sb.toString();
267 }
268
269 public static String getList(long[] s, String separator, String quote) {
270
271 int len = s.length;
272 StringBuffer sb = new StringBuffer(len * 8);
273
274 for (int i = 0; i < len; i++) {
275 sb.append(quote);
276 sb.append(s[i]);
277 sb.append(quote);
278
279 if (i + 1 < len) {
280 sb.append(separator);
281 }
282 }
283
284 return sb.toString();
285 }
286
287 /**
288 * Builds a CSV list from the specified String[][], separator string and
289 * quote string. <p>
290 *
291 * <ul>
292 * <li>All arguments are assumed to be non-null.
293 * <li>Uses only the first element in each subarray.
294 * <li>Separates each list element with the value of the
295 * <code>separator</code> argument.
296 * <li>Prepends and appends each element with the value of the
297 * <code>quote</code> argument.
298 * <li> No attempt is made to escape the quote character sequence if it is
299 * found internal to a list element.
300 * <ul>
301 * @return a CSV list
302 * @param separator the <code>String</code> to use as the list element separator
303 * @param quote the <code>String</code> with which to quote the list elements
304 * @param s the array of <code>String</code> array objects
305 */
306 public static String getList(String[][] s, String separator,
307 String quote) {
308
309 int len = s.length;
310 StringBuffer sb = new StringBuffer(len * 16);
311
312 for (int i = 0; i < len; i++) {
313 sb.append(quote);
314 sb.append(s[i][0]);
315 sb.append(quote);
316
317 if (i + 1 < len) {
318 sb.append(separator);
319 }
320 }
321
322 return sb.toString();
323 }
324
325 /**
326 * Checks if text is empty (characters <= space)
327 * @return boolean true if text is null or empty, false otherwise
328 * @param s java.lang.String
329 */
330 public static boolean isEmpty(String s) {
331
332 int i = s == null ? 0
333 : s.length();
334
335 while (i > 0) {
336 if (s.charAt(--i) > ' ') {
337 return false;
338 }
339 }
340
341 return true;
342 }
343
344 /**
345 * Returns the size of substring that does not contain any trailing spaces
346 * @param s the string
347 * @return trimmed size
348 */
349 public static int rightTrimSize(String s) {
350
351 int i = s.length();
352
353 while (i > 0) {
354 i--;
355
356 if (s.charAt(i) != ' ') {
357 return i + 1;
358 }
359 }
360
361 return 0;
362 }
363
364 /**
365 * Skips any spaces at or after start and returns the index of first
366 * non-space character;
367 * @param s the string
368 * @param start index to start
369 * @return index of first non-space
370 */
371 public static int skipSpaces(String s, int start) {
372
373 int limit = s.length();
374 int i = start;
375
376 for (; i < limit; i++) {
377 if (s.charAt(i) != ' ') {
378 break;
379 }
380 }
381
382 return i;
383 }
384
385 /**
386 * Splits the string into an array, using the separator. If separator is
387 * not found in the string, the whole string is returned in the array.
388 *
389 * @param s the string
390 * @param separator the separator
391 * @return array of strings
392 */
393 public static String[] split(String s, String separator) {
394
395 HsqlArrayList list = new HsqlArrayList();
396 int currindex = 0;
397
398 for (boolean more = true; more; ) {
399 int nextindex = s.indexOf(separator, currindex);
400
401 if (nextindex == -1) {
402 nextindex = s.length();
403 more = false;
404 }
405
406 list.add(s.substring(currindex, nextindex));
407
408 currindex = nextindex + separator.length();
409 }
410
411 return (String[]) list.toArray(new String[list.size()]);
412 }
413 }
414