1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17package com.android.inputmethod.latin;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.text.TextUtils;
22import android.util.Log;
23import android.util.Pair;
24
25import java.util.HashMap;
26import java.util.Locale;
27
28public class WhitelistDictionary extends ExpandableDictionary {
29
30    private static final boolean DBG = LatinImeLogger.sDBG;
31    private static final String TAG = WhitelistDictionary.class.getSimpleName();
32
33    private final HashMap<String, Pair<Integer, String>> mWhitelistWords =
34            new HashMap<String, Pair<Integer, String>>();
35
36    // TODO: Conform to the async load contact of ExpandableDictionary
37    public WhitelistDictionary(final Context context, final Locale locale) {
38        super(context, Suggest.DIC_WHITELIST);
39        final Resources res = context.getResources();
40        final Locale previousLocale = LocaleUtils.setSystemLocale(res, locale);
41        initWordlist(res.getStringArray(R.array.wordlist_whitelist));
42        LocaleUtils.setSystemLocale(res, previousLocale);
43    }
44
45    private void initWordlist(String[] wordlist) {
46        mWhitelistWords.clear();
47        final int N = wordlist.length;
48        if (N % 3 != 0) {
49            if (DBG) {
50                Log.d(TAG, "The number of the whitelist is invalid.");
51            }
52            return;
53        }
54        try {
55            for (int i = 0; i < N; i += 3) {
56                final int score = Integer.valueOf(wordlist[i]);
57                final String before = wordlist[i + 1];
58                final String after = wordlist[i + 2];
59                if (before != null && after != null) {
60                    mWhitelistWords.put(
61                            before.toLowerCase(), new Pair<Integer, String>(score, after));
62                    addWord(after, score);
63                }
64            }
65        } catch (NumberFormatException e) {
66            if (DBG) {
67                Log.d(TAG, "The score of the word is invalid.");
68            }
69        }
70    }
71
72    public String getWhitelistedWord(String before) {
73        if (before == null) return null;
74        final String lowerCaseBefore = before.toLowerCase();
75        if(mWhitelistWords.containsKey(lowerCaseBefore)) {
76            if (DBG) {
77                Log.d(TAG, "--- found whitelistedWord: " + lowerCaseBefore);
78            }
79            return mWhitelistWords.get(lowerCaseBefore).second;
80        }
81        return null;
82    }
83
84    // See LatinIME#updateSuggestions. This breaks in the (queer) case that the whitelist
85    // lists that word a should autocorrect to word b, and word c would autocorrect to
86    // an upper-cased version of a. In this case, the way this return value is used would
87    // remove the first candidate when the user typed the upper-cased version of A.
88    // Example : abc -> def  and  xyz -> Abc
89    // A user typing Abc would experience it being autocorrected to something else (not
90    // necessarily def).
91    // There is no such combination in the whitelist at the time and there probably won't
92    // ever be - it doesn't make sense. But still.
93    public boolean shouldForciblyAutoCorrectFrom(CharSequence word) {
94        if (TextUtils.isEmpty(word)) return false;
95        final String correction = getWhitelistedWord(word.toString());
96        if (TextUtils.isEmpty(correction)) return false;
97        return !correction.equals(word);
98    }
99
100    // Leave implementation of getWords and isValidWord to the superclass.
101    // The words have been added to the ExpandableDictionary with addWord() inside initWordlist.
102}
103