From cdd03b2ba03718a7fa85663a2438136284a1557c Mon Sep 17 00:00:00 2001 From: Bai Tao Date: Tue, 9 Mar 2010 12:31:58 +0800 Subject: Filter English contacts by initial char in Chinese Locale Filter Chinese and CJK contacts by initial char in neither Japanese nor Korean locale. Change-Id: Ie20b081a96421c56f1713cb676946743704549f3 --- .../providers/contacts/ContactLocaleUtils.java | 97 +++++++++++++++++++--- .../providers/contacts/ContactsProvider2.java | 4 +- .../providers/contacts/NameLookupBuilder.java | 3 +- .../android/providers/contacts/NameSplitter.java | 21 +---- 4 files changed, 93 insertions(+), 32 deletions(-) (limited to 'src/com/android') diff --git a/src/com/android/providers/contacts/ContactLocaleUtils.java b/src/com/android/providers/contacts/ContactLocaleUtils.java index 18d43cf..1c2ad97 100644 --- a/src/com/android/providers/contacts/ContactLocaleUtils.java +++ b/src/com/android/providers/contacts/ContactLocaleUtils.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.Locale; import android.provider.ContactsContract.FullNameStyle; import com.android.internal.util.HanziToPinyin; @@ -35,7 +36,7 @@ public class ContactLocaleUtils { *

* It should be the base class for other locales' implementation. */ - public static class ContactLocaleUtilsBase { + public class ContactLocaleUtilsBase { public String getSortKey(String displayName) { return displayName; } @@ -44,7 +45,20 @@ public class ContactLocaleUtils { } } - private static class ChineseContactUtils extends ContactLocaleUtilsBase { + /** + * The classes to generate the Chinese style sort and search keys. + *

+ * The sorting key is generated as each Chinese character' pinyin proceeding with + * space and character itself. If the character's pinyin unable to find, the character + * itself will be used. + *

+ * The below additional name lookup keys will be generated. + * a. Chinese character's pinyin and pinyin's initial character. + * b. Latin word and the initial character for Latin word. + * The name lookup keys are generated to make sure the name can be found by from any + * initial character. + */ + private class ChineseContactUtils extends ContactLocaleUtilsBase { @Override public String getSortKey(String displayName) { ArrayList tokens = HanziToPinyin.getInstance().get(displayName); @@ -109,19 +123,56 @@ public class ContactLocaleUtils { } } - private static HashMap mUtils = - new HashMap(); + private static final String CHINESE_LANGUAGE = Locale.CHINESE.getLanguage().toLowerCase(); + private static final String JAPANESE_LANGUAGE = Locale.JAPANESE.getLanguage().toLowerCase(); + private static final String KOREAN_LANGUAGE = Locale.KOREAN.getLanguage().toLowerCase(); + + private static ContactLocaleUtils sSingleton; + private HashMap mUtils = + new HashMap(); + + private ContactLocaleUtilsBase mBase = new ContactLocaleUtilsBase(); + + private String mLanguage; + + private ContactLocaleUtils() { + setLocale(null); + } + + public void setLocale(Locale currentLocale) { + if (currentLocale == null) { + mLanguage = Locale.getDefault().getLanguage().toLowerCase(); + } else { + mLanguage = currentLocale.getLanguage().toLowerCase(); + } + } - private static ContactLocaleUtilsBase mBase = new ContactLocaleUtilsBase(); - public static String getSortKey(String displayName, int nameStyle) { - return get(Integer.valueOf(nameStyle)).getSortKey(displayName); + public String getSortKey(String displayName, int nameStyle) { + return getForSort(Integer.valueOf(nameStyle)).getSortKey(displayName); } - public static Iterator getNameLookupKeys(String name, int nameStyle) { - return get(Integer.valueOf(nameStyle)).getNameLookupKeys(name); + public Iterator getNameLookupKeys(String name, int nameStyle) { + return getForNameLookup(Integer.valueOf(nameStyle)).getNameLookupKeys(name); } - private synchronized static ContactLocaleUtilsBase get(Integer nameStyle) { + /** + * Determine which utility should be used for generating NameLookupKey. + *

+ * a. For Western style name, if the current language is Chinese, the + * ChineseContactUtils should be used. + * b. For Chinese and CJK style name if current language is neither Japanese or Korean, + * the ChineseContactUtils should be used. + */ + private ContactLocaleUtilsBase getForNameLookup(Integer nameStyle) { + int nameStyleInt = nameStyle.intValue(); + Integer adjustedUtil = Integer.valueOf(getAdjustedStyle(nameStyleInt)); + if (CHINESE_LANGUAGE.equals(mLanguage) && nameStyleInt == FullNameStyle.WESTERN) { + adjustedUtil = Integer.valueOf(FullNameStyle.CHINESE); + } + return get(adjustedUtil); + } + + private synchronized ContactLocaleUtilsBase get(Integer nameStyle) { ContactLocaleUtilsBase utils = mUtils.get(nameStyle); if (utils == null) { if (nameStyle.intValue() == FullNameStyle.CHINESE) { @@ -131,4 +182,30 @@ public class ContactLocaleUtils { } return (utils == null) ? mBase: utils; } + + /** + * Determine the which utility should be used for generating sort key. + *

+ * For Chinese and CJK style name if current language is neither Japanese or Korean, + * the ChineseContactUtils should be used. + */ + private ContactLocaleUtilsBase getForSort(Integer nameStyle) { + return get(Integer.valueOf(getAdjustedStyle(nameStyle.intValue()))); + } + + public static synchronized ContactLocaleUtils getIntance() { + if (sSingleton == null) { + sSingleton = new ContactLocaleUtils(); + } + return sSingleton; + } + + private int getAdjustedStyle(int nameStyle) { + if (nameStyle == FullNameStyle.CJK && !JAPANESE_LANGUAGE.equals(mLanguage) && + !KOREAN_LANGUAGE.equals(mLanguage)) { + return FullNameStyle.CHINESE; + } else { + return nameStyle; + } + } } diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java index 91f31a2..36763db 100644 --- a/src/com/android/providers/contacts/ContactsProvider2.java +++ b/src/com/android/providers/contacts/ContactsProvider2.java @@ -1935,6 +1935,7 @@ public class ContactsProvider2 extends SQLiteContentProvider implements OnAccoun mNameLookupBuilder = new StructuredNameLookupBuilder(mNameSplitter); mPostalSplitter = new PostalSplitter(mCurrentLocale); mCommonNicknameCache = new CommonNicknameCache(mDbHelper.getReadableDatabase()); + ContactLocaleUtils.getIntance().setLocale(mCurrentLocale); } @Override @@ -2739,7 +2740,8 @@ public class ContactsProvider2 extends SQLiteContentProvider implements OnAccoun } if (displayNameStyle == FullNameStyle.CHINESE) { sortKeyPrimary = sortKeyAlternative = - ContactLocaleUtils.getSortKey(displayNamePrimary, FullNameStyle.CHINESE); + ContactLocaleUtils.getIntance().getSortKey( + displayNamePrimary, FullNameStyle.CHINESE); } } diff --git a/src/com/android/providers/contacts/NameLookupBuilder.java b/src/com/android/providers/contacts/NameLookupBuilder.java index 4bf06c3..00416c9 100644 --- a/src/com/android/providers/contacts/NameLookupBuilder.java +++ b/src/com/android/providers/contacts/NameLookupBuilder.java @@ -302,7 +302,8 @@ public abstract class NameLookupBuilder { private void insertNameShorthandLookup(long rawContactId, long dataId, String name, int fullNameStyle) { - Iterator it = ContactLocaleUtils.getNameLookupKeys(name, fullNameStyle); + Iterator it = + ContactLocaleUtils.getIntance().getNameLookupKeys(name, fullNameStyle); if (it != null) { while (it.hasNext()) { String key = it.next(); diff --git a/src/com/android/providers/contacts/NameSplitter.java b/src/com/android/providers/contacts/NameSplitter.java index 3055a19..f47b490 100644 --- a/src/com/android/providers/contacts/NameSplitter.java +++ b/src/com/android/providers/contacts/NameSplitter.java @@ -443,32 +443,13 @@ public class NameSplitter { } /** - * Flattens the given {@link Name} into a single field, usually for storage - * in {@link StructuredName#DISPLAY_NAME}. - */ - public String join(Name name) { - final boolean hasGiven = !TextUtils.isEmpty(name.givenNames); - final boolean hasFamily = !TextUtils.isEmpty(name.familyName); - - // TODO: write locale-specific blending logic here - if (hasGiven && hasFamily) { - return name.givenNames + " " + name.familyName; - } else if (hasFamily) { - return name.familyName; - } else if (hasGiven) { - return name.givenNames; - } else { - return null; - } - } - - /** * Concatenates components of a name according to the rules dictated by the name style. * * @param givenNameFirst is ignored for CJK display name styles */ public String join(Name name, boolean givenNameFirst) { switch (name.fullNameStyle) { + case FullNameStyle.CJK: case FullNameStyle.CHINESE: case FullNameStyle.KOREAN: return join(name.familyName, name.middleName, name.givenNames, name.suffix, -- cgit v1.1