001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/util/tags/sakai_2-4-1/util-util/util/src/java/org/sakaiproject/util/StringUtil.java $
003: * $Id: StringUtil.java 20281 2007-01-11 21:58:27Z ggolden@umich.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.util;
021:
022: import java.util.Vector;
023: import java.util.Collection;
024: import java.util.Iterator;
025:
026: /**
027: * <p>
028: * StringUtil collects together some string utility classes.
029: * </p>
030: */
031: public class StringUtil {
032: /**
033: * Like jdk1.4's String.split...
034: */
035: public static String[] split(String source, String splitter) {
036: // hold the results as we find them
037: Vector rv = new Vector();
038: int last = 0;
039: int next = 0;
040: do {
041: // find next splitter in source
042: next = source.indexOf(splitter, last);
043: if (next != -1) {
044: // isolate from last thru before next
045: rv.add(source.substring(last, next));
046: last = next + splitter.length();
047: }
048: } while (next != -1);
049: if (last < source.length()) {
050: rv.add(source.substring(last, source.length()));
051: }
052:
053: // convert to array
054: return (String[]) rv.toArray(new String[rv.size()]);
055: }
056:
057: /**
058: * Reverse the split operation.
059: *
060: * @param parts
061: * The parts to combine
062: * @param splitter
063: * The between-parts text
064: */
065: public static String unsplit(String[] parts, String splitter) {
066: if (parts == null)
067: return null;
068:
069: StringBuffer buf = new StringBuffer();
070: for (int i = 0; i < parts.length; i++) {
071: if (parts[i] != null)
072: buf.append(parts[i]);
073: if (i < parts.length - 1)
074: buf.append(splitter);
075: }
076:
077: return buf.toString();
078: }
079:
080: /**
081: * Reverse the split operation.
082: *
083: * @param parts
084: * The parts to combine
085: * @param index
086: * the index to the fist part to use
087: * @param length
088: * the number of parts to use
089: * @param splitter
090: * The between-parts text
091: */
092: public static String unsplit(String[] parts, int index, int length,
093: String splitter) {
094: if (parts == null)
095: return null;
096: if ((index < 0) || (index >= parts.length))
097: return null;
098: if (index + length > parts.length)
099: return null;
100:
101: StringBuffer buf = new StringBuffer();
102: for (int i = index; i < index + length; i++) {
103: if (parts[i] != null)
104: buf.append(parts[i]);
105: buf.append(splitter);
106: }
107:
108: // remove the trailing splitter
109: buf.setLength(buf.length() - splitter.length());
110: return buf.toString();
111: }
112:
113: /**
114: * Split the source into two strings at the first occurrence of the splitter Subsequent occurrences are not treated specially, and may be part of the second string.
115: *
116: * @param source
117: * The string to split
118: * @param splitter
119: * The string that forms the boundary between the two strings returned.
120: * @return An array of two strings split from source by splitter.
121: */
122: public static String[] splitFirst(String source, String splitter) {
123: // hold the results as we find them
124: Vector rv = new Vector();
125: int last = 0;
126: int next = 0;
127:
128: // find first splitter in source
129: next = source.indexOf(splitter, last);
130: if (next != -1) {
131: // isolate from last thru before next
132: rv.add(source.substring(last, next));
133: last = next + splitter.length();
134: }
135:
136: if (last < source.length()) {
137: rv.add(source.substring(last, source.length()));
138: }
139:
140: // convert to array
141: return (String[]) rv.toArray(new String[rv.size()]);
142: }
143:
144: /**
145: * Compute the reference path (i.e. the container) for a given reference.
146: *
147: * @param ref
148: * The reference string.
149: * @return The reference root for the given reference.
150: */
151: public static String referencePath(String ref) {
152: String path = null;
153:
154: // Note: there may be a trailing separator
155: int pos = ref.lastIndexOf("/", ref.length() - 2);
156:
157: // if no separators are found, place it even before the root!
158: if (pos == -1) {
159: path = "";
160: }
161:
162: // use the string up to and including that last separator
163: else {
164: path = ref.substring(0, pos + 1);
165: }
166:
167: return path;
168: }
169:
170: /**
171: * Create a full reference from a relative reference merged with a root reference.
172: *
173: * @param root
174: * The root reference, which is the root of the full reference.
175: * @param relative
176: * The relative reference, to add to the path of the root.
177: * @return A full reference from the root and relative references.
178: */
179: public static String fullReference(String root, String relative) {
180: String full = referencePath(root);
181: full += relative;
182: return full;
183: }
184:
185: /**
186: * Trim blanks, and if nothing left, make null.
187: *
188: * @param value
189: * The string to trim.
190: * @return value trimmed of blanks, and if nothing left, made null.
191: */
192: public static String trimToNull(String value) {
193: if (value == null)
194: return null;
195: value = value.trim();
196: if (value.length() == 0)
197: return null;
198: return value;
199: }
200:
201: /**
202: * Trim blanks, and if nothing left, make null, else lowercase.
203: *
204: * @param value
205: * The string to trim.
206: * @return value trimmed of blanks, lower cased, and if nothing left, made null.
207: */
208: public static String trimToNullLower(String value) {
209: if (value == null)
210: return null;
211: value = value.trim();
212: if (value.length() == 0)
213: return null;
214: return value.toLowerCase();
215: }
216:
217: /**
218: * Trim blanks, and assure there is a value, and it's not null.
219: *
220: * @param value
221: * The string to trim.
222: * @return value trimmed of blanks, assuring it not to be null.
223: */
224: public static String trimToZero(String value) {
225: if (value == null)
226: return "";
227: value = value.trim();
228: return value;
229: }
230:
231: /**
232: * Trim blanks, and assure there is a value, and it's not null, then lowercase.
233: *
234: * @param value
235: * The string to trim.
236: * @return value trimmed of blanks, lower cased, assuring it not to be null.
237: */
238: public static String trimToZeroLower(String value) {
239: if (value == null)
240: return "";
241: value = value.trim();
242: return value.toLowerCase();
243: }
244:
245: /**
246: * Check if the target contains the substring anywhere, ignore case.
247: *
248: * @param target
249: * The string to check.
250: * @param substring
251: * The value to check for.
252: * @return true of the target contains the substring anywhere, ignore case, or false if it does not.
253: */
254: public static boolean containsIgnoreCase(String target,
255: String substring) {
256: if ((target == null) || (substring == null))
257: return false;
258:
259: target = target.toLowerCase();
260: substring = substring.toLowerCase();
261: int pos = target.indexOf(substring);
262: return (pos != -1);
263: }
264:
265: /**
266: * Compare two strings for differences, either may be null
267: *
268: * @param a
269: * One String.
270: * @param b
271: * The other String.
272: * @return true if the strings are different, false if they are the same.
273: */
274: public static boolean different(String a, String b) {
275: // if both null, they are the same
276: if ((a == null) && (b == null))
277: return false;
278:
279: // if either are null (they both are not), they are different
280: if ((a == null) || (b == null))
281: return true;
282:
283: // now we know neither are null, so compare
284: return (!a.equals(b));
285: }
286:
287: /**
288: * Compare two strings for differences, either may be null, ignore case if specified
289: *
290: * @param a
291: * One String.
292: * @param b
293: * The other String.
294: * @param ignoreCase
295: * if true, we will do the compare case insensitive.
296: * @return true if the strings are different, false if they are the same.
297: */
298: public static boolean different(String a, String b,
299: boolean ignoreCase) {
300: // if both null, they are the same
301: if ((a == null) && (b == null))
302: return false;
303:
304: // if either are null (they both are not), they are different
305: if ((a == null) || (b == null))
306: return true;
307:
308: // now we know neither are null, so compare
309: if (ignoreCase) {
310: return (!a.equalsIgnoreCase(b));
311: }
312:
313: return (!a.equals(b));
314: }
315:
316: /**
317: * Compare two String[] for differences, either may be null
318: *
319: * @param a
320: * One String[].
321: * @param b
322: * The other String[].
323: * @return true if the String[]s are different, false if they are the same.
324: */
325: public static boolean different(String[] a, String[] b) {
326: // if both null, they are the same
327: if ((a == null) && (b == null))
328: return false;
329:
330: // if either are null (they both are not), they are different
331: if ((a == null) || (b == null))
332: return true;
333:
334: // if the lengths are different, they are different
335: if (a.length != b.length)
336: return true;
337:
338: // now we know neither are null, so compare, item for item (order counts)
339: for (int i = 0; i < a.length; i++) {
340: if (!a[i].equals(b[i]))
341: return true;
342: }
343:
344: // they are NOT different!
345: return false;
346: }
347:
348: /**
349: * Compare two byte[] for differences, either may be null
350: *
351: * @param a
352: * One byte[].
353: * @param b
354: * The other byte[].
355: * @return true if the byte[]s are different, false if they are the same.
356: */
357: public static boolean different(byte[] a, byte[] b) {
358: // if both null, they are the same
359: if ((a == null) && (b == null))
360: return false;
361:
362: // if either are null (they both are not), they are different
363: if ((a == null) || (b == null))
364: return true;
365:
366: // if the lengths are different, they are different
367: if (a.length != b.length)
368: return true;
369:
370: // now we know neither are null, so compare, item for item (order counts)
371: for (int i = 0; i < a.length; i++) {
372: if (a[i] != b[i])
373: return true;
374: }
375:
376: // they are NOT different!
377: return false;
378: }
379:
380: /**
381: * Limit the string to a certain number of characters, adding "..." if it was truncated
382: *
383: * @param value
384: * The string to limit.
385: * @param length
386: * the length to limit to (as an int).
387: * @return The limited string.
388: */
389: public static String limit(String value, int length) {
390: StringBuffer buf = new StringBuffer(value);
391: if (buf.length() > length) {
392: buf.setLength(length);
393: buf.append("...");
394: }
395:
396: return buf.toString();
397: }
398:
399: /**
400: * Determine if a String is contained in a String Collection
401: *
402: * @param stringCollection
403: * The collection of (String) to scan
404: * @param value
405: * The value to look for
406: * @return true if the string was found
407: */
408: public static boolean contains(Collection stringCollection,
409: String value) {
410: if (stringCollection == null || value == null)
411: return false;
412: if (value.length() == 0)
413: return false;
414: for (Iterator i = stringCollection.iterator(); i.hasNext();) {
415: Object o = i.next();
416: if (!(o instanceof String))
417: continue;
418: if (value.equals((String) o))
419: return true;
420: }
421: return false;
422: }
423:
424: /**
425: * Determine if a String is contained in a String[]
426: *
427: * @param stringCollection
428: * The String[] to scan
429: * @param value
430: * The value to look for
431: * @return true if the string was found
432: */
433: public static boolean contains(String[] stringCollection,
434: String value) {
435: if (stringCollection == null || value == null)
436: return false;
437: if ((stringCollection.length == 0) || (value.length() == 0))
438: return false;
439: for (String s : stringCollection) {
440: if (value.equals(s))
441: return true;
442: }
443: return false;
444: }
445:
446: /**
447: * Determine if a String is contained in a String Collection, ignoring case
448: *
449: * @param stringCollection
450: * The collection of (String) to scan
451: * @param value
452: * The value to look for
453: * @return true if the string was found
454: */
455: public static boolean containsIgnoreCase(
456: Collection stringCollection, String value) {
457: if (stringCollection == null || value == null)
458: return false;
459: if (value.length() == 0)
460: return false;
461: for (Iterator i = stringCollection.iterator(); i.hasNext();) {
462: Object o = i.next();
463: if (!(o instanceof String))
464: continue;
465: if (value.equalsIgnoreCase((String) o))
466: return true;
467: }
468: return false;
469: }
470:
471: /**
472: * Determine if a String is contained in a String [], ignoring case
473: *
474: * @param stringCollection
475: * The String[] to scan
476: * @param value
477: * The value to look for
478: * @return true if the string was found
479: */
480: public static boolean containsIgnoreCase(String[] stringCollection,
481: String value) {
482: if (stringCollection == null || value == null)
483: return false;
484: if ((stringCollection.length == 0) || (value.length() == 0))
485: return false;
486: for (String s : stringCollection) {
487: if (value.equalsIgnoreCase(s))
488: return true;
489: }
490: return false;
491: }
492:
493: /**
494: * Determine if a String is contained in a String [], ignoring case or not as specified
495: *
496: * @param stringCollection
497: * The String[] to scan
498: * @param value
499: * The value to look for
500: * @param ignoreCase
501: * if true, we will do the compare case insensitive.
502: * @return true if the string was found
503: */
504: public static boolean contains(String[] stringCollection,
505: String value, boolean ignoreCase) {
506: if (stringCollection == null || value == null)
507: return false;
508: if ((stringCollection.length == 0) || (value.length() == 0))
509: return false;
510: for (String s : stringCollection) {
511: if (ignoreCase) {
512: if (value.equalsIgnoreCase(s))
513: return true;
514: } else {
515: if (value.equals(s))
516: return true;
517: }
518: }
519: return false;
520: }
521: }
|