1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.inputmethod.latin.utils; 18 19import android.util.Log; 20 21import com.android.inputmethod.annotations.UsedForTesting; 22import com.android.inputmethod.latin.NgramContext; 23import com.android.inputmethod.latin.common.StringUtils; 24import com.android.inputmethod.latin.define.DecoderSpecificConstants; 25import com.android.inputmethod.latin.settings.SpacingAndPunctuations; 26 27import java.util.ArrayList; 28import java.util.List; 29import java.util.Locale; 30 31// Note: this class is used as a parameter type of a native method. You should be careful when you 32// rename this class or field name. See BinaryDictionary#addMultipleDictionaryEntriesNative(). 33public final class WordInputEventForPersonalization { 34 private static final String TAG = WordInputEventForPersonalization.class.getSimpleName(); 35 private static final boolean DEBUG_TOKEN = false; 36 37 public final int[] mTargetWord; 38 public final int mPrevWordsCount; 39 public final int[][] mPrevWordArray = 40 new int[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM][]; 41 public final boolean[] mIsPrevWordBeginningOfSentenceArray = 42 new boolean[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM]; 43 // Time stamp in seconds. 44 public final int mTimestamp; 45 46 @UsedForTesting 47 public WordInputEventForPersonalization(final CharSequence targetWord, 48 final NgramContext ngramContext, final int timestamp) { 49 mTargetWord = StringUtils.toCodePointArray(targetWord); 50 mPrevWordsCount = ngramContext.getPrevWordCount(); 51 ngramContext.outputToArray(mPrevWordArray, mIsPrevWordBeginningOfSentenceArray); 52 mTimestamp = timestamp; 53 } 54 55 // Process a list of words and return a list of {@link WordInputEventForPersonalization} 56 // objects. 57 public static ArrayList<WordInputEventForPersonalization> createInputEventFrom( 58 final List<String> tokens, final int timestamp, 59 final SpacingAndPunctuations spacingAndPunctuations, final Locale locale) { 60 final ArrayList<WordInputEventForPersonalization> inputEvents = new ArrayList<>(); 61 final int N = tokens.size(); 62 NgramContext ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO; 63 for (int i = 0; i < N; ++i) { 64 final String tempWord = tokens.get(i); 65 if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) { 66 // just skip this token 67 if (DEBUG_TOKEN) { 68 Log.d(TAG, "--- isEmptyStringOrWhiteSpaces: \"" + tempWord + "\""); 69 } 70 continue; 71 } 72 if (!DictionaryInfoUtils.looksValidForDictionaryInsertion( 73 tempWord, spacingAndPunctuations)) { 74 if (DEBUG_TOKEN) { 75 Log.d(TAG, "--- not looksValidForDictionaryInsertion: \"" 76 + tempWord + "\""); 77 } 78 // Sentence terminator found. Split. 79 // TODO: Detect whether the context is beginning-of-sentence. 80 ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO; 81 continue; 82 } 83 if (DEBUG_TOKEN) { 84 Log.d(TAG, "--- word: \"" + tempWord + "\""); 85 } 86 final WordInputEventForPersonalization inputEvent = 87 detectWhetherVaildWordOrNotAndGetInputEvent( 88 ngramContext, tempWord, timestamp, locale); 89 if (inputEvent == null) { 90 continue; 91 } 92 inputEvents.add(inputEvent); 93 ngramContext = ngramContext.getNextNgramContext(new NgramContext.WordInfo(tempWord)); 94 } 95 return inputEvents; 96 } 97 98 private static WordInputEventForPersonalization detectWhetherVaildWordOrNotAndGetInputEvent( 99 final NgramContext ngramContext, final String targetWord, final int timestamp, 100 final Locale locale) { 101 if (locale == null) { 102 return null; 103 } 104 return new WordInputEventForPersonalization(targetWord, ngramContext, timestamp); 105 } 106} 107