OSDN Git Service

3cfffbaed6f007551e16e7f9d1b84c45af48c74a
[mikutoga/TogaGem.git] / src / main / java / jp / sourceforge / mikutoga / corelib / I18nText.java
1 /*\r
2  * international text\r
3  *\r
4  * License : The MIT License\r
5  * Copyright(c) 2010 MikuToga Partners\r
6  */\r
7 \r
8 package jp.sourceforge.mikutoga.corelib;\r
9 \r
10 import java.util.ArrayList;\r
11 import java.util.HashMap;\r
12 import java.util.Iterator;\r
13 import java.util.List;\r
14 import java.util.Locale;\r
15 import java.util.Map;\r
16 import java.util.Set;\r
17 \r
18 /**\r
19  * 多言語のバリアントを持つ文字列情報。\r
20  * <ul>\r
21  * <li>プライマリ:識別子にはこちらを使う。基本は日本語。\r
22  * <li>グローバル:基本は英語。UCS Basic-Latinオンリーの貧弱な言語環境でも\r
23  * 読める文字列が望ましい。\r
24  * <li>その他:必要に応じて好きな言語を。\r
25  * </ul>\r
26  */\r
27 public class I18nText implements CharSequence {\r
28 \r
29     /** プライマリ言語のロケール。 */\r
30     public static final Locale LOCALE_PRIMARY = Locale.JAPANESE;\r
31     /** プライマリ言語の言語コード。 */\r
32     public static final String CODE639_PRIMARY = LOCALE_PRIMARY.getLanguage();\r
33 \r
34     /** グローバル言語のロケール。 */\r
35     public static final Locale LOCALE_GLOBAL = Locale.ENGLISH;\r
36     /** グローバル言語の言語コード。 */\r
37     public static final String CODE639_GLOBAL = LOCALE_GLOBAL.getLanguage();\r
38 \r
39     static{\r
40         assert CODE639_PRIMARY.equals("ja");\r
41         assert CODE639_GLOBAL .equals("en");\r
42     }\r
43 \r
44     private final Map<String, String> nameMap = new HashMap<String, String>();\r
45 \r
46     /**\r
47      * コンストラクタ。\r
48      */\r
49     public I18nText(){\r
50         super();\r
51         return;\r
52     }\r
53 \r
54     /**\r
55      * プライマリ文字列の登録。\r
56      * @param seq プライマリ文字列。nullの場合は削除動作\r
57      */\r
58     public void setPrimaryText(CharSequence seq){\r
59         setText(CODE639_PRIMARY, seq);\r
60         return;\r
61     }\r
62 \r
63     /**\r
64      * グローバル文字列の登録。\r
65      * @param seq グローバル文字列。nullの場合は削除動作\r
66      */\r
67     public void setGlobalText(CharSequence seq){\r
68         setText(CODE639_GLOBAL, seq);\r
69         return;\r
70     }\r
71 \r
72     /**\r
73      * 任意のロケールに関連付けられた文字列の登録。\r
74      * @param locale ロケール\r
75      * @param seq 文字列。nullの場合は削除動作\r
76      * @throws NullPointerException ロケール引数がnull\r
77      */\r
78     public void setText(Locale locale, CharSequence seq)\r
79             throws NullPointerException{\r
80         String code639 = locale.getLanguage();\r
81         setText(code639, seq);\r
82         return;\r
83     }\r
84 \r
85     /**\r
86      * 任意の言語コードに関連付けられた文字列の登録。\r
87      * @param code639 ISO639言語コード\r
88      * @param seq 文字列。nullの場合は削除動作\r
89      * @throws NullPointerException 言語コードがnull\r
90      */\r
91     public void setText(String code639, CharSequence seq)\r
92             throws NullPointerException{\r
93         if(code639 == null) throw new NullPointerException();\r
94 \r
95         if(seq != null){\r
96             String text = seq.toString();\r
97             this.nameMap.put(code639, text);\r
98         }else{\r
99             this.nameMap.remove(code639);\r
100         }\r
101 \r
102         return;\r
103     }\r
104 \r
105     /**\r
106      * 言語コードに応じた文字列を返す。\r
107      * @param code639 ISO639言語コード\r
108      * @return 文字列。見つからなければnullを返す。\r
109      * @throws NullPointerException 引数がnull\r
110      */\r
111     public String getText(String code639) throws NullPointerException{\r
112         if(code639 == null) throw new NullPointerException();\r
113         String result = this.nameMap.get(code639);\r
114         return result;\r
115     }\r
116 \r
117     /**\r
118      * ロケールに応じた文字列を返す。\r
119      * @param locale ロケール\r
120      * @return 文字列。見つからなければnullを返す。\r
121      * @throws NullPointerException 引数がnull\r
122      */\r
123     public String getText(Locale locale) throws NullPointerException{\r
124         String code639 = locale.getLanguage();\r
125         String result = getText(code639);\r
126         return result;\r
127     }\r
128 \r
129     /**\r
130      * プライマリ文字列を返す。\r
131      * @return 文字列。見つからなければnullを返す。\r
132      */\r
133     public String getPrimaryText(){\r
134         String result = getText(CODE639_PRIMARY);\r
135         return result;\r
136     }\r
137 \r
138     /**\r
139      * グローバル文字列を返す。\r
140      * @return 文字列。見つからなければnullを返す。\r
141      */\r
142     public String getGlobalText(){\r
143         String result = getText(CODE639_GLOBAL);\r
144         return result;\r
145     }\r
146 \r
147     /**\r
148      * プライマリ文字列を返す。\r
149      * 見つからなければグローバル文字列を返す。\r
150      * それでも見つからなければ空文字列を返す。\r
151      * @return 文字列\r
152      */\r
153     public String getText(){\r
154         String result;\r
155 \r
156         result = getPrimaryText();\r
157 \r
158         if(result == null){\r
159             result = getGlobalText();\r
160         }\r
161 \r
162         if(result == null){\r
163             result = "";\r
164         }\r
165 \r
166         return result;\r
167     }\r
168 \r
169     /**\r
170      * 実行環境のデフォルトロケールに応じた文字列を返す。\r
171      * 見つからなければグローバル文字列、プライマリ文字列の順に返す。\r
172      * それでも見つからなければ適当な言語コードの文字列を返す。\r
173      * それでも見つからなければ空文字列を返す。\r
174      * デフォルトロケールの確認はその都度行われる。\r
175      * @return 文字列\r
176      */\r
177     public String getLocalizedText(){\r
178         Locale locale = Locale.getDefault();\r
179         String langCode = locale.getLanguage();\r
180 \r
181         String result;\r
182 \r
183         result = this.nameMap.get(langCode);\r
184 \r
185         if(result == null){\r
186             result = this.nameMap.get(CODE639_GLOBAL);\r
187         }\r
188 \r
189         if(result == null){\r
190             result = this.nameMap.get(CODE639_PRIMARY);\r
191         }\r
192 \r
193         if(result == null){\r
194             Set<String> langSet = this.nameMap.keySet();\r
195             Iterator<String> it = langSet.iterator();\r
196             while(it.hasNext()){\r
197                 String lang = it.next();\r
198                 result = this.nameMap.get(lang);\r
199                 if(result != null) break;\r
200             }\r
201         }\r
202 \r
203         if(result == null){\r
204             result = "";\r
205         }\r
206 \r
207         return result;\r
208     }\r
209 \r
210     /**\r
211      * 全言語の文字列を削除する。\r
212      */\r
213     public void removeAllText(){\r
214         this.nameMap.clear();\r
215         return;\r
216     }\r
217 \r
218     /**\r
219      * 登録済みの全ISO639言語コードリストを返す。\r
220      * 優先度はプライマリ、グローバル、その他の順。\r
221      * @return 全ISO639言語コード\r
222      */\r
223     public List<String> lang639CodeList(){\r
224         Set<String> set = this.nameMap.keySet();\r
225         List<String> result = new ArrayList<String>(set.size());\r
226 \r
227         for(String lang : set){\r
228             if(lang.equals(CODE639_PRIMARY)) result.add(lang);\r
229         }\r
230 \r
231         for(String lang : set){\r
232             if(lang.equals(CODE639_GLOBAL)) result.add(lang);\r
233         }\r
234 \r
235         for(String lang : set){\r
236             if(lang.equals(CODE639_PRIMARY)) continue;\r
237             if(lang.equals(CODE639_GLOBAL)) continue;\r
238             result.add(lang);\r
239         }\r
240 \r
241         return result;\r
242     }\r
243 \r
244     /**\r
245      * プライマリ文字列が登録されているか判定する。\r
246      * @return 登録されていればtrue\r
247      */\r
248     public boolean hasPrimaryText(){\r
249         boolean result = this.nameMap.containsKey(CODE639_PRIMARY);\r
250         return result;\r
251     }\r
252 \r
253     /**\r
254      * グローバル文字列が登録されているか判定する。\r
255      * @return 登録されていればtrue\r
256      */\r
257     public boolean hasGlobalText(){\r
258         boolean result = this.nameMap.containsKey(CODE639_GLOBAL);\r
259         return result;\r
260     }\r
261 \r
262     /**\r
263      * {@inheritDoc}\r
264      * {@link #getText()}に準ずる。\r
265      * @param index {@inheritDoc}\r
266      * @return {@inheritDoc}\r
267      */\r
268     public char charAt(int index){\r
269         String text = getText();\r
270         char result = text.charAt(index);\r
271         return result;\r
272     }\r
273 \r
274     /**\r
275      * {@inheritDoc}\r
276      * {@link #getText()}に準ずる。\r
277      * @return {@inheritDoc}\r
278      */\r
279     public int length(){\r
280         String text = getText();\r
281         int result = text.length();\r
282         return result;\r
283     }\r
284 \r
285     /**\r
286      * {@inheritDoc}\r
287      * {@link #getText()}に準ずる。\r
288      * @param start {@inheritDoc}\r
289      * @param end {@inheritDoc}\r
290      * @return {@inheritDoc}\r
291      */\r
292     public CharSequence subSequence(int start, int end){\r
293         String text = getText();\r
294         CharSequence result = text.subSequence(start, end);\r
295         return result;\r
296     }\r
297 \r
298     /**\r
299      * {@inheritDoc}\r
300      * {@link #getText()}に準ずる。\r
301      * @return {@inheritDoc}\r
302      */\r
303     @Override\r
304     public String toString(){\r
305         return getText();\r
306     }\r
307 \r
308 }\r