1/**
2 *******************************************************************************
3 * Copyright (C) 2001-2015, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 *******************************************************************************
6 */
7package com.ibm.icu.dev.test;
8
9import java.io.BufferedReader;
10import java.io.File;
11import java.io.FileInputStream;
12import java.io.IOException;
13import java.io.InputStream;
14import java.io.InputStreamReader;
15import java.util.Locale;
16
17public 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     */
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     */
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     */
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     */
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     */
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
136        synchronized void inc() {
137            ++count;
138        }
139
140        synchronized void dec() {
141            --count;
142        }
143
144        synchronized int count() {
145            return count;
146        }
147
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
165        TestThread(Lock lock, Runnable target) {
166            this.lock = lock;
167            this.target = target;
168
169            lock.inc();
170        }
171
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
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    }
200    public static BufferedReader openUTF8Reader(String dir, String filename) throws IOException {
201        return openReader(dir,filename,"UTF-8");
202    }
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
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
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