001: //$Id: StringHelper.java 10318 2006-08-23 13:36:35Z steve.ebersole@jboss.com $
002: package org.hibernate.util;
003:
004: import java.util.Iterator;
005: import java.util.StringTokenizer;
006: import java.util.ArrayList;
007:
008: public final class StringHelper {
009:
010: private static final int ALIAS_TRUNCATE_LENGTH = 10;
011: public static final String WHITESPACE = " \n\r\f\t";
012:
013: private StringHelper() { /* static methods only - hide constructor */
014: }
015:
016: /*public static boolean containsDigits(String string) {
017: for ( int i=0; i<string.length(); i++ ) {
018: if ( Character.isDigit( string.charAt(i) ) ) return true;
019: }
020: return false;
021: }*/
022:
023: public static int lastIndexOfLetter(String string) {
024: for (int i = 0; i < string.length(); i++) {
025: char character = string.charAt(i);
026: if (!Character.isLetter(character) /*&& !('_'==character)*/)
027: return i - 1;
028: }
029: return string.length() - 1;
030: }
031:
032: public static String join(String seperator, String[] strings) {
033: int length = strings.length;
034: if (length == 0)
035: return "";
036: StringBuffer buf = new StringBuffer(length
037: * strings[0].length()).append(strings[0]);
038: for (int i = 1; i < length; i++) {
039: buf.append(seperator).append(strings[i]);
040: }
041: return buf.toString();
042: }
043:
044: public static String join(String seperator, Iterator objects) {
045: StringBuffer buf = new StringBuffer();
046: if (objects.hasNext())
047: buf.append(objects.next());
048: while (objects.hasNext()) {
049: buf.append(seperator).append(objects.next());
050: }
051: return buf.toString();
052: }
053:
054: public static String[] add(String[] x, String sep, String[] y) {
055: String[] result = new String[x.length];
056: for (int i = 0; i < x.length; i++) {
057: result[i] = x[i] + sep + y[i];
058: }
059: return result;
060: }
061:
062: public static String repeat(String string, int times) {
063: StringBuffer buf = new StringBuffer(string.length() * times);
064: for (int i = 0; i < times; i++)
065: buf.append(string);
066: return buf.toString();
067: }
068:
069: public static String replace(String template, String placeholder,
070: String replacement) {
071: return replace(template, placeholder, replacement, false);
072: }
073:
074: public static String[] replace(String templates[],
075: String placeholder, String replacement) {
076: String[] result = new String[templates.length];
077: for (int i = 0; i < templates.length; i++) {
078: result[i] = replace(templates[i], placeholder, replacement);
079: ;
080: }
081: return result;
082: }
083:
084: public static String replace(String template, String placeholder,
085: String replacement, boolean wholeWords) {
086: int loc = template == null ? -1 : template.indexOf(placeholder);
087: if (loc < 0) {
088: return template;
089: } else {
090: final boolean actuallyReplace = !wholeWords
091: || loc + placeholder.length() == template.length()
092: || !Character.isJavaIdentifierPart(template
093: .charAt(loc + placeholder.length()));
094: String actualReplacement = actuallyReplace ? replacement
095: : placeholder;
096: return new StringBuffer(template.substring(0, loc)).append(
097: actualReplacement).append(
098: replace(template.substring(loc
099: + placeholder.length()), placeholder,
100: replacement, wholeWords)).toString();
101: }
102: }
103:
104: public static String replaceOnce(String template,
105: String placeholder, String replacement) {
106: int loc = template == null ? -1 : template.indexOf(placeholder);
107: if (loc < 0) {
108: return template;
109: } else {
110: return new StringBuffer(template.substring(0, loc)).append(
111: replacement).append(
112: template.substring(loc + placeholder.length()))
113: .toString();
114: }
115: }
116:
117: public static String[] split(String seperators, String list) {
118: return split(seperators, list, false);
119: }
120:
121: public static String[] split(String seperators, String list,
122: boolean include) {
123: StringTokenizer tokens = new StringTokenizer(list, seperators,
124: include);
125: String[] result = new String[tokens.countTokens()];
126: int i = 0;
127: while (tokens.hasMoreTokens()) {
128: result[i++] = tokens.nextToken();
129: }
130: return result;
131: }
132:
133: public static String unqualify(String qualifiedName) {
134: int loc = qualifiedName.lastIndexOf(".");
135: return (loc < 0) ? qualifiedName : qualifiedName
136: .substring(qualifiedName.lastIndexOf(".") + 1);
137: }
138:
139: public static String qualifier(String qualifiedName) {
140: int loc = qualifiedName.lastIndexOf(".");
141: return (loc < 0) ? "" : qualifiedName.substring(0, loc);
142: }
143:
144: public static String[] suffix(String[] columns, String suffix) {
145: if (suffix == null)
146: return columns;
147: String[] qualified = new String[columns.length];
148: for (int i = 0; i < columns.length; i++) {
149: qualified[i] = suffix(columns[i], suffix);
150: }
151: return qualified;
152: }
153:
154: private static String suffix(String name, String suffix) {
155: return (suffix == null) ? name : name + suffix;
156: }
157:
158: public static String root(String qualifiedName) {
159: int loc = qualifiedName.indexOf(".");
160: return (loc < 0) ? qualifiedName : qualifiedName.substring(0,
161: loc);
162: }
163:
164: public static String unroot(String qualifiedName) {
165: int loc = qualifiedName.indexOf(".");
166: return (loc < 0) ? qualifiedName : qualifiedName.substring(
167: loc + 1, qualifiedName.length());
168: }
169:
170: public static boolean booleanValue(String tfString) {
171: String trimmed = tfString.trim().toLowerCase();
172: return trimmed.equals("true") || trimmed.equals("t");
173: }
174:
175: public static String toString(Object[] array) {
176: int len = array.length;
177: if (len == 0)
178: return "";
179: StringBuffer buf = new StringBuffer(len * 12);
180: for (int i = 0; i < len - 1; i++) {
181: buf.append(array[i]).append(", ");
182: }
183: return buf.append(array[len - 1]).toString();
184: }
185:
186: public static String[] multiply(String string,
187: Iterator placeholders, Iterator replacements) {
188: String[] result = new String[] { string };
189: while (placeholders.hasNext()) {
190: result = multiply(result, (String) placeholders.next(),
191: (String[]) replacements.next());
192: }
193: return result;
194: }
195:
196: private static String[] multiply(String[] strings,
197: String placeholder, String[] replacements) {
198: String[] results = new String[replacements.length
199: * strings.length];
200: int n = 0;
201: for (int i = 0; i < replacements.length; i++) {
202: for (int j = 0; j < strings.length; j++) {
203: results[n++] = replaceOnce(strings[j], placeholder,
204: replacements[i]);
205: }
206: }
207: return results;
208: }
209:
210: public static int countUnquoted(String string, char character) {
211: if ('\'' == character) {
212: throw new IllegalArgumentException(
213: "Unquoted count of quotes is invalid");
214: }
215: if (string == null)
216: return 0;
217: // Impl note: takes advantage of the fact that an escpaed single quote
218: // embedded within a quote-block can really be handled as two seperate
219: // quote-blocks for the purposes of this method...
220: int count = 0;
221: int stringLength = string.length();
222: boolean inQuote = false;
223: for (int indx = 0; indx < stringLength; indx++) {
224: char c = string.charAt(indx);
225: if (inQuote) {
226: if ('\'' == c) {
227: inQuote = false;
228: }
229: } else if ('\'' == c) {
230: inQuote = true;
231: } else if (c == character) {
232: count++;
233: }
234: }
235: return count;
236: }
237:
238: public static int[] locateUnquoted(String string, char character) {
239: if ('\'' == character) {
240: throw new IllegalArgumentException(
241: "Unquoted count of quotes is invalid");
242: }
243: if (string == null) {
244: return new int[0];
245: }
246:
247: ArrayList locations = new ArrayList(20);
248:
249: // Impl note: takes advantage of the fact that an escpaed single quote
250: // embedded within a quote-block can really be handled as two seperate
251: // quote-blocks for the purposes of this method...
252: int stringLength = string.length();
253: boolean inQuote = false;
254: for (int indx = 0; indx < stringLength; indx++) {
255: char c = string.charAt(indx);
256: if (inQuote) {
257: if ('\'' == c) {
258: inQuote = false;
259: }
260: } else if ('\'' == c) {
261: inQuote = true;
262: } else if (c == character) {
263: locations.add(new Integer(indx));
264: }
265: }
266: return ArrayHelper.toIntArray(locations);
267: }
268:
269: public static boolean isNotEmpty(String string) {
270: return string != null && string.length() > 0;
271: }
272:
273: public static boolean isEmpty(String string) {
274: return string == null || string.length() == 0;
275: }
276:
277: public static String qualify(String prefix, String name) {
278: if (name == null || prefix == null) {
279: throw new NullPointerException();
280: }
281: return new StringBuffer(prefix.length() + name.length() + 1)
282: .append(prefix).append('.').append(name).toString();
283: }
284:
285: public static String[] qualify(String prefix, String[] names) {
286: if (prefix == null)
287: return names;
288: int len = names.length;
289: String[] qualified = new String[len];
290: for (int i = 0; i < len; i++) {
291: qualified[i] = qualify(prefix, names[i]);
292: }
293: return qualified;
294: }
295:
296: public static int firstIndexOfChar(String sqlString, String string,
297: int startindex) {
298: int matchAt = -1;
299: for (int i = 0; i < string.length(); i++) {
300: int curMatch = sqlString.indexOf(string.charAt(i),
301: startindex);
302: if (curMatch >= 0) {
303: if (matchAt == -1) { // first time we find match!
304: matchAt = curMatch;
305: } else {
306: matchAt = Math.min(matchAt, curMatch);
307: }
308: }
309: }
310: return matchAt;
311: }
312:
313: public static String truncate(String string, int length) {
314: if (string.length() <= length) {
315: return string;
316: } else {
317: return string.substring(0, length);
318: }
319: }
320:
321: public static String generateAlias(String description) {
322: return generateAliasRoot(description) + '_';
323: }
324:
325: /**
326: * Generate a nice alias for the given class name or collection role
327: * name and unique integer. Subclasses of Loader do <em>not</em> have
328: * to use aliases of this form.
329: * @return an alias of the form <tt>foo1_</tt>
330: */
331: public static String generateAlias(String description, int unique) {
332: return generateAliasRoot(description)
333: + Integer.toString(unique) + '_';
334: }
335:
336: /**
337: * Generates a root alias by truncating the "root name" defined by
338: * the incoming decription and removing/modifying any non-valid
339: * alias characters.
340: *
341: * @param description The root name from which to generate a root alias.
342: * @return The generated root alias.
343: */
344: private static String generateAliasRoot(String description) {
345: String result = truncate(unqualifyEntityName(description),
346: ALIAS_TRUNCATE_LENGTH).toLowerCase().replace('/', '_') // entityNames may now include slashes for the representations
347: .replace('$', '_'); //classname may be an inner class
348: result = cleanAlias(result);
349: if (Character.isDigit(result.charAt(result.length() - 1))) {
350: return result + "x"; //ick!
351: } else {
352: return result;
353: }
354: }
355:
356: /**
357: * Clean the generated alias by removing any non-alpha characters from the
358: * beginning.
359: *
360: * @param alias The generated alias to be cleaned.
361: * @return The cleaned alias, stripped of any leading non-alpha characters.
362: */
363: private static String cleanAlias(String alias) {
364: char[] chars = alias.toCharArray();
365: // short cut check...
366: if (!Character.isLetter(chars[0])) {
367: for (int i = 1; i < chars.length; i++) {
368: // as soon as we encounter our first letter, return the substring
369: // from that position
370: if (Character.isLetter(chars[i])) {
371: return alias.substring(i);
372: }
373: }
374: }
375: return alias;
376: }
377:
378: public static String unqualifyEntityName(String entityName) {
379: String result = unqualify(entityName);
380: int slashPos = result.indexOf('/');
381: if (slashPos > 0) {
382: result = result.substring(0, slashPos - 1);
383: }
384: return result;
385: }
386:
387: public static String toUpperCase(String str) {
388: return str == null ? null : str.toUpperCase();
389: }
390:
391: public static String toLowerCase(String str) {
392: return str == null ? null : str.toLowerCase();
393: }
394:
395: public static String moveAndToBeginning(String filter) {
396: if (filter.trim().length() > 0) {
397: filter += " and ";
398: if (filter.startsWith(" and "))
399: filter = filter.substring(4);
400: }
401: return filter;
402: }
403:
404: }
|