aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java')
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java127
1 files changed, 111 insertions, 16 deletions
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 4a822d7b0..848dcbed5 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -16,35 +16,130 @@
package com.android.inputmethod.latin.spellcheck;
+import android.content.res.Resources;
import android.service.textservice.SpellCheckerService;
import android.util.Log;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
+import com.android.inputmethod.compat.ArraysCompatUtils;
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.Dictionary.DataType;
+import com.android.inputmethod.latin.Dictionary.WordCallback;
+import com.android.inputmethod.latin.DictionaryFactory;
+import com.android.inputmethod.latin.Utils;
+import com.android.inputmethod.latin.WordComposer;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+
/**
* Service for spell checking, using LatinIME's dictionaries and mechanisms.
*/
public class AndroidSpellCheckerService extends SpellCheckerService {
private static final String TAG = AndroidSpellCheckerService.class.getSimpleName();
private static final boolean DBG = true;
+
+ private final static String[] emptyArray = new String[0];
+ private final ProximityInfo mProximityInfo = ProximityInfo.getDummyProximityInfo();
+ private final Map<String, Dictionary> mDictionaries =
+ Collections.synchronizedMap(new TreeMap<String, Dictionary>());
+
+ private static class SuggestionsGatherer implements WordCallback {
+ private final int DEFAULT_SUGGESTION_LENGTH = 16;
+ private final String[] mSuggestions;
+ private final int[] mScores;
+ private final int mMaxLength;
+ private int mLength = 0;
+
+ SuggestionsGatherer(final int maxLength) {
+ mMaxLength = maxLength;
+ mSuggestions = new String[mMaxLength];
+ mScores = new int[mMaxLength];
+ }
+
+ @Override
+ synchronized public boolean addWord(char[] word, int wordOffset, int wordLength, int score,
+ int dicTypeId, DataType dataType) {
+ final int positionIndex = ArraysCompatUtils.binarySearch(mScores, 0, mLength, score);
+ // binarySearch returns the index if the element exists, and -<insertion index> - 1
+ // if it doesn't. See documentation for binarySearch.
+ final int insertIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1;
+
+ if (mLength < mMaxLength) {
+ final int copyLen = mLength - insertIndex;
+ ++mLength;
+ System.arraycopy(mScores, insertIndex, mScores, insertIndex + 1, copyLen);
+ System.arraycopy(mSuggestions, insertIndex, mSuggestions, insertIndex + 1, copyLen);
+ } else {
+ if (insertIndex == 0) return true;
+ System.arraycopy(mScores, 1, mScores, 0, insertIndex);
+ System.arraycopy(mSuggestions, 1, mSuggestions, 0, insertIndex);
+ }
+ mScores[insertIndex] = score;
+ mSuggestions[insertIndex] = new String(word, wordOffset, wordLength);
+
+ return true;
+ }
+
+ public String[] getGatheredSuggestions() {
+ if (0 == mLength) return null;
+
+ final String[] results = new String[mLength];
+ for (int i = mLength - 1; i >= 0; --i) {
+ results[mLength - i - 1] = mSuggestions[i];
+ }
+ return results;
+ }
+ }
+
+ private Dictionary getDictionary(final String locale) {
+ Dictionary dictionary = mDictionaries.get(locale);
+ if (null == dictionary) {
+ final Resources resources = getResources();
+ final int fallbackResourceId = Utils.getMainDictionaryResourceId(resources);
+ final Locale localeObject = Utils.constructLocaleFromString(locale);
+ dictionary = DictionaryFactory.createDictionaryFromManager(this, localeObject,
+ fallbackResourceId);
+ mDictionaries.put(locale, dictionary);
+ }
+ return dictionary;
+ }
+
+ // Note : this must be reentrant
+ /**
+ * Gets a list of suggestions for a specific string.
+ *
+ * This returns a list of possible corrections for the text passed as an
+ * arguments. It may split or group words, and even perform grammatical
+ * analysis.
+ */
@Override
- public SuggestionsInfo getSuggestions(TextInfo textInfo, int suggestionsLimit,
- String locale) {
- // TODO: implement this
+ public SuggestionsInfo getSuggestions(final TextInfo textInfo, final int suggestionsLimit,
+ final String locale) {
+ final Dictionary dictionary = getDictionary(locale);
final String text = textInfo.getText();
- if (DBG) {
- Log.w(TAG, "getSuggestions: " + text);
- }
- String[] candidates0 = new String[] {text, "candidate1", "candidate2", "candidate3"};
- String[] candidates1 = new String[] {text, "candidateA", "candidateB"};
- final int textLength = textInfo.getText().length() % 3;
- if (textLength % 3 == 0) {
- return new SuggestionsInfo(2
- | SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY, candidates0);
- } else if (textLength % 3 == 1) {
- return new SuggestionsInfo(SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY, candidates1);
- } else {
- return new SuggestionsInfo(0, null);
+
+ final SuggestionsGatherer suggestionsGatherer = new SuggestionsGatherer(suggestionsLimit);
+ final WordComposer composer = new WordComposer();
+ final int length = text.length();
+ for (int i = 0; i < length; ++i) {
+ int character = text.codePointAt(i);
+ composer.add(character, new int[] { character },
+ WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
}
+ dictionary.getWords(composer, suggestionsGatherer, mProximityInfo);
+ final boolean isInDict = dictionary.isValidWord(text);
+ final String[] suggestions = suggestionsGatherer.getGatheredSuggestions();
+
+ final int flags = (isInDict ? SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY : 0)
+ | (null != suggestions ? SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO : 0);
+ return new SuggestionsInfo(flags, suggestions);
}
}