2 * internationalization text
4 * License : The MIT License
5 * Copyright(c) 2010 MikuToga Partners
8 package jp.sfjp.mikutoga.corelib;
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Locale;
19 * 言語はISO639言語コードで区別される。
21 * <li>プライマリ:識別子にはこちらを使う。
22 * 基本はMMD発祥の地に敬意を表して日本語。
23 * <li>グローバル:基本は英語。UCS Basic-Latinオンリーの貧弱な言語環境でも
25 * <li>その他:必要に応じて好きな言語を。
28 public class I18nText implements CharSequence {
31 public static final Locale LOCALE_PRIMARY = Locale.JAPANESE;
32 /** プライマリ言語のISO639言語コード。 */
33 public static final String CODE639_PRIMARY =
34 LOCALE_PRIMARY.getLanguage();
37 public static final Locale LOCALE_GLOBAL = Locale.ENGLISH;
38 /** グローバル言語のISO639言語コード。 */
39 public static final String CODE639_GLOBAL =
40 LOCALE_GLOBAL.getLanguage();
43 assert "ja".equals(CODE639_PRIMARY);
44 assert "en".equals(CODE639_GLOBAL);
49 * キーはISO639、値は多言語テキスト。
51 private final Map<String, String> nameMap =
52 new HashMap<String, String>();
65 * @param seq プライマリ文字列。nullの場合は削除動作
67 public void setPrimaryText(CharSequence seq){
68 setI18nText(CODE639_PRIMARY, seq);
74 * @param seq グローバル文字列。nullの場合は削除動作
76 public void setGlobalText(CharSequence seq){
77 setI18nText(CODE639_GLOBAL, seq);
82 * 任意のロケールに関連付けられた文字列の登録。
84 * @param seq 文字列。nullの場合は削除動作
85 * @throws NullPointerException ロケール引数がnull
87 public void setI18nText(Locale locale, CharSequence seq)
88 throws NullPointerException{
89 String code639 = locale.getLanguage();
90 setI18nText(code639, seq);
95 * 任意の言語コードに関連付けられた文字列の登録。
96 * @param code639 ISO639言語コード
97 * @param seq 文字列。nullの場合は削除動作
98 * @throws NullPointerException 言語コードがnull
100 public void setI18nText(String code639, CharSequence seq)
101 throws NullPointerException{
102 if(code639 == null) throw new NullPointerException();
105 String text = seq.toString();
106 this.nameMap.put(code639, text);
108 this.nameMap.remove(code639);
116 * @return 文字列。見つからなければnullを返す。
118 public String getPrimaryText(){
119 String result = getI18nText(CODE639_PRIMARY);
125 * @return 文字列。見つからなければnullを返す。
127 public String getGlobalText(){
128 String result = getI18nText(CODE639_GLOBAL);
135 * @return 文字列。見つからなければnullを返す。
136 * @throws NullPointerException 引数がnull
138 public String getI18nText(Locale locale) throws NullPointerException{
139 String code639 = locale.getLanguage();
140 String result = getI18nText(code639);
146 * @param code639 ISO639言語コード
147 * @return 文字列。見つからなければnullを返す。
148 * @throws NullPointerException 引数がnull
150 public String getI18nText(String code639) throws NullPointerException{
151 if(code639 == null) throw new NullPointerException();
152 String result = this.nameMap.get(code639);
158 * <p>見つからなければグローバル文字列を返す。
159 * それでも見つからなければ長さ0の空文字列を返す。
163 public String getText(){
166 result = getPrimaryText();
169 result = getGlobalText();
180 * 実行環境のデフォルトロケールに応じた文字列を返す。
181 * <p>見つからなければグローバル文字列、プライマリ文字列の順に返す。
182 * それでも見つからなければ適当な言語コードの文字列を返す。
183 * それでも見つからなければ長さ0の空文字列を返す。
184 * <p>デフォルトロケールの確認はその都度行われる。
188 public String getLocalizedText(){
189 Locale locale = Locale.getDefault();
190 String langCode = locale.getLanguage();
194 result = this.nameMap.get(langCode);
197 result = this.nameMap.get(CODE639_GLOBAL);
201 result = this.nameMap.get(CODE639_PRIMARY);
205 Set<String> langSet = this.nameMap.keySet();
206 for(String lang : langSet){
207 result = this.nameMap.get(lang);
208 if(result != null) break;
222 public void clearI18nText(){
223 this.nameMap.clear();
228 * 登録済みの全ISO639言語コードリストを返す。
229 * 優先度はプライマリ、グローバル、その他の順。
230 * @return 全ISO639言語コード
232 public List<String> lang639CodeList(){
233 Set<String> set = this.nameMap.keySet();
234 List<String> result = new ArrayList<String>(set.size());
236 for(String lang : set){
237 if(lang.equals(CODE639_PRIMARY)) result.add(lang);
240 for(String lang : set){
241 if(lang.equals(CODE639_GLOBAL)) result.add(lang);
244 for(String lang : set){
245 if(lang.equals(CODE639_PRIMARY)) continue;
246 if(lang.equals(CODE639_GLOBAL)) continue;
254 * プライマリ文字列が登録されているか判定する。
255 * @return 登録されていればtrue
257 public boolean hasPrimaryText(){
258 boolean result = this.nameMap.containsKey(CODE639_PRIMARY);
263 * グローバル文字列が登録されているか判定する。
264 * @return 登録されていればtrue
266 public boolean hasGlobalText(){
267 boolean result = this.nameMap.containsKey(CODE639_GLOBAL);
273 * {@link #getText()}仕様に準ずる。
274 * @param index {@inheritDoc}
275 * @return {@inheritDoc}
278 public char charAt(int index){
279 String text = getText();
280 char result = text.charAt(index);
286 * {@link #getText()}仕様に準ずる。
287 * @return {@inheritDoc}
291 String text = getText();
292 int result = text.length();
298 * {@link #getText()}仕様に準ずる。
299 * @param start {@inheritDoc}
300 * @param end {@inheritDoc}
301 * @return {@inheritDoc}
304 public CharSequence subSequence(int start, int end){
305 String text = getText();
306 CharSequence result = text.subSequence(start, end);
312 * {@link #getText()}仕様に準ずる。
313 * @return {@inheritDoc}
316 public String toString(){