001// Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 
002// The Molly framework is freely distributable under the terms of an
003// MIT-style license. For details, see the molly pages web site at:
004// http://www.mollypages.org/. Use, modify, have fun !
005
006package fc.util;
007
008import java.util.*;
009
010/** 
011Utility functions related to java.lang.String, i.e 
012functions that are useful but not provided by that class.
013
014@author hursh jain
015*/
016public final class StringUtil
017{
018/** 
019Returns an empty string if the specified argument was null,
020otherwise returns the argument itself. 
021**/
022public static String nullToEmpty(String val) 
023  {
024  if (val == null) {
025    return "";
026    }
027  return val;
028  }
029
030/** 
031Returns an empty string if the specified argument was null,
032otherwise returns the value of the toString() method invoked
033on the specified object. 
034**/
035public static String nullToEmpty(Object val) 
036  {
037  if (val == null) {
038    return "";
039    }
040  return val.toString();
041  }
042
043
044/** 
045Returns true if the specified String is either null or empty. 
046**/
047public static boolean nullOrEmpty(String str) 
048  {
049  return str != null && str.isEmpty();
050  }
051
052
053/** 
054Returns a String containing a string of the specified character concatenated
055the specified number of times. Returns an empty string if length
056is less than/equal to zero
057
058@param c    the character to be repeated
059@param length the repeat length
060*/
061public static String repeat(char c, int length)
062  {
063  StringBuffer b = new StringBuffer();
064  for (int n = 0; n < length; n++) {
065    b.append(c);
066    }
067  return b.toString();
068  }
069
070/** 
071Returns a String containing the specified string concatenated
072the specified number of times.
073
074@param str    the string to be repeated
075@param length the repeat length
076*/
077public static String repeat(String str, int length)
078  {
079  int len = str.length();
080  StringBuffer b = new StringBuffer(len*length);
081  for (int n = 0; n < length; n++) {
082    b.append(str);
083    }
084  return b.toString();
085  }
086
087/** 
088Contatenates the given string so that the maximum length reached
089is the specified length. If the specified string does not fit in
090the length, then the string is truncated appropriately.
091
092@param  str   the string to repeat 
093@param  length  the length of the returned string
094**/
095public static String repeatToWidth(String str, int length)
096  {
097  Argcheck.notnull(str, "specified string was null");
098    
099  int strlen = str.length();  
100  
101  //strlen.range:     [0,inf)
102  //repeat length range:  (-inf, inf)
103  
104  if (strlen == length)   
105    return str;
106
107  if (strlen > length)
108    return str.substring(0, length);
109
110
111  //strlen.range now    [1, inf)  
112
113  int multiple   = length / strlen; 
114  int fractional = length % strlen;
115
116  String result = repeat(str, multiple);
117
118  if (fractional != 0) { 
119    result = result.concat(str.substring(0, fractional));
120    }
121    
122  return result;
123  }
124
125
126/** 
127Converts the specified String into a fixed width string,
128left padding (with a blank space) or truncating on the right as necessary. 
129(i.e., the specified string is aligned left w.r.t to the specified width).
130
131@param  str   the target string
132@param  width the fixed width
133
134@return the transformed string
135**/
136public static String fixedWidth(String str, int width) 
137  {   
138  return fixedWidth(str, width, HAlign.LEFT, ' ');
139  }
140  
141/** 
142Calls {@link fixedWidth(String, int, HAlign, char)} specifying
143the padding character as a blank space.
144**/
145public static String fixedWidth(String str, int width, HAlign align) 
146  {
147  return fixedWidth(str, width, align, ' ');
148  }
149  
150
151/** 
152Converts the specified String into a fixed width string. Strings
153lesser in size than the fixed width are padded or truncated as
154required by the specified alignment.
155
156@param  str     the target string
157@param  width   the fixed width
158@param  align     the alignment of the target string within the width
159@param  paddingChar the character to pad the string (if necessary);
160
161@return the transformed string
162**/
163public static String fixedWidth(
164 String str, int width, HAlign align, char paddingChar) 
165  {
166  if (str == null)
167    str = "";
168    
169  int len = str.length();
170
171  if (len < width) 
172    {
173    if (align == HAlign.LEFT) {
174      str = str + repeat(paddingChar, width-len);
175      }
176    else if (align == HAlign.RIGHT) {
177      str = repeat(paddingChar, width-len) + str;
178      }
179    else if (align == HAlign.CENTER) {
180      //arbitrary tie-break, if the diff is odd then the
181      //1 extra space is padded on the right side
182  
183      int diff = (width-len);   
184      String temp = repeat(paddingChar, diff/2);
185      str = temp + str + temp + repeat(paddingChar, diff%2);
186      }
187    else throw new IllegalArgumentException("Do not understand the specified alignment: " + align);
188    }
189
190
191  else if (len > width) {
192    str = str.substring(0, width);
193    }
194    
195  return str; 
196  }
197
198/**
199Converts the specified String into a string with maxlen characters, using the specified
200ellipsis as the suffix to denote the missing characters.
201
202@param  str     the target string
203@param  ellipsis  the ellipsis suffix
204@param  width   the max length, <b>including</b> the ellipsis
205
206@return the transformed string
207*/
208public static String ellipsis(String str, String ellipsis, int maxlen)
209  {
210  if (str.length() > maxlen)
211    {
212      str = str.substring(0, maxlen - ellipsis.length()) + ellipsis;
213    }
214  
215  return str;
216  }
217
218/**
219Converts the specified String into a string with maxlen characters, using <code>...<code>
220as the suffix to denote the missing characters.
221
222@param  str     the target string
223@param  width   the max length, <b>including</b> the ellipsis ("...")
224
225@return the transformed string
226*/
227public static String ellipsis(String str, int maxlen)
228  {
229  return ellipsis(str, "...", maxlen);
230  }
231
232
233/** 
234Removes all occurences of specified characters from the specified 
235string and returns the new resulting string.
236@param  target  the string to remove characters from
237@param  chars an array of characters, each of which is to be removed
238*/
239public static String remove(String target, char[] chars)
240  {
241  if (target == null || chars == null) return target;
242  int strlen = target.length();
243  char[] newstr = new char[strlen];
244  char[] oldstr = new char[strlen];
245  target.getChars(0,strlen,oldstr,0);
246  int replacelen = chars.length;
247  
248  int oldindex = -1;
249  int newindex = -1;
250  char c = 0;
251  boolean found = false;
252
253  while (++oldindex < strlen) 
254    {
255    c = oldstr[oldindex];
256    found = false;
257    for (int j = 0; j < replacelen; j++) 
258      {
259      if (c == chars[j]) {
260        found = true;
261        break;
262        }
263      } //~for
264    if (!found) 
265      {
266      newstr[++newindex] = c;
267      }
268    }   //~while
269  return new String(newstr, 0, newindex+1);
270  }     //~remove()
271
272
273/**
274Removes the last forward or backward slash from the specified
275string (if any) and returns the resulting String. Returns <tt>null</tt>
276if a null argument is specified. The trailing slash is a slash that
277is the last character of the specified string.
278**/
279public static String removeTrailingSlash(String str)
280  {
281  String res = str;
282  if (str == null) return null; 
283  int len = str.length();
284  if (len == 0)
285    return str;  //str was ""
286  char c = str.charAt(len-1);
287  if (c == '/' || c == '\\') {
288    res = str.substring(0, len-1);  //len-1 will be >= 0
289    }
290  return res;     
291  }
292
293/**
294Removes the starting (at the very beginning of the string) forward or 
295backward slash from the specified string (if any) and returns the 
296resulting String. Returns <tt>null</tt> if  null argument is specified.
297**/
298public static String removeBeginningSlash(String str)
299  {
300  if (str == null) return null; 
301  int len = str.length();
302  if (len == 0) 
303    return str;  //str was ""
304  char c = str.charAt(0);
305  if (c == '/' || c == '\\') 
306    {
307    if (len > 1) { 
308      return str.substring(1);
309      }
310    else { //str was "/"
311      return "";  
312      }
313    }
314  return str;
315  }
316
317/**
318Removes the any file extension (.foo for example) from the specified name
319and returns the resulting String. Returns <tt>null</tt> if the specified
320path was null. This method takes a String as a parameter, as opposed to a
321<tt>java.io.File</tt> because the caller knows best what portion of the
322filename should be modified and returned by this method (full path name,
323name without path information etc).
324
325@param  name the String denoting the file name to remove the extension from
326**/
327public static String removeSuffix(String name)
328  {
329  String result = null;
330  if (name == null)
331    return result;
332  result = name.replaceFirst("(.+)(\\..+)","$1");
333  //System.out.println("File " + name + " after removing extension =" + name);  
334  return result;
335  }
336
337/** 
338Returns the path component of the specified filename. If no path exists
339or the specified string is null, returns the empty string <tt>""</tt>.
340<u>The path separator in the specified string should be <tt>/</tt></u>.
341If on a platform where this is not the case, the specified string should
342be modified to contain "/" before invoking this method. The returned
343pathName <b>does</b>
344contain the trailing "/". This ensures that 
345<tt>dirName(somepath) + fileName(somepath)</tt> will always be equal to <tt>somepath</tt>.
346<p>
347<blockquote>
348<pre>
349The functionality of this method is different than java.io.File.getName()
350and getParent(). Also unix dirname, basename are also compared below.
351
352//Using java.io.File (getPath() returns the entire name, identical to
353//the input, so is not shown. Sample run on windows:
354Name=''         ; getName()='';       getParent()='null'
355Name='/'        ; getName()='';       getParent()='null'
356Name='/a'       ; getName()='a';      getParent()='\'
357Name='a/b'      ; getName()='b';      getParent()='a'
358Name='a/b.txt'  ; getName()='b.txt';  getParent()='a'
359Name='b.txt'    ; getName()='b.txt';  getParent()='null'
360
361Name='/a/'      ; getName()='a';      getParent()='\'
362Name='/a/b/'    ; getName()='b';      getParent()='\a'
363Name='a/b/'     ; getName()='b';      getParent()='a'
364----------------------------
365//Using these methods:
366Name=''         ; fileName()='';      dirName()=''
367Name='/'        ; fileName()='';      dirName()='/' 
368Name='/a'       ; fileName()='a';     dirName()='/' 
369Name='a/b'      ; fileName()='b';     dirName()='a/' 
370Name='a/b.txt'  ; fileName()='b.txt'; dirName()='a/' 
371Name='b.txt'    ; fileName()='b.txt'; dirName()='' 
372
373Name='/a/'      ; fileName()='';      dirName()='/a/'
374Name='/a/b/'    ; fileName()='';      dirName()='/a/b/'
375Name='a/b/'     ; fileName()='';      dirName()='a/b/'
376-----------------------------
377//unix basename, dirname
378Name=''         ; basename()='';    dirname()=''
379Name='/'        ; basename()='/';   dirname()='/' 
380Name='/a'       ; basename()='a';     dirname()='/' 
381Name='a/b'      ; basename()='b';     dirname()='a/' 
382Name='a/b.txt'  ; basename()='b.txt'; dirname()='a/' 
383Name='b.txt'    ; basename()='b.txt'; dirname()='.' 
384
385Name='/a/'      ; basename()='a';     dirname()='/'
386Name='a/b/'     ; basename()='b';     dirname()='a'
387Name='/a/b/'  ; fileName()='b';     dirName()='a'
388
389-----------------------------
390</pre>
391Note, the main differences among the 3 approaches above are in the last 
3922 statements in each section.
393</blockquote>
394**/
395public static String dirName(String str) 
396  {
397  String res = "";
398  if (str == null)
399    return res;
400  int pos = str.lastIndexOf("/");
401  if (pos == -1)
402    return "";
403  return str.substring(0, (pos+1));
404  }
405
406/** 
407Returns the file component of specified filename. If no filename exists
408or the specified string is null, returns the empty string <tt>""</tt>.
409<u>The path separator in the specified string is always assumed to be
410<tt>/</tt></u>. If on a platform where this is not the case, the
411specified string should be modified to contain "/" before invoking this
412method. The returned file name does <b>not</b> contain the preceding "/".
413**/
414public static String fileName(String str) 
415  {
416  String res = "";
417  if (str == null)
418    return res;
419  int pos = str.lastIndexOf("/");
420  if (pos == -1)
421    return str;
422  
423  int strlen = str.length();
424  if (strlen == 1)
425    return res; //we return "" since the string has to be "/" 
426  else
427    pos++;    //skip "/" in other strings
428    
429  return str.substring(pos, strlen); //will return "" if str = "/"
430  }
431
432
433/** 
434Splits the string using the specified delimiters and
435returns the splits parts in a List. Use {@link
436java.lang.String#split} instead for greater options.
437
438@param  str   the string to be tokenized
439@param  delim delimiter string, each character in the string will be used 
440        as a delimiter to use while tokenizing
441*/
442public static List split(String str, String delim)
443  {   
444  int pos = 0;    //current position pointer in the string (str)
445  List result = new ArrayList();  
446  StringTokenizer st = new StringTokenizer(str,delim);
447    while (st.hasMoreTokens()) {
448            //tokens are stored as lowercase
449        result.add(st.nextToken().toLowerCase());  
450        }
451  return result;  
452  }
453
454/** 
455Joins the elements of the specified list, delimited by
456the specified delimiter.
457
458@param  list  containing the elements to be joined.
459@param  delim delimits each element from the next
460*/
461public static String join(List list, String delim)
462  { 
463  Argcheck.notnull(list, "specified list param was null");
464  Argcheck.notnull(delim, "specified delim param was null");
465
466  int size = list.size();
467  int size_minus_one = size -1 ;
468  StringBuffer buf = new StringBuffer(size * 16);
469  
470  for (int n = 0; n < size; n++) {
471    buf.append(list.get(n).toString());
472    if ( n < (size_minus_one)) {
473      buf.append(delim);
474      }
475    }
476    
477  return buf.toString();  
478  } 
479
480
481/* TO DO: LATER
482Removes all whitespace in the specified string and returns all words 
483with only a single space between them. Uses a Perl regular expression 
484to do this.
485  public synchronized static void makeSingleSpaced(String target)
486  throws Exception
487  {
488  String regex1 = "s\\?([^\"]+)\\s*(target)?[^>]*>([^>]*)</a>"; 
489  MatchResult result;
490  Perl5Pattern pattern =  (Perl5Pattern)StringUtil.compiler.compile(
491                regex1,
492                Perl5Compiler.CASE_INSENSITIVE_MASK | 
493                Perl5Compiler.SINGLELINE_MASK); 
494  
495  }
496*/
497
498/**
499Converts the specified String to start with a capital letter. Only
500the first character is made uppercase, the rest of the specified
501string is not affected.
502**/
503public static String capitalWord(String str) 
504  {
505  int strlen = str.length();
506  StringBuffer buf = new StringBuffer(strlen);
507  buf.append( str.substring(0,1).toUpperCase() + 
508        str.substring(1, strlen) ); 
509  return buf.toString(); 
510  }
511
512/**
513Converts the specified String to be in sentence case, whereby
514the first letter of each word in the sentence is uppercased
515and all other letters are lowercased. The characters in the
516delimiter string are used to delimit words in the sentence.
517If the delimiter string is <tt>null</tt>, the original string
518is returned as-is.
519<br>
520A runtime exception will be thrown if the specified string
521was <tt>null</tt>.
522**/
523public static String sentenceCase(String str, String delimiters)
524  {
525  Argcheck.notnull(str, "specified string was null");
526  if (delimiters == null) 
527    return str;
528    
529  int strlen = str.length();
530  StringBuffer out = new StringBuffer(strlen);
531  StringBuffer temp = new StringBuffer(strlen);
532  for (int n = 0; n < strlen; n++)
533    {
534    //System.out.print("["+n+"] ");
535    char current_char = str.charAt(n);
536    if (delimiters.indexOf(current_char) >= 0) {
537      //System.out.println("->"+current_char);
538      if (temp.length() > 0 ) {
539        out.append( temp.substring(0, 1).toUpperCase() );
540        out.append( temp.substring(1, temp.length()).toLowerCase() );
541        }
542      out.append(current_char);
543      //System.out.println("temp="+temp);
544      temp = new StringBuffer(strlen);
545      continue;
546      }
547    temp.append(current_char);  
548    }
549  if (temp.length() > 0 ) {
550    out.append( temp.substring(0, 1).toUpperCase() );
551    out.append( temp.substring(1, temp.length()).toLowerCase() );
552    }
553  return out.toString();
554  }
555  
556static final String[] VIEW_ASCII = {
557/*0*/ "NUL", "[ascii(1)]", "[ascii(2)]", "[ascii(3)]", "[ascii(4)]",
558/*5*/ "[ascii(5)]", "[ascii(6)]", "\\a", "\\b", "\\t",
559/*10*/  "\\n", "\\v", "[ascii(12)]", "\\r", "[ascii(14)]",
560/*15*/  "[ascii(15)]", "[ascii(16)]", "[ascii(17)", "[ascii(18)]", "[ascii(19)]",
561/*20*/  "[ascii(20)]", "[ascii(21)]", "[ascii(22)]", "ascii(23)]", "[ascii(24)]",
562/*25*/  "[ascii(25)]", "[ascii(26)]", "\\e", "[ascii(28)]", "[ascii(29)]",
563/*30*/  "[ascii(30)]", "[ascii(31)]" 
564};  
565  
566/**
567Converts non printable ascii characters in the specified String
568to escaped or readable equivalents. For example, a newline is
569converted to the sequence <tt>\n</tt> and say, ascii character 29 is 
570converted to the sequence of chars: '<tt>ascii(29)</tt>'. 
571<p>
572If the specified String is <tt>null</tt>, this method returns 
573<tt>null</tt>.
574
575@param  str   the String to convert
576@return the converted String
577**/     
578public static String viewableAscii(String str) 
579  {
580  if (str == null)
581    return null;
582  
583  int strlen = str.length();
584  StringBuffer buf = new StringBuffer(strlen);
585  
586  //ignore all non ascii data, including UTF-16 surrogate bytes etc.
587  //by replacing such data with '?'   
588  for(int n = 0; n < strlen; n++) 
589    {
590    char c = str.charAt(n);
591    if ( c < 32) 
592      buf.append(VIEW_ASCII[c]);
593    else if ( c > 255) 
594      buf.append('?');
595    else
596      buf.append(c);
597    } 
598  return buf.toString();
599  } 
600
601/**
602A version of {@link viewableAscii(String)} that takes a
603single char as a parameter.
604
605@param  char the char to convert
606@return the ascii readable char
607**/
608public static String viewableAscii(char c) 
609  {
610  if ( c < 32) 
611    return VIEW_ASCII[c];
612  else if ( c > 255) 
613    return "?";
614  else
615    return new String(new char[] {c});
616  }
617
618/**
619Converts a character array into a viewable comma delimited
620string. Non-printable/readable characters are shown as
621readable equivalents.
622*/
623public static String arrayToString(char[] array) {
624  if (array == null) {
625    return "null";
626    }
627  int arraylen = array.length;
628  StringBuffer buf = new StringBuffer(arraylen * 2);
629  buf.append("[");
630  int n = 0;
631  while (n < arraylen) {
632    buf.append(viewableAscii(array[n]));
633    n++;
634    if (n != arraylen)
635      buf.append(", ");
636    }
637  buf.append("]");
638  return buf.toString();
639  }
640
641
642/**
643Converts a list into a string, each item being seperated by the specified delimiter.
644Each item in the list is converted by invokign <code>toString</code> on that item
645so the specified delimiter only applies to the outermost level. 
646<p>
647The converted string does not start or end with any characters. To specify the start/end, use {@link listToString(List, String, String, String)} 
648*/
649public static String listToString(List list, String delim) 
650  {
651  return listToString(list, delim, "", "");
652  }
653
654/**
655Converts a list into a string, each item being seperated by the specified delimiter.
656Each item in the list is converted by invokign <code>toString</code> on that item
657so the specified delimiter only applies to the outermost level. 
658<p>
659The converted string start and ends with the specified chars as well. 
660*/
661public static String listToString(List list, String delim, String start, String end) 
662  {
663  StringBuilder buf = new StringBuilder();
664  buf.append(start);  
665    
666  if (list != null) 
667    {
668    final int size = list.size();
669    for (int n = 0; n < size; n++) 
670      {
671      buf.append(list.get(n));
672      if (n + 1 < size) {
673        buf.append(delim);
674        }
675      }
676    }
677    
678  buf.append(end);
679  
680  return buf.toString();
681  }
682
683/**
684Escapes all single quotes in the specified a string with a backslash
685character. 
686*/
687public static String escapeSingleQuotes(final String str)
688  {
689  return escapeSingleQuotes(str, "\\");
690  }
691
692/**
693Escapes all single quotes in the specified a string with the specified
694escape character. So, if the specified escape character is <tt>'</tt>, 
695all occurrences of <tt>o'tis the ele'phant</tt> becomes 
696<tt>o''tis the ele''phant</tt>
697*/
698public static String escapeSingleQuotes(final String str, String escape)
699  {
700  if (str == null)
701    return null;
702  
703  final int len = str.length();
704  if (len == 0)
705    return str;
706    
707  final StringBuilder buf = new StringBuilder(len * 2);
708  for (int n = 0; n < len; n++) 
709    {
710    char c = str.charAt(n);
711    if (c == '\'') {
712      buf.append(escape);
713      buf.append('\'');
714      }
715    else{
716      buf.append(c);
717      }
718    }
719  return buf.toString();
720  }
721  
722/**
723Escapes all double quotes in the specified a string with a backslash
724character. 
725*/
726public static String escapeDoubleQuotes(final String str)
727  {
728  return escapeSingleQuotes(str, "\\");
729  }
730
731/**
732Escapes all double quotes in the specified a string with the specified
733escape character. So, if the specified escape character is <tt>\</tt>, 
734all occurrences of <tt>o"tis the ele"phant</tt> becomes 
735<tt>o\"tis the ele\"phant</tt>
736*/
737public static String escapeDoubleQuotes(final String str, String escape)
738  {
739  if (str == null)
740    return null;
741  
742  final int len = str.length();
743  if (len == 0)
744    return str;
745    
746  final StringBuilder buf = new StringBuilder(len * 2);
747  for (int n = 0; n < len; n++) 
748    {
749    char c = str.charAt(n);
750    if (c == '"') {
751      buf.append(escape);
752      buf.append('"');
753      }
754    else{
755      buf.append(c);
756      }
757    }
758  return buf.toString();
759  } 
760
761//unit test
762public static void main(String[] args)
763{
764String teststr = "hahaha, my name is ha";
765char[] remove = new char[] {'h','m'};
766System.out.println("testing StringUtil.remove(\"" + teststr + "\",'" + String.valueOf(remove) + "')");
767String newstr = StringUtil.remove(teststr,remove);
768System.out.println("result>>" + newstr + "<<");
769System.out.println("Original String length: " + teststr.length() +" ; New String length: " + newstr.length());
770System.out.println(":" + repeat(' ',20) + ":");
771
772System.out.println("sentenceCase(\"hello world\", \" \"): ["
773          + sentenceCase("hello world", " ") + "]");
774System.out.println("sentenceCase(\"helloworld\", \" \"): ["
775          + sentenceCase("helloworld", " ") + "]");
776System.out.println("sentenceCase(\"  hello world\", \" \"): ["
777          + sentenceCase("  hello world", " ") + "]");
778System.out.println("sentenceCase(\"hello world  \", \" \"): ["
779          + sentenceCase("hello world  ", " ") + "]");
780System.out.println("sentenceCase(\"hello_world  \", \"_\"): ["
781          + sentenceCase("hello_world  ", "_") + "]");
782System.out.println("sentenceCase(\"__hello_world_ foo  \", \"_ \"): ["
783          + sentenceCase("__hello_world_ foo  ", "_ ") + "]");
784System.out.println("sentenceCase(\"foXbAr\", \"X\"): ["
785          + sentenceCase("foXbAr", "X") + "]");
786      
787
788System.out.println("viewableAscii(abc[newline]foo[tab]\\u4234)="+viewableAscii("abc\nfoo\t\u4234"));
789for(char c = 0; c < 255; c++) {
790  System.out.print(viewableAscii(c));   
791  }
792System.out.println("");
793
794System.out.println("remove trailing slash on '' = " + removeTrailingSlash(""));
795System.out.println("remove trailing slash on '/' = " + removeTrailingSlash(""));
796System.out.println("remove trailing slash on 'foo/' = " + removeTrailingSlash("foo/"));
797System.out.println("remove beginning slash on '' = " + removeBeginningSlash(""));
798System.out.println("remove beginning slash on '/' = " + removeBeginningSlash("/"));
799System.out.println("remove beginning slash on '/foo' = " + removeBeginningSlash("/foo"));
800
801System.out.println("====fixed width tests");
802String fixedin = "hello";
803int width = 15;
804System.out.println("fixed width input string: " + fixedin);
805System.out.println("fixed width = 15");
806System.out.println("align default: [" + fixedWidth(fixedin, width) + "]");
807System.out.println("align left: [" + fixedWidth(fixedin, width, HAlign.LEFT) + "]");
808System.out.println("align right : [" + fixedWidth(fixedin, width, HAlign.RIGHT) + "]");
809System.out.println("align center: [" + fixedWidth(fixedin, width, HAlign.CENTER) + "]");
810
811System.out.println("repeatToWidth('hello', 0)="+repeatToWidth("hello", 0));
812System.out.println("repeatToWidth('hello', 1)="+repeatToWidth("hello", 1));
813System.out.println("repeatToWidth('hello', 5)="+repeatToWidth("hello", 5));
814System.out.println("repeatToWidth('hello', 9)="+repeatToWidth("hello", 9));
815System.out.println("repeatToWidth('hello', 10)="+repeatToWidth("hello", 10));
816System.out.println("repeatToWidth('hello', 11)="+repeatToWidth("hello", 11));
817
818System.out.println("repeatToWidth('X', 0)=["+repeatToWidth("X", 0) +"]");
819
820System.out.println("escapeSingleQuotes(\"'\")="+escapeSingleQuotes("'"));
821System.out.println("escapeSingleQuotes(\"\")="+escapeSingleQuotes(""));
822System.out.println("escapeSingleQuotes(\"'foo'bar'\")="+escapeSingleQuotes("'foo'bar'"));
823System.out.println("escapeSingleQuotes(\"'''\")="+escapeSingleQuotes("'''"));
824System.out.println("escapeSingleQuotes(\"'foo'bar'\", \"'\")="+escapeSingleQuotes("'foo'bar'", "'"));
825
826
827System.out.println("listToString(null):" + listToString(null, "x"));
828List list = new ArrayList();
829list.add(1);
830list.add(2);
831System.out.println("listToString([1,2] / [ ]): " +listToString(list,"/","[","]"));
832
833System.out.println("ellipsis('hello world', 8): " + ellipsis("hello world", 8));
834}
835
836}     //~class StringUtil