/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.value; import java.lang.reflect.Method; import java.util.Comparator; import java.util.Locale; import org.h2.message.DbException; import org.h2.util.StringUtils; import org.h2.util.Utils; /** * An implementation of CompareMode that uses the ICU4J Collator. */ public class CompareModeIcu4J extends CompareMode { private final Comparator<String> collator; protected CompareModeIcu4J(String name, int strength) { super(name, strength); collator = getIcu4jCollator(name, strength); } public int compareString(String a, String b, boolean ignoreCase) { if (ignoreCase) { a = a.toUpperCase(); b = b.toUpperCase(); } return collator.compare(a, b); } public boolean equalsChars(String a, int ai, String b, int bi, boolean ignoreCase) { return compareString(a.substring(ai, ai + 1), b.substring(bi, bi + 1), ignoreCase) == 0; } @SuppressWarnings("unchecked") private static Comparator<String> getIcu4jCollator(String name, int strength) { try { Comparator<String> result = null; Class<?> collatorClass = Utils.loadUserClass("com.ibm.icu.text.Collator"); Method getInstanceMethod = collatorClass.getMethod("getInstance", Locale.class); if (name.length() == 2) { Locale locale = new Locale(StringUtils.toLowerEnglish(name), ""); if (compareLocaleNames(locale, name)) { result = (Comparator<String>) getInstanceMethod.invoke(null, locale); } } else if (name.length() == 5) { // LL_CC (language_country) int idx = name.indexOf('_'); if (idx >= 0) { String language = StringUtils.toLowerEnglish(name.substring(0, idx)); String country = name.substring(idx + 1); Locale locale = new Locale(language, country); if (compareLocaleNames(locale, name)) { result = (Comparator<String>) getInstanceMethod.invoke(null, locale); } } } if (result == null) { for (Locale locale : (Locale[]) collatorClass.getMethod("getAvailableLocales").invoke(null)) { if (compareLocaleNames(locale, name)) { result = (Comparator<String>) getInstanceMethod.invoke(null, locale); break; } } } if (result == null) { throw DbException.getInvalidValueException("collator", name); } collatorClass.getMethod("setStrength", int.class).invoke(result, strength); return result; } catch (Exception e) { throw DbException.convert(e); } } }