OpenWnnEngineEN.java revision 30a7808f3a52f23f6fd8085aa63b1336e6ed03c7
1/* 2 * Copyright (C) 2008,2009 OMRON SOFTWARE Co., Ltd. 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 jp.co.omronsoft.openwnn.EN; 18 19import java.util.HashMap; 20import java.util.ArrayList; 21 22import jp.co.omronsoft.openwnn.*; 23import android.content.SharedPreferences; 24import android.util.Log; 25 26/** 27 * OpenWnn engine for English IME 28 * 29 * @author Copyright (C) 2009, OMRON SOFTWARE CO., LTD. All Rights Reserved. 30 */ 31public class OpenWnnEngineEN implements WnnEngine { 32 /** Normal dictionary */ 33 public static final int DICT_DEFAULT = 0; 34 /** Dictionary for mistype correction */ 35 public static final int DICT_FOR_CORRECT_MISTYPE = 1; 36 /** Score(frequency value) of word in the learning dictionary */ 37 public static final int FREQ_LEARN = 600; 38 /** Score(frequency value) of word in the user dictionary */ 39 public static final int FREQ_USER = 500; 40 41 /** OpenWnn dictionary */ 42 private WnnDictionary mDictionary; 43 /** Word list */ 44 private ArrayList<WnnWord> mConvResult; 45 /** HashMap for checking duplicate word */ 46 private HashMap<String, WnnWord> mCandTable; 47 /** Input string */ 48 private String mInputString; 49 /** Searching string */ 50 private String mSearchKey; 51 /** Number of output candidates */ 52 private int mOutputNum; 53 /** The candidate filter */ 54 private CandidateFilter mFilter = null; 55 56 /** 57 * Candidate's case 58 * <br> 59 * CASE_LOWER: all letters are lower.<br> 60 * CASE_HEAD_UPPER: the first letter is upper; others are lower.<br> 61 * CASE_UPPER: all letters are upper.<br> 62 */ 63 private int mCandidateCase; 64 private static final int CASE_LOWER = 0; 65 private static final int CASE_UPPER = 1; 66 private static final int CASE_HEAD_UPPER = 3; 67 68 /** 69 * Constructor 70 * @param writableDictionaryName writable dictionary file name(null if not use) 71 */ 72 public OpenWnnEngineEN(String writableDictionaryName) { 73 mConvResult = new ArrayList<WnnWord>(); 74 mCandTable = new HashMap<String, WnnWord>(); 75 mSearchKey = null; 76 mOutputNum = 0; 77 78 mDictionary = new OpenWnnDictionaryImpl( 79 "/system/lib/libWnnEngDic.so", 80 writableDictionaryName); 81 82 mDictionary.clearDictionary( ); 83 84 mDictionary.setDictionary(0, 400, 550); 85 mDictionary.setDictionary(1, 400, 550); 86 mDictionary.setDictionary(2, 400, 550); 87 mDictionary.setDictionary(WnnDictionary.INDEX_USER_DICTIONARY, FREQ_USER, FREQ_USER); 88 mDictionary.setDictionary(WnnDictionary.INDEX_LEARN_DICTIONARY, FREQ_LEARN, FREQ_LEARN); 89 90 mDictionary.setApproxPattern(WnnDictionary.APPROX_PATTERN_EN_QWERTY_NEAR); 91 92 mDictionary.setInUseState( false ); 93 } 94 95 /** 96 * Get a candidate. 97 * 98 * @param index index of candidate 99 * @return a candidate; {@code null} if no candidate for the index. 100 */ 101 private WnnWord getCandidate(int index) { 102 WnnWord word; 103 /* search the candidate from the dictionaries */ 104 while (index >= mConvResult.size()) { 105 while ((word = mDictionary.getNextWord()) != null) { 106 /* adjust the case of letter */ 107 char c = word.candidate.charAt(0); 108 if (mCandidateCase == CASE_LOWER) { 109 if (Character.isLowerCase(c)) { 110 break; 111 } 112 } else if (mCandidateCase == CASE_HEAD_UPPER) { 113 if (Character.isLowerCase(c)) { 114 word.candidate = Character.toString(Character.toUpperCase(c)) + word.candidate.substring(1); 115 } 116 break; 117 } else { 118 word.candidate = word.candidate.toUpperCase(); 119 break; 120 } 121 } 122 if (word == null) { 123 break; 124 } 125 /* check duplication */ 126 addCandidate(word); 127 } 128 129 /* get the default candidates */ 130 if (index >= mConvResult.size()) { 131 /* input string itself */ 132 addCandidate(new WnnWord(mInputString, mSearchKey)); 133 134 /* Capitalize the head of input */ 135 if (mSearchKey.length() > 1) { 136 addCandidate(new WnnWord(mSearchKey.substring(0,1).toUpperCase() + mSearchKey.substring(1), 137 mSearchKey)); 138 } 139 140 /* Capitalize all */ 141 addCandidate(new WnnWord(mSearchKey.toUpperCase(), mSearchKey)); 142 } 143 144 if (index >= mConvResult.size()) { 145 return null; 146 } 147 return mConvResult.get(index); 148 } 149 150 /** 151 * Add a word to the candidates list if there is no duplication. 152 * @param word a word 153 * @return {@code true} if the word is added to the list; {@code false} if not. 154 */ 155 private boolean addCandidate(WnnWord word) { 156 if (word.candidate == null || mCandTable.containsKey(word.candidate)) { 157 return false; 158 } 159 if (mFilter != null && !mFilter.isAllowed(word)) { 160 return false; 161 } 162 mCandTable.put(word.candidate, word); 163 mConvResult.add(word); 164 return true; 165 } 166 167 private void clearCandidates() { 168 mConvResult.clear(); 169 mCandTable.clear(); 170 mOutputNum = 0; 171 mSearchKey = null; 172 } 173 174 /** 175 * Set dictionary. 176 * 177 * @param type type of dictionary (DIC_DEFAULT or DIC_FOR_CORRECT_MISTYPE) 178 * @return {@code true} if the dictionary is changed; {@code false} if not. 179 */ 180 public boolean setDictionary(int type) { 181 if (type == DICT_FOR_CORRECT_MISTYPE) { 182 mDictionary.clearApproxPattern(); 183 mDictionary.setApproxPattern(WnnDictionary.APPROX_PATTERN_EN_QWERTY_NEAR); 184 } else { 185 mDictionary.clearApproxPattern(); 186 } 187 return true; 188 } 189 190 /** 191 * Set search key for the dictionary. 192 * <br> 193 * To search the dictionary, this method set the lower case of 194 * input string to the search key. And hold the input string's 195 * capitalization information to adjust the candidates 196 * capitalization later. 197 * 198 * @param input input string 199 * @return {@code true} if the search key is set; {@code false} if not. 200 */ 201 private boolean setSearchKey(String input) { 202 if (input.length() == 0) { 203 return false; 204 } 205 206 /* set mInputString */ 207 mInputString = input; 208 209 /* set mSearchKey */ 210 mSearchKey = input.toLowerCase(); 211 212 /* set mCandidateCase */ 213 if (Character.isUpperCase(input.charAt(0))) { 214 if (input.length() > 1 && Character.isUpperCase(input.charAt(1))) { 215 mCandidateCase = CASE_UPPER; 216 } else { 217 mCandidateCase = CASE_HEAD_UPPER; 218 } 219 } else { 220 mCandidateCase = CASE_LOWER; 221 } 222 223 return true; 224 } 225 226 /** 227 * Set the candidate filter 228 * @param filter 229 */ 230 public void setFilter(CandidateFilter filter) { 231 mFilter = filter; 232 } 233 234 /*********************************************************************** 235 * WnnEngine's interface 236 **********************************************************************/ 237 /** @see jp.co.omronsoft.openwnn.WnnEngine#init */ 238 public void init() {} 239 240 /** @see jp.co.omronsoft.openwnn.WnnEngine#close */ 241 public void close() {} 242 243 /** @see jp.co.omronsoft.openwnn.WnnEngine#predict */ 244 public int predict(ComposingText text, int minLen, int maxLen) { 245 clearCandidates(); 246 247 if (text == null) { return 0; } 248 249 String input = text.toString(2); 250 if (!setSearchKey(input)) { 251 return 0; 252 } 253 254 /* set dictionaries by the length of input */ 255 WnnDictionary dict = mDictionary; 256 dict.setInUseState( true ); 257 258 dict.clearDictionary(); 259 dict.setDictionary(0, 400, 550); 260 if (input.length() > 1) { 261 dict.setDictionary(1, 400, 550); 262 } 263 if (input.length() > 2) { 264 dict.setDictionary(2, 400, 550); 265 } 266 dict.setDictionary(WnnDictionary.INDEX_USER_DICTIONARY, FREQ_USER, FREQ_USER); 267 dict.setDictionary(WnnDictionary.INDEX_LEARN_DICTIONARY, FREQ_LEARN, FREQ_LEARN); 268 269 /* search dictionaries */ 270 dict.searchWord(WnnDictionary.SEARCH_PREFIX, WnnDictionary.ORDER_BY_FREQUENCY, mSearchKey); 271 return 1; 272 } 273 274 /** @see jp.co.omronsoft.openwnn.WnnEngine#convert */ 275 public int convert(ComposingText text) { 276 clearCandidates(); 277 return 0; 278 } 279 280 /** @see jp.co.omronsoft.openwnn.WnnEngine#searchWords */ 281 public int searchWords(String key) { 282 clearCandidates(); 283 return 0; 284 } 285 286 /** @see jp.co.omronsoft.openwnn.WnnEngine#searchWords */ 287 public int searchWords(WnnWord word) { 288 clearCandidates(); 289 return 0; 290 } 291 292 /** @see jp.co.omronsoft.openwnn.WnnEngine#getNextCandidate */ 293 public WnnWord getNextCandidate() { 294 if (mSearchKey == null) { 295 return null; 296 } 297 WnnWord word = getCandidate(mOutputNum); 298 if (word != null) { 299 mOutputNum++; 300 } 301 return word; 302 } 303 304 /** @see jp.co.omronsoft.openwnn.WnnEngine#learn */ 305 public boolean learn(WnnWord word) { 306 return ( mDictionary.learnWord(word) == 0 ); 307 } 308 309 /** @see jp.co.omronsoft.openwnn.WnnEngine#addWord */ 310 public int addWord(WnnWord word) { 311 WnnDictionary dict = mDictionary; 312 dict.setInUseState( true ); 313 dict.addWordToUserDictionary(word); 314 dict.setInUseState( false ); 315 return 0; 316 } 317 318 /** @see jp.co.omronsoft.openwnn.WnnEngine#deleteWord */ 319 public boolean deleteWord(WnnWord word) { 320 WnnDictionary dict = mDictionary; 321 dict.setInUseState( true ); 322 dict.removeWordFromUserDictionary(word); 323 dict.setInUseState( false ); 324 return false; 325 } 326 327 /** @see jp.co.omronsoft.openwnn.WnnEngine#setPreferences */ 328 public void setPreferences(SharedPreferences pref) {} 329 330 /** @see jp.co.omronsoft.openwnn.WnnEngine#breakSequence */ 331 public void breakSequence() {} 332 333 /** @see jp.co.omronsoft.openwnn.WnnEngine#makeCandidateListOf */ 334 public int makeCandidateListOf(int clausePosition) {return 0;} 335 336 /** @see jp.co.omronsoft.openwnn.WnnEngine#initializeDictionary */ 337 public boolean initializeDictionary(int dictionary) { 338 WnnDictionary dict = mDictionary; 339 340 switch( dictionary ) { 341 case WnnEngine.DICTIONARY_TYPE_LEARN: 342 dict.setInUseState( true ); 343 dict.clearLearnDictionary(); 344 dict.setInUseState( false ); 345 return true; 346 347 case WnnEngine.DICTIONARY_TYPE_USER: 348 dict.setInUseState( true ); 349 dict.clearUserDictionary(); 350 dict.setInUseState( false ); 351 return true; 352 } 353 return false; 354 } 355 356 /** @see jp.co.omronsoft.openwnn.WnnEngine#initializeDictionary */ 357 public boolean initializeDictionary(int dictionary, int type) { 358 return initializeDictionary(dictionary); 359 } 360 361 /** @see jp.co.omronsoft.openwnn.WnnEngine#getUserDictionaryWords */ 362 public WnnWord[] getUserDictionaryWords( ) { 363 WnnDictionary dict = mDictionary; 364 dict.setInUseState( true ); 365 WnnWord[] result = dict.getUserDictionaryWords( ); 366 dict.setInUseState( false ); 367 return result; 368 } 369 370} 371