/*
** Copyright 2010, The LimeIME Open Source Project
**
** Project Url: http://code.google.com/p/limeime/
** http://android.toload.net/
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.toload.main.hd.limedb;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import net.toload.main.hd.R;
import net.toload.main.hd.global.LIMEUtilities;
import net.toload.main.hd.global.ImObj;
import net.toload.main.hd.global.KeyboardObj;
import net.toload.main.hd.global.LIME;
import net.toload.main.hd.global.LIMEPreferenceManager;
import net.toload.main.hd.global.Mapping;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.widget.Toast;
/**
* @author Art Hung and Jeremy Wu.
*/
public class LimeDB extends LimeSQLiteOpenHelper {
private static boolean DEBUG = false;
private static String TAG = "LIMEDB";
private static SQLiteDatabase db = null; //Jeremy '12,5,1 add static modifier. Shared db instance for dbserver and searchserver
private final static int DATABASE_VERSION = 77;
//private final static int DATABASE_RELATED_SIZE = 50;
//Jeremy '11,8,5
private final static String INITIAL_RESULT_LIMIT = "10";
private final static int INITIAL_RELATED_LIMIT = 5;
private final static int COMPOSING_CODE_LENGTH_LIMIT = 16; //Jermey '12,5,30 changed from 12 to 16 because of improved performance using binary tree.
private final static int DUALCODE_COMPOSING_LIMIT = 16; //Jermey '12,5,30 changed from 7 to 16 because of improved performance using binary tree.
private final static int DUALCODE_NO_CHECK_LIMIT = 3; //Jermey '12,5,30 changed from 5 to 3 for phonetic correct valid code display.
//private final static int DUALCODE_ITERATION_LIMIT = 512;
public final static String FIELD_ID = "_id";
public final static String FIELD_CODE = "code";
public final static String FIELD_WORD = "word";
public final static String FIELD_RELATED = "related";
public final static String FIELD_SCORE = "score";
public final static String FIELD_BASESCORE = "basescore"; //jeremy '11,9,8 base frequency got from hanconverter when table loading.
public final static String FIELD_CODE3R = "code3r";
public final static String FIELD_DIC_id = "_id";
public final static String FIELD_DIC_pcode = "pcode";
public final static String FIELD_DIC_pword = "pword";
public final static String FIELD_DIC_ccode = "ccode";
public final static String FIELD_DIC_cword = "cword";
public final static String FIELD_DIC_score = "score";
public final static String FIELD_DIC_is = "isDictionary";
// for keyToChar
private final static String DAYI_KEY = "1234567890qwertyuiopasdfghjkl;zxcvbnm,./";
private final static String DAYI_CHAR =
"言|牛|目|四|王|門|田|米|足|金|石|山|一|工|糸|火|艸|木|口|耳|人|革|日|土|手|鳥|月|立|女|虫|心|水|鹿|禾|馬|魚|雨|力|舟|竹";
private final static String ARRAY_KEY = "qazwsxedcrfvtgbyhnujmik,ol.p;/";
private final static String ARRAY_CHAR =
"1^|1-|1v|2^|2-|2v|3^|3-|3v|4^|4-|4v|5^|5-|5v|6^|6-|6v|7^|7-|7v|8^|8-|8v|9^|9-|9v|0^|0-|0v|";
private final static String BPMF_KEY = "1qaz2wsx3edc4rfv5tgb6yhn7ujm8ik,9ol.0p;/-";
private final static String BPMF_CHAR =
"ㄅ|ㄆ|ㄇ|ㄈ|ㄉ|ㄊ|ㄋ|ㄌ|ˇ|ㄍ|ㄎ|ㄏ|ˋ|ㄐ|ㄑ|ㄒ|ㄓ|ㄔ|ㄕ|ㄖ|ˊ|ㄗ|ㄘ|ㄙ|˙|ㄧ|ㄨ|ㄩ|ㄚ|ㄛ|ㄜ|ㄝ|ㄞ|ㄟ|ㄠ|ㄡ|ㄢ|ㄣ|ㄤ|ㄥ|ㄦ";
private final static String SHIFTED_NUMBERIC_KEY = "!@#$%^&*()";
private final static String SHIFTED_NUMBERIC_KEY_REMAP = "1234567890";
private final static String SHIFTED_SYMBOL_KEY = "<>?_:+\"";
private final static String SHIFTED_SYMBOL_KEY_REMAP = ",./-;='";
private final static String ETEN_KEY = "abcdefghijklmnopqrstuvwxyz12347890-=;',./!@#$&*()<>?_+:\"";
private final static String ETEN_KEY_REMAP = "81v2uzrc9bdxasiqoknwme,j.l7634f0p;/-yh5tg7634f0p;5tg/yh-";
//private final static String DESIREZ_ETEN_KEY_REMAP = "-`81v2uzrc9bdxasiqoknwme,j.l7634f0p;/-yh5tg/";
//private final static String MILESTONE_ETEN_KEY_REMAP = "-`81v2uzrc9bdxasiqoknwme,j.l7634f0p;/-yh5tg/";
//private final static String MILESTONE3_ETEN_KEY_REMAP = "-h81v2uzrc9bdxasiqoknwme,j.l7634f0p;/-yh5tg/";
private final static String DESIREZ_ETEN_DUALKEY = "o,ukm9iq5axesa"; // remapped from "qwer uiop,vlnm";
private final static String DESIREZ_ETEN_DUALKEY_REMAP = "7634f0p;thg/-h"; // remapped from "1234 7890;-/='";
private final static String CHACHA_ETEN_DUALKEY = ",uknljvcrx1?"; // remapped from "werszxchglb?"
private final static String CHACHA_ETEN_DUALKEY_REMAP = "7634f0p/g-hy"; // remapped from "1234789-/=';";
private final static String XPERIAPRO_ETEN_DUALKEY = "o,ukm9iqa52z"; // remapped from "qweruiopm,df";
private final static String XPERIAPRO_ETEN_DUALKEY_REMAP = "7634f0p;th/-"; // remapped from "12347890;'=-";
private final static String MILESTONE_ETEN_DUALKEY = "o,ukm9iq5aec"; // remapped from "qweruiop,mvh";
private final static String MILESTONE_ETEN_DUALKEY_REMAP = "7634f0p;th/-"; // remapped from "12347890;'=-";
private final static String MILESTONE2_ETEN_DUALKEY = "o,ukm9iq5aer"; //remapped from "qweruiop,mvg";
private final static String MILESTONE2_ETEN_DUALKEY_REMAP = "7634f0p;th/-";
private final static String MILESTONE3_ETEN_DUALKEY = "5aew"; // ",mvt"
private final static String MILESTONE3_ETEN_DUALKEY_REMAP = "th/-";
private final static String ETEN_CHAR=
"ㄚ|ㄅ|ㄒ|ㄉ|ㄧ|ㄈ|ㄐ|ㄏ|ㄞ|ㄖ|ㄎ|ㄌ|ㄇ|ㄋ|ㄛ|ㄆ|ㄟ|ㄜ|ㄙ|ㄊ|ㄩ|ㄍ|ㄝ|ㄨ|ㄡ|ㄠ" +
"|˙|ˊ|ˇ|ˋ|ㄑ|ㄢ|ㄣ|ㄤ|ㄥ|ㄦ|ㄗ|ㄘ|ㄓ|ㄔ|ㄕ|˙|ˊ|ˇ|ˋ|ㄑ|ㄢ|ㄣ|ㄤ|ㄓ|ㄔ|ㄕ|ㄥ|ㄦ|ㄗ|ㄘ";
private final static String DESIREZ_ETEN_CHAR=
"@|`|ㄚ|ㄅ|ㄒ|ㄉ|(ㄧ/ˇ)|ㄈ|ㄐ|ㄏ|(ㄞ/ㄢ)|ㄖ|ㄎ|(ㄌ/ㄕ)|(ㄇ/ㄘ)|(ㄋ/ㄦ)|(ㄛ/ㄣ)|(ㄆ/ㄤ)|(ㄟ/˙)" +
"|(ㄜ/ˋ)|ㄙ|ㄊ|(ㄩ/ㄑ)|(ㄍ/ㄥ)|(ㄝ/ˊ)|ㄨ|ㄡ|ㄠ" +
"|˙|ˊ|ˇ|ˋ|ㄑ|ㄢ|ㄣ|ㄤ|ㄥ|ㄦ|ㄗ|ㄘ|(ㄓ/ㄗ)|ㄔ|ㄕ|?";
private final static String MILESTONE_ETEN_CHAR=
"ㄦ|`|ㄚ|ㄅ|ㄒ|ㄉ|(ㄧ/ˇ)|ㄈ|ㄐ|(ㄏ/ㄦ)|(ㄞ/ㄢ)|ㄖ|ㄎ|ㄌ|(ㄇ/ㄘ)|ㄋ|(ㄛ/ㄣ)|(ㄆ/ㄤ)|(ㄟ/˙)" +
"|(ㄜ/ˋ)|ㄙ|ㄊ|(ㄩ/ㄑ)|(ㄍ/ㄥ)|(ㄝ/ˊ)|ㄨ|ㄡ|ㄠ" +
"|˙|ˊ|ˇ|ˋ|ㄑ|ㄢ|ㄣ|ㄤ|ㄥ|ㄦ|ㄗ|ㄘ|(ㄓ/ㄗ)|ㄔ|ㄕ|ㄥ";
private final static String MILESTONE2_ETEN_CHAR=
"ㄦ|`|ㄚ|ㄅ|ㄒ|ㄉ|(ㄧ/ˇ)|ㄈ|(ㄐ/ㄦ)|ㄏ|(ㄞ/ㄢ)|ㄖ|ㄎ|ㄌ|(ㄇ/ㄘ)|ㄋ|(ㄛ/ㄣ)|(ㄆ/ㄤ)|(ㄟ/˙)" +
"|(ㄜ/ˋ)|ㄙ|ㄊ|(ㄩ/ㄑ)|(ㄍ/ㄥ)|(ㄝ/ˊ)|ㄨ|ㄡ|ㄠ" +
"|˙|ˊ|ˇ|ˋ|ㄑ|ㄢ|ㄣ|ㄤ|ㄥ|ㄦ|ㄗ|ㄘ|(ㄓ/ㄗ)|ㄔ|ㄕ|ㄥ";
private final static String MILESTONE3_ETEN_CHAR=
"ㄦ|ㄘ|ㄚ|ㄅ|ㄒ|ㄉ|ㄧ|ㄈ|ㄐ|ㄏ|ㄞ|ㄖ|ㄎ|ㄌ|(ㄇ/ㄘ)|ㄋ|ㄛ|ㄆ|ㄟ|ㄜ|ㄙ|(ㄊ/ㄦ)|ㄩ|ㄍ|ㄝ|ㄨ|ㄡ|ㄠ" +
"|˙|ˊ|ˇ|ˋ|ㄑ|ㄢ|ㄣ|ㄤ|(ㄍ/ㄥ)|ㄦ|ㄗ|ㄘ|(ㄓ/ㄗ)|ㄔ|ㄕ|ㄥ";
private final static String ETEN26_KEY = "qazwsxedcrfvtgbyhnujmikolp,.";
private final static String ETEN26_KEY_REMAP_INITIAL = "y8lhnju2vkzewr1tcsmba9dixq<>";
private final static String ETEN26_KEY_REMAP_FINAL = "y8lhnju7vk6ewr1tcsm3a94ixq<>";
private final static String ETEN26_DUALKEY_REMAP = "o,gf;5p-s0/.pbdz2";
private final static String ETEN26_DUALKEY = "yhvewrscpaxqs3467";
private final static String ETEN26_CHAR_INITIAL =
"(ㄗ/ㄟ)|ㄚ|ㄠ|(ㄘ/ㄝ)|ㄙ|ㄨ|ㄧ|ㄉ|(ㄕ/ㄒ)|ㄜ|ㄈ|(ㄍ/ㄑ)|(ㄊ/ㄤ)|(ㄐ/ㄓ)|ㄅ|ㄔ|(ㄏ/ㄦ)|(ㄋ/ㄣ)|ㄩ|ㄖ|(ㄇ/ㄢ)|ㄞ|ㄎ|ㄛ|(ㄌ/ㄥ)|(ㄆ/ㄡ)|,|。";
private final static String ETEN26_CHAR_FINAL =
"(ㄗ/ㄟ)|ㄚ|ㄠ|(ㄘ/ㄝ)|ㄙ|ㄨ|ㄧ|˙|(ㄕ/ㄒ)|ㄜ|ˊ|(ㄍ/ㄑ)|(ㄊ/ㄤ)|(ㄐ/ㄓ)|ㄅ|ㄔ|(ㄏ/ㄦ)|(ㄋ/ㄣ)|ㄩ|ˇ|(ㄇ/ㄢ)|ㄞ|ˋ|ㄛ|(ㄌ/ㄥ)|(ㄆ/ㄡ)|,|。";
//Jeremy '12,5,31 use dual codes instead of initial/final remap for Hsu phonetic keyboard
private final static String HSU_KEY = "azwsxedcrfvtgbyhnujmikolpq,.";
private final static String HSU_KEY_REMAP_INITIAL = "hylnju2vbzfwe18csm5a9d.xq`<>";
private final static String HSU_KEY_REMAP_FINAL = "hyl7ju6vb3fwe18csm4a9d.xq`<>";
private final static String HSU_DUALKEY_REMAP = "g8t5r/-,okip0;n2z";
private final static String HSU_DUALKEY = "vbf45x/uhecsad763";
private final static String HSU_CHAR_INITIAL =
"(ㄘ/ㄟ)|ㄗ|ㄠ|ㄙ|ㄨ|(ㄧ/ㄝ)|ㄉ|(ㄕ/ㄒ)|ㄖ|ㄈ|(ㄔ/ㄑ)|ㄊ|(ㄍ/ㄜ)|ㄅ|ㄚ|(ㄏ/ㄛ)|(ㄋ/ㄣ)|ㄩ|(ㄐ/ㄓ)|(ㄇ/ㄢ)|ㄞ|(ㄎ/ㄤ)|ㄡ|(ㄌ/ㄥ/ㄦ)|ㄆ|q|,|。";
private final static String HSU_CHAR_FINAL =
"(ㄘ/ㄟ)|ㄗ|ㄠ|(ㄙ/˙)|ㄨ|(ㄧ/ㄝ)|(ㄉ/ˊ)|(ㄕ/ㄒ)|ㄖ|(ㄈ/ˇ)|(ㄔ/ㄑ)|ㄊ|(ㄍ/ㄜ)|ㄅ|ㄚ|(ㄏ/ㄛ)|(ㄋ/ㄣ)|ㄩ|(ㄐ/ㄓ/ˋ)|(ㄇ/ㄢ)|ㄞ|(ㄎ/ㄤ)|ㄡ|(ㄥ/ㄦ)|ㄆ|q|,|。";
private final static String DESIREZ_KEY = "@qazwsxedcrfvtgbyhnujmik?olp,.";
private final static String DESIREZ_BPMF_KEY_REMAP = "1qaz2wsedc5tg6yh4uj8ik9ol0;-,.";
private final static String DESIREZ_BPMF_DUALKEY_REMAP = "xrfvb3n7m,.p/";
private final static String DESIREZ_BPMF_DUALKEY = "sedcg6h4jkl0;";
private final static String DESIREZ_DUALKEY_REMAP = "1234567890;-/='";
private final static String DESIREZ_DUALKEY = "qwertyuiop,vlnm";
private final static String DESIREZ_BPMF_CHAR =
"ㄅ|ㄆ|ㄇ|ㄈ|ㄉ|ㄊ|(ㄋ/ㄌ)|(ㄍ/ㄐ)|(ㄎ/ㄑ)|(ㄏ/ㄒ)|ㄓ|ㄔ|(ㄕ/ㄖ)|(ˊ/ˇ)|ㄗ|(ㄘ/ㄙ)|(ˋ/˙)" +
"|ㄧ|(ㄨ/ㄩ)|ㄚ|ㄛ|(ㄜ/ㄝ)|ㄞ|ㄟ|(ㄠ/ㄡ)|(ㄢ/ㄣ)|(ㄤ/ㄥ)|ㄦ|,|.";
private final static String DESIREZ_DAYI_CHAR =
"@|(言/石)|人|心|(牛/山)|革|水|(目/一)|日|鹿|(四/工)|土|禾|(王/糸)|手|馬|(門/火)|鳥|魚|(田/艸)|月|雨|"
+"(米/木)|立|?|(足/口)|(女/竹)|(金/耳)|(力/虫)|舟";
private final static String CHACHA_KEY = "qazwsxedcrfvtgbyhnujmik?olp,.";
private final static String CHACHA_BPMF_KEY_REMAP = "qax2scedb5t3yh4uj68k.9o/0p-<>";
private final static String CHACHA_BPMF_DUALKEY_REMAP = "1zwrfvnmgi,7l;";
private final static String CHACHA_BPMF_DUALKEY = "qxsedchjt8k6op";
private final static String CHACHA_DUALKEY_REMAP = "123456789-/=';";
private final static String CHACHA_DUALKEY = "wersdfzxchglb?";
private final static String CHACHA_BPMF_CHAR =
"(ㄅ/ㄆ)|(ㄇ/ㄈ)|ㄌ|ㄉ|(ㄊ/ㄋ)|(ㄏ/ㄒ)|(ㄍ/ㄐ)|(ㄎ/ㄑ)|ㄖ|ㄓ|(ㄔ/ㄕ)|ˇ|ㄗ|(ㄘ/ㄙ)|ˋ|ㄧ|(ㄨ/ㄩ)|(ˊ/˙)" +
"|(ㄚ/ㄛ)|(ㄜ/ㄝ)|ㄡ|ㄞ|(ㄟ/ㄠ)|ㄥ|ㄢ|(ㄣ/ㄤ)|ㄦ|,|.";
private final static String XPERIAPRO_KEY = "qazZwsxXedcCrfvVtgbByhnNujmMik`~ol'\"pP!/@";
private final static String XPERIAPRO_BPMF_KEY_REMAP = "1qaz2wsx3edc4rfv5tgb6yhn7ujm8ik,9ol.0p;/-";
//private final static String XPERIAPRO_BPMF_DUALKEY_REMAP = "";
//private final static String XPERIAPRO_BPMF_DUALKEY = "";
private final static String XPERIAPRO_DUALKEY_REMAP = "1234567890;,=-";
private final static String XPERIAPRO_DUALKEY = "qwertyuiopm.df";
//private final static String XPERIAPRO_BPMF_CHAR =; // Use BPMF_CHAR
private final static String MILESTONE_DUALKEY_REMAP = "1234567890;'=-";
private final static String MILESTONE_DUALKEY = "qwertyuiop,mhv";
private final static String MILESTONE_KEY = "qazwsxedcrfvtgbyhnujmik,ol.p/?";
private final static String MILESTONE_BPMF_CHAR =
"(ㄅ/ㄆ)|ㄇ|ㄈ|(ㄉ/ㄊ)|ㄋ|ㄌ|(ㄍ/ˇ)|ㄎ|ㄏ|(ㄐ/ˋ)|ㄑ|ㄒ|(ㄓ/ㄔ)|ㄕ|ㄖ|(ㄗ/ˊ)|ㄘ|ㄙ|(ㄧ/˙)" +
"|ㄨ|ㄩ|(ㄚ/ㄛ)|ㄜ|(ㄝ/ㄤ)|(ㄞ/ㄟ)|ㄠ|ㄡ|(ㄢ/ㄣ)|ㄥ|ㄦ";
private final static String MILESTONE_DAYI_CHAR =
"(言/石)|人|心|(牛/山)|革|水|(目/一)|日|鹿|(四/工)|土|禾|(王/糸)|手|馬|(門/火)|鳥|魚|(田/艸)|月|雨|"
+"(米/木)|立|(力/虫)|(足/口)|女|舟|(金/耳)|竹|?";
private final static String MILESTONE2_DUALKEY_REMAP = "1234567890;'=-";
private final static String MILESTONE2_DUALKEY = "qwertyuiop,mgv";
private final static String MILESTONE3_KEY = "1qaz2wsx3edc4rfv5tgb6yhn7ujm8ik,9ol.0p/";
private final static String MILESTONE3_DUALKEY_REMAP = ";";
private final static String MILESTONE3_DUALKEY = ",";
private final static String MILESTONE3_BPMF_DUALKEY_REMAP = ";/-";
private final static String MILESTONE3_BPMF_DUALKEY = "l.p";
private final static String MILESTONE3_BPMF_CHAR =
"ㄅ|ㄆ|ㄇ|ㄈ|ㄉ|ㄊ|ㄋ|ㄌ|ˇ|ㄍ|ㄎ|ㄏ|ˋ|ㄐ|ㄑ|ㄒ|ㄓ|ㄔ|ㄕ|ㄖ|ˊ|ㄗ|ㄘ|ㄙ|˙|" +
"ㄧ|ㄨ|ㄩ|ㄚ|ㄛ|ㄜ|ㄝ|ㄞ|ㄟ|(ㄠ/ㄤ)|(ㄡ/ㄥ)|ㄢ|ㄣ|ㄥ";
private final static String MILESTONE3_DAYI_CHAR =
"言|石|人|心|牛|山|革|水|目|一|日|鹿|四|工|土|禾|王|糸|手|馬|門|火|鳥|魚|田|" +
"艸|月|雨|米|木|立|(力/虫)|足|口|女|舟|金|耳|竹";
private final static String CJ_KEY = "qwertyuiopasdfghjklzxcvbnm";
private final static String CJ_CHAR = "手|田|水|口|廿|卜|山|戈|人|心|日|尸|木|火|土|竹|十|大|中|重|難|金|女|月|弓|一";
private HashMap<String, HashMap<String,String>> keysDefMap = new HashMap<String, HashMap<String,String>>();
private HashMap<String, HashMap<String,String>> keysReMap = new HashMap<String, HashMap<String,String>>();
private HashMap<String, HashMap<String,String>> keysDualMap = new HashMap<String, HashMap<String,String>>();
private String lastCode = "";
private String lastValidDualCodeList = "";
public String DELIMITER = "";
private File filename = null;
private String tablename = "custom";
private int count = 0;
private int percentageDone = 0; // Jeremy '11,7,27
//private int ncount = 0;
private boolean finish = false;
//private boolean relatedfinish = false;
//Jeremy '11,6,16 keep the soft/physical keyboard flag from getmapping()
private boolean isPhysicalKeyboardPressed = false;
/** Black list cache stored code without valid return. Jeremy '12,6,3 */
private static ConcurrentHashMap<String, Boolean> blackListCache = null;
private LIMEPreferenceManager mLIMEPref;
//private Map<String, String> codeDualMap = new HashMap<String, String>();
private Context mContext;
// Db loading thread.
private Thread thread = null;
private boolean threadAborted = false;
private LimeHanConverter hanConverter;
public boolean isLoadingMappingFinished() {
if(DEBUG) Log.i(TAG, "isLoadingMapingThreadAborted()"+finish+"");
return this.finish;
}
public void setLoadingMappingThreadAborted(boolean value) {
this.threadAborted = value;
}
public boolean isLoadingMappingThreadAborted() {
if(DEBUG) Log.i(TAG, "isLoadingMapingThreadAborted()"+ threadAborted+"");
return this.threadAborted;
}
public boolean isLoadingMappingThreadAlive() {
boolean result = false;
if(thread==null) result = false;
else result = thread.isAlive();
if(DEBUG) Log.i(TAG, "isLoadingMappingThreadAlive()"+ result+"");
return result;
}
public void setFinish(boolean value) {
this.finish = value;
}
/*
* For DBService to set the filename to be load to database
*/
public void setFilename(File filename) {
this.filename = filename;
}
/*
* For LIMEService to setup tablename for further word mapping query
*/
public void setTablename(String tablename) {
this.tablename = tablename;
if (DEBUG) {
Log.i(TAG, "settTableName(), tablename:" + tablename + " this.tablename:"
+ this.tablename);
}
}
public String getTablename(){
return this.tablename;
}
/*
* Initialize LIME database, Context and LIMEPreferenceManager
*/
public LimeDB(Context context) {
super(context, LIME.DATABASE_NAME, null, DATABASE_VERSION);
this.mContext = context;
mLIMEPref = new LIMEPreferenceManager(mContext.getApplicationContext());
blackListCache = new ConcurrentHashMap<String, Boolean>(LIME.LIMEDB_CACHE_SIZE);
// Jeremy '12,4,7 open DB connection in constructor
openDBConnection(true);
}
/**
* Create SQLite Database and create related tables
*/
//Jeremy'12,4,7 on OnCreate now. db is always preloaded.
//@Override
//public void onCreate(SQLiteDatabase dbin) {
// Start from 3.0v no need to create internal database
//}
/*
* Update Database Schema
*
* @see
* android.database.sqlite.SQLit eOpenHelper#onUpgrade(android.database.sqlite
* .SQLiteDatabase, int, int)
*/
/**
* Jeremy '12,6,6
* Do upgrade here if db version is not up to date.
*/
@Override
public void onUpgrade(SQLiteDatabase dbin, int oldVersion, int newVersion) {
if(DEBUG)
Log.i(TAG,"OnUpgrade() db old version = " + oldVersion + ", new version = " + newVersion);
checkCode3RIndexAndRecsordsInPhonetic(dbin);
if(oldVersion<75){
try{
int ecjcount = dbin.query("ecj", null, null, null, null, null, null, null).getCount();
if(ecjcount == 0){
execSQL(dbin, "delete from im where code ='ecj';");
}
} catch (Exception e) {}
try{
execSQL(dbin, "CREATE TABLE hs (_id INTEGER primary key autoincrement, code text, code3r text, word text, related text, score integer, 'basescore' type integer);");
execSQL(dbin, "CREATE INDEX [hs_idx_code] ON [hs] ([code]);");
} catch (Exception e) {}
try{
int count = dbin.query("keyboard", null, FIELD_CODE +" = 'phoneticet41'", null, null, null, null, null).getCount();
if(count == 0){
ContentValues cv = new ContentValues();
cv.put("code", "phoneticet41");
cv.put("name", "注音倚天");
cv.put("desc", "注音倚天41鍵");
cv.put("type", "phone");
cv.put("image", "lime_et_41_keyboard_preview");
cv.put("imkb", "lime_et_41");
cv.put("imshiftkb", "lime_et_41_shift");
cv.put("engkb", "lime_english_number");
cv.put("engshiftkb", "lime_english_shift");
cv.put("symbolkb", "symbols");
cv.put("symbolshiftkb", "symbols_shift");
cv.put("disable", "false");
dbin.insert("keyboard" ,null , cv);
}
} catch (Exception e) {
//e.printStackTrace();
Log.w(TAG, "OnUpgrade() exception:"+ e.getStackTrace());
}
try{
execSQL(dbin, "alter table hs add 'basescore' type integer");
execSQL(dbin, "alter table ecj add 'basescore' type integer");
execSQL(dbin, "alter table custom add 'basescore' type integer");
execSQL(dbin, "alter table wb add 'basescore' type integer");
execSQL(dbin, "alter table array add 'basescore' type integer");
execSQL(dbin, "alter table array10 add 'basescore' type integer");
execSQL(dbin, "alter table cj add 'basescore' type integer");
execSQL(dbin, "alter table dayi add 'basescore' type integer");
execSQL(dbin, "alter table ez add 'basescore' type integer");
execSQL(dbin, "alter table phonetic add 'basescore' type integer");
execSQL(dbin, "alter table scj add 'basescore' type integer");
execSQL(dbin, "alter table cj5 add 'basescore' type integer");
execSQL(dbin, "alter table imtable1 add 'basescore' type integer");
execSQL(dbin, "alter table imtable2 add 'basescore' type integer");
execSQL(dbin, "alter table imtable3 add 'basescore' type integer");
execSQL(dbin, "alter table imtable4 add 'basescore' type integer");
execSQL(dbin, "alter table imtable5 add 'basescore' type integer");
execSQL(dbin, "alter table imtable6 add 'basescore' type integer");
execSQL(dbin, "alter table imtable7 add 'basescore' type integer");
execSQL(dbin, "alter table imtable8 add 'basescore' type integer");
execSQL(dbin, "alter table imtable9 add 'basescore' type integer");
execSQL(dbin, "alter table imtable10 add 'basescore' type integer");
} catch (Exception e) {
//e.printStackTrace();
Log.w(TAG, "OnUpgrade() exception:"+ e.getStackTrace());
}
}
if(oldVersion<77) { // add phonetic hsu keyboard '12,6,6 by jeremy
if(DEBUG)
Log.i(TAG, "Create new hsu and et26 keyboard for version 76.");
try{
int count = dbin.query("keyboard", null, FIELD_CODE +" = 'hsu'", null, null, null, null, null).getCount();
if(count == 0){
ContentValues cv = new ContentValues();
cv.put("code", "hsu");
cv.put("name", "注音許氏");
cv.put("desc", "注音許氏鍵盤");
cv.put("type", "phone");
cv.put("image", "hsu_keyboard_preview");
cv.put("imkb", "lime_hsu");
cv.put("imshiftkb", "lime_hsu_shift");
cv.put("engkb", "lime_english_number");
cv.put("engshiftkb", "lime_english_shift");
cv.put("symbolkb", "symbols");
cv.put("symbolshiftkb", "symbols_shift");
cv.put("disable", "false");
dbin.insert("keyboard" ,null , cv);
}
count = dbin.query("keyboard", null, FIELD_CODE +" = 'et26'", null, null, null, null, null).getCount();
if(count == 0){
ContentValues cv = new ContentValues();
cv.put("code", "et26");
cv.put("name", "注音倚天26");
cv.put("desc", "注音倚天26鍵");
cv.put("type", "phone");
cv.put("image", "et26_keyboard_preview");
cv.put("imkb", "lime_et26");
cv.put("imshiftkb", "lime_et26_shift");
cv.put("engkb", "lime_english_number");
cv.put("engshiftkb", "lime_english_shift");
cv.put("symbolkb", "symbols");
cv.put("symbolshiftkb", "symbols_shift");
cv.put("disable", "false");
dbin.insert("keyboard" ,null , cv);
}
checkPhoneticKeyboardSettingOnDB(dbin);
dbin.execSQL("ALTER TABLE imtable1 RENAME TO pinyin");
String pIMActiveState = mLIMEPref.getIMActivatedState(); //Jeremy '12,7,3 set pinyin to be active keyboard
if(!pIMActiveState.endsWith(";12")){
pIMActiveState += ";12";
mLIMEPref.setIMActivatedState(pIMActiveState);
}
} catch (Exception e) {
e.printStackTrace();
//Log.w(TAG, "OnUpgrade() exception:"+ e.getStackTrace());
}
}
}
/**
* Check the consistency of phonetic keyboard setting in preference and db.
* Jeremy '12,6,8
*
*/
public void checkPhoneticKeyboardSetting(){
if(!checkDBConnection()) return;
try{
checkPhoneticKeyboardSettingOnDB(db);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param dbin
*/
private void checkPhoneticKeyboardSettingOnDB(SQLiteDatabase dbin) {
String selectedPhoneticKeyboardType = mLIMEPref.getPhoneticKeyboardType();
if(DEBUG)
Log.i("OnUpgrade()", "phonetickeyboardtype:" + selectedPhoneticKeyboardType);
if(selectedPhoneticKeyboardType.equals("hsu")){
setIMKeyboardOnDB(dbin, "phonetic",
getKeyboardInfoOnDB(dbin, "hsu", "desc"), "hsu");//jeremy '12,6,6 new hsu and et26 keybaord
}else if(selectedPhoneticKeyboardType.equals("eten26")){
setIMKeyboardOnDB(dbin, "phonetic",
getKeyboardInfoOnDB(dbin, "et26", "desc"), "et26");
}else if(selectedPhoneticKeyboardType.equals("eten")){
setIMKeyboardOnDB(dbin, "phonetic",
getKeyboardInfoOnDB(dbin, "phoneticet41", "desc"), "phoneticet41");
}else
setIMKeyboardOnDB(dbin, "phonetic",
getKeyboardInfoOnDB(dbin, "phonetic", "desc"), "phonetic");
}
private void execSQL(SQLiteDatabase dbin, String command){
try{
//SQLiteDatabase db = getSqliteDb(false);
dbin.execSQL(command);
//db.close();
}catch(Exception e){
Log.w(TAG, "Ignore all possible exceptions~");
}
}
private void checkCode3RIndexAndRecsordsInPhonetic(SQLiteDatabase dbin){
//mLIMEPref.setParameter("checkLDPhonetic", "");
if (DEBUG)
Log.i(TAG, "checkCode3RIndexAndRecsordsInPhonetic(): checked:"
+ mLIMEPref.getParameterString("checkLDPhonetic")
+ " has valid code3r index and records:" + mLIMEPref.getParameterBoolean("doLDPhonetic", true));
String doLDPhonetic = mLIMEPref.getParameterString("checkLDPhonetic", "");
if(!doLDPhonetic.equals("done")){
Cursor cursor = dbin.query("sqlite_master", null, "type='index' and name = 'phonetic_idx_code3r'",
null, null, null, null);
boolean hasIndex = false, hasValidRecords = false;
if(cursor.moveToFirst()){
Log.d(TAG, "checkLDPhonetic(), code3r index is exist!!");
hasIndex =true;
}
cursor = dbin.query("phonetic", null, "code3r='ru'", null, null, null, null);
if(cursor.moveToFirst()){
Log.d(TAG, "checkLDPhonetic(), code3r has vaid records.!!");
hasValidRecords = true;
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
mLIMEPref.setParameter("checkLDPhonetic", "done");
mLIMEPref.setParameter("doLDPhonetic", hasIndex && hasValidRecords);
}
}
//Jeremy '11,9,8 deprecated after 3.6
/*public void updateDBVersion(){
checkCode3RIndexAndRecsordsInPhonetic();
String kbversion = mLIMEPref.getParameterString("kbversion");
// Upgrade DB version below 330
if(kbversion == null || kbversion.equals("") || Integer.parseInt(kbversion) < 330){
SQLiteDatabase db = null;
String dbtarget = mLIMEPref.getParameterString("dbtarget");
String dblocation = "";
if(dbtarget.equals("sdcard")){
dblocation = LIME.DATABASE_DECOMPRESS_FOLDER_SDCARD + File.separator + LIME.DATABASE_NAME;
}else{
dblocation = LIME.DATABASE_DECOMPRESS_FOLDER + File.separator + LIME.DATABASE_NAME;
}
db = SQLiteDatabase.openDatabase(dblocation, null, SQLiteDatabase.OPEN_READWRITE);
int count = db.query("keyboard", null, FIELD_CODE +" = 'limenumsym'", null, null, null, null, null).getCount();
if(count == 0){
try{
ContentValues cv = new ContentValues();
cv.put("code", "limenumsym");
cv.put("name", "LIMENUMSYM");
cv.put("desc", "LIME 預設鍵盤");
cv.put("type", "phone");
cv.put("image", "lime_number_symbol_keyboard_priview");
cv.put("imkb", "lime_number_symbol");
cv.put("imshiftkb", "lime_number_symbol_shift");
cv.put("engkb", "lime_english_number");
cv.put("engshiftkb", "lime_english_shift");
cv.put("symbolkb", "symbols");
cv.put("symbolshiftkb", "symbols_shift");
cv.put("disable", "false");
db.insert("keyboard" ,null , cv);
} catch (Exception e) {
e.printStackTrace();
}
}
db.close();
mLIMEPref.setParameter("kbversion","330");
}
// Upgrade DB version below 332
if(kbversion == null || kbversion.equals("") || Integer.parseInt(kbversion) < 332){
SQLiteDatabase db = null;
String dbtarget = mLIMEPref.getParameterString("dbtarget");
String dblocation = "";
if(dbtarget.equals("sdcard")){
dblocation = LIME.DATABASE_DECOMPRESS_FOLDER_SDCARD + File.separator + LIME.DATABASE_NAME;
}else{
dblocation = LIME.DATABASE_DECOMPRESS_FOLDER + File.separator + LIME.DATABASE_NAME;
}
db = SQLiteDatabase.openDatabase(dblocation, null, SQLiteDatabase.OPEN_READWRITE);
boolean hasNewTable = false;
try{
//int count = db.query("cj5", null, null, null, null, null, null, null).getCount();
hasNewTable = true;
}catch(Exception e){}
if(!hasNewTable){
try{
db.execSQL("CREATE TABLE cj5 (" + FIELD_id + " INTEGER primary key autoincrement, " + " "
+ FIELD_CODE + " text, " + FIELD_CODE3R + " text, " + FIELD_WORD + " text, " + FIELD_RELATED + " text, " + FIELD_SCORE + " integer)");
db.execSQL("CREATE TABLE ecj (" + FIELD_id + " INTEGER primary key autoincrement, " + " "
+ FIELD_CODE + " text, " + FIELD_CODE3R + " text, " + FIELD_WORD + " text, " + FIELD_RELATED + " text, " + FIELD_SCORE + " integer)");
db.execSQL("CREATE TABLE wb (" + FIELD_id + " INTEGER primary key autoincrement, " + " "
+ FIELD_CODE + " text, " + FIELD_CODE3R + " text, " + FIELD_WORD + " text, " + FIELD_RELATED + " text, " + FIELD_SCORE + " integer)");
// To modify the user keyboard selection
String keybaord_state_string = mLIMEPref.getSelectedKeyboardState();
if(!keybaord_state_string.equals("0;1;2;3;4;5;6;7;8;9;10;11")){
String ks[] = keybaord_state_string.split(";");
String update_value = "";
for(String u: ks){
try{
int i = Integer.parseInt(u);
if(i < 3){
update_value += i+";";
}else{
update_value += (i+2)+";";
}
}catch(Exception e){}
}
mLIMEPref.setParameter("keyboard_state", update_value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
db.close();
mLIMEPref.setParameter("kbversion","332");
}
// Upgrade DB version below 333
//mLIMEPref.setParameter("kbversion","332");
if(kbversion == null || kbversion.equals("") || Integer.parseInt(kbversion) < 333){
SQLiteDatabase db = null;
String dbtarget = mLIMEPref.getParameterString("dbtarget");
String dblocation = "";
if(dbtarget.equals("sdcard")){
dblocation = LIME.DATABASE_DECOMPRESS_FOLDER_SDCARD + File.separator + LIME.DATABASE_NAME;
}else{
dblocation = LIME.DATABASE_DECOMPRESS_FOLDER + File.separator + LIME.DATABASE_NAME;
}
db = SQLiteDatabase.openDatabase(dblocation, null, SQLiteDatabase.OPEN_READWRITE);
int count = db.query("keyboard", null, FIELD_CODE +" = 'phoneticet41'", null, null, null, null, null).getCount();
if(count == 0){
try{
ContentValues cv = new ContentValues();
cv.put("code", "phoneticet41");
cv.put("name", "注音倚天");
cv.put("desc", "注音倚天41鍵");
cv.put("type", "phone");
cv.put("image", "lime_et_41_keyboard_priview");
cv.put("imkb", "lime_et_41");
cv.put("imshiftkb", "lime_et_41_shift");
cv.put("engkb", "lime_english_number");
cv.put("engshiftkb", "lime_english_shift");
cv.put("symbolkb", "symbols");
cv.put("symbolshiftkb", "symbols_shift");
cv.put("disable", "false");
db.insert("keyboard" ,null , cv);
} catch (Exception e) {
e.printStackTrace();
}
}
db.close();
mLIMEPref.setParameter("kbversion","333");
}
}*/
// //Jeremy '12,4,7 deprecated and moved to LimeSQLHelper
// @Deprecated
// private String getDBPath(String dbTarget){
// String dbLocationPrefix = (dbTarget.equals("sdcard"))
// ?LIME.DATABASE_DECOMPRESS_FOLDER_SDCARD:LIME.DATABASE_DECOMPRESS_FOLDER;
//
// return dbLocationPrefix + File.separator + LIME.DATABASE_NAME;
// }
//Jeremy '12,4,7
public SQLiteDatabase openDBConnection(boolean force_reload){
if(DEBUG) {
Log.i(TAG,"openDBConnection(), force_reload = " + force_reload );
if(db != null)
Log.i(TAG, "db.isOpen()" + db.isOpen());
}
try{
if(force_reload && db != null && db.isOpen()){
mLIMEPref.setParameter("reload_database", false);
db.close();
}
}catch(Exception e){}
if(db == null || (db!=null && !db.isOpen())){
db = this.getWritableDatabase();
mLIMEPref.setMappingLoading(false); // Jeremy '12,4,10 reset mapping_loading status
/*if(db!=null && !db.isOpen())
checkCode3RIndexAndRecsordsInPhonetic(db); // Jeremy '12,6,5 check if phonetic table has code3r clumn and index
*/ }
return db;
}
/**
* Jeremy '12,5,1 checkDBconnection try to openDBconection if db is not open.
* Return true if the db connection is valid, return false if dbconnection is not valid
*
*/
private boolean checkDBConnection(){
//Jeremy '12,5,1 mapping loading. db is locked
if(mLIMEPref.getMappingLoading()) {
Toast.makeText(mContext, mContext.getText(R.string.l3_database_loading), Toast.LENGTH_SHORT/2).show();
return false;
}else if(openDBConnection(false)==null){ //Jermey'12,5,1 db == null if dabase is not exist
//Toast.makeText(ctx, ctx.getText(R.string.l3_database_not_exist), Toast.LENGTH_SHORT/2).show(); //annoying.. removed first
return false;
}else
return true;
}
//
// //Deprecated by Jeremy '12,4,7
// @Deprecated
// public SQLiteDatabase getSqliteDb(boolean readonly){
//
// // Execute database schema update process
// //updateDBVersion();
// //SQLiteDatabase db = null;
// try{
//
// String dbtarget = mLIMEPref.getParameterString("dbtarget");
//
//
// //Jeremy '11',9,11 clean code
// db = SQLiteDatabase.openDatabase(getDBPath(dbtarget),
// null, (readonly)? SQLiteDatabase.OPEN_READONLY: SQLiteDatabase.OPEN_READWRITE
// | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
//
// /*if(dbtarget.equals("sdcard")){
// String sdcarddb = LIME.DATABASE_DECOMPRESS_FOLDER_SDCARD + File.separator + LIME.DATABASE_NAME;
//
// if(readonly){
// db = SQLiteDatabase.openDatabase(sdcarddb, null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
// }else{
// db = SQLiteDatabase.openDatabase(sdcarddb, null, SQLiteDatabase.OPEN_READWRITE | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
// }
// }else{
// String devicedb = LIME.DATABASE_DECOMPRESS_FOLDER + File.separator + LIME.DATABASE_NAME;
//
// if(readonly){
// db = SQLiteDatabase.openDatabase(devicedb, null, SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
// //db = this.getReadableDatabase();
// }else{
// db = SQLiteDatabase.openDatabase(devicedb, null, SQLiteDatabase.OPEN_READWRITE |SQLiteDatabase.NO_LOCALIZED_COLLATORS);
// //db = this.getWritableDatabase();
// }
// }*/
//
// }catch(Exception e){
// //e.printStackTrace();
// //Toast.makeText(ctx, ctx.getText(R.string.l3_initial_database_failed), Toast.LENGTH_SHORT).show();
// return null;
// }
//
// /*//Jeremy '11,9, 8 starting from 3.6 using db.getVersion and onUpgrade() again.
// if(DEBUG) Log.i(TAG, "databaseversion= " +
// db.getVersion() + " helperVersion= " + DATABASE_VERSION);
// if (db!=null && db.getVersion() != DATABASE_VERSION) {
// if(readonly){
// Log.w(TAG, "Can't upgrade read-only database from version " +
// db.getVersion() + " to " + DATABASE_VERSION);
// }else{
// //db.setVersion(67);
// onUpgrade(db, db.getVersion(), DATABASE_VERSION);
// }
// }*/
//
//
//
// return db;
//
// }
/**
* Base on given table name to remove records
*/
public void deleteAll(String table) {
if(DEBUG)
Log.i(TAG,"deleteAll()");
if(thread != null){
threadAborted = true;
while(thread.isAlive()){
Log.d(TAG, "deleteAll():waiting for thread stopped...");
SystemClock.sleep(1000);
};
}
//SQLiteDatabase db = this.getSqliteDb(false);
//db.execSQL("DELETE FROM " + table);
if(countMapping(table)>0)
db.delete(table, null, null);
//db.close();
finish = false;
resetImInfo(table);
//mLIMEPref.setParameter("im_loading", false);
//mLIMEPref.setParameter("im_loading_table", "");
if(blackListCache != null) blackListCache.clear();//Jeremy '12, 6,3 clear black list cache after mapping file updated
}
/**
* Empty Related table records
*/
public synchronized void deleteUserDictAll() {
mLIMEPref.setTotalUserdictRecords("0");
// -------------------------------------------------------------------------
//SQLiteDatabase db = this.getSqliteDb(false);
db.delete("related", FIELD_DIC_score + " > 0", null);
//db.close();
}
/**
* Count total amount of specific table
*
* @return
*/
public int countMapping(String table) {
if(DEBUG)
Log.i(TAG,"countMapping() on table:" + table);
try {
Cursor cursor = db.rawQuery("SELECT * FROM " + table, null);
if(cursor ==null) return 0;
int total = cursor.getCount();
cursor.close();
if(DEBUG)
Log.i(TAG, "countMapping" + "Table," + table + ": " + total);
return total;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
public int getCount(){
return count;
}
public int getPercentageDone(){
return percentageDone;
}
/**
* Count total amount loaded records amount
*
* @return
*/
public int countUserdic() {
int total = 0;
try {
//SQLiteDatabase db = this.getSqliteDb(true);
total += db.rawQuery(
"SELECT * FROM related where " + FIELD_DIC_score + " > 0",
null).getCount();
//db.close();
} catch (Exception e) {
e.printStackTrace();
}
return total;
}
/**
* Insert mapping item into database
*
* @param source
*/
public synchronized void insertList(ArrayList<String> source) {
this.identifyDelimiter(source);
//SQLiteDatabase db = this.getSqliteDb(false);
for (String unit : source) {
try {
String code = unit.substring(0, unit.indexOf(this.DELIMITER));
String word = unit.substring(unit.indexOf(this.DELIMITER) + 1);
if (code == null || code.trim().equals("")) {
continue;
} else {
code = code.toLowerCase(Locale.US);
}
if (word == null || word.trim().equals("")) {
continue;
}
if (code.equalsIgnoreCase("@VERSION@")) {
mLIMEPref.setTableVersion("lime", word.trim());
continue;
}
ContentValues cv = new ContentValues();
cv.put(FIELD_CODE, code);
cv.put(FIELD_WORD, word);
cv.put(FIELD_SCORE, 0);
db.insert("mapping", null, cv);
count++;
} catch (Exception e) {
e.printStackTrace();
}
}
//db.close();
}
/**
* Return the score after add or updated. Jerem '12,6,7
* @param pword
* @param cword
* @return
*/
public synchronized int addOrUpdateUserdictRecord(String pword, String cword){
//Jeremy '12,4,17 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return -1;
// Jeremy '11,6,12
// Return if not learing related words and cword is not null (recording word frequency in IM relatedlist field)
if(!mLIMEPref.getLearnRelatedWord() && cword!=null) return -1;
int dictotal = Integer.parseInt(mLIMEPref.getTotalUserdictRecords());
if(DEBUG)
Log.i(TAG, "addOrUpdateUserdictRecord(): pword:"+pword+" cword:"+cword + "dictotoal:"+dictotal);
int score = 1;
ContentValues cv = new ContentValues();
try {
Mapping munit = this.isUserDictExistOnDB(db, pword , cword);
if (munit == null) {
cv.put(FIELD_DIC_pword, pword);
cv.put(FIELD_DIC_cword, cword);
cv.put(FIELD_DIC_score, score);
db.insert("related", null, cv);
dictotal++;
mLIMEPref.setTotalUserdictRecords(String.valueOf(dictotal));
if(DEBUG)
Log.i(TAG, "addOrUpdateUserdictRecord(): new record, dictotal:" + dictotal);
}else{//the item exist in preload related database.
score = munit.getScore()+1;
cv.put(FIELD_SCORE, score);
db.update("related", cv, FIELD_ID + " = " + munit.getId(), null);
if(DEBUG)
Log.i(TAG, "addOrUpdateUserdictRecord():update score on existing record; score:"+score);
}
} catch (Exception e) {
e.printStackTrace();
}
return score;
}
/**
* learn user dict based on the input maaping list.
*
* @param srclist
*//*
//Jeremy '11,8,1 moved to postfinishinput in searchservice.
//Jeremy '11,6,12 rename from addDictionary for consistency
public void addUserDict(List<Mapping> srclist) {
//Jeremy '11,6,12 move the db updating to addOrUpdateUserdictRecord
if(DEBUG){
Log.i(TAG, "addUserDict():Entering addDictionary, srclist.size=" + srclist.size());
}
if (srclist != null && srclist.size() > 0) {
for (int i = 0; i < srclist.size(); i++) {
Mapping unit = srclist.get(i);
if(unit == null){continue;}
if(i+1 <srclist.size()){
Mapping unit2 = srclist.get((i + 1));
if(unit2 == null){continue;}
if (unit != null
&& unit.getWord() != null && !unit.getWord().equals("")
&& unit2 != null
&& unit2.getWord() != null && !unit2.getWord().equals("")) {
addOrUpdateUserdictRecord(unit.getWord(),unit2.getWord());
}
}
}
}
}*/
/**
* Add new mapping into current table
* @param code, word
*/
//Jeremy '11, 7, 31 add new phrase mapping into current table (for LD phrase learning).
public synchronized void addOrUpdateMappingRecord(String code, String word) {
//String code = preProcessingRemappingCode(raw_code); //Jeremy '12,6,4 the code is build from mapping.getcode() should not do remap again.
if(DEBUG)
Log.i(TAG, "addOrUpdateMappingRecord(), code = '" + code + "'. word=" + word );
//Jeremy '12,4,17 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return;
try {
Mapping munit = isMappingExistOnDB(db, code, word);
ContentValues cv = new ContentValues();
if(munit==null){
if (code.length()>0 && word.length()>0) {
cv.put(FIELD_CODE, code);
removeFromBlackList(code); // remove from black list if it listed. Jeremy 12,6, 4
if(tablename.equals("phonetic")) {
String code3r = code.replaceAll("[ 3467]", "");
cv.put(FIELD_CODE3R, code3r);//Jeremy '12,6,1, add missing space
removeFromBlackList(code3r); // remove from black list if it listed. Jeremy 12,6, 4
}
cv.put(FIELD_WORD, word);
cv.put(FIELD_SCORE, 1);
db.insert(tablename, null, cv);
if(DEBUG)
Log.i(TAG, "addOrUpdateMappingRecord(): mapping does not exist, new cored inserted");
}
// build related list
//updateRelatedList(code);
}else{//the item exist in preload related database.
int score = munit.getScore()+1;
cv.put(FIELD_SCORE, score);
db.update(tablename, cv, FIELD_ID + " = " + munit.getId(), null);
if(DEBUG)
Log.i(TAG, "addOrUpdateMappingRecord(): mapping exist, update score on existing record; score:"+score);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Add score to the mapping item
*
* @param srcunit
*/
public synchronized void addScore(Mapping srcunit) {
//Jeremy '12,4,17 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return;
//Jeremy '11,7,31 even selected from realted list, udpate the corresponding score in im table.
// Jeremy '11,6,12 Id=null denotes selection from related list in im table
// if(srcunit !=null && srcunit.getId()== null &&
// srcunit.getWord() != null && !srcunit.getWord().trim().equals("")){
// String code = srcunit.getCode().trim().toLowerCase(Locale.US);
// if(DEBUG) Log.i("LIMEDb.addScore()","related selectd, code:" + code);
// // sotre the phrase frequency of relatedlist in reated table with cword =null
// addOrUpdateUserdictRecord(srcunit.getWord(),null);
// //updateRelatedList(code); move to search service Jeremy '11,7,29
//
// }else
//Jeremy '11,9,8 query highest score first. Erase relatedlist if new score is not highest.
try {
int highestScore = getHighestScoreOnDB(db, srcunit.getCode());
int newScore = srcunit.getScore() + 1;
if (srcunit != null && //srcunit.getId() != null &&
srcunit.getWord() != null &&
!srcunit.getWord().trim().equals("") ) {
if(DEBUG) Log.i(TAG, "addScore(): addScore on code:"+srcunit.getCode());
if(srcunit.isDictionary()){
ContentValues cv = new ContentValues();
cv.put(FIELD_SCORE, srcunit.getScore() + 1);
db.update("related", cv, FIELD_ID + " = " + srcunit.getId(), null);
}else{
ContentValues cv = new ContentValues();
cv.put(FIELD_SCORE, newScore);
if(newScore< highestScore)
cv.put(FIELD_RELATED, "");
// Jeremy 11',7,29 update according to word instead of ID, may have multiple records mathing word but withd diff code/id
db.update(tablename, cv, FIELD_WORD + " = '" + srcunit.getWord() + "'", null);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Jeremy '12,6,7 for phrase learning to get code from word
* @param keyword
* @param tablenam
* @return
*/
public List<Mapping> getRMapping(Mapping mapping, String table) {
String keyword = mapping.getWord();
return getRMapping(keyword, table);
}
public List<Mapping> getRMapping(String keyword, String table) {
if(DEBUG)
Log.i(TAG,"getRmapping():tablename:" + table + " keyworad:" + keyword);
List<Mapping> result = new LinkedList<Mapping>();
try {
if (keyword != null && !keyword.trim().equals("")) {
Cursor cursor = null;
cursor = db.query(table, null, FIELD_WORD + " = '" + keyword +"'", null, null,
null, FIELD_SCORE +" DESC", null);
if (DEBUG)
Log.i(TAG,"getRmapping():tablename:" + table + " keyworad:"
+ keyword + " cursor.getCount:"
+ cursor.getCount());
if (cursor.moveToFirst()) {
do{
int idColumn = cursor.getColumnIndex(FIELD_ID);
int codeColumn = cursor.getColumnIndex(FIELD_CODE);
int wordColumn = cursor.getColumnIndex(FIELD_WORD);
int scoreColumn = cursor.getColumnIndex(FIELD_SCORE);
Mapping munit = new Mapping();
munit.setId(cursor.getString(idColumn));
munit.setCode(cursor.getString(codeColumn));
munit.setWord(cursor.getString(wordColumn));
munit.setRelated(false);
munit.setScore(cursor.getInt(scoreColumn));
munit.setDictionary(false);
result.add(munit);
}while (cursor.moveToNext());
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
}
} catch (Exception e) {
}
if (DEBUG)
Log.i(TAG,"getRmapping() Result.size() = " + result.size());
return result;
}
// Add by jeremy '10, 4, 1. For reverse lookup
/**
* Reverse lookup on keyword.
*
* @param keyword
* @return
*/
public String getRMappingInConvertedKeynameString(String keyword) {
//Log.i("ART", "run get rmapping:"+ keyword);
String table = mLIMEPref.getRerverseLookupTable(tablename);
if (table.equals("none")) {
return null;
}
String result = new String("");
try {
if (keyword != null && !keyword.trim().equals("")) {
Cursor cursor = null;
cursor = db.query(table, null, FIELD_WORD + " = '" + keyword +"'", null, null,
null, null, null);
if (DEBUG)
Log.i(TAG,"getRmapping():tablename:" + table + " keyworad:"
+ keyword + " cursor.getCount:"
+ cursor.getCount());
if (cursor.moveToFirst()) {
int codeColumn = cursor.getColumnIndex(FIELD_CODE);
int wordColumn = cursor.getColumnIndex(FIELD_WORD);
result = cursor.getString(wordColumn) + "="
+ keyToKeyname(cursor.getString(codeColumn), table, false);
if (DEBUG)
Log.i(TAG, "getRmapping():Code:"
+ cursor.getString(codeColumn));
while (cursor.moveToNext()) {
result = result
+ "; "
+ keyToKeyname(cursor.getString(codeColumn),
table, false);
if (DEBUG)
Log.i(TAG,"getRmapping():Code:"
+ cursor.getString(codeColumn));
}
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
}
} catch (Exception e) {
}
if (DEBUG)
Log.i(TAG,"getRmapping() Result:" + result);
return result;
}
/**
* Jeremy '11,7,26 Updated related list
*
* @param code
*/
public synchronized List<Mapping> updateRelatedList(String code){
// Jeremy '11,7,31 rebuild relatedlist by query from table directly
// Update relatedlist in IM table now.
//SQLiteDatabase db = this.getSqliteDb(false);
LinkedList<Mapping> scorelist = new LinkedList<Mapping>(); //Jeremy '12,5,29 should not return null thus new linklist instead of initial with null
try {
scorelist = updateRelatedListOnDB(db, tablename,code); //Jeremy '12,6,5 the code is retrieve from mapping, and thus should not remap.
//preProcessingRemappingCode(code)); //Jeremy '12,4,11 should do remapping before update score
} catch (Exception e) {
e.printStackTrace();
}
//db.close();
return scorelist;
}
private LinkedList<Mapping> updateRelatedListOnDB(SQLiteDatabase db, String table, String code) {
String escapedCode = code.replaceAll("'", "''"); //Jeremy '11,9,10 escape '
if(DEBUG)
Log.i(TAG, "updateRelatedListOnDB(): escapedCodes: "+ escapedCode);
char[] charray = escapedCode.toCharArray();
charray[escapedCode.length()-1]++;
String nextcode = new String(charray);
// Jeremy '11,9,8 sorting with score + basescore
String selectString = "SELECT * FROM '" + table +"" +
"' WHERE " + FIELD_CODE + " > '" + escapedCode + "' AND " + FIELD_CODE + " < '" + nextcode + "'"+
" ORDER BY " + FIELD_SCORE + " DESC, "+ FIELD_BASESCORE +" DESC LIMIT 50";
Cursor cursor = db.rawQuery(selectString ,null);
if(DEBUG)
Log.i(TAG, "updateRelatedListOnDB(): raw query string: "+ selectString);
LinkedList <Mapping> scorelist = new LinkedList<Mapping>();
if(cursor.moveToFirst()){
HashSet <String> duplicateCheck = new HashSet<String>();
//scorelist = new LinkedList<Mapping>();
int idColumn = cursor.getColumnIndex(FIELD_ID);
int codeColumn = cursor.getColumnIndex(FIELD_CODE);
int wordColumn = cursor.getColumnIndex(FIELD_WORD);
int scoreColumn = cursor.getColumnIndex(FIELD_SCORE);
do {
Mapping munit = new Mapping();
munit.setCode(cursor.getString(codeColumn));
munit.setWord(cursor.getString(wordColumn));
munit.setId(cursor.getString(idColumn));
munit.setScore(cursor.getInt(scoreColumn));
munit.setDictionary(false);
if(munit.getWord() == null || munit.getWord().trim().equals(""))
continue;
if(duplicateCheck.add(munit.getWord())){
scorelist.add(munit);
}
} while (cursor.moveToNext());
// Rebuild the related list string and update the record.
String newRelatedlist;
newRelatedlist = "";
for (Mapping munit : scorelist) {
if (newRelatedlist.equals(""))
newRelatedlist = munit.getWord();
else
newRelatedlist = newRelatedlist + "|" + munit.getWord();
}
ContentValues cv = new ContentValues();
cv.put(FIELD_RELATED, newRelatedlist);
int highestScoreID = getHighestScoreID(db, table, code) ;
if (highestScoreID > 0) {
db.update(table, cv, FIELD_ID + " = " + highestScoreID, null);
if(DEBUG)
Log.i(TAG, "updateRelatedListOnDB(): updating code ="+ code
+", the new relatedlist:" + newRelatedlist);
} else {
cv.put(FIELD_CODE, code);
cv.put(FIELD_SCORE, 0);
cv.put(FIELD_BASESCORE, 0);
if(table.equals("phonetic"))
cv.put(FIELD_CODE3R, code.replaceAll("[3467 ]", "'")); //Jeremy '12,6,6 should build code3r for phonetic
db.insert(table, null, cv);
if(DEBUG)
Log.i(TAG, "updateRelatedListOnDB(): insert new code ="+ code
+", the new relatedlist:" + newRelatedlist);
}
}
if(DEBUG)
Log.i(TAG, "updateRelatedListOnDB(): scorelist.size() = "+ scorelist.size());
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
return scorelist;
}
//Rewrite by Jeremy 11,6,4. Supporting array and dayi now.
public String keyToKeyname(String code, String table, Boolean composingText) {
//Jeremy '11,8,30
if(composingText && code.length()> COMPOSING_CODE_LENGTH_LIMIT )
return code;
String keyboardtype = mLIMEPref.getPhysicalKeyboardType();
String phonetickeyboardtype = mLIMEPref.getPhoneticKeyboardType();
String keytable = table;
if(DEBUG)
Log.i(TAG, "keyToKeyname():code:" + code +
" lastValidDualCodeList=" + lastValidDualCodeList +
" table:"+table + " tablename:" + tablename +
" isPhysicalKeybaordPressed:" + isPhysicalKeyboardPressed +
" keyboardtype: " + keyboardtype +
" composingText:" + composingText);
if(isPhysicalKeyboardPressed){
if(composingText && table.equals("phonetic")) {// doing composing popup
keytable = table + keyboardtype + phonetickeyboardtype;
} else if(composingText)
keytable = table + keyboardtype;
}else if(composingText && tablename.equals("phonetic") ){
keytable = table + phonetickeyboardtype;
}
if(DEBUG)
Log.i(TAG, "keyToKeyname():keytable:" + keytable);
if(composingText){// building composing text and get dual mapped codes
if(!code.equals(lastCode)){
// unsynchronized cache. do the preprocessing again.
//preProcessingForExtraQueryConditions(preProcessingRemappingCode(code));
getMapping(code,false,false);
}
//String dualCodeList = lastValidDualCodeList;
if(lastValidDualCodeList !=null ){
if(DEBUG)
Log.i(TAG,"keyToKeyname():lastValidDualCodeList:" + lastValidDualCodeList +
" table:"+table + " tablename:" + tablename);
//code = dualCodeList;
if(tablename.equals("phonetic")){
keytable = "phonetic";
keyboardtype = "normal_keyboard";
phonetickeyboardtype = "standard";
}if(tablename.equals("dayi")){
keytable = "dayi";
keyboardtype = "normal_keyboard";
}
}
}
if(DEBUG)
Log.i(TAG, "keyToKeyname():code:" + code +
" table:"+table + " tablename:" + tablename + " keytable:"+keytable);
if(keysDefMap.get(keytable)==null
|| keysDefMap.get(keytable).size()==0){
String keyString="", keynameString="", finalKeynameString = null;
//Jeremy 11,6,4 Load keys and keynames from im table.
keyString = getImInfo(table,"imkeys");
keynameString = getImInfo(table,"imkeynames");
if(DEBUG)
Log.i(TAG,"keyToKeyname(): load from db: imkeys:keyString=" + keyString + ", imkeynames="+keynameString);
if(table.equals("phonetic")|| table.equals("dayi") ||
keyString.equals("")||keynameString.equals("")){
if(table.equals("cj")||table.equals("scj")||table.equals("cj5")||table.equals("ecj")){
keyString = CJ_KEY;
keynameString = CJ_CHAR;
}else if(table.equals("phonetic") ) {
if(composingText){ // building composing text popup
if(phonetickeyboardtype.equals("eten")){
keyString = ETEN_KEY;
if(keyboardtype.equals("milestone") && isPhysicalKeyboardPressed)
keynameString = MILESTONE_ETEN_CHAR;
else if(keyboardtype.equals("milestone2") && isPhysicalKeyboardPressed)
keynameString = MILESTONE2_ETEN_CHAR;
else if(keyboardtype.equals("milestone3") && isPhysicalKeyboardPressed)
keynameString = MILESTONE3_ETEN_CHAR;
else if(keyboardtype.equals("desireZ") && isPhysicalKeyboardPressed)
keynameString = DESIREZ_ETEN_CHAR;
else
keynameString = ETEN_CHAR;
}else if(phonetickeyboardtype.equals("eten26")){
keyString = ETEN26_KEY;
keynameString = ETEN26_CHAR_INITIAL;
finalKeynameString = ETEN26_CHAR_FINAL;
}else if(phonetickeyboardtype.equals("hsu")){
keyString = HSU_KEY;
keynameString = HSU_CHAR_INITIAL;
finalKeynameString = HSU_CHAR_FINAL;
}else if((keyboardtype.equals("milestone")||keyboardtype.equals("milestone2"))
&& isPhysicalKeyboardPressed){
keyString = MILESTONE_KEY;
keynameString = MILESTONE_BPMF_CHAR;
}else if(keyboardtype.equals("milestone3") && isPhysicalKeyboardPressed){
keyString = MILESTONE3_KEY;
keynameString = MILESTONE3_BPMF_CHAR;
}else if(keyboardtype.equals("desireZ") && isPhysicalKeyboardPressed){
keyString = DESIREZ_KEY;
keynameString = DESIREZ_BPMF_CHAR;
}else if(keyboardtype.equals("chacha") && isPhysicalKeyboardPressed){
keyString = CHACHA_KEY;
keynameString = CHACHA_BPMF_CHAR;
}else if(keyboardtype.equals("xperiapro") && isPhysicalKeyboardPressed){
keyString = XPERIAPRO_KEY;
keynameString = BPMF_CHAR;
}else{
keyString = BPMF_KEY;
keynameString = BPMF_CHAR;
}
}else{
keyString = BPMF_KEY;
keynameString = BPMF_CHAR;
}
}else if(table.equals("array")) {
keyString = ARRAY_KEY;
keynameString = ARRAY_CHAR;
}else if(table.equals("dayi")) {
if(isPhysicalKeyboardPressed&&composingText){ // only do this on composing mapping popup
if(keyboardtype.equals("milestone")||keyboardtype.equals("milestone2")){
keyString = MILESTONE_KEY;
keynameString = MILESTONE_DAYI_CHAR;
}else if(keyboardtype.equals("milestone3")){
keyString = MILESTONE3_KEY;
keynameString = MILESTONE3_DAYI_CHAR;
}else if(keyboardtype.equals("desireZ")){
keyString = DESIREZ_KEY;
keynameString = DESIREZ_DAYI_CHAR;
}else{
keyString = DAYI_KEY;
keynameString = DAYI_CHAR;
}
}else{
keyString = DAYI_KEY;
keynameString = DAYI_CHAR;
}
}
}
if(DEBUG)
Log.i(TAG, "keyToKeyname():keyboardtype:" +keyboardtype + " phonetickeyboardtype:" + phonetickeyboardtype +
" composing?:" + composingText +
" keyString:"+keyString + " keynameString:" +keynameString + " finalkeynameString:" + finalKeynameString);
if(keyString!=null && keyString.length()>0){
HashMap<String,String> keyMap = new HashMap<String,String>();
HashMap<String,String> finalKeyMap = null;
if(finalKeynameString != null)
finalKeyMap = new HashMap<String,String>();
String charlist[] = keynameString.split("\\|");
String finalCharlist[] = null;
if(finalKeyMap != null)
finalCharlist = finalKeynameString.split("\\|");
// Ignore the exception of key name mapping.
try{
for (int i = 0; i < keyString.length(); i++) {
keyMap.put(keyString.substring(i, i + 1), charlist[i]);
if(finalKeyMap != null && finalCharlist!=null)
finalKeyMap.put(keyString.substring(i, i + 1), finalCharlist[i]);
}
}catch(Exception e){}
keyMap.put("|", "|"); //put the seperator for multi-code display
keysDefMap.put(keytable, keyMap);
if(finalKeyMap != null)
keysDefMap.put("final_"+keytable, finalKeyMap);
}
}
// Starting doing key to keyname conversion ------------------------------------
if(keysDefMap.get(keytable)==null
|| keysDefMap.get(keytable).size()==0){
if(DEBUG)
Log.i(TAG, "keyToKeyname():nokeysDefMap found!!");
return code;
}else{
if(composingText && (lastValidDualCodeList !=null )) //Jeremy '11,10,6 bug fixed on rmapping returning orignal code.
code = lastValidDualCodeList;
if(DEBUG)
Log.i(TAG, "keyToKeyname():lastValidDualCodeList=" + lastValidDualCodeList);
String result = "";
HashMap <String,String> keyMap = keysDefMap.get(keytable);
HashMap <String,String> finalKeyMap = keysDefMap.get("final_"+keytable);
// do the real conversion
if(finalKeyMap == null){
for (int i = 0; i < code.length(); i++) {
String c = keyMap.get(code.substring(i, i + 1));
if(c!=null) result = result + c;
}
}else{
if(code.length()==1){
String c = "";
if(phonetickeyboardtype.equals("eten26") &&
(code.equals("q") || code.equals("w")
|| code.equals("d")|| code.equals("f")
|| code.equals("j") || code.equals("k"))){
// Dual mapped INITIALS have words mapped for ��and �� for ETEN26
c = keyMap.get(code);
}else if (phonetickeyboardtype.equals("hsu")) //Jeremy '12,5,31 process hsu with dual code mapping only.
c = keyMap.get(code);
//}else{
// c = finalKeyMap.get(code);
//}
if(c!=null) result = c.trim();
}else{
for (int i = 0; i < code.length(); i++) {
String c = "";
if(i>0){
//Jeremy '12,6,3 If the last character is a tone symbol, the preceding will be intial
if(tablename.equals("phonetic")
&& i >1
&& code.substring(0, i).matches(".+[sdfj ]$")
&& phonetickeyboardtype.equals("hsu") ){
if(DEBUG) Log.i(TAG, "preProcessingRemappingCode() hsu finalremap, subcode = " + code.substring(0, i));
c = keyMap.get(code.substring(i, i + 1));
}else if(tablename.equals("phonetic")
&& i >1
&& code.substring(0, i).matches(".+[dfjk ]$")
&& phonetickeyboardtype.equals("eten26") ){
if(DEBUG) Log.i(TAG, "preProcessingRemappingCode() hsu finalremap, subcode = " + code.substring(0, i));
c = keyMap.get(code.substring(i, i + 1));
}else
c = finalKeyMap.get(code.substring(i, i + 1));
}else{
c = keyMap.get(code.substring(i, i + 1));
}
if(c!=null) result = result + c.trim();
}
}
}
if(DEBUG)
Log.i(TAG, "keyToKeyname():returning:" + result);
if(result.equals("")){
return code;
}else{
return result;
}
}
}
/*
* Retrieve matched records
public Pair<List<Mapping>,List<Mapping>> getMappingSimiliar(String code) {
Pair<List<Mapping>,List<Mapping>> result = null;
if(mLIMEPref.getSimilarCodeCandidates() > 0){
//HashSet<String> wordlist = new HashSet<String>();
if (code != null && !code.trim().equals("")) {
int ssize = mLIMEPref.getSimilarCodeCandidates();
boolean sort = mLIMEPref.getSortSuggestions();
code = code.toLowerCase(Locale.US);
if(code != null){
// Process the escape characters of query
code = code.replaceAll("'", "''");
}
SQLiteDatabase db = this.getSqliteDb(true);
try {
Cursor cursor = null;
// When Code3r mode is disable
if(sort){
cursor = db.query(tablename, null, FIELD_CODE + " LIKE '"
+ code + "%' ", null, null, null, FIELD_SCORE +" DESC LIMIT " + ssize, null);
}else{
cursor = db.query(tablename, null, FIELD_CODE + " LIKE '"
+ code + "%' LIMIT " + ssize, null, null, null, null, null);
}
result = buildQueryResult(code, cursor);
if (cursor != null) {
cursor.deactivate();
cursor.close();
}
} catch (Exception e) {
e.printStackTrace();
}
db.close();
}
}
return result;
}*/
/**
* Retrieve matched records
*/
public Pair<List<Mapping>,List<Mapping>> getMapping( String code, boolean softKeyboard, boolean getAllRecords) {
//Jeremy '12,5,1 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return null;
boolean sort = true;
if(softKeyboard) sort = mLIMEPref.getSortSuggestions();
else sort = mLIMEPref.getPhysicalKeyboardSortSuggestions();
isPhysicalKeyboardPressed = !softKeyboard;
if(DEBUG)
Log.i(TAG, "getmapping(): code='"+ code + "' doLDPhonetic="
+mLIMEPref.getParameterBoolean("doLDPhonetic")
+ ", table=" + tablename + ", getAllRecords=" + getAllRecords );
// Add by Jeremy '10, 3, 27. Extension on multi table query.
lastCode = code;
lastValidDualCodeList = null; // reset the lastValidDualCodeList
Pair<List<Mapping>,List<Mapping>> result = null;
//Two-steps qeury code pre-processing. Jeremy '11,6,15
// Step.1 Code re-mapping.
code = preProcessingRemappingCode(code);
code = code.toLowerCase(Locale.US); //Jeremy '12,4,1 moved from SearchService.query();
// Step.2 Build extra query conditions. (e.g. 3row remap)
String extraConditions = preProcessingForExtraQueryConditions(code);
//Jeremy '11,6,11 seperated suggestions sorting option for physical keyboard
try{
if (!code.equals("")) {
try {
Cursor cursor = null;
// Jeremy '11,8,2 Query code3r instead of code for code contains no tone symbols
// Jeremy '12,6,5 rewrite to consistent with expanddualcode
final boolean useCode3r = tablename.equals("phonetic");//&& mLIMEPref.getParameterBoolean("doLDPhonetic", true);
String codeCol = FIELD_CODE;
if( tablename.equals("phonetic") ){
final boolean tonePresent = code.matches(".+[3467 ].*"); // Tone symbols present in any locoation except the first character
final boolean toneNotLast = code.matches(".+[3467 ].+"); // Tone symbols present in any locoation except the first and last character
if(useCode3r){ //code3r (phonetic comibnation without tones) is present
if(tonePresent){
//LD phrase if tone symbols present but not in last character or in last character but the lenth > 4 (phonetic combinations never has length >4)
if(toneNotLast || ( !toneNotLast && code.length() >4 ))
code = code.replaceAll("[3467 ]", "");
}else{ // no tone symbols present, check code3r column
codeCol = FIELD_CODE3R;
}
}else if(tonePresent && (toneNotLast || ( !toneNotLast && code.length() >4 ))) //LD phrase and no code3r column present
code = code.replaceAll("[3467 ]", "");
code = code.trim();
}
// Do escape code here.
String selectClause = codeCol + " = '" + code.replaceAll("'", "''") + "' " + extraConditions;
/*if(tablename.equals("phonetic") && code.matches(".+[3467 ].+")){
//Jeremy '12,6,3 should replace the tone symbol at last character because it may be dual mapped non-tone symbols
if(code.matches(".+[ 3467]$")){
String prefix = code.substring(0, code.length()-1).replaceAll("[3467 ]", "");
String postfix = code.substring(code.length()-1, code.length());
code = prefix+postfix;
}else
code = code.replaceAll("[3467 ]", "");
}
if(tablename.equals("phonetic")
&& mLIMEPref.getParameterBoolean("doLDPhonetic", false)
&&!code.matches(".+[3467 ].*")){
selectClause = FIELD_CODE3R + " = '" + code + "' " + extraConditions;
}else{
selectClause = FIELD_CODE + " = '" + code.trim() + "' " + extraConditions;
}*/
if(DEBUG)
Log.i(TAG, "getMapping(): code = '" + code + "' selectClause=" + selectClause );
// Jeremy '11,8,5 limit initial query to limited records
String limitClause = null;
if(!getAllRecords)
limitClause = INITIAL_RESULT_LIMIT;
// Jeremy '11,6,15 Using query with preprocessed code and extra query conditions.
if(sort){
cursor = db.query(tablename, null, selectClause , null, null, null,
FIELD_SCORE +" DESC, +" +FIELD_BASESCORE + " DESC, " + "_id ASC"
, limitClause);
}else{
cursor = db.query(tablename, null, selectClause
//, null, null, null, FIELD_BASESCORE + " DESC, _id ASC", limitClause);
, null, null, null, "_id ASC", limitClause); //Jeremy '12,4,28 ignore the basescore when not sorintg
}
result = buildQueryResult(code, cursor, getAllRecords);
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
}catch(SQLiteException e){
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}catch(Exception e){
e.printStackTrace();
}
return result;
}
private String preProcessingRemappingCode(String code){
if(DEBUG)
Log.i(TAG, "preProcessingRemappingCode(): tablename = " + tablename +" , code="+code);
if(code != null){
String keyboardtype = mLIMEPref.getPhysicalKeyboardType();
String phonetickeyboardtype = mLIMEPref.getPhoneticKeyboardType();
String keyString = "", keyRemapString ="", finalKeyRemapString = null;
String newcode = code;
String remaptable = tablename;
// Build cached hashmap remapping table name
if(isPhysicalKeyboardPressed ){
if(tablename.equals("phonetic"))
remaptable = tablename + keyboardtype + phonetickeyboardtype;
else
remaptable = tablename + keyboardtype;
}else if(tablename.equals("phonetic"))
remaptable = tablename + phonetickeyboardtype;
// Build cached hashmap remapping table if it's not exist
if(keysReMap.get(remaptable)==null
|| keysReMap.get(remaptable).size()==0){
if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("eten26")){
keyString = ETEN26_KEY;
keyRemapString = ETEN26_KEY_REMAP_INITIAL;
finalKeyRemapString = ETEN26_KEY_REMAP_FINAL;
}else if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("hsu")){
keyString = HSU_KEY;
keyRemapString = HSU_KEY_REMAP_INITIAL;
finalKeyRemapString = HSU_KEY_REMAP_FINAL;
}else if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("eten")){
keyString = ETEN_KEY;
//+ SHIFTED_NUMBERIC_KEY + SHIFTED_SYMBOL_KEY;
keyRemapString = ETEN_KEY_REMAP ;
//+ SHIFTED_NUMBERIC_ETEN_KEY_REMAP + SHIFTED_SYMBOL_ETEN_KEY_REMAP;
}else if(isPhysicalKeyboardPressed
&& tablename.equals("phonetic") && keyboardtype.equals("desireZ")){
//Desire Z phonetic keybaord
keyString = DESIREZ_KEY;
keyRemapString = DESIREZ_BPMF_KEY_REMAP;
}else if(isPhysicalKeyboardPressed
&& tablename.equals("phonetic") && keyboardtype.equals("chacha")){
//Desire Z phonetic keybaord
keyString = CHACHA_KEY;
keyRemapString = CHACHA_BPMF_KEY_REMAP;
}else if(isPhysicalKeyboardPressed
&& tablename.equals("phonetic") && keyboardtype.equals("xperiapro")){
//XPERIA PRO phonetic keybaord
keyString = XPERIAPRO_KEY;
keyRemapString = XPERIAPRO_BPMF_KEY_REMAP;
}else if(!isPhysicalKeyboardPressed){
if(tablename.equals("dayi") || tablename.equals("ez")
||tablename.equals("phonetic")&&phonetickeyboardtype.equals("standard") ){
keyString = SHIFTED_NUMBERIC_KEY + SHIFTED_SYMBOL_KEY;
keyRemapString = SHIFTED_NUMBERIC_KEY_REMAP + SHIFTED_SYMBOL_KEY_REMAP;
}else if(tablename.equals("array")){
keyString = SHIFTED_SYMBOL_KEY;
keyRemapString = SHIFTED_SYMBOL_KEY_REMAP;
}
}
if(DEBUG)
Log.i(TAG, "preProcessingRemappingCode(): keyString=\"" + keyString +"\";keyRemapString=\"" + keyRemapString +"\"" );
if(!keyString.equals("")){
HashMap<String,String> reMap = new HashMap<String,String>();
HashMap<String,String> finalReMap = null;
if( finalKeyRemapString!=null)
finalReMap = new HashMap<String,String>();
for (int i = 0; i < keyString.length(); i++) {
reMap.put(keyString.substring(i, i + 1), keyRemapString.substring(i, i + 1));
if(finalReMap!=null)
finalReMap.put(keyString.substring(i, i + 1), finalKeyRemapString.substring(i, i + 1));
}
keysReMap.put(remaptable, reMap);
if(finalReMap!=null)
keysReMap.put("final_"+remaptable, finalReMap);
}
}
// Do the remapping here using the cached remapping table
//if(keysReMap.get(remaptable)==null
// || keysReMap.get(remaptable).size()==0){
//return code; //Jeremy '12,5,21 need to do escape. should not return here.
//}
//else{
if(keysReMap.get(remaptable)!=null
&& keysReMap.get(remaptable).size()!=0) {
HashMap<String,String> reMap = keysReMap.get(remaptable);
HashMap<String,String> finalReMap = keysReMap.get("final_"+remaptable);
newcode = "";
String c = null;
if(finalReMap == null){
for (int i = 0; i < code.length(); i++) {
String s = code.substring(i, i + 1);
c = reMap.get(s);
if(c!=null) newcode = newcode + c;
else newcode = newcode + s;
}
}else {
if(code.length() == 1){
if(phonetickeyboardtype.equals("eten26") &&
(code.equals("q") || code.equals("w")
|| code.equals("d")|| code.equals("f")
|| code.equals("j") || code.equals("k"))){
// Dual mapped INITIALS have words mapped for ��and �� for ETEN26
c = reMap.get(code);
}else if (phonetickeyboardtype.equals("hsu") &&
(code.equals("a") || code.equals("e") ||
code.equals("s") || code.equals("d") || code.equals("f") ||code.equals("j"))){
// Dual mapped INITIALS have words mapped for a and e
// and no mapped word on finals s,d,f,j for HSU
c = reMap.get(code);
}else{
/*if(tablename.equals("array")){
if(code.equals("<")){
c = finalReMap.get(',');
}else if(code.equals(">")){
c = finalReMap.get('.');
}else if(code.equals("?")){
c = finalReMap.get('/');
}else if(code.equals(":")){
c = finalReMap.get(';');
}
}else{
}*/
c = finalReMap.get(code);
}
if(c!=null) newcode = c;
else newcode = code;
}else {
for (int i = 0; i < code.length(); i++) {
String s = code.substring(i, i + 1);
if(i>0){
//Jeremy '12,6,3 If the last character is a tone symbol, the preceding will be intial
if(tablename.equals("phonetic")
&& i >1
&& code.substring(0, i).matches(".+[sdfj ]$")
&& phonetickeyboardtype.equals("hsu") ){
if(DEBUG) Log.i(TAG, "preProcessingRemappingCode() hsu finalremap, subcode = " + code.substring(0, i));
c = reMap.get(s);
}else if(tablename.equals("phonetic")
&& i >1
&& code.substring(0, i).matches(".+[dfjk ]$")
&& phonetickeyboardtype.equals("eten26") ){
if(DEBUG) Log.i(TAG, "preProcessingRemappingCode() hsu finalremap, subcode = " + code.substring(0, i));
c = reMap.get(s);
}else
c = finalReMap.get(s);
}else
c = reMap.get(s);
if(c!=null) newcode = newcode + c;
else newcode = newcode + s;
}
}
}
}
//Process the escape characters of query
//newcode = newcode.replaceAll("'", "''"); // Jeremy '12,7,7 do the code escaped before query.
if(DEBUG)
Log.i(TAG, "preProcessingRemappingCode():newcode="+newcode);
return newcode;
}else
return "";
}
//Jeremy '12,4,5 add db parameter because db open/closed is handled in searchservice now.
private String preProcessingForExtraQueryConditions(String code){
if(DEBUG)
Log.i(TAG, "preProcessingForExtraQueryConditions(): code = '"+code
+ "', isPhysicalKeyboardPressed=" + isPhysicalKeyboardPressed);
if(code != null ){
String keyboardtype = mLIMEPref.getPhysicalKeyboardType();
String phonetickeyboardtype = mLIMEPref.getPhoneticKeyboardType();
String dualcode ="";
String dualKey = "";
String dualKeyRemap = "";
String remaptable = tablename;
if(isPhysicalKeyboardPressed ){
if(tablename.equals("phonetic"))
remaptable = tablename + keyboardtype + phonetickeyboardtype;
else
remaptable = tablename + keyboardtype;
}else if(tablename.equals("phonetic")){
remaptable = tablename + phonetickeyboardtype;
}
if(keysDualMap.get(remaptable)==null
|| keysDualMap.get(remaptable).size()==0){
if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("eten26")){
dualKey = ETEN26_DUALKEY;
dualKeyRemap = ETEN26_DUALKEY_REMAP;
}else if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("hsu")){
dualKey = HSU_DUALKEY;
dualKeyRemap = HSU_DUALKEY_REMAP;
}else if(keyboardtype.equals("milestone") && isPhysicalKeyboardPressed ){
if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("eten")){
dualKey = MILESTONE_ETEN_DUALKEY;
dualKeyRemap = MILESTONE_ETEN_DUALKEY_REMAP;
}else{
dualKey = MILESTONE_DUALKEY;
dualKeyRemap = MILESTONE_DUALKEY_REMAP;
}
}else if(keyboardtype.equals("milestone2") && isPhysicalKeyboardPressed ){
if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("eten")){
dualKey = MILESTONE2_ETEN_DUALKEY;
dualKeyRemap = MILESTONE2_ETEN_DUALKEY_REMAP;
}else{
dualKey = MILESTONE2_DUALKEY;
dualKeyRemap = MILESTONE2_DUALKEY_REMAP;
}
}else if(keyboardtype.equals("milestone3") && isPhysicalKeyboardPressed ){
if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("eten")){
dualKey = MILESTONE3_ETEN_DUALKEY;
dualKeyRemap = MILESTONE3_ETEN_DUALKEY_REMAP;
}else if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("standard")){
dualKey = MILESTONE3_BPMF_DUALKEY;
dualKeyRemap = MILESTONE3_BPMF_DUALKEY_REMAP;
}else{
dualKey = MILESTONE3_DUALKEY;
dualKeyRemap = MILESTONE3_DUALKEY_REMAP;
}
}else if(keyboardtype.equals("desireZ") && isPhysicalKeyboardPressed ) {
if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("eten")){
dualKey = DESIREZ_ETEN_DUALKEY;
dualKeyRemap = DESIREZ_ETEN_DUALKEY_REMAP;
}else if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("standard")){
dualKey = DESIREZ_BPMF_DUALKEY;
dualKeyRemap = DESIREZ_BPMF_DUALKEY_REMAP;
}else{
dualKey = DESIREZ_DUALKEY;
dualKeyRemap = DESIREZ_DUALKEY_REMAP;
}
}else if(keyboardtype.equals("chacha") && isPhysicalKeyboardPressed ) {
if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("eten")){
dualKey = CHACHA_ETEN_DUALKEY;
dualKeyRemap = CHACHA_ETEN_DUALKEY_REMAP;
}else if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("standard")){
dualKey = CHACHA_BPMF_DUALKEY;
dualKeyRemap = CHACHA_BPMF_DUALKEY_REMAP;
}else{
dualKey = CHACHA_DUALKEY;
dualKeyRemap = CHACHA_DUALKEY_REMAP;
}
}else if(keyboardtype.equals("xperiapro") && isPhysicalKeyboardPressed ) { //Jeremy '12,4,1
if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("eten")){
dualKey = XPERIAPRO_ETEN_DUALKEY;
dualKeyRemap = XPERIAPRO_ETEN_DUALKEY_REMAP;
}else if(tablename.equals("phonetic")&&phonetickeyboardtype.equals("standard")){
// no dual key here
dualKey = "";
dualKeyRemap = "";
}else{
dualKey = XPERIAPRO_DUALKEY;
dualKeyRemap = XPERIAPRO_DUALKEY_REMAP;
}
}else if(tablename.equals("ez") && !isPhysicalKeyboardPressed ){ //jeremy '12,7,5 remap \ to `.
dualKey = "\\";
dualKeyRemap = "`";
}
HashMap<String,String> reMap = new HashMap<String,String>();
if(DEBUG)
Log.i(TAG, "preProcessingForExtraQueryConditions(): dualKey="+dualKey+" dualKeyRemap="+dualKeyRemap);
for(int i=0; i< dualKey.length(); i++){
String key = dualKey.substring(i,i+1);
String value = dualKeyRemap.substring(i,i+1);
//Process the escape characters of query
//if(key.equals("'")) key = "''";
//if(value.equals("'")) value = "''"; \\Jeremy '12,5,21 do the escape in getmapping
reMap.put(key, value);
reMap.put(value, value);
}
keysDualMap.put(remaptable, reMap);
}
// do real prcoessing now
if(keysDualMap.get(remaptable)==null
|| keysDualMap.get(remaptable).size()==0){
dualcode = code;
}else{
HashMap<String,String> reMap = keysDualMap.get(remaptable);
dualcode = "";
// testing if code contains dual mapped characters.
for (int i = 0; i < code.length(); i++) {
String c = reMap.get(code.substring(i, i + 1));
if(c!=null) dualcode = dualcode + c;
}
if(DEBUG)
Log.i(TAG, "preProcessingForExtraQueryConditions(): dualcode="+dualcode);
}
//Jeremy '11,8,12 if phonetic has tone symbol in the middle do the expanddualcode
if(!dualcode.equalsIgnoreCase(code)
|| !code.equalsIgnoreCase(lastCode) // '11,8,18 Jeremy
||(tablename.equals("phonetic") && code.matches(".+[ 3467].+") )
){
return expandDualCode(code, remaptable);
}
}
return "";
}
private HashSet<String> buildDualCodeList(String code, String keytablename){
if(DEBUG) Log.i(TAG, "buildDualCodeList(): code:"+ code);
HashMap<String,String> codeDualMap = keysDualMap.get(keytablename);
HashSet<String> dualCodeList = new HashSet<String>();
//HashSet<String> resultDualCodeList = new HashSet<String>();
HashSet<String> treeDualCodeList = new HashSet<String>();
dualCodeList.add(code);
//resultDualCodeList.add(code);
if(codeDualMap != null && codeDualMap.size()>0) {
//Jeremy '12,6,4
SparseArray< List<String>> treemap = new SparseArray<List<String>>();
for(int i=0;i < code.length(); i++ ){
if(DEBUG)
Log.i(TAG, "buildDualCodeList() level : " + i);
List<String> levelnMap = new LinkedList<String>();
List<String> lastLevelMap = null;
if(i==0) {
lastLevelMap = new LinkedList<String>();
lastLevelMap.add(code);
}else
lastLevelMap = treemap.get(i-1);
String c = null;
String n = null;
if(lastLevelMap ==null ||
(lastLevelMap!=null &&lastLevelMap.size()==0) ){
if(DEBUG)
Log.i(TAG, "buildDualCodeList() level : " + i + " ended because last level map is empty");
continue;
}
if(DEBUG)
Log.i(TAG, "buildDualCodeList() level : " + i + " lastlevelmap size = " + lastLevelMap.size());
for(String entry : lastLevelMap){
if(DEBUG)
Log.i(TAG, "buildDualCodeList() level : " + i +", entry = " + entry);
if(entry.length()==1) c = entry;
else
c = entry.substring(i, i+1);
boolean codeMapped = false;
do{
if(DEBUG)
Log.i(TAG, "buildDualCodeList() newCode = '" + entry
+ "' blacklistKey = '" + cacheKey(entry.substring(0,i+1)+"%")
+ "' blacklistValue = " + blackListCache.get(cacheKey(entry.substring(0,i+1)+"%")));
if(entry.length()==1 && !levelnMap.contains(entry) ){
if(blackListCache.get(cacheKey(entry))==null) treeDualCodeList.add(entry);
levelnMap.add(entry);
if(DEBUG)
Log.i(TAG, "buildDualCodeList() entry.length()==1 new code = '" + entry
+ "' added. treeDualCodeList.size = " + treeDualCodeList.size());
codeMapped = true;
}else if((entry.length()>1 && !levelnMap.contains(entry))
&& blackListCache.get(cacheKey(entry.substring(0,i+1)+"%"))==null){
if(blackListCache.get(cacheKey(entry))==null) treeDualCodeList.add(entry);
levelnMap.add(entry);
if(DEBUG)
Log.i(TAG, "buildDualCodeList() new code = '" + entry
+ "' added. treeDualCodeList.size = " + treeDualCodeList.size());
codeMapped = true;
}else if(codeDualMap.get(c)!=null && !codeDualMap.get(c).equals(c)){
n = codeDualMap.get(c);
String newCode = "";
if(entry.length()==1)
newCode =n;
else if(i==0)
newCode = n + entry.substring(1,entry.length());
else if(i == entry.length()-1 )
newCode = entry.substring(0, entry.length()-1) + n;
else
newCode = entry.substring(0,i) + n
+ entry.substring(i+1, entry.length());
if(DEBUG)
Log.i(TAG, "buildDualCodeList() newCode = '" + newCode
+ "' blacklistKey = '" + cacheKey(newCode)
+ "' blacklistValue = " + blackListCache.get(cacheKey(newCode))
+ "' blacklistKey = '" + cacheKey(newCode.substring(0,i+1)+"%")
+ "' blacklistValue = " + blackListCache.get(cacheKey(newCode.substring(0,i+1)+"%"))
);
if(newCode.length()==1 && !levelnMap.contains(newCode) ){
if(blackListCache.get(cacheKey(newCode))==null) treeDualCodeList.add(newCode);
levelnMap.add(newCode);
if(DEBUG)
Log.i(TAG, "buildDualCodeList() newCode.length()==1 treeDualCodeList new code = '" + newCode
+ "' added. treeDualCodeList.size = " + treeDualCodeList.size());
codeMapped = true;
}else if((newCode.length()>1 && !levelnMap.contains(newCode))
&& blackListCache.get(cacheKey(newCode.substring(0,i+1)+"%"))==null){
levelnMap.add(newCode);
if(blackListCache.get(cacheKey(newCode))==null) treeDualCodeList.add(newCode);
if(DEBUG)
Log.i(TAG, "buildDualCodeList() treeDualCodeList new code = '" + newCode
+ ", c = " + c
+ ", n = " + n
+ "' added. treeDualCodeList.size = " + treeDualCodeList.size());
codeMapped = true;
}else if(DEBUG)
Log.i(TAG, "buildDualCodeList() blacklisted code = '" + newCode.substring(0,i+1)+"%"
+ "'");
c = n;
}else {
if(DEBUG)
Log.i(TAG, "buildDualCodeList() level : " + i
+ " ended. treeDualCodeList.size = " + treeDualCodeList.size());
codeMapped = false;
}
}while(codeMapped);
treemap.put(i, levelnMap);
}
}
//Jeremy '11,8,12 added for continuous typing.
if(tablename.equals("phonetic")){
HashSet<String> tempList = new HashSet<String>(treeDualCodeList);
for(String iterator_code: tempList){
if(iterator_code.matches(".+[ 3467].+")){ // regular expression mathes tone in the middle
String newCode = iterator_code.replaceAll("[3467 ]","");
//Jeremy '12,6,3 look-up the blacklist cache before add to the list.
if(DEBUG)
Log.i(TAG, "buildDualCodeList(): processing no tone code :"+ newCode);
if(newCode.length()>0
&& !treeDualCodeList.contains(newCode)
&& !checkBlackList(cacheKey(newCode), false) ){
treeDualCodeList.add(newCode);
if(DEBUG)
Log.i(TAG, "buildDualCodeList(): no tone code added:"+ newCode);
}
}
}
}
}
if(DEBUG) Log.i(TAG, "buildDualCodeList(): treeDualCodeList.size()="+ treeDualCodeList.size());
return treeDualCodeList;
}
/**
* Jeremy '12,6,4 check black list on code , code + wildcard and reduced code with wildcard
* @param code
* @return
*/
private boolean checkBlackList(String code, Boolean wildCardOnly){
Boolean isBlacklisted = false;
if(code.length()< DUALCODE_NO_CHECK_LIMIT){ //code too short, add anyway
isBlacklisted = false;
if(DEBUG)
Log.i(TAG, "buildDualCodeList(): code too short add without check code=" + code);
}else if(!wildCardOnly && blackListCache.get(cacheKey(code)) != null){ //the code is blacklisted
isBlacklisted = true;
if(DEBUG)
Log.i(TAG, "buildDualCodeList(): black listed code:"+ code);
/*}else if(blackListCache.get(cacheKey(code+"%")) != null){ //the code with wildcard is blacklisted
if(DEBUG)
Log.i(TAG, "buildDualCodeList(): check black list code:"+ code
+ ", blackListCache.get(cacheKey(codeToCheck+%))="+blackListCache.get(cacheKey(code+"%")));
isBlacklisted = true;
if(DEBUG)
Log.i(TAG, "buildDualCodeList(): black listed code:"+ code+"%");*/
}else {
for(int i=DUALCODE_NO_CHECK_LIMIT-1; i <= code.length(); i++){
String codeToCheck = code.substring(0, i) + "%";
if(blackListCache.get(cacheKey(codeToCheck)) != null){
isBlacklisted = true;
if(DEBUG)
Log.i(TAG, "buildDualCodeList(): black listed code:"+ codeToCheck);
break;
}
}
}
return isBlacklisted;
}
/**
* Jeremy '12,6,4 check black list on code , code + wildcard and reduced code with wildcard
* @param code
* @return
*/
private void removeFromBlackList(String code){
if(blackListCache.get(cacheKey(code)) != null)
blackListCache.remove(cacheKey(code));
/*if(blackListCache.get(cacheKey(code+"%")) != null)
blackListCache.remove(cacheKey(code+"%"));
*/
for(int i=DUALCODE_NO_CHECK_LIMIT-1; i <= code.length(); i++){
String codeToCheck = code.substring(0, i) + "%";
if(blackListCache.get(cacheKey(codeToCheck)) != null)
blackListCache.remove(cacheKey(codeToCheck));
}
}
private String expandDualCode(String code, String keytablename){
HashSet <String> dualCodeList = buildDualCodeList(code, keytablename);
String result="";
String validDualCodeList = "";
if(dualCodeList != null) {
final boolean NOCheckOnExpand = code.length() < DUALCODE_NO_CHECK_LIMIT;
final boolean useCode3r = tablename.equals("phonetic");//&& mLIMEPref.getParameterBoolean("doLDPhonetic", true);
for(String dualcode : dualCodeList){
if(DEBUG)
Log.i(TAG, "expandDualCode(): processing dualcode = '" + dualcode + "'" + ". result = " + result);
String noToneCode = dualcode;
String codeCol = FIELD_CODE;
String[] col = {codeCol};
if( tablename.equals("phonetic") ){
final boolean tonePresent = dualcode.matches(".+[3467 ].*"); // Tone symbols present in any locoation except the first character
final boolean toneNotLast = dualcode.matches(".+[3467 ].+"); // Tone symbols present in any locoation except the first and last character
if(useCode3r){ //code3r (phonetic comibnation without tones) is present
if(tonePresent){
//LD phrase if tone symbols present but not in last character or in last character but the lenth > 4 (phonetic combinations never has length >4)
if(toneNotLast || ( !toneNotLast && dualcode.length() >4 ))
noToneCode = dualcode.replaceAll("[3467 ]", "");
}else{ // no tone symbols present, check code3r column
codeCol = FIELD_CODE3R;
}
}else if(tonePresent && (toneNotLast || ( !toneNotLast && dualcode.length() >4 ))) //LD phrase and no code3r column present
noToneCode = dualcode.replaceAll("[3467 ]", "");
}
// do escape code for codes
String querycode = dualcode.trim().replaceAll("'", "''");
String queryNoToneCode = noToneCode.trim().replaceAll("'", "''");
if(querycode.length()==0) continue;
if(NOCheckOnExpand){
if(!dualcode.equals(code)){
result = result + " OR " + codeCol + "= '"+ querycode +"'";
}
}else{
//Jeremy '11,8, 26 move valid code list building to buildqueryresult to avoid repeat query.
try{
String selectClause = codeCol + " = '" + querycode + "'";
if(!dualcode.equals(noToneCode)){ //code with tones. should strip tone symbols and add to the select condition.
selectClause = FIELD_CODE + " = '" + querycode + "' OR " + FIELD_CODE3R + " = '" + queryNoToneCode + "'";
}
if(DEBUG)
Log.i(TAG,"expandDualCode() selectClause = " +selectClause );
Cursor cursor = db.query(tablename, col, selectClause,
null, null, null, null, "1");
if(cursor.moveToFirst()){ //fist entry exist, the code is valid.
if(DEBUG)
Log.i(TAG,"expandDualCode() code = '" + dualcode + "' is validcode" );
if(validDualCodeList.equals("")) validDualCodeList = dualcode;
else validDualCodeList = validDualCodeList + "|" + dualcode;
if(!dualcode.equals(code))
result = result + " OR " + codeCol + "= '"+ querycode +"'";
}else{ //the code is not valid, keep it in the black list cache. Jeremy '12,6,3
char[] charray = dualcode.toCharArray();
charray[querycode.length()-1]++;
String nextcode = new String(charray);
nextcode = nextcode.replaceAll("'", "''");
selectClause = codeCol + " > '" + querycode + "' AND " + codeCol + " < '" + nextcode + "'";
if(!dualcode.equals(noToneCode)){ //code with tones. should strip tone symbols and add to the select condition.
charray = queryNoToneCode.toCharArray();
charray[noToneCode.length()-1]++;
String nextNoToneCode = new String(charray);
nextNoToneCode = nextNoToneCode.replaceAll("'", "''");
selectClause = "(" + codeCol + " > '" + querycode + "' AND " + codeCol + " < '" + nextcode + "') "
+ "OR (" + codeCol + " > '" + queryNoToneCode + "' AND " + codeCol + " < '" + nextNoToneCode + "')";
}
if(DEBUG)
Log.i(TAG,"expandDualCode() dualcode = '" + dualcode + "' noToneCode = '"
+ noToneCode + "' selectClause = " + selectClause );
cursor = db.query(tablename, col, selectClause,
null, null, null, null, "1");
if(!cursor.moveToFirst()){ //code* returns no valid records add the code with wildcard to blacklist
blackListCache.put(cacheKey(dualcode+"%"), true);
if(DEBUG)
Log.i(TAG, " expandDualCode() blackList wildcard code added, code = " + dualcode+"%"
+ ", cachkey = :"+ cacheKey(dualcode+"%")
+ ", black list size = " + blackListCache.size()
+ ", blackListCache.get() = " + blackListCache.get(cacheKey(dualcode+"%")));
}else{ //only add the code to black list
blackListCache.put(cacheKey(dualcode), true);
if(DEBUG)
Log.i(TAG, " expandDualCode() blackList code added, code = " +dualcode);
}
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
if(validDualCodeList.equals(""))
lastValidDualCodeList = null;
else
lastValidDualCodeList = validDualCodeList;
}
if(DEBUG)
Log.i(TAG, "expandDualCode(): result:" + result + " validDualCodeList:" + validDualCodeList);
return result;
}
/**
* Jeremy '12,6,3 Build unique cache key for black list cache.
* @param code
* @return
*/
private String cacheKey(String code){
return tablename+"_"+code;
}
/**
* Process search results
*/
private synchronized Pair<List<Mapping>,List<Mapping>> buildQueryResult(String query_code, Cursor cursor, Boolean getAllRecords) {
List<Mapping> result = new ArrayList<Mapping>();
List<Mapping> relatedresult = new ArrayList<Mapping>();
Pair<List<Mapping>,List<Mapping>> resultPair = new Pair<List<Mapping>,List<Mapping>>(result, relatedresult);
HashSet<String> duplicateCheck = new HashSet<String>();
HashSet<String> validCodeMap = new HashSet<String>(); //Jeremy '11,8,26
int rsize = 0;
//jeremy '11,8,30 reset lastVaidDualCodeList first.
final boolean buildValidCodeList = lastValidDualCodeList==null;
boolean useCode3r =tablename.equals("phonetic")
//&& mLIMEPref.getParameterBoolean("doLDPhonetic", true)
&& !query_code.matches(".+[3467 ].*");
if(DEBUG) Log.i(TAG,"buildQueryResutl(): cursor.getCount()=" + cursor.getCount()
+ ". lastValidDualCodeList = " + lastValidDualCodeList);
if (cursor.moveToFirst()) {
int idColumn = cursor.getColumnIndex(FIELD_ID);
int codeColumn = cursor.getColumnIndex(FIELD_CODE);
int noToneCodeColumn = cursor.getColumnIndex(FIELD_CODE3R); //Jeremy '12,5,31 renamed from code3rColumn
int wordColumn = cursor.getColumnIndex(FIELD_WORD);
int scoreColumn = cursor.getColumnIndex(FIELD_SCORE);
int relatedColumn = cursor.getColumnIndex(FIELD_RELATED);
HashMap<String, String> relatedMap = new HashMap<String, String>();
do {
String code = cursor.getString(codeColumn);
String relatedlist = cursor.getString(relatedColumn);
//if(DEBUG)
// Log.i(TAG, "buildQueryResult() code = '" + code + "' relatedlist = " + relatedlist);
Mapping munit = new Mapping();
munit.setWord(cursor.getString(wordColumn));
munit.setId(cursor.getString(idColumn));
munit.setCode(code);
munit.setRelated(false);//Jeremy '12,5,30 exact match, not from related list
//Jeremy '11,8,26 build valid code map
//jeremy '11,8,30 add limit for vali code words for composing display
if(buildValidCodeList){
String noToneCode = cursor.getString(noToneCodeColumn);
if(useCode3r && noToneCode!=null
&& validCodeMap.size()< DUALCODE_COMPOSING_LIMIT)
validCodeMap.add(noToneCode);
else if(code!=null)
validCodeMap.add(code);
}
// 06/Aug/2011 by Art: ignore the result when word == keyToKeyname(code)
// Only apply to Array IM
try{
if(code != null && code.length() == 1 && tablename.equals("array")){
if(keyToKeyname(code, tablename, false).equals(munit.getWord())){
continue;
}
}
}catch(Exception e){}
if(relatedlist!=null && relatedMap.get(code) == null){
relatedMap.put(code, relatedlist);
if(DEBUG)
Log.i(TAG, "buildQueryResult() build relatedmap on code = '" + code + "' relatedlist = " + relatedlist);
}
munit.setScore(cursor.getInt(scoreColumn));
munit.setDictionary(false);
if(munit.getWord() == null || munit.getWord().trim().equals(""))
continue;
if(duplicateCheck.add(munit.getWord())){
result.add(munit);
}
rsize++;
} while (cursor.moveToNext());
//Jeremy '11,8,26 build valid code map
if(buildValidCodeList && validCodeMap.size()>0){
for(String validCode : validCodeMap){
if(DEBUG) Log.i(TAG, "buildQueryResult(): buildValidCodeList: valicode=" + validCode);
if(lastValidDualCodeList==null) lastValidDualCodeList = validCode;
else lastValidDualCodeList = lastValidDualCodeList + "|" + validCode;
}
}
int ssize = mLIMEPref.getSimilarCodeCandidates();
//Jeremy '11,6,1 The related field may have only one word and thus no "|" inside
//Jeremy '11,6,11 allow multiple relatedlist from different codes.
int scount = 0;
for(Entry<String, String> entry: relatedMap.entrySet()){
String relatedlist = entry.getValue();
if (ssize > 0 && relatedlist != null && scount <= ssize){
String templist[] = relatedlist.split("\\|");
for (String unit : templist) {
if(ssize != 0 && scount > ssize){break;}
if(duplicateCheck.add(unit)){
Mapping munit = new Mapping();
munit.setWord(unit);
//munit.setPword(relatedlist);
munit.setScore(0);
munit.setCode(entry.getKey());
//Jeremy '11,6,18 skip if word is empty
if(munit.getWord() == null || munit.getWord().trim().equals(""))
continue;
relatedresult.add(munit);
scount++;
// Jeremy '11, 8, 5 break if limit number exceeds
if(!getAllRecords && scount == INITIAL_RELATED_LIMIT) break;
}
}
}
}
}
if(query_code.length() == 1){
// processing full shaped , and .
if( (query_code.equals(",")||query_code.equals("<")) && duplicateCheck.add(",") ){
Mapping temp = new Mapping();
temp.setCode(query_code);
temp.setWord(",");
temp.setRelated(false);
if(result.size()>3)
result.add(3,temp);
else
result.add(temp);
}
if( (query_code.equals(".")||query_code.equals(">")) && duplicateCheck.add("。") ){
Mapping temp = new Mapping();
temp.setCode(query_code);
temp.setWord("。");
if(result.size()>3)
result.add(3,temp);
else
result.add(temp);
}
}
Mapping temp = new Mapping();
temp.setCode("has_more_records");
temp.setWord("...");
if(!getAllRecords && rsize == Integer.parseInt(INITIAL_RESULT_LIMIT))
result.add(temp);
if(!getAllRecords && relatedresult.size() == INITIAL_RELATED_LIMIT)
relatedresult.add(temp);
if(DEBUG)
Log.i(TAG, "buildQueryResult():query_code:" + query_code + " query_code.length:" + query_code.length()
+ " result.size=" + result.size() + " query size:" + rsize
+ " relatedlist.size=" + relatedresult.size());
return resultPair;
}
/**
*
* @return Cursor for
*/
public Cursor getDictionaryAll() {
//Jeremy '12,5,1 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return null;
Cursor cursor = null;
//SQLiteDatabase db = this.getSqliteDb(true);
cursor = db.query("dictionary", null, null, null, null, null, null, null);
return cursor;
}
/**
* Get dictionary database contents
*
* @param keyword
* @return
*/
public List<Mapping> queryUserDict(String pword, boolean getAllRecords) {
if(DEBUG)
Log.i(TAG,"queryUserDict(), " +getAllRecords);
List<Mapping> result = new LinkedList<Mapping>();
if(mLIMEPref.getSimiliarEnable()){
if (pword != null && !pword.trim().equals("")) {
Cursor cursor = null;
// Jeremy '11,8.23 remove group by condition to avoid sorting ordr
// Jeremy '11,8,1 add group by cword to remove duplicate items.
//Jeremy '11,6,12, Add constraint on cword is not null (cword =null is for recoding im related list selected count).
//Jeremy '12,12,21 Add limitClause to limit candidates in only 1 page first.
// to do 2 stage query.
String limitClause = null;
if(!getAllRecords) limitClause = INITIAL_RESULT_LIMIT;
cursor = db.query("related", null, FIELD_DIC_pword + " = '"
+ pword + "' AND " + FIELD_DIC_cword + " IS NOT NULL"
, null, null , null, FIELD_SCORE + " DESC", limitClause);
if (cursor.moveToFirst()) {
int pwordColumn = cursor.getColumnIndex(FIELD_DIC_pword);
int cwordColumn = cursor.getColumnIndex(FIELD_DIC_cword);
int scoreColumn = cursor.getColumnIndex(FIELD_DIC_score);
int idColumn = cursor.getColumnIndex(FIELD_ID);
int rsize = 0;
do {
Mapping munit = new Mapping();
munit.setId(cursor.getString(idColumn));
munit.setPword(cursor.getString(pwordColumn));
munit.setCode("");
munit.setWord(cursor.getString(cwordColumn));
munit.setScore(cursor.getInt(scoreColumn));
munit.setDictionary(true);
result.add(munit);
rsize++;
} while (cursor.moveToNext());
Mapping temp = new Mapping();
temp.setCode("has_more_records");
temp.setWord("...");
if(!getAllRecords && rsize == Integer.parseInt(INITIAL_RESULT_LIMIT))
result.add(temp);
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
}
}
return result;
}
/**
* Jeremy '11,9,8 loadFile() with basescore got from hanconverter
* @param table
*/
public synchronized void loadFileV2(final String table) {
if(DEBUG)
Log.i(TAG,"loadFileV2()");
//Jeremy '12,5,1 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return;
this.DELIMITER = "";
finish = false;
percentageDone = 0;
count = 0;
if (thread != null ) {
//threadAborted = true;
while(thread.isAlive()){
Log.d(TAG, "loadFile():waiting for last loading thread stopped...");
SystemClock.sleep(1000);
}
thread = null;
}
thread = new Thread() {
public void run() {
// Reset Database Table
//SQLiteDatabase db = getSqliteDb(false);
if(DEBUG)
Log.i(TAG,"loadFileV2 thread starting...");
try {
if(countMapping(table)>0) db.delete(table, null, null);
if(table.equals("phonetic") ) {
//&&!mLIMEPref.getParameterBoolean("doLDPhonetic", false)
if(DEBUG) Log.i(TAG, "loadfile(), build code3r index.");
mLIMEPref.setParameter("doLDPhonetic", true);
db.execSQL("CREATE INDEX phonetic_idx_code3r ON phonetic(code3r)");
}
} catch (Exception e1) {
e1.printStackTrace();
}
//db.close();
resetImInfo(table);
//boolean hasMappingVersion = false;
boolean isCinFormat = false;
//ArrayList<ContentValues> resultlist = new ArrayList<ContentValues>();
String imname = "";
String line = "";
String endkey ="";
String selkey ="";
String spacestyle = "";
String imkeys = "";
String imkeynames = "";
// Check if source file is .cin format
if (filename.getName().toLowerCase(Locale.US).endsWith(".cin")) {
isCinFormat = true;
}
// Base on first 100 line to identify the Delimiter
try {
// Prepare Source File
FileReader fr = new FileReader(filename);
BufferedReader buf = new BufferedReader(fr);
//boolean firstline = true;
int i = 0;
List<String> templist = new ArrayList<String>();
while ((line = buf.readLine()) != null
&& isCinFormat == false) {
templist.add(line);
if (i >= 100) {
break;
} else {
i++;
}
}
identifyDelimiter(templist);
templist.clear();
buf.close();
fr.close();
} catch (Exception e) {
}
// Create Related Words
HashSet<String> codeList = new HashSet<String>();
//db = getSqliteDb(false);
//Jeremy '12,4,10 db will locked after beginTrasaction();
mLIMEPref.setMappingLoading(true);
db.beginTransaction();
try {
// Prepare Source File
long fileLength = filename.length();
long processedLength = 0;
FileReader fr = new FileReader(filename);
BufferedReader buf = new BufferedReader(fr);
boolean firstline = true;
boolean inChardefBlock = false;
boolean inKeynameBlock = false;
//String precode = "";
while ((line = buf.readLine()) != null && !threadAborted) {
processedLength += line.getBytes().length + 2; // +2 for the eol mark.
percentageDone = (int) ((float)processedLength/(float)fileLength *50);
//if(DEBUG)
// Log.i(TAG, "loadFile():loadFile()"+ percentageDone +"% processed"
// + ". processedLength:" + processedLength + ". fileLength:" + fileLength + ", threadAborted=" + threadAborted);
if(percentageDone>49) percentageDone = 49;
/*
* If source is cin format start from the tag %chardef
* begin until %chardef end
*/
if (isCinFormat) {
if (!(inChardefBlock || inKeynameBlock)) {
// Modified by Jeremy '10, 3, 28. Some .cin have
// double space between $chardef and begin or
// end
if (line != null
&& line.trim().toLowerCase(Locale.US).startsWith("%chardef")
&& line.trim().toLowerCase(Locale.US).endsWith("begin")
) {
inChardefBlock = true;
}
if (line != null
&& line.trim().toLowerCase(Locale.US).startsWith("%keyname")
&& line.trim().toLowerCase(Locale.US).endsWith("begin")
) {
inKeynameBlock = true;
}
// Add by Jeremy '10, 3 , 27
// use %cname as mapping_version of .cin
// Jeremy '11,6,5 add selkey, endkey and spacestyle support
if (!( line.trim().toLowerCase(Locale.US).startsWith("%cname")
||line.trim().toLowerCase(Locale.US).startsWith("%selkey")
||line.trim().toLowerCase(Locale.US).startsWith("%endkey")
||line.trim().toLowerCase(Locale.US).startsWith("%spacestyle")
)) {
continue;
}
}
if (line != null
&& line.trim().toLowerCase(Locale.US).startsWith("%keyname")
&& line.trim().toLowerCase(Locale.US).endsWith("end")
) {
inKeynameBlock = false;
continue;
}
if (line != null
&& line.trim().toLowerCase(Locale.US).startsWith("%chardef")
&& line.trim().toLowerCase(Locale.US).endsWith("end")
) {
break;
}
}
// Check if file contain BOM MARK at file header
if (firstline) {
byte srcstring[] = line.getBytes();
if (srcstring.length > 3) {
if (srcstring[0] == -17 && srcstring[1] == -69
&& srcstring[2] == -65) {
byte tempstring[] = new byte[srcstring.length - 3];
//int a = 0;
for (int j = 3; j < srcstring.length; j++) {
tempstring[j - 3] = srcstring[j];
}
line = new String(tempstring);
}
}
firstline = false;
} else if (line == null || line.trim().equals("") || line.length() < 3) {
continue;
}
try {
String code = null, word = null;
if (isCinFormat) {
if (line.indexOf("\t") != -1) {
code = line
.substring(0, line.indexOf("\t"));
word = line
.substring(line.indexOf("\t") + 1);
} else if (line.indexOf(" ") != -1) {
code = line.substring(0, line.indexOf(" "));
word = line
.substring(line.indexOf(" ") + 1);
}
} else {
code = line.substring(0, line
.indexOf(DELIMITER));
word = line
.substring(line.indexOf(DELIMITER) + 1);
}
if (code == null || code.trim().equals("")) {
continue;
} else {
code = code.trim();
}
if (word == null || word.trim().equals("")) {
continue;
} else {
word = word.trim();
}
if (code.toLowerCase(Locale.US).contains("@version@")) {
imname = word.trim();
continue;
} else if (code.toLowerCase(Locale.US).contains("%cname")) {
imname = word.trim();
continue;
} else if (code.toLowerCase(Locale.US).contains("%selkey")) {
selkey = word.trim();
if(DEBUG) Log.i(TAG, "loadfile(): selkey:"+selkey);
continue;
} else if (code.toLowerCase(Locale.US).contains("%endkey")) {
endkey = word.trim();
if(DEBUG) Log.i(TAG, "loadfile(): endkey:"+endkey);
continue;
} else if (code.toLowerCase(Locale.US).contains("%spacestyle")) {
spacestyle = word.trim();
continue;
} else {
code = code.toLowerCase(Locale.US);
}
if(inKeynameBlock) { //Jeremy '11,6,5 preserve keyname blocks here.
imkeys = imkeys + code.toLowerCase(Locale.US).trim();
String c = word.trim();
if(!c.equals("")){
if(imkeynames.equals(""))
imkeynames = c;
else
imkeynames = imkeynames + "|"+c;
}
}
else {
if (code.length() > 1) {
int len = code.length();
if(len > 5 ) len = 5; //Jeremy '12,6,12 track code bakcward for 5 levels.
for (int k = 1; k < len; k++) {
String subCode = code.substring(0, code.length() - k);
codeList.add(subCode);
}
}
count++;
ContentValues cv = new ContentValues();
cv.put(FIELD_CODE, code);
if(table.equals("phonetic")) {
String code3r = code.replaceAll("[3467 ]", "");
cv.put(FIELD_CODE3R, code3r);;
}
cv.put(FIELD_WORD, word);
cv.put(FIELD_SCORE, 0);
int basescore = getBaseScore(word);
cv.put(FIELD_BASESCORE, basescore);
//if(DEBUG) Log.i(TAG, "loadfilev2():code="+code+", word="+word+", basescore="+basescore);
db.insert(table, null, cv);
}
} catch (StringIndexOutOfBoundsException e) {}
}
buf.close();
fr.close();
db.setTransactionSuccessful();
} catch (Exception e) {
//db.close();
setImInfo(table, "amount", "0");
setImInfo(table, "source", "Failed!!!");
e.printStackTrace();
} finally {
if(DEBUG) Log.i(TAG, "loadfile(): main import loop final section");
db.endTransaction();
mLIMEPref.setMappingLoading(false); // Jeremy '12,4,10 reset mapping_loading status
//db.close();
}
if(!threadAborted){
//db = getSqliteDb(false);
mLIMEPref.setMappingLoading(true); // Jeremy '12,4,10 reset mapping_loading status
db.beginTransaction();
try{
long entrySize = codeList.size();
long i = 0;
for(String entry: codeList) {
if(threadAborted) break;
percentageDone = (int) ((float)(i++)/(float)entrySize *50 +50);
if(percentageDone>99) percentageDone = 99;
if(DEBUG)
Log.i(TAG, "loadFileV2():building related list:" + i +"/" + entrySize);
try{
updateRelatedListOnDB(db, table ,entry);
}catch(Exception e2){
// Just ignore all problem statement
Log.i(TAG, "loadfile():create related field error on code ="+entry);
}
}
codeList.clear();
db.setTransactionSuccessful();
}catch (Exception e){
setImInfo(table, "amount", "0");
setImInfo(table, "source", "Failed!!!");
e.printStackTrace();
}finally {
if(DEBUG) Log.i(TAG, "loadfile(): related list buiding loop final section");
db.endTransaction();
mLIMEPref.setMappingLoading(false); // Jeremy '12,4,10 reset mapping_loading status
//db.close();
}
}
if(!threadAborted) {
if(!threadAborted) percentageDone = 100;
finish = true;
mLIMEPref.setParameter("_table", "");
setImInfo(table, "source", filename.getName());
setImInfo(table, "name", imname);
setImInfo(table, "amount", String.valueOf(count));
setImInfo(table, "import", new Date().toString()); //Jeremy '12,4,21 toLocaleString() is deprecated
if(DEBUG)
Log.i("limedb:loadfile()","Fianlly section: source:"
+ getImInfo(table,"source") + " amount:"+getImInfo(table,"amount"));
// If user download from LIME Default IM SET then fill in related information
if(filename.getName().equals("phonetic.lime") || filename.getName().equals("phonetic_adv.lime")){
setImInfo("phonetic", "selkey", "123456789");
setImInfo("phonetic", "endkey", "3467'[]\\=<>?:\"{}|~!@#$%^&*()_+");
setImInfo("phonetic", "imkeys", ",-./0123456789;abcdefghijklmnopqrstuvwxyz'[]\\=<>?:\"{}|~!@#$%^&*()_+");
setImInfo("phonetic", "imkeynames", "ㄝ|ㄦ|ㄡ|ㄥ|ㄢ|ㄅ|ㄉ|ˇ|ˋ|ㄓ|ˊ|˙|ㄚ|ㄞ|ㄤ|ㄇ|ㄖ|ㄏ|ㄎ|ㄍ|ㄑ|ㄕ|ㄘ|ㄛ|ㄨ|ㄜ|ㄠ|ㄩ|ㄙ|ㄟ|ㄣ|ㄆ|ㄐ|ㄋ|ㄔ|ㄧ|ㄒ|ㄊ|ㄌ|ㄗ|ㄈ|、|「|」|\|=|,|。|?|:|;|『|』|│|~|!|@|#|$|%|︿|&|*|(|)|-|+");
}if(filename.getName().equals("array.lime")){
setImInfo("array", "selkey", "1234567890");
setImInfo("array", "imkeys", "abcdefghijklmnopqrstuvwxyz./;,?*#1#2#3#4#5#6#7#8#9#0");
setImInfo("array", "imkeynames", "1-|5⇣|3⇣|3-|3⇡|4-|5-|6-|8⇡|7-|8-|9-|7⇣|6⇣|9⇡|0⇡|1⇡|4⇡|2-|5⇡|7⇡|4⇣|2⇡|2⇣|6⇡|1⇣|9⇣|0⇣|0-|8⇣|?|*|1|2|3|4|5|6|7|8|9|0");
}else{
if (!selkey.equals("")) setImInfo(table, "selkey", selkey);
if (!endkey.equals("")) setImInfo(table, "endkey", endkey);
if (!spacestyle.equals("")) setImInfo(table, "spacestyle", spacestyle);
if (!imkeys.equals("")) setImInfo(table, "imkeys", imkeys);
if (!imkeynames.equals("")) setImInfo(table, "imkeynames", imkeynames);
}
if(DEBUG)
Log.i(TAG, "loadfilev2():update IM info: imkeys:" +imkeys + " imkeynames:"+imkeynames);
// If there is no keyboard assigned for current input method then use default keyboard layout
//String keyboard = getImInfo(table, "keyboard");
//if(keyboard == null || keyboard.equals("")){
//setImInfo(table, "keyboard", "lime");
// '11,5,23 by Jeremy: Preset keyboard info. by tablename
KeyboardObj kobj = getKeyboardObj(table);
if( table.equals("phonetic")){
String selectedPhoneticKeyboardType =
mLIMEPref.getParameterString("phonetic_keyboard_type", "standard");
if(selectedPhoneticKeyboardType.equals("standard")){
kobj = getKeyboardObj("phonetic");
}else if(selectedPhoneticKeyboardType.equals("eten")){
kobj = getKeyboardObj("phoneticet41");
}else if(selectedPhoneticKeyboardType.equals("eten26")){
if(mLIMEPref.getParameterBoolean("number_row_in_english", false)){
kobj = getKeyboardObj("limenum");
}else{
kobj = getKeyboardObj("lime");
}
}else if(selectedPhoneticKeyboardType.equals("eten26_symbol")){
kobj = getKeyboardObj("et26");
}else if(selectedPhoneticKeyboardType.equals("hsu")){ //Jeremy '12,7,6 Add HSU english keyboard support
if(mLIMEPref.getParameterBoolean("number_row_in_english", false)){
kobj = getKeyboardObj("limenum");
}else{
kobj = getKeyboardObj("lime");
}
}else if(selectedPhoneticKeyboardType.equals("hsu_symbol")){
kobj = getKeyboardObj("hsu");
}
}else if( table.equals("dayi")){
kobj = getKeyboardObj("dayisym");
}else if( table.equals("cj5")){
kobj = getKeyboardObj("cj");
}else if( table.equals("ecj")){
kobj = getKeyboardObj("cj");
}else if( table.equals("array")){
kobj = getKeyboardObj("arraynum");
}else if( table.equals("array10")){
kobj = getKeyboardObj("phonenum");
}else if( table.equals("wb")){
kobj = getKeyboardObj("wb");
}else if( table.equals("hs")){
kobj = getKeyboardObj("hs");
}else if( kobj == null){ //Jeremy '12,5,21 chose english with number keyboard if the optione is on for default keyboard.
if(mLIMEPref.getParameterBoolean("number_row_in_english", false)){
kobj = getKeyboardObj("limenum");
}else{
kobj = getKeyboardObj("lime");
}
}
setIMKeyboard(table, kobj.getDescription(), kobj.getCode());
}
}
};
threadAborted = false;
thread.start();
}
/*
public ContentValues getInsertItem(String code, String word) {
try {
ContentValues cv = new ContentValues();
cv.put(FIELD_CODE, code);
cv.put(FIELD_WORD, word);
cv.put(FIELD_SCORE, 0);
return cv;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
*/
/**
* Identify the delimiter of the source file
*
* @param src
*/
public void identifyDelimiter(List<String> src) {
int commaCount = 0;
int tabCount = 0;
int pipeCount = 0;
if (this.DELIMITER.equals("")) {
for (String line : src) {
if (line.indexOf("\t") != -1) {
tabCount++;
}
if (line.indexOf(",") != -1) {
commaCount++;
}
if (line.indexOf("|") != -1) {
pipeCount++;
}
}
if (commaCount > 0 || tabCount > 0 || pipeCount > 0) {
if (commaCount >= tabCount && commaCount >= pipeCount) {
this.DELIMITER = ",";
} else if (tabCount >= commaCount && tabCount >= pipeCount) {
this.DELIMITER = "\t";
} else if (pipeCount >= tabCount && pipeCount >= commaCount) {
this.DELIMITER = "|";
}
}
}
}
/**
* Check if the specific mapping exists in current table
*
* @param code
* @param word
* @return
*/
public Mapping isMappingExist(String code, String word) {
Mapping munit =null;
//SQLiteDatabase db = this.getSqliteDb(true);
try {
munit = isMappingExistOnDB(db, code, word);
} catch (Exception e) {
e.printStackTrace();
//db.close();
}
//db.close();
return munit;
}
private Mapping isMappingExistOnDB(SQLiteDatabase db, String code, String word) throws RemoteException {
if(DEBUG)
Log.i(TAG, "isMappingExistOnDB(), code = '" + code +"'");
Mapping munit = null;
if (code != null && code.trim().length()>0){
Cursor cursor = null;
// Process the escape characters of query
code = code.replaceAll("'", "''");
if(word==null || word.trim().length()==0){
cursor = db.query(tablename, null, FIELD_CODE + " = '"
+ code + "'" , null, null, null, null, null);
}else{
cursor = db.query(tablename, null, FIELD_CODE + " = '"
+ code + "'" + " AND " + FIELD_WORD + " = '"
+ word + "'", null, null, null, null, null);
}
if (cursor.moveToFirst()) {
munit = new Mapping();
int idColumn = cursor.getColumnIndex(FIELD_ID);
int codeColumn = cursor.getColumnIndex(FIELD_CODE);
int wordColumn = cursor.getColumnIndex(FIELD_WORD);
int scoreColumn = cursor.getColumnIndex(FIELD_SCORE);
//int relatedColumn = cursor.getColumnIndex(FIELD_RELATED);
munit.setId(cursor.getString(idColumn));
munit.setCode(cursor.getString(codeColumn));
munit.setWord(cursor.getString(wordColumn));
munit.setScore(cursor.getInt(scoreColumn));
//munit.setRelated(cursor.getString(relatedColumn));
munit.setRelated(false);
munit.setDictionary(false);
if(DEBUG)
Log.i(TAG, "isMappingExistOnDB(), mapping is exist");
} else if(DEBUG)
Log.i(TAG, "isMappingExistOnDB(), mapping is not exist");
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
}
return munit;
}
/**
* Jeremy '11,9,8 get Highest socre for 'code'. relatedList will be stored on highest score record after 3.6.
* @param code
* @return
*/
public int getHighestScore(String code) {
if(!checkDBConnection()) return 0;
int highestScore=0;
if (code != null && code.trim().length()>0){
try {
highestScore = getHighestScoreOnDB(db, code);
//db.close();
} catch (Exception e) {
e.printStackTrace();
//db.close();
}
}
return highestScore;
}
/**
* Jeremy '12,4,6 core of getHightestScore()
* @param code
* @return
*/
private int getHighestScoreOnDB(SQLiteDatabase db, String code) throws RemoteException {
int highestScore=0;
if (code != null && code.trim().length()>0){
// Process the escape characters of query
code = code.replaceAll("'", "''");
Cursor cursor = db.query(tablename, null, FIELD_CODE + " = '"
+ code + "'" , null, null, null, FIELD_SCORE + " DESC", null);
if (cursor.moveToFirst()) {
int scoreColumn = cursor.getColumnIndex(FIELD_SCORE);
highestScore = cursor.getInt(scoreColumn);
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
}
return highestScore;
}
/**
* Jeremy '11,9,8 get Highest socre for 'code'. relatedList will be stored on highest score record after 3.6.
* @param code
* @return
*/
public int getHighestScoreID(SQLiteDatabase db, String table, String code) {
int ID = -1;
if (code != null && code.trim().length()>0){
// Process the escape characters of query
code = code.replaceAll("'", "''");
Cursor cursor = db.query(table, null, FIELD_CODE + " = '"
+ code + "'" , null, null, null,
FIELD_SCORE + " DESC, "+ FIELD_BASESCORE + " DESC", null);
if (cursor.moveToFirst()) {
int idColumn = cursor.getColumnIndex(FIELD_ID);
ID = cursor.getInt(idColumn);
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
}
return ID;
}
/**
* Check if usesr dictionary record exists
*
* @param pword
* @param cword
* @return
*/
public Mapping isUserDictExist(String pword, String cword) {
Mapping munit =null;
//SQLiteDatabase db = this.getSqliteDb(true);
try {
munit = isUserDictExistOnDB(db, pword, cword);
//db.close();
} catch (Exception e) {
//db.close();
e.printStackTrace();
}
return munit;
}
/**
* Jeremy '12/4/16 core of isUserDictExist()
*
* @param pword
* @param cword
* @return
*/
private Mapping isUserDictExistOnDB(SQLiteDatabase db, String pword, String cword) throws RemoteException {
Mapping munit =null;
if (pword != null && !pword.trim().equals("")){
Cursor cursor = null;
if(cword==null || cword.trim().equals("")){
cursor = db.query("related", null, FIELD_DIC_pword + " = '"
+ pword + "'" + " AND " + FIELD_DIC_cword + " IS NULL"
, null, null, null, null, null);
}else{
cursor = db.query("related", null, FIELD_DIC_pword + " = '"
+ pword + "'" + " AND " + FIELD_DIC_cword + " = '"
+ cword + "'", null, null, null, null, null);
}
if (cursor.moveToFirst()) {
int pwordColumn = cursor.getColumnIndex(FIELD_DIC_pword);
int cwordColumn = cursor.getColumnIndex(FIELD_DIC_cword);
int scoreColumn = cursor.getColumnIndex(FIELD_DIC_score);
int idColumn = cursor.getColumnIndex(FIELD_ID);
munit = new Mapping();
munit.setId(cursor.getString(idColumn));
munit.setPword(cursor.getString(pwordColumn));
munit.setWord(cursor.getString(cwordColumn));
munit.setScore(cursor.getInt(scoreColumn));
munit.setDictionary(true);
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
}
return munit;
}
/**
* @param srcunit
*/
public synchronized void resetImInfo(String im) {
//Jeremy '12,5,1
if(openDBConnection(false)==null) return;
String removeString = "DELETE FROM im WHERE code='"+im+"'";
//SQLiteDatabase db = this.getSqliteDb(false);
db.execSQL(removeString);
// db.close();
}
/**
* @param srcunit
*/
public String getImInfo(String im, String field) {
//Jeremy '12,5,1 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return "";
String iminfo = "";
try{
//String value = "";
String selectString = "SELECT * FROM im WHERE code='"+im+"' AND title='"+field+"'";
//SQLiteDatabase db = this.getSqliteDb(true);
Cursor cursor = db.rawQuery(selectString ,null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
int descCol = cursor.getColumnIndex("desc");
iminfo = cursor.getString(descCol);
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
//db.close();
}catch(Exception e){e.printStackTrace();}
return iminfo;
}
/**
* @param srcunit
*/
public synchronized void removeImInfo(String im, String field) {
if(DEBUG)
Log.i(TAG, "removeImInfo()");
if(!checkDBConnection()) return;
try{
removeImInfoOnDB(db, im, field);
}catch(Exception e){e.printStackTrace();}
}
/**
* Jeremy '12,6,7 for working with OnUpgrade() before db is created
* @param im
* @param field
*/
private void removeImInfoOnDB(SQLiteDatabase dbin, String im, String field) {
if(DEBUG)
Log.i(TAG, "removeImInfoOnDB()");
String removeString = "DELETE FROM im WHERE code='"+im+"' AND title='"+field+"'";
dbin.execSQL(removeString);
}
/**
* @param srcunit
*/
public synchronized void setImInfo(String im, String field, String value) {
//Jeremy '12,4,17 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return;
ContentValues cv = new ContentValues();
cv.put("code", im);
cv.put("title", field);
cv.put("desc", value);
removeImInfo(im, field);
//SQLiteDatabase db = this.getSqliteDb(false);
db.insert("im",null, cv);
//db.close();
}
public List<ImObj> getImList() {
if(DEBUG)
Log.i(TAG,"getIMList()");
//Jeremy '12,5,1 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return null;
List<ImObj> result = new LinkedList<ImObj>();
try {
//SQLiteDatabase db = this.getSqliteDb(true);
Cursor cursor = db.query("im", null, null, null, null, null, "code ASC", null);
if (cursor.moveToFirst()) {
do{
String title = cursor.getString(cursor.getColumnIndex("title"));
if(title.equals("keyboard")){
ImObj kobj = new ImObj();
kobj.setCode(cursor.getString(cursor.getColumnIndex("code")));
kobj.setKeyboard(cursor.getString(cursor.getColumnIndex("keyboard")));
result.add(kobj);
}
} while (cursor.moveToNext());
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
} catch (Exception e) {
Log.i(TAG,"getImList(): Cannot get IM List : " + e );
}
return result;
}
public KeyboardObj getKeyboardObj(String keyboard){
//Jeremy '12,5,1 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return null;
if( keyboard == null || keyboard.equals(""))
return null;
KeyboardObj kobj=null;
if(!keyboard.equals("wb") && !keyboard.equals("hs")){
try {
//SQLiteDatabase db = this.getSqliteDb(true);
Cursor cursor = db.query("keyboard", null, FIELD_CODE +" = '"+keyboard+"'", null, null, null, null, null);
if (cursor.moveToFirst()) {
kobj = new KeyboardObj();
kobj.setCode(cursor.getString(cursor.getColumnIndex("code")));
kobj.setName(cursor.getString(cursor.getColumnIndex("name")));
kobj.setDescription(cursor.getString(cursor.getColumnIndex("desc")));
kobj.setType(cursor.getString(cursor.getColumnIndex("type")));
kobj.setImage(cursor.getString(cursor.getColumnIndex("image")));
kobj.setImkb(cursor.getString(cursor.getColumnIndex("imkb")));
kobj.setImshiftkb(cursor.getString(cursor.getColumnIndex("imshiftkb")));
kobj.setEngkb(cursor.getString(cursor.getColumnIndex("engkb")));
kobj.setEngshiftkb(cursor.getString(cursor.getColumnIndex("engshiftkb")));
kobj.setSymbolkb(cursor.getString(cursor.getColumnIndex("symbolkb")));
kobj.setSymbolshiftkb(cursor.getString(cursor.getColumnIndex("symbolshiftkb")));
kobj.setDefaultkb(cursor.getString(cursor.getColumnIndex("defaultkb")));
kobj.setDefaultshiftkb(cursor.getString(cursor.getColumnIndex("defaultshiftkb")));
kobj.setExtendedkb(cursor.getString(cursor.getColumnIndex("extendedkb")));
kobj.setExtendedshiftkb(cursor.getString(cursor.getColumnIndex("extendedshiftkb")));
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
//db.close();
} catch (Exception e) {
e.printStackTrace();
}
}else if(keyboard.equals("wb")){
kobj = new KeyboardObj();
kobj.setCode("wb");
kobj.setName("筆順五碼");
kobj.setDescription("筆順五碼輸入法鍵盤");
kobj.setType("phone");
kobj.setImage("wb_keyboard_preview");
kobj.setImkb("lime_wb");
kobj.setImshiftkb("lime_wb");
kobj.setEngkb("lime_abc");
kobj.setEngshiftkb("lime_abc_shift");
kobj.setSymbolkb("symbols");
kobj.setSymbolshiftkb("symbols_shift");
}else if(keyboard.equals("hs")){
kobj = new KeyboardObj();
kobj.setCode("hs");
kobj.setName("華象直覺");
kobj.setDescription("華象直覺輸入法鍵盤");
kobj.setType("phone");
kobj.setImage("hs_keyboard_preview");
kobj.setImkb("lime_hs");
kobj.setImshiftkb("lime_hs_shift");
kobj.setEngkb("lime_abc");
kobj.setEngshiftkb("lime_abc_shift");
kobj.setSymbolkb("symbols");
kobj.setSymbolshiftkb("symbols_shift");
}
return kobj;
}
public String getKeyboardInfo(String keyboardCode, String field) {
if(DEBUG)
Log.i(TAG, "getKeyboardInfo()");
if(!checkDBConnection()) return null;
String info=null;
try {
info=getKeyboardInfoOnDB(db, keyboardCode, field);
} catch (Exception e) {
e.printStackTrace();
}
return info;
}
/**
* Jeremy '12,6,7 for working with OnUpgrade() before db is created
* @param keyboardCode
* @param field
* @return
*/
private String getKeyboardInfoOnDB(SQLiteDatabase dbin, String keyboardCode, String field) {
if(DEBUG)
Log.i(TAG, "getKeyboardInfoOnDB()");
String info=null;
Cursor cursor = dbin.query("keyboard", null, FIELD_CODE +" = '"+keyboardCode+"'"
, null, null, null, null, null);
if (cursor.moveToFirst()) {
info = cursor.getString(cursor.getColumnIndex(field));
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
if(DEBUG)
Log.i(TAG, "getKeyboardInfoOnDB() info = " + info);
return info;
}
public List<KeyboardObj> getKeyboardList() {
//Jeremy '12,5,1 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return null;
List<KeyboardObj> result = new LinkedList<KeyboardObj>();
try {
//SQLiteDatabase db = this.getSqliteDb(true);
Cursor cursor = db.query("keyboard", null, null, null, null, null, "name ASC", null);
if (cursor.moveToFirst()) {
do{
KeyboardObj kobj = new KeyboardObj();
kobj.setCode(cursor.getString(cursor.getColumnIndex("code")));
kobj.setName(cursor.getString(cursor.getColumnIndex("name")));
kobj.setDescription(cursor.getString(cursor.getColumnIndex("desc")));
kobj.setType(cursor.getString(cursor.getColumnIndex("type")));
kobj.setImage(cursor.getString(cursor.getColumnIndex("image")));
kobj.setImkb(cursor.getString(cursor.getColumnIndex("imkb")));
kobj.setImshiftkb(cursor.getString(cursor.getColumnIndex("imshiftkb")));
kobj.setEngkb(cursor.getString(cursor.getColumnIndex("engkb")));
kobj.setEngshiftkb(cursor.getString(cursor.getColumnIndex("engshiftkb")));
kobj.setSymbolkb(cursor.getString(cursor.getColumnIndex("symbolkb")));
kobj.setSymbolshiftkb(cursor.getString(cursor.getColumnIndex("symbolshiftkb")));
kobj.setDefaultkb(cursor.getString(cursor.getColumnIndex("defaultkb")));
kobj.setDefaultshiftkb(cursor.getString(cursor.getColumnIndex("defaultshiftkb")));
kobj.setExtendedkb(cursor.getString(cursor.getColumnIndex("extendedkb")));
kobj.setExtendedshiftkb(cursor.getString(cursor.getColumnIndex("extendedshiftkb")));
result.add(kobj);
} while (cursor.moveToNext());
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
//db.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public synchronized void setIMKeyboard(String im, String value,
String keyboard) {
if(DEBUG)
Log.i(TAG,"setIMKeyboard()");
if(!checkDBConnection()) ;
try{
setIMKeyboardOnDB(db, im, value, keyboard);
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* Jeremy '12,6,7 for working with OnUpgrade() before db is created
* @param im
* @param value
* @param keyboard
*/
private void setIMKeyboardOnDB(SQLiteDatabase dbin, String im, String value, String keyboard) {
if(DEBUG)
Log.i(TAG,"setIMKeyboardOnDB()");
ContentValues cv = new ContentValues();
cv.put("code", im);
cv.put("title", "keyboard");
cv.put("desc", value);
cv.put("keyboard", keyboard);
removeImInfoOnDB(dbin, im, "keyboard");
dbin.insert("im",null, cv);
}
public String getKeyboardCode(String im) {
//Jeremy '12,5,1 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return "";
try{
//String value = "";
String selectString = "SELECT * FROM im WHERE code='"+im+"' AND title='keyboard'";
//SQLiteDatabase db = this.getSqliteDb(true);
Cursor cursor = db.rawQuery(selectString ,null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
int descCol = cursor.getColumnIndex("keyboard");
String keyboardCode = cursor.getString(descCol);
//db.close();
return keyboardCode;
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
//db.close();
}catch(Exception e){}
return "";
}
public List<String> queryDictionary(String word) {
//Jeremy '12,5,1 !checkDBConnection() when db is restoring or replaced.
if(!checkDBConnection()) return null;
List<String> result = new ArrayList<String>();
try{
//String value = "";
int ssize = mLIMEPref.getSimilarCodeCandidates();
String selectString = "SELECT word FROM dictionary WHERE word MATCH '"+word+"*' ORDER BY word ASC LIMIT "+ssize+";";
//SQLiteDatabase db = this.getSqliteDb(true);
Cursor cursor = db.rawQuery(selectString ,null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
do{
String w = cursor.getString(cursor.getColumnIndex("word"));
if(w != null && !w.equals("")){
result.add(w);
}
} while (cursor.moveToNext());
}
if (cursor != null) {
//cursor.deactivate();
cursor.close();
}
//db.close();
}catch(Exception e){}
return result;
}
/**
* Jeremy '11,9,8 moved from searchService
* @param input
* @param hanConvertOption
* @return
*/
public String hanConvert(String input, int hanConvertOption){
checkHanDB();
return hanConverter.convert(input, hanConvertOption);
}
/**
* Jeremy '11,9,8 get basescore of word store in hanconverter
* @param input
* @return
*/
public int getBaseScore(String input){
checkHanDB();
return hanConverter.getBaseScore(input);
}
private void checkHanDB() {
if(hanConverter == null){
//Jeremy '11,9,8 update handconverdb to v2 with base score in TCSC table
File hanDBFile = LIMEUtilities.isFileExist("/data/data/net.toload.main.hd/databases/hanconvert.db");
if(hanDBFile!=null)
hanDBFile.delete();
File hanDBV2File = LIMEUtilities.isFileNotExist("/data/data/net.toload.main.hd/databases/hanconvertv2.db");
if(hanDBV2File!=null)
LIMEUtilities.copyRAWFile(mContext.getResources().openRawResource(R.raw.hanconvertv2), hanDBV2File);
else { // Jeremy '11,9,14 copy the db file if it's newer.
hanDBV2File = LIMEUtilities.isFileExist("/data/data/net.toload.main.hd/databases/hanconvertv2.db");
if(hanDBV2File!=null && mLIMEPref.getParameterLong("hanDBDate") != hanDBV2File.lastModified())
LIMEUtilities.copyRAWFile(mContext.getResources().openRawResource(R.raw.hanconvertv2), hanDBV2File);
}
hanConverter = new LimeHanConverter(mContext);
}
}
/**
* This is the method to rename the table name in database
* @param source
* @param target
* @return
*/
public boolean renameTableName(String source, String target) {
if(!checkDBConnection()) return false;
try{
//ALTER TABLE foo RENAME TO bar
db.execSQL("ALTER TABLE "+source+" RENAME TO "+target);
}catch(Exception e){
e.printStackTrace();
return false;
}
return true;
}
}