2 **********************************************************************
3 * Copyright (c) 2009, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
7 * Created: January 14 2004
9 **********************************************************************
11 package com.ibm.icu.dev.test.util;
13 import java.lang.reflect.InvocationTargetException;
14 import java.lang.reflect.Method;
15 import java.util.Locale;
17 import com.ibm.icu.dev.test.TestFmwk;
18 import com.ibm.icu.text.Collator;
19 import com.ibm.icu.util.ULocale;
21 public class ULocaleCollationTest extends TestFmwk {
23 public static void main(String[] args) throws Exception {
24 new ULocaleCollationTest().run(args);
27 public void TestCollator() {
28 checkService("ja_JP_YOKOHAMA", new ServiceFacade() {
29 public Object create(ULocale req) {
30 return Collator.getInstance(req);
32 }, null, new Registrar() {
33 public Object register(ULocale loc, Object prototype) {
34 return Collator.registerInstance((Collator) prototype, loc);
36 public boolean unregister(Object key) {
37 return Collator.unregister(key);
44 * Interface used by checkService defining a protocol to create an
45 * object, given a requested locale.
47 interface ServiceFacade {
48 Object create(ULocale requestedLocale);
52 * Interface used by checkService defining a protocol to get a
53 * contained subobject, given its parent object.
56 Object get(Object parent);
60 * Interface used by checkService defining a protocol to register
61 * and unregister a service object prototype.
64 Object register(ULocale loc, Object prototype);
65 boolean unregister(Object key);
71 * Compare two locale IDs. If they are equal, return 0. If `string'
72 * starts with `prefix' plus an additional element, that is, string ==
73 * prefix + '_' + x, then return 1. Otherwise return a value < 0.
75 static int loccmp(String string, String prefix) {
76 int slen = string.length(),
77 plen = prefix.length();
78 /* 'root' is "less than" everything */
79 if (prefix.equals("root")) {
80 return string.equals("root") ? 0 : 1;
82 // ON JAVA (only -- not on C -- someone correct me if I'm wrong)
83 // consider "" to be an alternate name for "root".
85 return slen == 0 ? 0 : 1;
87 if (!string.startsWith(prefix)) return -1; /* mismatch */
88 if (slen == plen) return 0;
89 if (string.charAt(plen) == '_') return 1;
90 return -2; /* false match, e.g. "en_USX" cmp "en_US" */
94 * Check the relationship between requested locales, and report problems.
95 * The caller specifies the expected relationships between requested
96 * and valid (expReqValid) and between valid and actual (expValidActual).
97 * Possible values are:
98 * "gt" strictly greater than, e.g., en_US > en
99 * "ge" greater or equal, e.g., en >= en
100 * "eq" equal, e.g., en == en
102 void checklocs(String label,
107 String expValidActual) {
108 String valid = validLoc.toString();
109 String actual = actualLoc.toString();
110 int reqValid = loccmp(req, valid);
111 int validActual = loccmp(valid, actual);
112 boolean reqOK = (expReqValid.equals("gt") && reqValid > 0) ||
113 (expReqValid.equals("ge") && reqValid >= 0) ||
114 (expReqValid.equals("eq") && reqValid == 0);
115 boolean valOK = (expValidActual.equals("gt") && validActual > 0) ||
116 (expValidActual.equals("ge") && validActual >= 0) ||
117 (expValidActual.equals("eq") && validActual == 0);
118 if (reqOK && valOK) {
119 logln("Ok: " + label + "; req=" + req + ", valid=" + valid +
120 ", actual=" + actual);
122 errln("FAIL: " + label + "; req=" + req + ", valid=" + valid +
123 ", actual=" + actual +
124 (reqOK ? "" : "\n req !" + expReqValid + " valid") +
125 (valOK ? "" : "\n val !" + expValidActual + " actual"));
130 * Use reflection to call getLocale() on the given object to
131 * determine both the valid and the actual locale. Verify these
134 void checkObject(String requestedLocale, Object obj,
135 String expReqValid, String expValidActual) {
136 Class[] getLocaleParams = new Class[] { ULocale.Type.class };
138 Class cls = obj.getClass();
139 Method getLocale = cls.getMethod("getLocale", getLocaleParams);
140 ULocale valid = (ULocale) getLocale.invoke(obj, new Object[] {
141 ULocale.VALID_LOCALE });
142 ULocale actual = (ULocale) getLocale.invoke(obj, new Object[] {
143 ULocale.ACTUAL_LOCALE });
144 checklocs(cls.getName(), requestedLocale,
145 valid.toLocale(), actual.toLocale(),
146 expReqValid, expValidActual);
149 // Make the following exceptions _specific_ -- do not
150 // catch(Exception), since that will catch the exception
151 // that errln throws.
152 catch(NoSuchMethodException e1) {
153 // no longer an error, Currency has no getLocale
154 // errln("FAIL: reflection failed: " + e1);
155 } catch(SecurityException e2) {
156 errln("FAIL: reflection failed: " + e2);
157 } catch(IllegalAccessException e3) {
158 errln("FAIL: reflection failed: " + e3);
159 } catch(IllegalArgumentException e4) {
160 errln("FAIL: reflection failed: " + e4);
161 } catch(InvocationTargetException e5) {
162 // no longer an error, Currency has no getLocale
163 // errln("FAIL: reflection failed: " + e5);
168 * Verify the correct getLocale() behavior for the given service.
169 * @param requestedLocale the locale to request. This MUST BE
170 * FAKE. In other words, it should be something like
171 * en_US_FAKEVARIANT so this method can verify correct fallback
173 * @param svc a factory object that can create the object to be
174 * tested. This isn't necessary here (one could just pass in the
175 * object) but is required for the overload of this method that
178 void checkService(String requestedLocale, ServiceFacade svc) {
179 checkService(requestedLocale, svc, null, null);
183 * Verify the correct getLocale() behavior for the given service.
184 * @param requestedLocale the locale to request. This MUST BE
185 * FAKE. In other words, it should be something like
186 * en_US_FAKEVARIANT so this method can verify correct fallback
188 * @param svc a factory object that can create the object to be
190 * @param sub an object that can be used to retrieve a subobject
191 * which should also be tested. May be null.
192 * @param reg an object that supplies the registration and
193 * unregistration functionality to be tested. May be null.
195 void checkService(String requestedLocale, ServiceFacade svc,
196 Subobject sub, Registrar reg) {
197 ULocale req = new ULocale(requestedLocale);
198 Object obj = svc.create(req);
199 checkObject(requestedLocale, obj, "gt", "ge");
201 Object subobj = sub.get(obj);
202 checkObject(requestedLocale, subobj, "gt", "ge");
205 logln("Info: Registering service");
206 Object key = reg.register(req, obj);
207 Object objReg = svc.create(req);
208 checkObject(requestedLocale, objReg, "eq", "eq");
210 Object subobj = sub.get(obj);
211 // Assume subobjects don't come from services, so
212 // their metadata should be structured normally.
213 checkObject(requestedLocale, subobj, "gt", "ge");
215 logln("Info: Unregistering service");
216 if (!reg.unregister(key)) {
217 errln("FAIL: unregister failed");
219 Object objUnreg = svc.create(req);
220 checkObject(requestedLocale, objUnreg, "gt", "ge");