00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 package Acme;
00030
00031 import java.util.*;
00032 import java.io.*;
00033 import java.net.*;
00034 import java.text.SimpleDateFormat;
00035
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 public class Utils
00055 {
00056
00058
00059 static final SimpleDateFormat shortfmt = new SimpleDateFormat("MMM dd HH:mm");
00060 static final SimpleDateFormat longfmt = new SimpleDateFormat("MMM dd yyyy");
00061 public static String lsDateStr( Date date )
00062 {
00063 if ( Math.abs( System.currentTimeMillis() - date.getTime() ) < 183L * 24L * 60L * 60L * 1000L )
00064 return shortfmt.format(date);
00065 else
00066 return longfmt.format(date);
00067 }
00068
00069
00071 public static String pluralStr( long n )
00072 {
00073 if ( n == 1 )
00074 return "";
00075 else
00076 return "s";
00077 }
00078
00079
00080
00081 public static final long INT_SECOND = 1000L;
00082 public static final long INT_MINUTE = INT_SECOND * 60L;
00083 public static final long INT_HOUR = INT_MINUTE * 60L;
00084 public static final long INT_DAY = INT_HOUR * 24L;
00085 public static final long INT_WEEK = INT_DAY * 7L;
00086 public static final long INT_MONTH = INT_DAY * 30L;
00087 public static final long INT_YEAR = INT_DAY * 365L;
00088 public static final long INT_DECADE = INT_DAY * 3652L;
00089
00091
00092 public static String intervalStr( long interval )
00093 {
00094 long decades, years, months, weeks, days, hours, minutes, seconds, millis;
00095
00096 decades = interval / INT_DECADE;
00097 interval -= decades * INT_DECADE;
00098 years = interval / INT_YEAR;
00099 interval -= years * INT_YEAR;
00100 months = interval / INT_MONTH;
00101 interval -= months * INT_MONTH;
00102 weeks = interval / INT_WEEK;
00103 interval -= weeks * INT_WEEK;
00104 days = interval / INT_DAY;
00105 interval -= days * INT_DAY;
00106 hours = interval / INT_HOUR;
00107 interval -= hours * INT_HOUR;
00108 minutes = interval / INT_MINUTE;
00109 interval -= minutes * INT_MINUTE;
00110 seconds = interval / INT_SECOND;
00111 interval -= seconds * INT_SECOND;
00112 millis = interval;
00113
00114 if ( decades > 0 )
00115 if ( years == 0 )
00116 return decades + " decade" + pluralStr( decades );
00117 else
00118 return
00119 decades + " decade" + pluralStr( decades ) + ", " +
00120 years + " years" + pluralStr( years );
00121 else if ( years > 0 )
00122 if ( months == 0 )
00123 return years + " year" + pluralStr( years );
00124 else
00125 return
00126 years + " year" + pluralStr( years ) + ", " +
00127 months + " month" + pluralStr( months );
00128 else if ( months > 0 )
00129 if ( weeks == 0 )
00130 return months + " month" + pluralStr( months );
00131 else
00132 return
00133 months + " month" + pluralStr( months ) + ", " +
00134 weeks + " week" + pluralStr( weeks );
00135 else if ( weeks > 0 )
00136 if ( days == 0 )
00137 return weeks + " week" + pluralStr( weeks );
00138 else
00139 return
00140 weeks + " week" + pluralStr( weeks ) + ", " +
00141 days + " day" + pluralStr( days );
00142 else if ( days > 0 )
00143 if ( hours == 0 )
00144 return days + " day" + pluralStr( days );
00145 else
00146 return
00147 days + " day" + pluralStr( days ) + ", " +
00148 hours + " hour" + pluralStr( hours );
00149 else if ( hours > 0 )
00150 if ( minutes == 0 )
00151 return hours + " hour" + pluralStr( hours );
00152 else
00153 return
00154 hours + " hour" + pluralStr( hours ) + ", " +
00155 minutes + " minute" + pluralStr( minutes );
00156 else if ( minutes > 0 )
00157 if ( seconds == 0 )
00158 return minutes + " minute" + pluralStr( minutes );
00159 else
00160 return
00161 minutes + " minute" + pluralStr( minutes ) + ", " +
00162 seconds + " second" + pluralStr( seconds );
00163 else if ( seconds > 0 )
00164 if ( millis == 0 )
00165 return seconds + " second" + pluralStr( seconds );
00166 else
00167 return
00168 seconds + " second" + pluralStr( seconds ) + ", " +
00169 millis + " millisecond" + pluralStr( millis );
00170 else
00171 return millis + " millisecond" + pluralStr( millis );
00172 }
00173
00174
00176
00177 public static int strSpan( String str, String charSet )
00178 {
00179 return strSpan( str, charSet, 0 );
00180 }
00181
00183
00184 public static int strSpan( String str, String charSet, int fromIdx )
00185 {
00186 int i;
00187 for ( i = fromIdx; i < str.length(); ++i )
00188 if ( charSet.indexOf( str.charAt( i ) ) == -1 )
00189 break;
00190 return i - fromIdx;
00191 }
00192
00194
00195 public static int strCSpan( String str, String charSet )
00196 {
00197 return strCSpan( str, charSet, 0 );
00198 }
00199
00201
00202 public static int strCSpan( String str, String charSet, int fromIdx )
00203 {
00204 int i;
00205 for ( i = fromIdx; i < str.length(); ++i )
00206 if ( charSet.indexOf( str.charAt( i ) ) != -1 )
00207 break;
00208 return i - fromIdx;
00209 }
00210
00212
00213 public static boolean match( String pattern, String string )
00214 {
00215 for ( int p = 0; ; ++p )
00216 {
00217 for ( int s = 0; ; ++p, ++s )
00218 {
00219 boolean sEnd = ( s >= string.length() );
00220 boolean pEnd = ( p >= pattern.length() ||
00221 pattern.charAt( p ) == '|' );
00222 if ( sEnd && pEnd )
00223 return true;
00224 if ( sEnd || pEnd )
00225 break;
00226 if ( pattern.charAt( p ) == '?' )
00227 continue;
00228 if ( pattern.charAt( p ) == '*' )
00229 {
00230 int i;
00231 ++p;
00232 for ( i = string.length(); i >= s; --i )
00233 if ( match(
00234 pattern.substring( p ),
00235 string.substring( i ) ) )
00236 return true;
00237 break;
00238 }
00239 if ( pattern.charAt( p ) != string.charAt( s ) )
00240 break;
00241 }
00242 p = pattern.indexOf( '|', p );
00243 if ( p == -1 )
00244 return false;
00245 }
00246 }
00247
00249
00250 public static int matchSpan( String pattern, String string )
00251 {
00252 int result = 0;
00253 StringTokenizer st = new StringTokenizer(pattern, "|");
00254
00255 while (st.hasMoreTokens())
00256 {
00257 int len = matchSpan1(st.nextToken(), string);
00258 if (len > result)
00259 result = len;
00260 }
00261 return result;
00262 }
00263
00264 static int matchSpan1( String pattern, String string )
00265 {
00266 int p=0;
00267 for (; p < string.length() && p < pattern.length(); p++)
00268 {
00269 if (pattern.charAt(p) == string.charAt(p))
00270 continue;
00271 if (pattern.charAt(p) == '*')
00272 return p-1;
00273 return 0;
00274 }
00275 return p<(pattern.length()-1)?-1:p;
00276 }
00277
00279 public static int sameSpan( String str1, String str2 )
00280 {
00281 int i;
00282 for ( i = 0;
00283 i < str1.length() && i < str2.length() &&
00284 str1.charAt( i ) == str2.charAt( i );
00285 ++i )
00286 ;
00287 return i;
00288 }
00289
00291 public static int charCount( String str, char c )
00292 {
00293 int n = 0;
00294 for ( int i = 0; i < str.length(); ++i )
00295 if ( str.charAt( i ) == c )
00296 ++n;
00297 return n;
00298 }
00299
00300
00302
00303 public static String[] splitStr( String str )
00304 {
00305 StringTokenizer st = new StringTokenizer( str );
00306 int n = st.countTokens();
00307 String[] strs = new String[n];
00308 for ( int i = 0; i < n; ++i )
00309 strs[i] = st.nextToken();
00310 return strs;
00311 }
00312
00314
00315
00316 public static String[] splitStr( String str, char delim )
00317 {
00318 int n = 1;
00319 int index = -1;
00320 while ( true )
00321 {
00322 index = str.indexOf( delim, index + 1 );
00323 if ( index == -1 )
00324 break;
00325 ++n;
00326 }
00327 String[] strs = new String[n];
00328 index = -1;
00329 for ( int i = 0; i < n - 1; ++i )
00330 {
00331 int nextIndex = str.indexOf( delim, index + 1 );
00332 strs[i] = str.substring( index + 1, nextIndex );
00333 index = nextIndex;
00334 }
00335 strs[n - 1] = str.substring( index + 1 );
00336 return strs;
00337 }
00338
00340
00341 public static String flattenStrarr( String[] strs )
00342 {
00343 StringBuffer sb = new StringBuffer();
00344 for ( int i = 0; i < strs.length; ++i )
00345 {
00346 if ( i > 0 )
00347 sb.append( ' ' );
00348 sb.append( strs[i] );
00349 }
00350 return sb.toString();
00351 }
00352
00354
00355
00356 public static void sortStrings( String[] strings )
00357 {
00358
00359 for ( int i = 0; i < strings.length - 1; ++i )
00360 {
00361 for ( int j = i + 1; j < strings.length; ++j )
00362 {
00363 if ( strings[i].compareTo( strings[j] ) > 0 )
00364 {
00365 String t = strings[i];
00366 strings[i] = strings[j];
00367 strings[j] = t;
00368 }
00369 }
00370 }
00371 }
00372
00374
00375 public static int indexOfString( String[] strings, String string )
00376 {
00377 for ( int i = 0; i < strings.length; ++i )
00378 if ( string.equals( strings[i] ) )
00379 return i;
00380 return -1;
00381 }
00382
00384
00385 public static int indexOfStringIgnoreCase( String[] strings, String string )
00386 {
00387 for ( int i = 0; i < strings.length; ++i )
00388 if ( string.equalsIgnoreCase( strings[i] ) )
00389 return i;
00390 return -1;
00391 }
00392
00394 public static boolean equalsStrings( String[] strings1, String[] strings2 )
00395 {
00396 if ( strings1.length != strings2.length )
00397 return false;
00398 for ( int i = 0; i < strings1.length; ++i )
00399 if ( ! strings1[i].equals( strings2[i] ) )
00400 return false;
00401 return true;
00402 }
00403
00404
00406
00407 public static long pow( long a, long b ) throws ArithmeticException
00408 {
00409 if ( b < 0 )
00410 throw new ArithmeticException();
00411 long r = 1;
00412 while ( b != 0 )
00413 {
00414 if ( odd( b ) )
00415 r *= a;
00416 b >>>= 1;
00417 a *= a;
00418 }
00419 return r;
00420 }
00421
00422
00424 public static int parseInt( String str, int def )
00425 {
00426 try
00427 {
00428 return Integer.parseInt( str );
00429 }
00430 catch ( Exception e )
00431 {
00432 return def;
00433 }
00434 }
00435
00437 public static long parseLong( String str, long def )
00438 {
00439 try
00440 {
00441 return Long.parseLong( str );
00442 }
00443 catch ( Exception e )
00444 {
00445 return def;
00446 }
00447 }
00448
00449
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 public static String arrayToString( Object o )
00464 {
00465 if ( o == null )
00466 return "null";
00467 String cl = o.getClass().getName();
00468 if ( ! cl.startsWith( "[" ) )
00469
00470 return o.toString();
00471 StringBuffer sb = new StringBuffer( "{ " );
00472 if ( o instanceof byte[] )
00473 {
00474 byte[] ba = (byte[]) o;
00475 for ( int i = 0; i < ba.length; ++i )
00476 {
00477 if ( i > 0 ) sb.append( ", " );
00478 sb.append( "(byte)" );
00479 sb.append( ba[i] );
00480 }
00481 }
00482 else if ( o instanceof char[] )
00483 {
00484 char[] ca = (char[]) o;
00485 for ( int i = 0; i < ca.length; ++i )
00486 {
00487 if ( i > 0 ) sb.append( ", " );
00488 sb.append( "'" );
00489 sb.append( ca[i] );
00490 sb.append( "'" );
00491 }
00492 }
00493 else if ( o instanceof short[] )
00494 {
00495 short[] sa = (short[]) o;
00496 for ( int i = 0; i < sa.length; ++i )
00497 {
00498 if ( i > 0 ) sb.append( ", " );
00499 sb.append( "(short)" );
00500 sb.append( sa[i] );
00501 }
00502 }
00503 else if ( o instanceof int[] )
00504 {
00505 int[] ia = (int[]) o;
00506 for ( int i = 0; i < ia.length; ++i )
00507 {
00508 if ( i > 0 ) sb.append( ", " );
00509 sb.append( ia[i] );
00510 }
00511 }
00512 else if ( o instanceof long[] )
00513 {
00514 long[] la = (long[]) o;
00515 for ( int i = 0; i < la.length; ++i )
00516 {
00517 if ( i > 0 ) sb.append( ", " );
00518 sb.append( la[i] );
00519 sb.append( "L" );
00520 }
00521 }
00522 else if ( o instanceof float[] )
00523 {
00524 float[] fa = (float[]) o;
00525 for ( int i = 0; i < fa.length; ++i )
00526 {
00527 if ( i > 0 ) sb.append( ", " );
00528 sb.append( fa[i] );
00529 sb.append( "F" );
00530 }
00531 }
00532 else if ( o instanceof double[] )
00533 {
00534 double[] da = (double[]) o;
00535 for ( int i = 0; i < da.length; ++i )
00536 {
00537 if ( i > 0 ) sb.append( ", " );
00538 sb.append( da[i] );
00539 sb.append( "D" );
00540 }
00541 }
00542 else if ( o instanceof String )
00543 {
00544
00545 String[] sa = (String[]) o;
00546 for ( int i = 0; i < sa.length; ++i )
00547 {
00548 if ( i > 0 ) sb.append( ", " );
00549 sb.append( "\"" );
00550 sb.append( sa[i] );
00551 sb.append( "\"" );
00552 }
00553 }
00554 else if ( cl.startsWith( "[L" ) )
00555 {
00556
00557 Object[] oa = (Object[]) o;
00558 for ( int i = 0; i < oa.length; ++i )
00559 {
00560 if ( i > 0 ) sb.append( ", " );
00561 sb.append( oa[i] );
00562 }
00563 }
00564 else if ( cl.startsWith( "[[" ) )
00565 {
00566
00567 Object[] aa = (Object[]) o;
00568 for ( int i = 0; i < aa.length; ++i )
00569 {
00570 if ( i > 0 ) sb.append( ", " );
00571 sb.append( arrayToString( aa[i] ) );
00572 }
00573 }
00574 else
00575 sb.append( "(unknown array type)" );
00576 sb.append( " }" );
00577 return sb.toString();
00578 }
00579
00580
00582
00583
00584 public static boolean instanceOf( Object o, Class cl )
00585 {
00586
00587 if ( o == null || cl == null )
00588 return false;
00589 Class ocl = o.getClass();
00590
00591 if ( ocl.equals( cl ) )
00592 return true;
00593
00594 if ( ! cl.isInterface() )
00595 {
00596 Class ifs[] = cl.getInterfaces();
00597 for ( int i = 0; i < ifs.length; ++i )
00598 if ( instanceOf( o, ifs[i] ) )
00599 return true;
00600 }
00601
00602 Class scl = cl.getSuperclass();
00603 if ( scl != null )
00604 if ( instanceOf( o, scl ) )
00605 return true;
00606
00607 return false;
00608 }
00609
00610
00612 public static boolean even( long n )
00613 {
00614 return ( n & 1 ) == 0;
00615 }
00616
00618 public static boolean odd( long n )
00619 {
00620 return ( n & 1 ) != 0;
00621 }
00622
00623
00625 public static int countOnes( byte n )
00626 {
00627 return countOnes( n & 0xffL );
00628 }
00629
00631 public static int countOnes( int n )
00632 {
00633 return countOnes( n & 0xffffffffL );
00634 }
00635
00637 public static int countOnes( long n )
00638 {
00639
00640
00641 int count = 0;
00642 while ( n != 0 )
00643 {
00644 if ( odd( n ) )
00645 ++count;
00646 n >>>= 1;
00647 }
00648 return count;
00649 }
00650
00651
00653
00654
00655 public static int read( InputStream in, byte[] b, int off, int len ) throws IOException
00656 {
00657 if ( len <= 0 )
00658 return 0;
00659 int c = in.read();
00660 if ( c == -1 )
00661 return -1;
00662 if ( b != null )
00663 b[off] = (byte) c;
00664 int i;
00665 for ( i = 1; i < len ; ++i )
00666 {
00667 c = in.read();
00668 if ( c == -1 )
00669 break;
00670 if ( b != null )
00671 b[off + i] = (byte) c;
00672 }
00673 return i;
00674 }
00675
00677
00678
00679 public static int readFully( InputStream in, byte[] b, int off, int len ) throws IOException
00680 {
00681 int l, r;
00682 for ( l = 0; l < len; )
00683 {
00684 r = read( in, b, l, len - l );
00685 if ( r == -1 )
00686 return -1;
00687 l += r;
00688 }
00689 return len;
00690 }
00691
00692
00694
00695 public static URL plainUrl( URL context, String urlStr ) throws MalformedURLException
00696 {
00697 URL url = new URL( context, urlStr );
00698 String fileStr = url.getFile();
00699 int i = fileStr.indexOf( '?' );
00700 if ( i != -1 )
00701 fileStr = fileStr.substring( 0, i );
00702 url = new URL(
00703 url.getProtocol(), url.getHost(), url.getPort(), fileStr );
00704 if ( ( ! fileStr.endsWith( "/" ) ) &&
00705 urlStrIsDir( url.toExternalForm() ) )
00706 {
00707 fileStr = fileStr + "/";
00708 url = new URL(
00709 url.getProtocol(), url.getHost(), url.getPort(), fileStr );
00710 }
00711 return url;
00712 }
00713
00715
00716 public static URL plainUrl( String urlStr ) throws MalformedURLException
00717 {
00718 return plainUrl( null, urlStr );
00719 }
00720
00722
00723
00724 public static String baseUrlStr( String urlStr )
00725 {
00726 if ( urlStr.endsWith( "/" ) )
00727 return urlStr;
00728 if ( urlStrIsDir( urlStr ) )
00729 return urlStr + "/";
00730 return urlStr.substring( 0, urlStr.lastIndexOf( '/' ) + 1 );
00731 }
00732
00734 public static String fixDirUrlStr( String urlStr )
00735 {
00736 if ( urlStr.endsWith( "/" ) )
00737 return urlStr;
00738 if ( urlStrIsDir( urlStr ) )
00739 return urlStr + "/";
00740 return urlStr;
00741 }
00742
00744
00745
00746
00747
00748
00749
00750 public static boolean urlStrIsDir( String urlStr )
00751 {
00752
00753 if ( urlStr.endsWith( "/" ) )
00754 return true;
00755
00756
00757 int lastSlash = urlStr.lastIndexOf( '/' );
00758 int lastPeriod = urlStr.lastIndexOf( '.' );
00759 if ( lastPeriod != -1 && ( lastSlash == -1 || lastPeriod > lastSlash ) )
00760 return false;
00761
00762
00763
00764 String urlStrWithSlash = urlStr + "/";
00765 try
00766 {
00767 URL url = new URL( urlStrWithSlash );
00768 InputStream f = url.openStream();
00769 f.close();
00770
00771 return true;
00772 }
00773 catch ( Exception e )
00774 {
00775
00776 return false;
00777 }
00778 }
00779
00780
00781
00782 public static boolean urlStrIsAbsolute( String urlStr )
00783 {
00784 if ( urlStr.startsWith( "/" ) || urlStr.indexOf( ":/" ) != -1 )
00785 return true;
00786
00787 return false;
00788 }
00789
00790
00791 public static String absoluteUrlStr( String urlStr, URL contextUrl ) throws MalformedURLException
00792 {
00793 URL url = new URL( contextUrl, urlStr );
00794 return url.toExternalForm();
00795 }
00796
00797
00799
00800 public static String urlDecoder( String encoded )
00801 {
00802 StringBuffer decoded = new StringBuffer();
00803 int len = encoded.length();
00804 for ( int i = 0; i < len; ++i )
00805 {
00806 if ( encoded.charAt( i ) == '%' && i + 2 < len )
00807 {
00808 int d1 = Character.digit( encoded.charAt( i + 1 ), 16 );
00809 int d2 = Character.digit( encoded.charAt( i + 2 ), 16 );
00810 if ( d1 != -1 && d2 != -1 )
00811 decoded.append( (char) ( ( d1 << 4 ) + d2 ) );
00812 i += 2;
00813 }
00814 else if ( encoded.charAt( i ) == '+' )
00815 decoded.append( ' ' );
00816 else
00817 decoded.append( encoded.charAt( i ) );
00818 }
00819 return decoded.toString();
00820 }
00821
00822
00824 public static boolean arraycontains( Object[] array, Object element )
00825 {
00826 for ( int i = 0; i < array.length; ++i )
00827 if ( array[i].equals( element ) )
00828 return true;
00829 return false;
00830 }
00831
00832
00834
00835
00836
00837
00838
00839 public static int system( String cmd )
00840 {
00841 try
00842 {
00843 return runCommand( cmd ).waitFor();
00844 }
00845 catch ( IOException e )
00846 {
00847 return -1;
00848 }
00849 catch ( InterruptedException e )
00850 {
00851 return -1;
00852 }
00853 }
00854
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 public static InputStream popenr( String cmd )
00867 {
00868 try
00869 {
00870 return runCommand( cmd ).getInputStream();
00871 }
00872 catch ( IOException e )
00873 {
00874 return null;
00875 }
00876 }
00877
00879
00880
00881
00882 public static OutputStream popenw( String cmd )
00883 {
00884 try
00885 {
00886 return runCommand( cmd ).getOutputStream();
00887 }
00888 catch ( IOException e )
00889 {
00890 return null;
00891 }
00892 }
00893
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905 public static Process runCommand( String cmd ) throws IOException
00906 {
00907 Runtime runtime = Runtime.getRuntime();
00908 String[] shCmd = new String[3];
00909 shCmd[0] = "/bin/sh";
00910 shCmd[1] = "-c";
00911 shCmd[2] = cmd;
00912 return runtime.exec( shCmd );
00913 }
00914
00915
00917 public static void copyStream( InputStream in, OutputStream out ) throws IOException
00918 {
00919 byte[] buf = new byte[4096];
00920 int len;
00921 while ( ( len = in.read( buf ) ) != -1 )
00922 out.write( buf, 0, len );
00923 }
00924
00926 public static void copyStream( Reader in, Writer out ) throws IOException
00927 {
00928 char[] buf = new char[4096];
00929 int len;
00930 while ( ( len = in.read( buf ) ) != -1 )
00931 out.write( buf, 0, len );
00932 }
00933
00935 public static void copyStream( InputStream in, Writer out ) throws IOException
00936 {
00937 byte[] buf1 = new byte[4096];
00938 char[] buf2 = new char[4096];
00939 int len, i;
00940 while ( ( len = in.read( buf1 ) ) != -1 )
00941 {
00942 for ( i = 0; i < len; ++i )
00943 buf2[i] = (char) buf1[i];
00944 out.write( buf2, 0, len );
00945 }
00946 }
00947
00949 public static void copyStream( Reader in, OutputStream out ) throws IOException
00950 {
00951 char[] buf1 = new char[4096];
00952 byte[] buf2 = new byte[4096];
00953 int len, i;
00954 while ( ( len = in.read( buf1 ) ) != -1 )
00955 {
00956 for ( i = 0; i < len; ++i )
00957 buf2[i] = (byte) buf1[i];
00958 out.write( buf2, 0, len );
00959 }
00960 }
00961
00963 public static void dumpStack( PrintStream p )
00964 {
00965 (new Throwable()).printStackTrace( p );
00966 }
00967
00969 public static void dumpStack()
00970 {
00971 (new Throwable()).printStackTrace();
00972 }
00973
00975 public static void putAll(Hashtable _dest, Hashtable _src) {
00976 }
00977
00978 }
00979