blob: 7e079f27272473d616f93277f7db5681689973b2 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23/*
24 * @test
25 * @bug 5102289 6278334
26 * @summary Test the default Control implementation. The expiration
27 * functionality of newBundle, getTimeToLive, and needsReload is
28 * tested by ExpirationTest.sh. The factory methods are tested
29 * separately.
30 * @build TestResourceRB
31 * @build NonResourceBundle
32 * @run main DefaultControlTest
33 */
34
35import java.util.*;
36import static java.util.ResourceBundle.Control.*;
37
38public class DefaultControlTest {
39 // The ResourceBundle.Control instance
40 static final ResourceBundle.Control CONTROL
41 = ResourceBundle.Control.getControl(FORMAT_DEFAULT);
42
43 static final ResourceBundle BUNDLE = new ResourceBundle() {
44 public Enumeration<String> getKeys() { return null; }
45 protected Object handleGetObject(String key) { return null; }
46 };
47
48 static final String CLAZZ = FORMAT_CLASS.get(0);
49
50 static final String PROPERTIES = FORMAT_PROPERTIES.get(0);
51
52 static final ClassLoader LOADER = DefaultControlTest.class.getClassLoader();
53
54 // Full arguments for NPE testing
55 static final Object[] FULLARGS = { "any",
56 Locale.US,
57 FORMAT_PROPERTIES.get(0),
58 LOADER,
59 BUNDLE };
60
61 static int errors;
62
63 public static void main(String[] args) {
64 checkConstants();
65
66 // Test getFormats(String)
67 testGetFormats();
68
69 // Test getCandidateLocales(String, Locale)
70 testGetCandidateLocales();
71
72 // Test getFallbackLocale(String, Locale)
73 testGetFallbackLocale();
74
75 // Test newBundle(String, Locale, String, ClassLoader, boolean)
76 testNewBundle();
77
78 // Test toBundleName(String, Locale)
79 testToBundleName();
80
81 // Test getTimeToLive(String, Locale)
82 testGetTimeToLive();
83
84 // Test needsReload(String, Locale, String, ClassLoader,
85 // ResourceBundle, long)
86 testNeedsReload();
87
88 // Test toResourceName(String, String)
89 testToResourceName();
90
91 if (errors > 0) {
92 throw new RuntimeException("FAILED: " + errors + " error(s)");
93 }
94 }
95
96 private static void checkConstants() {
97 // Check FORMAT_*
98 if (!CONTROL.FORMAT_DEFAULT.equals(Arrays.asList("java.class",
99 "java.properties"))) {
100 error("Wrong Control.FORMAT_DEFAULT");
101 }
102 checkImmutableList(CONTROL.FORMAT_DEFAULT);
103 if (!CONTROL.FORMAT_CLASS.equals(Arrays.asList("java.class"))) {
104 error("Wrong Control.FORMAT_CLASS");
105 }
106 checkImmutableList(CONTROL.FORMAT_CLASS);
107 if (!CONTROL.FORMAT_PROPERTIES.equals(Arrays.asList("java.properties"))) {
108 error("Wrong Control.FORMAT_PROPERTIES");
109 }
110 checkImmutableList(CONTROL.FORMAT_PROPERTIES);
111
112 // Check TTL_*
113 if (CONTROL.TTL_DONT_CACHE != -1) {
114 error("Wrong Control.TTL_DONT_CACHE: %d%n", CONTROL.TTL_DONT_CACHE);
115 }
116 if (CONTROL.TTL_NO_EXPIRATION_CONTROL != -2) {
117 error("Wrong Control.TTL_NO_EXPIRATION_CONTROL: %d%n",
118 CONTROL.TTL_NO_EXPIRATION_CONTROL);
119 }
120 }
121
122 private static void checkImmutableList(List<String> list) {
123 try {
124 list.add("hello");
125 error("%s is mutable%n", list);
126 } catch (UnsupportedOperationException e) {
127 }
128 }
129
130 private static void testGetFormats() {
131 List<String> list = CONTROL.getFormats("foo");
132 if (list != CONTROL.FORMAT_DEFAULT) {
133 error("getFormats returned " + list);
134 }
135 try {
136 list = CONTROL.getFormats(null);
137 error("getFormats doesn't throw NPE.");
138 } catch (NullPointerException e) {
139 }
140 }
141
142 private static void testGetCandidateLocales() {
143 Map<Locale, Locale[]> candidateData = new HashMap<Locale, Locale[]>();
144 candidateData.put(new Locale("ja", "JP", "YOK"), new Locale[] {
145 new Locale("ja", "JP", "YOK"),
146 new Locale("ja", "JP"),
147 new Locale("ja"),
148 new Locale("") });
149 candidateData.put(new Locale("ja", "JP"), new Locale[] {
150 new Locale("ja", "JP"),
151 new Locale("ja"),
152 new Locale("") });
153 candidateData.put(new Locale("ja"), new Locale[] {
154 new Locale("ja"),
155 new Locale("") });
156
157 candidateData.put(new Locale("ja", "", "YOK"), new Locale[] {
158 new Locale("ja", "", "YOK"),
159 new Locale("ja"),
160 new Locale("") });
161 candidateData.put(new Locale("", "JP", "YOK"), new Locale[] {
162 new Locale("", "JP", "YOK"),
163 new Locale("", "JP"),
164 new Locale("") });
165 candidateData.put(new Locale("", "", "YOK"), new Locale[] {
166 new Locale("", "", "YOK"),
167 new Locale("") });
168 candidateData.put(new Locale("", "JP"), new Locale[] {
169 new Locale("", "JP"),
170 new Locale("") });
171 candidateData.put(new Locale(""), new Locale[] {
172 new Locale("") });
173
174 for (Locale locale : candidateData.keySet()) {
175 List<Locale> candidates = CONTROL.getCandidateLocales("any", locale);
176 List<Locale> expected = Arrays.asList(candidateData.get(locale));
177 if (!candidates.equals(expected)) {
178 error("Wrong candidates for %s: got %s, expected %s%n",
179 toString(locale), candidates, expected);
180 }
181 }
182 final int NARGS = 2;
183 for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
184 Object[] data = getNpeArgs(NARGS, mask);
185 try {
186 List<Locale> candidates = CONTROL.getCandidateLocales((String) data[0],
187 (Locale) data[1]);
188 error("getCandidateLocales(%s, %s) doesn't throw NPE.%n",
189 data[0], toString((Locale)data[1]));
190 } catch (NullPointerException e) {
191 }
192 }
193 }
194
195 private static void testGetFallbackLocale() {
196 Locale current = Locale.getDefault();
197 Locale.setDefault(Locale.ITALY);
198 try {
199 Locale loc = CONTROL.getFallbackLocale("any", Locale.FRANCE);
200 if (loc != Locale.ITALY) {
201 error("getFallbackLocale: got %s, expected %s%n",
202 toString(loc), toString(Locale.ITALY));
203 }
204 loc = CONTROL.getFallbackLocale("any", Locale.ITALY);
205 if (loc != null) {
206 error("getFallbackLocale: got %s, expected null%n", toString(loc));
207 }
208 } finally {
209 Locale.setDefault(current);
210 }
211
212 final int NARGS = 2;
213 for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
214 Object[] data = getNpeArgs(NARGS, mask);
215 try {
216 Locale loc = CONTROL.getFallbackLocale((String) data[0], (Locale) data[1]);
217 error("getFallbackLocale(%s, %s) doesn't throw NPE.%n", data[0], data[1]);
218 } catch (NullPointerException e) {
219 }
220 }
221 }
222
223 private static void testNewBundle() {
224 int testNo = 0;
225 ResourceBundle rb = null;
226 try {
227 testNo = 1;
228 rb = CONTROL.newBundle("StressOut", Locale.JAPANESE,
229 PROPERTIES, LOADER, false);
230 String s = rb.getString("data");
231 if (!s.equals("Japan")) {
232 error("newBundle: #%d got %s, expected Japan%n", testNo, s);
233 }
234
235 testNo = 2;
236 rb = CONTROL.newBundle("TestResourceRB", new Locale(""),
237 CLAZZ, LOADER, false);
238 s = rb.getString("type");
239 if (!s.equals(CLAZZ)) {
240 error("newBundle: #%d got %s, expected %s%n", testNo, s, CLAZZ);
241 }
242 } catch (Throwable e) {
243 error("newBundle: #%d threw %s%n", testNo, e);
244 e.printStackTrace();
245 }
246
247 // Test exceptions
248
249 try {
250 // MalformedDataRB contains an invalid Unicode notation which
251 // causes to throw an IllegalArgumentException.
252 rb = CONTROL.newBundle("MalformedDataRB", Locale.ENGLISH,
253 PROPERTIES, LOADER, false);
254 error("newBundle: doesn't throw IllegalArgumentException with malformed data.");
255 } catch (IllegalArgumentException iae) {
256 } catch (Exception e) {
257 error("newBundle: threw %s%n", e);
258 }
259
260 try {
261 rb = CONTROL.newBundle("StressOut", Locale.JAPANESE,
262 "foo.bar", LOADER, false);
263 error("newBundle: doesn't throw IllegalArgumentException with invalid format.");
264 } catch (IllegalArgumentException iae) {
265 } catch (Exception e) {
266 error("newBundle: threw %s%n", e);
267 }
268
269 try {
270 rb = CONTROL.newBundle("NonResourceBundle", new Locale(""),
271 "java.class", LOADER, false);
272 error("newBundle: doesn't throw ClassCastException with a non-ResourceBundle subclass.");
273 } catch (ClassCastException cce) {
274 } catch (Exception e) {
275 error("newBundle: threw %s%n", e);
276 }
277
278 // NPE test
279 final int NARGS = 4;
280 for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
281 Object[] data = getNpeArgs(NARGS, mask);
282 Locale loc = (Locale) data[1];
283 try {
284 rb = CONTROL.newBundle((String) data[0], loc,
285 (String) data[2], (ClassLoader) data[3],
286 false);
287 error("newBundle(%s, %s, %s, %s, false) doesn't throw NPE.%n",
288 data[0], toString(loc), data[2], data[3]);
289 } catch (NullPointerException npe) {
290 } catch (Exception e) {
291 error("newBundle(%s, %s, %s, %s, false) threw %s.%n",
292 data[0], toString(loc), data[2], data[3], e);
293 }
294 }
295 }
296
297 private static void testGetTimeToLive() {
298 long ttl = CONTROL.getTimeToLive("any", Locale.US);
299 if (ttl != CONTROL.TTL_NO_EXPIRATION_CONTROL) {
300 error("getTimeToLive: got %d, expected %d%n", ttl,
301 CONTROL.TTL_NO_EXPIRATION_CONTROL);
302 }
303 final int NARGS = 2;
304 for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
305 Object[] data = getNpeArgs(NARGS, mask);
306 try {
307 ttl = CONTROL.getTimeToLive((String) data[0], (Locale) data[1]);
308 error("getTimeToLive(%s, %s) doesn't throw NPE.%n", data[0], data[1]);
309 } catch (NullPointerException e) {
310 }
311 }
312 }
313
314 // The functionality of needsReload is tested by
315 // ExpirationTest.sh. Only parameter checking is tested here.
316 private static void testNeedsReload() {
317 long loadTime = System.currentTimeMillis();
318
319 // NPE test
320 final int NARGS = 5;
321 for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
322 Object[] data = getNpeArgs(NARGS, mask);
323 Locale loc = (Locale) data[1];
324 try {
325 boolean b = CONTROL.needsReload((String) data[0], loc,
326 (String) data[2], (ClassLoader) data[3],
327 (ResourceBundle) data[4], loadTime);
328 error("needsReload(%s, %s, %s, %s, %s, loadTime) doesn't throw NPE.%n",
329 data[0], toString(loc), data[2], data[3], data[4]);
330 } catch (NullPointerException e) {
331 }
332 }
333 }
334
335 private static void testToBundleName() {
336 final String name = "J2SE";
337 Map<Locale, String> bundleNames = new HashMap<Locale, String>();
338 bundleNames.put(new Locale("ja", "JP", "YOK"),
339 name + "_" + "ja" + "_" + "JP" + "_" + "YOK");
340 bundleNames.put(new Locale("ja", "JP"),
341 name + "_" + "ja" + "_" + "JP");
342 bundleNames.put(new Locale("ja"),
343 name + "_" + "ja");
344 bundleNames.put(new Locale("ja", "", "YOK"),
345 name + "_" + "ja" + "_" + "" + "_" + "YOK");
346 bundleNames.put(new Locale("", "JP", "YOK"),
347 name + "_" + "" + "_" + "JP" + "_" + "YOK");
348 bundleNames.put(new Locale("", "", "YOK"),
349 name + "_" + "" + "_" + "" + "_" + "YOK");
350 bundleNames.put(new Locale("", "JP"),
351 name + "_" + "" + "_" + "JP");
352 bundleNames.put(new Locale(""),
353 name);
354
355 for (Locale locale : bundleNames.keySet()) {
356 String bn = CONTROL.toBundleName(name, locale);
357 String expected = bundleNames.get(locale);
358 if (!bn.equals(expected)) {
359 error("toBundleName: got %s, expected %s%n", bn, expected);
360 }
361 }
362
363 final int NARGS = 2;
364 for (int mask = 0; mask < (1 << NARGS)-1; mask++) {
365 Object[] data = getNpeArgs(NARGS, mask);
366 try {
367 String s = CONTROL.toBundleName((String) data[0], (Locale) data[1]);
368 error("toBundleName(%s, %s) doesn't throw NPE.%n", data[0], data[1]);
369 } catch (NullPointerException e) {
370 }
371 }
372 }
373
374 private static void testToResourceName() {
375 String[][] names = {
376 // bundleName, suffix, expected result
377 { "com.sun.J2SE", "xml", "com/sun/J2SE.xml" },
378 { ".J2SE", "xml", "/J2SE.xml" },
379 { "J2SE", "xml", "J2SE.xml" },
380 { "com/sun/J2SE", "xml", "com/sun/J2SE.xml" },
381 { "com.sun.J2SE", "", "com/sun/J2SE." },
382 { ".", "", "/." },
383 { "", "", "." },
384
385 // data for NPE tests
386 { null, "any", null },
387 { "any", null, null },
388 { null, null, null },
389 };
390
391 for (String[] data : names) {
392 String result = null;
393 boolean npeThrown = false;
394 try {
395 result = CONTROL.toResourceName(data[0], data[1]);
396 } catch (NullPointerException npe) {
397 npeThrown = true;
398 }
399 String expected = data[2];
400 if (expected != null) {
401 if (!result.equals(expected)) {
402 error("toResourceName: got %s, expected %s%n", result, data[2]);
403 }
404 } else {
405 if (!npeThrown) {
406 error("toResourceName(%s, %s) doesn't throw NPE.%n", data[0], data[1]);
407 }
408 }
409 }
410 }
411
412 /**
413 * Produces permutations argument data that contains at least one
414 * null.
415 */
416 private static Object[] getNpeArgs(int length, int mask) {
417 Object[] data = new Object[length];
418 for (int i = 0; i < length; i++) {
419 if ((mask & (1 << i)) == 0) {
420 data[i] = null;
421 } else {
422 data[i] = FULLARGS[i];
423 }
424 }
425 return data;
426 }
427
428 private static String toString(Locale loc) {
429 if (loc == null)
430 return "null";
431 return "\"" + loc.getLanguage() + "_" + loc.getCountry() + "_" + loc.getVariant() + "\"";
432 }
433
434 private static void error(String msg) {
435 System.out.println(msg);
436 errors++;
437 }
438
439 private static void error(String fmt, Object... args) {
440 System.out.printf(fmt, args);
441 errors++;
442 }
443}