001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032: package com.vividsolutions.jump.util;
033:
034: import java.io.ByteArrayOutputStream;
035: import java.io.PrintStream;
036: import java.util.ArrayList;
037: import java.util.Collection;
038: import java.util.Iterator;
039: import java.util.List;
040: import java.util.StringTokenizer;
041:
042: import com.vividsolutions.jts.util.Assert;
043:
044: /**
045: * Useful String-related utilities.
046: */
047: public class StringUtil {
048:
049: /**
050: * Warning: hinders internationalization
051: */
052: public static String s(int n) {
053: return (n != 1) ? "s" : "";
054: }
055:
056: /**
057: * Warning: hinders internationalization
058: */
059: public static String ies(int n) {
060: return (n != 1) ? "ies" : "y";
061: }
062:
063: public static String substitute(String string,
064: Object[] substitutions) {
065: for (int i = 0; i < substitutions.length; i++) {
066: string = StringUtil.replaceAll(string, "$" + (i + 1),
067: substitutions[i].toString());
068: }
069: return string;
070: }
071:
072: public static String classNameWithoutQualifiers(String className) {
073: return className.substring(Math.max(className.lastIndexOf("."),
074: className.lastIndexOf("$")) + 1);
075: }
076:
077: public static String classNameWithoutPackageQualifiers(
078: String className) {
079: return className.substring(className.lastIndexOf(".") + 1);
080: }
081:
082: public static String repeat(char c, int n) {
083: StringBuffer b = new StringBuffer();
084:
085: for (int i = 0; i < n; i++) {
086: b.append(c);
087: }
088:
089: return b.toString();
090: }
091:
092: /**
093: * Line-wraps s by inserting a newline instead of the first space after the nth
094: * column. Word-wraps.
095: */
096: public static String split(String s, int n) {
097: StringBuffer b = new StringBuffer();
098: boolean wrapPending = false;
099:
100: for (int i = 0; i < s.length(); i++) {
101: if (((i % n) == 0) && (i > 0)) {
102: wrapPending = true;
103: }
104:
105: char c = s.charAt(i);
106:
107: if (wrapPending && (c == ' ')) {
108: b.append("\n");
109: wrapPending = false;
110: } else {
111: b.append(c);
112: }
113: }
114:
115: return b.toString();
116: }
117:
118: public static String capitalize(String word) {
119: if (word.length() == 0) {
120: return word;
121: }
122:
123: return (word.charAt(0) + "").toUpperCase() + word.substring(1);
124: }
125:
126: public static String uncapitalize(String word) {
127: if (word.length() == 0) {
128: return word;
129: }
130:
131: return (word.charAt(0) + "").toLowerCase() + word.substring(1);
132: }
133:
134: /**
135: * Converts the comma-delimited string into a List of trimmed strings.
136: * @param s a String with comma-delimited values
137: * @return a List of the Strings that were delimited by commas
138: */
139: public static List fromCommaDelimitedString(String s) {
140: if (s.trim().length() == 0) {
141: return new ArrayList();
142: }
143: ArrayList result = new ArrayList();
144: StringTokenizer tokenizer = new StringTokenizer(s, ",");
145:
146: while (tokenizer.hasMoreTokens()) {
147: result.add(tokenizer.nextToken().toString().trim());
148: }
149:
150: return result;
151: }
152:
153: /**
154: * Returns a List of empty Strings.
155: * @param size the size of the List to create
156: * @return a List of blank Strings
157: */
158: public static List blankStringList(int size) {
159: ArrayList list = new ArrayList();
160:
161: for (int i = 0; i < size; i++) {
162: list.add("");
163: }
164:
165: return list;
166: }
167:
168: public static String toFriendlyName(String className) {
169: return toFriendlyName(className, null);
170: }
171:
172: public static String friendlyName(Class c) {
173: return toFriendlyName(c.getName());
174: }
175:
176: public static String toFriendlyName(String className,
177: String substringToRemove) {
178: String name = className;
179:
180: //Remove substring sooner rather than later because, for example,
181: //?"PlugIn" will become "Plug In". [Jon Aquino]
182: if (substringToRemove != null) {
183: name = StringUtil.replaceAll(name, substringToRemove, "");
184: }
185:
186: name = StringUtil.classNameWithoutQualifiers(name);
187: name = insertSpaces(name);
188:
189: return name;
190: }
191:
192: public static String insertSpaces(String s) {
193: if (s.length() < 2) {
194: return s;
195: }
196:
197: String result = "";
198:
199: for (int i = 0; i < (s.length() - 2); i++) { //-2
200: result += s.charAt(i);
201:
202: if ((Character.isLowerCase(s.charAt(i)) && Character
203: .isUpperCase(s.charAt(i + 1)))
204: || (Character.isUpperCase(s.charAt(i + 1)) && Character
205: .isLowerCase(s.charAt(i + 2)))) {
206: result += " ";
207: }
208: }
209:
210: result += s.charAt(s.length() - 2);
211: result += s.charAt(s.length() - 1);
212:
213: return result.trim();
214: }
215:
216: /**
217: * Returns the elements of c separated by commas. If c is empty, an empty
218: * String will be returned.
219: * @param c a Collection of objects to convert to Strings and delimit by commas
220: * @return a String containing c's elements, delimited by commas
221: */
222: public static String toCommaDelimitedString(Collection c) {
223: return toDelimitedString(c, ", ");
224: }
225:
226: /**
227: * Returns original with all occurrences of oldSubstring replaced by
228: * newSubstring
229: */
230: public static String replaceAll(String original,
231: String oldSubstring, String newSubstring) {
232: return replace(original, oldSubstring, newSubstring, true);
233: }
234:
235: /**
236: * Returns original with occurrences of oldSubstring replaced by
237: * newSubstring. Set all to true to replace all occurrences, or false to
238: * replace the first occurrence only.
239: */
240: public static String replace(String original, String oldSubstring,
241: String newSubstring, boolean all) {
242: StringBuffer b = new StringBuffer(original);
243: replace(b, oldSubstring, newSubstring, all);
244:
245: return b.toString();
246: }
247:
248: /**
249: * Replaces all instances of the String o with the String n in the
250: * StringBuffer orig if all is true, or only the first instance if all is
251: * false. Posted by Steve Chapel <schapel@breakthr.com> on UseNet
252: */
253: public static void replace(StringBuffer orig, String o, String n,
254: boolean all) {
255: if ((orig == null) || (o == null) || (o.length() == 0)
256: || (n == null)) {
257: throw new IllegalArgumentException(
258: "Null or zero-length String");
259: }
260:
261: int i = 0;
262:
263: while ((i + o.length()) <= orig.length()) {
264: if (orig.substring(i, i + o.length()).equals(o)) {
265: orig.replace(i, i + o.length(), n);
266:
267: if (!all) {
268: break;
269: } else {
270: i += n.length();
271: }
272: } else {
273: i++;
274: }
275: }
276: }
277:
278: /**
279: * Returns an throwable's stack trace
280: */
281: public static String stackTrace(Throwable t) {
282: ByteArrayOutputStream os = new ByteArrayOutputStream();
283: PrintStream ps = new PrintStream(os);
284: t.printStackTrace(ps);
285:
286: return os.toString();
287: }
288:
289: public static String head(String s, int lines) {
290: int newlinesEncountered = 0;
291: for (int i = 0; i < s.length(); i++) {
292: if (s.charAt(i) == '\n') {
293: newlinesEncountered++;
294: if (newlinesEncountered == lines) {
295: return s.substring(0, i);
296: }
297: }
298: }
299: return s;
300: }
301:
302: public static String limitLength(String s, int maxLength) {
303: Assert.isTrue(maxLength >= 3);
304:
305: if (s == null) {
306: return null;
307: }
308:
309: if (s.length() > maxLength) {
310: return s.substring(0, maxLength - 3) + "...";
311: }
312:
313: return s;
314: }
315:
316: public static boolean isNumber(String token) {
317: try {
318: Double.parseDouble(token);
319:
320: return true;
321: } catch (NumberFormatException e) {
322: return false;
323: }
324: }
325:
326: public static String toDelimitedString(Collection c,
327: String delimiter) {
328: if (c.isEmpty()) {
329: return "";
330: }
331:
332: StringBuffer result = new StringBuffer();
333:
334: for (Iterator i = c.iterator(); i.hasNext();) {
335: Object o = i.next();
336: result
337: .append(delimiter
338: + ((o == null) ? "" : o.toString()));
339: }
340:
341: return result.substring(delimiter.length());
342: }
343:
344: public static String toTimeString(long milliseconds) {
345: long remainder = milliseconds;
346: long days = remainder / 86400000;
347: remainder = remainder % 86400000;
348:
349: long hours = remainder / 3600000;
350: remainder = remainder % 3600000;
351:
352: long minutes = remainder / 60000;
353: remainder = remainder % 60000;
354:
355: long seconds = remainder / 1000;
356: String s = "";
357:
358: if (days > 0) {
359: s += (days + " days ");
360: }
361:
362: s += (Fmt.fmt(hours, 2, Fmt.ZF) + ":"
363: + Fmt.fmt(minutes, 2, Fmt.ZF) + ":" + Fmt.fmt(seconds,
364: 2, Fmt.ZF));
365:
366: return s;
367: }
368:
369: public static boolean isEmpty(String value) {
370: return (value == null || value.trim().length() == 0);
371: }
372: }
|