1 /** 2 ******************************************************************************* 3 * Copyright (C) 2001-2015, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ******************************************************************************* 6 */ 7 package com.ibm.icu.dev.test; 8 9 import java.io.BufferedReader; 10 import java.io.File; 11 import java.io.FileInputStream; 12 import java.io.IOException; 13 import java.io.InputStream; 14 import java.io.InputStreamReader; 15 import java.util.Locale; 16 17 public final class TestUtil { 18 /** 19 * Path to test data in icu4jtest.jar 20 */ 21 public static final String DATA_PATH = "/com/ibm/icu/dev/data/"; 22 23 /** 24 * Return an input stream on the data file at path 'name' rooted at the data path 25 */ getDataStream(String name)26 public static final InputStream getDataStream(String name) throws IOException { 27 InputStream is = null; 28 try { 29 is = TestUtil.class.getResourceAsStream(DATA_PATH + name); 30 } catch (Throwable t) { 31 IOException ex = 32 new IOException("data resource '" + name + "' not found"); 33 ex.initCause(t); 34 throw ex; 35 } 36 return is; 37 } 38 39 /** 40 * Return a buffered reader on the data file at path 'name' rooted at the data path. 41 */ getDataReader(String name, String charset)42 public static final BufferedReader getDataReader(String name, String charset) throws IOException { 43 InputStream is = getDataStream(name); 44 InputStreamReader isr = 45 charset == null 46 ? new InputStreamReader(is) 47 : new InputStreamReader(is, charset); 48 return new BufferedReader(isr); 49 } 50 51 /** 52 * Return a buffered reader on the data file at path 'name' rooted at the data path, 53 * using the provided encoding. 54 */ getDataReader(String name)55 public static final BufferedReader getDataReader(String name) 56 throws IOException { 57 return getDataReader(name, null); 58 } 59 60 static final char DIGITS[] = 61 { 62 '0', 63 '1', 64 '2', 65 '3', 66 '4', 67 '5', 68 '6', 69 '7', 70 '8', 71 '9', 72 'A', 73 'B', 74 'C', 75 'D', 76 'E', 77 'F', 78 'G', 79 'H', 80 'I', 81 'J', 82 'K', 83 'L', 84 'M', 85 'N', 86 'O', 87 'P', 88 'Q', 89 'R', 90 'S', 91 'T', 92 'U', 93 'V', 94 'W', 95 'X', 96 'Y', 97 'Z' }; 98 /** 99 * Return true if the character is NOT printable ASCII. The tab, 100 * newline and linefeed characters are considered unprintable. 101 */ isUnprintable(int c)102 public static boolean isUnprintable(int c) { 103 return !(c >= 0x20 && c <= 0x7E); 104 } 105 /** 106 * Escape unprintable characters using <backslash>uxxxx notation 107 * for U+0000 to U+FFFF and <backslash>Uxxxxxxxx for U+10000 and 108 * above. If the character is printable ASCII, then do nothing 109 * and return FALSE. Otherwise, append the escaped notation and 110 * return TRUE. 111 */ escapeUnprintable(StringBuffer result, int c)112 public static boolean escapeUnprintable(StringBuffer result, int c) { 113 if (isUnprintable(c)) { 114 result.append('\\'); 115 if ((c & ~0xFFFF) != 0) { 116 result.append('U'); 117 result.append(DIGITS[0xF & (c >> 28)]); 118 result.append(DIGITS[0xF & (c >> 24)]); 119 result.append(DIGITS[0xF & (c >> 20)]); 120 result.append(DIGITS[0xF & (c >> 16)]); 121 } else { 122 result.append('u'); 123 } 124 result.append(DIGITS[0xF & (c >> 12)]); 125 result.append(DIGITS[0xF & (c >> 8)]); 126 result.append(DIGITS[0xF & (c >> 4)]); 127 result.append(DIGITS[0xF & c]); 128 return true; 129 } 130 return false; 131 } 132 133 static class Lock { 134 private int count; 135 inc()136 synchronized void inc() { 137 ++count; 138 } 139 dec()140 synchronized void dec() { 141 --count; 142 } 143 count()144 synchronized int count() { 145 return count; 146 } 147 go()148 void go() { 149 try { 150 while (count() > 0) { 151 synchronized (this) { 152 notifyAll(); 153 } 154 Thread.sleep(50); 155 } 156 } catch (InterruptedException e) { 157 } 158 } 159 } 160 161 static class TestThread extends Thread { 162 Lock lock; 163 Runnable target; 164 TestThread(Lock lock, Runnable target)165 TestThread(Lock lock, Runnable target) { 166 this.lock = lock; 167 this.target = target; 168 169 lock.inc(); 170 } 171 run()172 public void run() { 173 try { 174 synchronized (lock) { 175 lock.wait(); 176 } 177 target.run(); 178 } catch (InterruptedException e) { 179 } 180 181 lock.dec(); 182 } 183 } 184 runUntilDone(Runnable[] targets)185 public static void runUntilDone(Runnable[] targets) { 186 if (targets == null) { 187 throw new IllegalArgumentException("targets is null"); 188 } 189 if (targets.length == 0) { 190 return; 191 } 192 193 Lock lock = new Lock(); 194 for (int i = 0; i < targets.length; ++i) { 195 new TestThread(lock, targets[i]).start(); 196 } 197 198 lock.go(); 199 } openUTF8Reader(String dir, String filename)200 public static BufferedReader openUTF8Reader(String dir, String filename) throws IOException { 201 return openReader(dir,filename,"UTF-8"); 202 } openReader(String dir, String filename, String encoding)203 public static BufferedReader openReader(String dir, String filename, String encoding) throws IOException { 204 File file = new File(dir + filename); 205 return new BufferedReader( 206 new InputStreamReader( 207 new FileInputStream(file), 208 encoding), 209 4*1024); 210 } 211 212 public enum JavaVendor { 213 Unknown, 214 Oracle, 215 IBM, 216 Android 217 } 218 getJavaVendor()219 public static JavaVendor getJavaVendor() { 220 JavaVendor vendor = JavaVendor.Unknown; 221 String javaVendorProp = System.getProperty("java.vendor", "").toLowerCase(Locale.US).trim(); 222 if (javaVendorProp.startsWith("ibm")) { 223 vendor = JavaVendor.IBM; 224 } else if (javaVendorProp.startsWith("sun") || javaVendorProp.startsWith("oracle")) { 225 vendor = JavaVendor.Oracle; 226 } else if (javaVendorProp.contains("android")) { 227 vendor = JavaVendor.Android; 228 } 229 return vendor; 230 } 231 getJavaVersion()232 public static int getJavaVersion() { 233 int ver = -1; 234 String verstr = System.getProperty("java.version"); 235 if (verstr != null) { 236 String[] numbers = verstr.split("\\."); 237 try { 238 ver = Integer.parseInt(numbers[1]); 239 } catch (NumberFormatException e) { 240 ver = -1; 241 } 242 } 243 return ver; 244 } 245 } 246