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 = new HashMap<>();
64 * @param seq プライマリ文字列。nullの場合は削除動作
66 public void setPrimaryText(CharSequence seq){
67 setI18nText(CODE639_PRIMARY, seq);
73 * @param seq グローバル文字列。nullの場合は削除動作
75 public void setGlobalText(CharSequence seq){
76 setI18nText(CODE639_GLOBAL, seq);
81 * 任意のロケールに関連付けられた文字列の登録。
83 * @param seq 文字列。nullの場合は削除動作
84 * @throws NullPointerException ロケール引数がnull
86 public void setI18nText(Locale locale, CharSequence seq)
87 throws NullPointerException{
88 String code639 = locale.getLanguage();
89 setI18nText(code639, seq);
94 * 任意の言語コードに関連付けられた文字列の登録。
95 * @param code639 ISO639言語コード
96 * @param seq 文字列。nullの場合は削除動作
97 * @throws NullPointerException 言語コードがnull
99 public void setI18nText(String code639, CharSequence seq)
100 throws NullPointerException{
101 if(code639 == null) throw new NullPointerException();
104 String text = seq.toString();
105 this.nameMap.put(code639, text);
107 this.nameMap.remove(code639);
115 * @return 文字列。見つからなければnullを返す。
117 public String getPrimaryText(){
118 String result = getI18nText(CODE639_PRIMARY);
124 * @return 文字列。見つからなければnullを返す。
126 public String getGlobalText(){
127 String result = getI18nText(CODE639_GLOBAL);
134 * @return 文字列。見つからなければnullを返す。
135 * @throws NullPointerException 引数がnull
137 public String getI18nText(Locale locale) throws NullPointerException{
138 String code639 = locale.getLanguage();
139 String result = getI18nText(code639);
145 * @param code639 ISO639言語コード
146 * @return 文字列。見つからなければnullを返す。
147 * @throws NullPointerException 引数がnull
149 public String getI18nText(String code639) throws NullPointerException{
150 if(code639 == null) throw new NullPointerException();
151 String result = this.nameMap.get(code639);
158 * <p>見つからなければグローバル文字列を返す。
159 * それでも見つからなければ長さ0の空文字列を返す。
165 public String getText(){
168 result = getPrimaryText();
171 result = getGlobalText();
182 * 実行環境のデフォルトロケールに応じた文字列を返す。
184 * <p>見つからなければグローバル文字列、プライマリ文字列の順に返す。
185 * それでも見つからなければ適当な言語コードの文字列を返す。
186 * それでも見つからなければ長さ0の空文字列を返す。
188 * <p>デフォルトロケールの確認はその都度行われる。
194 public String getLocalizedText(){
195 Locale locale = Locale.getDefault();
196 String langCode = locale.getLanguage();
200 result = this.nameMap.get(langCode);
203 result = this.nameMap.get(CODE639_GLOBAL);
207 result = this.nameMap.get(CODE639_PRIMARY);
211 Set<String> langSet = this.nameMap.keySet();
212 for(String lang : langSet){
213 result = this.nameMap.get(lang);
214 if(result != null) break;
228 public void clearI18nText(){
229 this.nameMap.clear();
234 * 登録済みの全ISO639言語コードリストを返す。
235 * 優先度はプライマリ、グローバル、その他の順。
236 * @return 全ISO639言語コード
238 public List<String> lang639CodeList(){
239 Set<String> set = this.nameMap.keySet();
240 List<String> result = new ArrayList<>(set.size());
242 for(String lang : set){
243 if(lang.equals(CODE639_PRIMARY)) result.add(lang);
246 for(String lang : set){
247 if(lang.equals(CODE639_GLOBAL)) result.add(lang);
250 for(String lang : set){
251 if(lang.equals(CODE639_PRIMARY)) continue;
252 if(lang.equals(CODE639_GLOBAL)) continue;
260 * プライマリ文字列が登録されているか判定する。
261 * @return 登録されていればtrue
263 public boolean hasPrimaryText(){
264 boolean result = this.nameMap.containsKey(CODE639_PRIMARY);
269 * グローバル文字列が登録されているか判定する。
270 * @return 登録されていればtrue
272 public boolean hasGlobalText(){
273 boolean result = this.nameMap.containsKey(CODE639_GLOBAL);
279 * {@link #getText()}仕様に準ずる。
280 * @param index {@inheritDoc}
281 * @return {@inheritDoc}
284 public char charAt(int index){
285 String text = getText();
286 char result = text.charAt(index);
292 * {@link #getText()}仕様に準ずる。
293 * @return {@inheritDoc}
297 String text = getText();
298 int result = text.length();
304 * {@link #getText()}仕様に準ずる。
305 * @param start {@inheritDoc}
306 * @param end {@inheritDoc}
307 * @return {@inheritDoc}
310 public CharSequence subSequence(int start, int end){
311 String text = getText();
312 CharSequence result = text.subSequence(start, end);
318 * {@link #getText()}仕様に準ずる。
319 * @return {@inheritDoc}
322 public String toString(){