1 /*
2  * Copyright (C) 2008-2012  OMRON SOFTWARE Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package jp.co.omronsoft.openwnn.JAJP;
18 
19 import java.text.DecimalFormat;
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Locale;
24 import jp.co.omronsoft.openwnn.WnnDictionary;
25 import jp.co.omronsoft.openwnn.WnnPOS;
26 import jp.co.omronsoft.openwnn.WnnWord;
27 
28 /**
29  * The EISU-KANA converter class for Japanese IME.
30  *
31  * @author Copyright (C) 2009 OMRON SOFTWARE CO., LTD.  All Rights Reserved.
32  */
33 public class KanaConverter {
34 
35 	/** Conversion rule for half-width numeric */
36     private static final HashMap<String,String> mHalfNumericMap = new HashMap<String,String>() {{
37         put( "\u3042", "1");
38         put( "\u3044", "11");
39         put( "\u3046", "111");
40         put( "\u3048", "1111");
41         put( "\u304a", "11111");
42         put( "\u3041", "111111");
43         put( "\u3043", "1111111");
44         put( "\u3045", "11111111");
45         put( "\u3047", "111111111");
46         put( "\u3049", "1111111111");
47         put( "\u304b", "2");
48         put( "\u304d", "22");
49         put( "\u304f", "222");
50         put( "\u3051", "2222");
51         put( "\u3053", "22222");
52         put( "\u3055", "3");
53         put( "\u3057", "33");
54         put( "\u3059", "333");
55         put( "\u305b", "3333");
56         put( "\u305d", "33333");
57         put( "\u305f", "4");
58         put( "\u3061", "44");
59         put( "\u3064", "444");
60         put( "\u3066", "4444");
61         put( "\u3068", "44444");
62         put( "\u3063", "444444");
63         put( "\u306a", "5");
64         put( "\u306b", "55");
65         put( "\u306c", "555");
66         put( "\u306d", "5555");
67         put( "\u306e", "55555");
68         put( "\u306f", "6");
69         put( "\u3072", "66");
70         put( "\u3075", "666");
71         put( "\u3078", "6666");
72         put( "\u307b", "66666");
73         put( "\u307e", "7");
74         put( "\u307f", "77");
75         put( "\u3080", "777");
76         put( "\u3081", "7777");
77         put( "\u3082", "77777");
78         put( "\u3084", "8");
79         put( "\u3086", "88");
80         put( "\u3088", "888");
81         put( "\u3083", "8888");
82         put( "\u3085", "88888");
83         put( "\u3087", "888888");
84         put( "\u3089", "9");
85         put( "\u308a", "99");
86         put( "\u308b", "999");
87         put( "\u308c", "9999");
88         put( "\u308d", "99999");
89         put( "\u308f", "0");
90         put( "\u3092", "00");
91         put( "\u3093", "000");
92         put( "\u308e", "0000");
93         put( "\u30fc", "00000");
94     }};
95 
96     /** Conversion rule for full-width numeric */
97     private static final HashMap<String,String> mFullNumericMap = new HashMap<String,String>() {{
98         put( "\u3042", "\uff11");
99         put( "\u3044", "\uff11\uff11");
100         put( "\u3046", "\uff11\uff11\uff11");
101         put( "\u3048", "\uff11\uff11\uff11\uff11");
102         put( "\u304a", "\uff11\uff11\uff11\uff11\uff11");
103         put( "\u3041", "\uff11\uff11\uff11\uff11\uff11\uff11");
104         put( "\u3043", "\uff11\uff11\uff11\uff11\uff11\uff11\uff11");
105         put( "\u3045", "\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11");
106         put( "\u3047", "\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11");
107         put( "\u3049", "\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11\uff11");
108         put( "\u304b", "\uff12");
109         put( "\u304d", "\uff12\uff12");
110         put( "\u304f", "\uff12\uff12\uff12");
111         put( "\u3051", "\uff12\uff12\uff12\uff12");
112         put( "\u3053", "\uff12\uff12\uff12\uff12\uff12");
113         put( "\u3055", "\uff13");
114         put( "\u3057", "\uff13\uff13");
115         put( "\u3059", "\uff13\uff13\uff13");
116         put( "\u305b", "\uff13\uff13\uff13\uff13");
117         put( "\u305d", "\uff13\uff13\uff13\uff13\uff13");
118         put( "\u305f", "\uff14");
119         put( "\u3061", "\uff14\uff14");
120         put( "\u3064", "\uff14\uff14\uff14");
121         put( "\u3066", "\uff14\uff14\uff14\uff14");
122         put( "\u3068", "\uff14\uff14\uff14\uff14\uff14");
123         put( "\u3063", "\uff14\uff14\uff14\uff14\uff14\uff14");
124         put( "\u306a", "\uff15");
125         put( "\u306b", "\uff15\uff15");
126         put( "\u306c", "\uff15\uff15\uff15");
127         put( "\u306d", "\uff15\uff15\uff15\uff15");
128         put( "\u306e", "\uff15\uff15\uff15\uff15\uff15");
129         put( "\u306f", "\uff16");
130         put( "\u3072", "\uff16\uff16");
131         put( "\u3075", "\uff16\uff16\uff16");
132         put( "\u3078", "\uff16\uff16\uff16\uff16");
133         put( "\u307b", "\uff16\uff16\uff16\uff16\uff16");
134         put( "\u307e", "\uff17");
135         put( "\u307f", "\uff17\uff17");
136         put( "\u3080", "\uff17\uff17\uff17");
137         put( "\u3081", "\uff17\uff17\uff17\uff17");
138         put( "\u3082", "\uff17\uff17\uff17\uff17\uff17");
139         put( "\u3084", "\uff18");
140         put( "\u3086", "\uff18\uff18");
141         put( "\u3088", "\uff18\uff18\uff18");
142         put( "\u3083", "\uff18\uff18\uff18\uff18");
143         put( "\u3085", "\uff18\uff18\uff18\uff18\uff18");
144         put( "\u3087", "\uff18\uff18\uff18\uff18\uff18\uff18");
145         put( "\u3089", "\uff19");
146         put( "\u308a", "\uff19\uff19");
147         put( "\u308b", "\uff19\uff19\uff19");
148         put( "\u308c", "\uff19\uff19\uff19\uff19");
149         put( "\u308d", "\uff19\uff19\uff19\uff19\uff19");
150         put( "\u308f", "\uff10");
151         put( "\u3092", "\uff10\uff10");
152         put( "\u3093", "\uff10\uff10\uff10");
153         put( "\u308e", "\uff10\uff10\uff10\uff10");
154         put( "\u30fc", "\uff10\uff10\uff10\uff10\uff10");
155     }};
156 
157     /** Conversion rule for half-width Katakana */
158     private static final HashMap<String,String> mHalfKatakanaMap = new HashMap<String,String>() {{
159         put( "\u3042", "\uff71");
160         put( "\u3044", "\uff72");
161         put( "\u3046", "\uff73");
162         put( "\u3048", "\uff74");
163         put( "\u304a", "\uff75");
164         put( "\u3041", "\uff67");
165         put( "\u3043", "\uff68");
166         put( "\u3045", "\uff69");
167         put( "\u3047", "\uff6a");
168         put( "\u3049", "\uff6b");
169         put( "\u30f4\u3041", "\uff73\uff9e\uff67");
170         put( "\u30f4\u3043", "\uff73\uff9e\uff68");
171         put( "\u30f4", "\uff73\uff9e");
172         put( "\u30f4\u3047", "\uff73\uff9e\uff6a");
173         put( "\u30f4\u3049", "\uff73\uff9e\uff6b");
174         put( "\u304b", "\uff76");
175         put( "\u304d", "\uff77");
176         put( "\u304f", "\uff78");
177         put( "\u3051", "\uff79");
178         put( "\u3053", "\uff7a");
179         put( "\u304c", "\uff76\uff9e");
180         put( "\u304e", "\uff77\uff9e");
181         put( "\u3050", "\uff78\uff9e");
182         put( "\u3052", "\uff79\uff9e");
183         put( "\u3054", "\uff7a\uff9e");
184         put( "\u3055", "\uff7b");
185         put( "\u3057", "\uff7c");
186         put( "\u3059", "\uff7d");
187         put( "\u305b", "\uff7e");
188         put( "\u305d", "\uff7f");
189         put( "\u3056", "\uff7b\uff9e");
190         put( "\u3058", "\uff7c\uff9e");
191         put( "\u305a", "\uff7d\uff9e");
192         put( "\u305c", "\uff7e\uff9e");
193         put( "\u305e", "\uff7f\uff9e");
194         put( "\u305f", "\uff80");
195         put( "\u3061", "\uff81");
196         put( "\u3064", "\uff82");
197         put( "\u3066", "\uff83");
198         put( "\u3068", "\uff84");
199         put( "\u3063", "\uff6f");
200         put( "\u3060", "\uff80\uff9e");
201         put( "\u3062", "\uff81\uff9e");
202         put( "\u3065", "\uff82\uff9e");
203         put( "\u3067", "\uff83\uff9e");
204         put( "\u3069", "\uff84\uff9e");
205         put( "\u306a", "\uff85");
206         put( "\u306b", "\uff86");
207         put( "\u306c", "\uff87");
208         put( "\u306d", "\uff88");
209         put( "\u306e", "\uff89");
210         put( "\u306f", "\uff8a");
211         put( "\u3072", "\uff8b");
212         put( "\u3075", "\uff8c");
213         put( "\u3078", "\uff8d");
214         put( "\u307b", "\uff8e");
215         put( "\u3070", "\uff8a\uff9e");
216         put( "\u3073", "\uff8b\uff9e");
217         put( "\u3076", "\uff8c\uff9e");
218         put( "\u3079", "\uff8d\uff9e");
219         put( "\u307c", "\uff8e\uff9e");
220         put( "\u3071", "\uff8a\uff9f");
221         put( "\u3074", "\uff8b\uff9f");
222         put( "\u3077", "\uff8c\uff9f");
223         put( "\u307a", "\uff8d\uff9f");
224         put( "\u307d", "\uff8e\uff9f");
225         put( "\u307e", "\uff8f");
226         put( "\u307f", "\uff90");
227         put( "\u3080", "\uff91");
228         put( "\u3081", "\uff92");
229         put( "\u3082", "\uff93");
230         put( "\u3084", "\uff94");
231         put( "\u3086", "\uff95");
232         put( "\u3088", "\uff96");
233         put( "\u3083", "\uff6c");
234         put( "\u3085", "\uff6d");
235         put( "\u3087", "\uff6e");
236         put( "\u3089", "\uff97");
237         put( "\u308a", "\uff98");
238         put( "\u308b", "\uff99");
239         put( "\u308c", "\uff9a");
240         put( "\u308d", "\uff9b");
241         put( "\u308f", "\uff9c");
242         put( "\u3092", "\uff66");
243         put( "\u3093", "\uff9d");
244         put( "\u308e", "\uff9c");
245         put( "\u30fc", "\uff70");
246     }};
247 
248     /** Conversion rule for full-width Katakana */
249     private static final HashMap<String,String> mFullKatakanaMap = new HashMap<String,String>() {{
250         put( "\u3042", "\u30a2");
251         put( "\u3044", "\u30a4");
252         put( "\u3046", "\u30a6");
253         put( "\u3048", "\u30a8");
254         put( "\u304a", "\u30aa");
255         put( "\u3041", "\u30a1");
256         put( "\u3043", "\u30a3");
257         put( "\u3045", "\u30a5");
258         put( "\u3047", "\u30a7");
259         put( "\u3049", "\u30a9");
260         put( "\u30f4\u3041", "\u30f4\u30a1");
261         put( "\u30f4\u3043", "\u30f4\u30a3");
262         put( "\u30f4", "\u30f4");
263         put( "\u30f4\u3047", "\u30f4\u30a7");
264         put( "\u30f4\u3049", "\u30f4\u30a9");
265         put( "\u304b", "\u30ab");
266         put( "\u304d", "\u30ad");
267         put( "\u304f", "\u30af");
268         put( "\u3051", "\u30b1");
269         put( "\u3053", "\u30b3");
270         put( "\u304c", "\u30ac");
271         put( "\u304e", "\u30ae");
272         put( "\u3050", "\u30b0");
273         put( "\u3052", "\u30b2");
274         put( "\u3054", "\u30b4");
275         put( "\u3055", "\u30b5");
276         put( "\u3057", "\u30b7");
277         put( "\u3059", "\u30b9");
278         put( "\u305b", "\u30bb");
279         put( "\u305d", "\u30bd");
280         put( "\u3056", "\u30b6");
281         put( "\u3058", "\u30b8");
282         put( "\u305a", "\u30ba");
283         put( "\u305c", "\u30bc");
284         put( "\u305e", "\u30be");
285         put( "\u305f", "\u30bf");
286         put( "\u3061", "\u30c1");
287         put( "\u3064", "\u30c4");
288         put( "\u3066", "\u30c6");
289         put( "\u3068", "\u30c8");
290         put( "\u3063", "\u30c3");
291         put( "\u3060", "\u30c0");
292         put( "\u3062", "\u30c2");
293         put( "\u3065", "\u30c5");
294         put( "\u3067", "\u30c7");
295         put( "\u3069", "\u30c9");
296         put( "\u306a", "\u30ca");
297         put( "\u306b", "\u30cb");
298         put( "\u306c", "\u30cc");
299         put( "\u306d", "\u30cd");
300         put( "\u306e", "\u30ce");
301         put( "\u306f", "\u30cf");
302         put( "\u3072", "\u30d2");
303         put( "\u3075", "\u30d5");
304         put( "\u3078", "\u30d8");
305         put( "\u307b", "\u30db");
306         put( "\u3070", "\u30d0");
307         put( "\u3073", "\u30d3");
308         put( "\u3076", "\u30d6");
309         put( "\u3079", "\u30d9");
310         put( "\u307c", "\u30dc");
311         put( "\u3071", "\u30d1");
312         put( "\u3074", "\u30d4");
313         put( "\u3077", "\u30d7");
314         put( "\u307a", "\u30da");
315         put( "\u307d", "\u30dd");
316         put( "\u307e", "\u30de");
317         put( "\u307f", "\u30df");
318         put( "\u3080", "\u30e0");
319         put( "\u3081", "\u30e1");
320         put( "\u3082", "\u30e2");
321         put( "\u3084", "\u30e4");
322         put( "\u3086", "\u30e6");
323         put( "\u3088", "\u30e8");
324         put( "\u3083", "\u30e3");
325         put( "\u3085", "\u30e5");
326         put( "\u3087", "\u30e7");
327         put( "\u3089", "\u30e9");
328         put( "\u308a", "\u30ea");
329         put( "\u308b", "\u30eb");
330         put( "\u308c", "\u30ec");
331         put( "\u308d", "\u30ed");
332         put( "\u308f", "\u30ef");
333         put( "\u3092", "\u30f2");
334         put( "\u3093", "\u30f3");
335         put( "\u308e", "\u30ee");
336         put( "\u30fc", "\u30fc");
337     }};
338 
339     /** Conversion rule for half-width alphabet */
340     private static final HashMap<String,String> mHalfAlphabetMap = new HashMap<String,String>() {{
341         put( "\u3042", ".");
342         put( "\u3044", "@");
343         put( "\u3046", "-");
344         put( "\u3048", "_");
345         put( "\u304a", "/");
346         put( "\u3041", ":");
347         put( "\u3043", "~");
348         put( "\u304b", "A");
349         put( "\u304d", "B");
350         put( "\u304f", "C");
351         put( "\u3055", "D");
352         put( "\u3057", "E");
353         put( "\u3059", "F");
354         put( "\u305f", "G");
355         put( "\u3061", "H");
356         put( "\u3064", "I");
357         put( "\u306a", "J");
358         put( "\u306b", "K");
359         put( "\u306c", "L");
360         put( "\u306f", "M");
361         put( "\u3072", "N");
362         put( "\u3075", "O");
363         put( "\u307e", "P");
364         put( "\u307f", "Q");
365         put( "\u3080", "R");
366         put( "\u3081", "S");
367         put( "\u3084", "T");
368         put( "\u3086", "U");
369         put( "\u3088", "V");
370         put( "\u3089", "W");
371         put( "\u308a", "X");
372         put( "\u308b", "Y");
373         put( "\u308c", "Z");
374         put( "\u308f", "-");
375     }};
376 
377     /** Conversion rule for full-width alphabet */
378     private static final HashMap<String,String> mFullAlphabetMap = new HashMap<String,String>() {{
379         put( "\u3042", "\uff0e");
380         put( "\u3044", "\uff20");
381         put( "\u3046", "\u30fc");
382         put( "\u3048", "\uff3f");
383         put( "\u304a", "\uff0f");
384         put( "\u3041", "\uff1a");
385         put( "\u3043", "\u301c");
386         put( "\u304b", "\uff21");
387         put( "\u304d", "\uff22" );
388         put( "\u304f", "\uff23");
389         put( "\u3055", "\uff24" );
390         put( "\u3057", "\uff25" );
391         put( "\u3059", "\uff26" );
392         put( "\u305f", "\uff27");
393         put( "\u3061", "\uff28" );
394         put( "\u3064", "\uff29");
395         put( "\u306a", "\uff2a");
396         put( "\u306b", "\uff2b" );
397         put( "\u306c", "\uff2c" );
398         put( "\u306f", "\uff2d");
399         put( "\u3072", "\uff2e");
400         put( "\u3075", "\uff2f");
401         put( "\u307e", "\uff30");
402         put( "\u307f", "\uff31");
403         put( "\u3080", "\uff32");
404         put( "\u3081", "\uff33" );
405         put( "\u3084", "\uff34" );
406         put( "\u3086", "\uff35" );
407         put( "\u3088", "\uff36" );
408         put( "\u3089", "\uff37" );
409         put( "\u308a", "\uff38" );
410         put( "\u308b", "\uff39");
411         put( "\u308c", "\uff3a" );
412         put( "\u308f", "\u30fc" );
413     }};
414 
415     /** Conversion rule for full-width alphabet (QWERTY mode) */
416     private static final HashMap<String,String> mFullAlphabetMapQwety = new HashMap<String,String>() {{
417         put( "a", "\uff41");
418         put( "b", "\uff42");
419         put( "c", "\uff43");
420         put( "d", "\uff44");
421         put( "e", "\uff45");
422         put( "f", "\uff46");
423         put( "g", "\uff47");
424         put( "h", "\uff48");
425         put( "i", "\uff49");
426         put( "j", "\uff4a");
427         put( "k", "\uff4b");
428         put( "l", "\uff4c");
429         put( "m", "\uff4d");
430         put( "n", "\uff4e");
431         put( "o", "\uff4f");
432         put( "p", "\uff50");
433         put( "q", "\uff51");
434         put( "r", "\uff52");
435         put( "s", "\uff53");
436         put( "t", "\uff54");
437         put( "u", "\uff55");
438         put( "v", "\uff56");
439         put( "w", "\uff57");
440         put( "x", "\uff58");
441         put( "y", "\uff59");
442         put( "z", "\uff5a");
443 
444         put( "A", "\uff21");
445         put( "B", "\uff22");
446         put( "C", "\uff23");
447         put( "D", "\uff24");
448         put( "E", "\uff25");
449         put( "F", "\uff26");
450         put( "G", "\uff27");
451         put( "H", "\uff28");
452         put( "I", "\uff29");
453         put( "J", "\uff2a");
454         put( "K", "\uff2b");
455         put( "L", "\uff2c");
456         put( "M", "\uff2d");
457         put( "N", "\uff2e");
458         put( "O", "\uff2f");
459         put( "P", "\uff30");
460         put( "Q", "\uff31");
461         put( "R", "\uff32");
462         put( "S", "\uff33");
463         put( "T", "\uff34");
464         put( "U", "\uff35");
465         put( "V", "\uff36");
466         put( "W", "\uff37");
467         put( "X", "\uff38");
468         put( "Y", "\uff39");
469         put( "Z", "\uff3a");
470     }};
471 
472     /** Decimal format using comma */
473     private static final DecimalFormat mFormat = new DecimalFormat("###,###");
474 
475     /** List of the generated candidates */
476     private List<WnnWord> mAddCandidateList;
477     /** Work area for generating string */
478     private StringBuffer mStringBuff;
479 
480     /** part of speech (default) */
481     private WnnPOS mPosDefault;
482     /** part of speech (number) */
483     private WnnPOS mPosNumber;
484     /** part of speech (symbol) */
485     private WnnPOS mPosSymbol;
486 
487     /**
488      * Constructor
489      */
KanaConverter()490     public KanaConverter() {
491         mAddCandidateList = new ArrayList<WnnWord>();
492         mStringBuff = new StringBuffer();
493     }
494 
495     /**
496      * Set The dictionary.
497      * <br>
498      * {@link KanaConverter} gets part-of-speech tags from the dictionary.
499      *
500      * @param dict  The dictionary
501      */
setDictionary(WnnDictionary dict)502     public void setDictionary(WnnDictionary dict) {
503         /* get part of speech tags */
504         mPosDefault  = dict.getPOS(WnnDictionary.POS_TYPE_MEISI);
505         mPosNumber   = dict.getPOS(WnnDictionary.POS_TYPE_SUUJI);
506         mPosSymbol   = dict.getPOS(WnnDictionary.POS_TYPE_KIGOU);
507     }
508 
509     /**
510      * Create the pseudo candidate list
511      * <br>
512      * @param inputHiragana     The input string (Hiragana)
513      * @param inputRomaji       The input string (Romaji)
514      * @param keyBoardMode      The mode of keyboard
515      * @return                  The candidate list
516      */
createPseudoCandidateList(String inputHiragana, String inputRomaji, int keyBoardMode)517     public List<WnnWord> createPseudoCandidateList(String inputHiragana, String inputRomaji, int keyBoardMode) {
518         List<WnnWord> list = mAddCandidateList;
519 
520         list.clear();
521         if (inputHiragana.length() == 0) {
522         	return list;
523         }
524 
525         /* Create pseudo candidates for all keyboard type */
526         /* Hiragana(reading) / Full width katakana / Half width katakana */
527         list.add(new WnnWord(inputHiragana, inputHiragana));
528         if (createCandidateString(inputHiragana, mFullKatakanaMap, mStringBuff)) {
529             list.add(new WnnWord(mStringBuff.toString(), inputHiragana, mPosDefault));
530         }
531         if (createCandidateString(inputHiragana, mHalfKatakanaMap, mStringBuff)) {
532             list.add(new WnnWord(mStringBuff.toString(), inputHiragana, mPosDefault));
533         }
534 
535         if (keyBoardMode == OpenWnnEngineJAJP.KEYBOARD_QWERTY) {
536             /* Create pseudo candidates for Qwerty keyboard */
537             createPseudoCandidateListForQwerty(inputHiragana, inputRomaji);
538         } else {
539             /* Create pseudo candidates for 12key */
540 
541         	/* Create pseudo candidates for half width numeric */
542             if (createCandidateString(inputHiragana, mHalfNumericMap, mStringBuff)) {
543                 String convHanSuuji = mStringBuff.toString();
544                 String convNumComma = convertNumber(convHanSuuji);
545                 list.add(new WnnWord(convHanSuuji, inputHiragana, mPosNumber));
546                 if (convNumComma != null) {
547                     list.add(new WnnWord(convNumComma, inputHiragana, mPosNumber));
548                 }
549             }
550 
551             /* Create pseudo candidates for full width numeric */
552             if (createCandidateString(inputHiragana, mFullNumericMap, mStringBuff)) {
553                 list.add(new WnnWord(mStringBuff.toString(), inputHiragana, mPosNumber));
554             }
555 
556             /* Create pseudo candidates for half width alphabet */
557             if (createCandidateString(inputHiragana, mHalfAlphabetMap, mStringBuff)) {
558                 String convHanEiji = mStringBuff.toString();
559                 String convHanEijiLower = convHanEiji.toLowerCase();
560                 list.add(new WnnWord(convHanEijiLower, inputHiragana, mPosSymbol));
561                 list.add(new WnnWord(convertCaps(convHanEijiLower), inputHiragana, mPosSymbol));
562                 list.add(new WnnWord(convHanEiji, inputHiragana, mPosSymbol));
563             }
564 
565             /* Create pseudo candidates for full width alphabet */
566             if (createCandidateString(inputHiragana, mFullAlphabetMap, mStringBuff)) {
567                 String convZenEiji = mStringBuff.toString();
568                 String convZenEijiLower = convZenEiji.toLowerCase(Locale.JAPAN);
569                 list.add(new WnnWord(convZenEijiLower, inputHiragana, mPosSymbol));
570                 list.add(new WnnWord(convertCaps(convZenEijiLower), inputHiragana, mPosSymbol));
571                 list.add(new WnnWord(convZenEiji, inputHiragana, mPosSymbol));
572             }
573         }
574         return list;
575     }
576 
577     /**
578      * Create the pseudo candidate list for Qwerty keyboard
579      * <br>
580      * @param inputHiragana     The input string (Hiragana)
581      * @param inputRomaji       The input string (Romaji)
582      */
createPseudoCandidateListForQwerty(String inputHiragana, String inputRomaji)583     private void createPseudoCandidateListForQwerty(String inputHiragana, String inputRomaji) {
584         List<WnnWord> list = mAddCandidateList;
585 
586         /* Create pseudo candidates for half width alphabet */
587         String convHanEijiLower = inputRomaji.toLowerCase();
588         list.add(new WnnWord(inputRomaji, inputHiragana, mPosDefault));
589         list.add(new WnnWord(convHanEijiLower, inputHiragana, mPosSymbol));
590         list.add(new WnnWord(convertCaps(convHanEijiLower), inputHiragana, mPosSymbol));
591         list.add(new WnnWord(inputRomaji.toUpperCase(), inputHiragana, mPosSymbol));
592 
593         /* Create pseudo candidates for the full width alphabet */
594         if (createCandidateString(inputRomaji, mFullAlphabetMapQwety, mStringBuff)) {
595             String convZenEiji = mStringBuff.toString();
596             String convZenEijiLower = convZenEiji.toLowerCase(Locale.JAPAN);
597             list.add(new WnnWord(convZenEiji, inputHiragana, mPosSymbol));
598             list.add(new WnnWord(convZenEijiLower, inputHiragana, mPosSymbol));
599             list.add(new WnnWord(convertCaps(convZenEijiLower), inputHiragana, mPosSymbol));
600             list.add(new WnnWord(convZenEiji.toUpperCase(Locale.JAPAN), inputHiragana, mPosSymbol));
601         }
602     }
603 
604     /**
605      * Create the candidate string
606      * <br>
607      * @param input     The input string
608      * @param map       The hash map
609      * @param outBuf    The output string
610      * @return          {@code true} if success
611      */
createCandidateString(String input, HashMap<String,String> map, StringBuffer outBuf)612     private boolean createCandidateString(String input, HashMap<String,String> map, StringBuffer outBuf) {
613         if (outBuf.length() > 0) {
614             outBuf.delete(0, outBuf.length());
615         }
616         for (int index = 0; index < input.length(); index++) {
617             String convChar = map.get(input.substring(index, index + 1));
618             if (convChar == null) {
619                 return false;
620             }
621             outBuf.append(convChar);
622         }
623         return true;
624     }
625 
626     /**
627      * Convert into both small and capital letter
628      * <br>
629      * @param moji  The input string
630      * @return      The converted string
631      */
convertCaps(String moji)632     private String convertCaps(String moji) {
633         String tmp = "";
634         if (moji != null && moji.length() > 0) {
635             tmp = moji.substring(0, 1).toUpperCase(Locale.JAPAN)
636                     + moji.substring(1).toLowerCase(Locale.JAPAN);
637         }
638         return tmp;
639     }
640 
641     /**
642      * Convert the numeric into formatted string
643      * <br>
644      * @param numComma  The value
645      * @return          {@code true} if success
646      */
convertNumber(String numComma)647     private String convertNumber(String numComma) {
648         try {
649             return mFormat.format(Double.parseDouble(numComma));
650         } catch (NumberFormatException e) {
651             return null;
652         }
653     }
654 }
655