4 * License : The MIT License
\r
5 * Copyright(c) 2010 MikuToga Partners
\r
8 package jp.sourceforge.mikutoga.corelib;
\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
19 * 多言語のバリアントを持つ文字列情報。
\r
21 * <li>プライマリ:識別子にはこちらを使う。基本は日本語。
\r
22 * <li>グローバル:基本は英語。UCS Basic-Latinオンリーの貧弱な言語環境でも
\r
24 * <li>その他:必要に応じて好きな言語を。
\r
27 public class I18nText implements CharSequence {
\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
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
40 assert CODE639_PRIMARY.equals("ja");
\r
41 assert CODE639_GLOBAL .equals("en");
\r
44 private final Map<String, String> nameMap = new HashMap<String, String>();
\r
56 * @param seq プライマリ文字列。nullの場合は削除動作
\r
58 public void setPrimaryText(CharSequence seq){
\r
59 setText(CODE639_PRIMARY, seq);
\r
65 * @param seq グローバル文字列。nullの場合は削除動作
\r
67 public void setGlobalText(CharSequence seq){
\r
68 setText(CODE639_GLOBAL, seq);
\r
73 * 任意のロケールに関連付けられた文字列の登録。
\r
74 * @param locale ロケール
\r
75 * @param seq 文字列。nullの場合は削除動作
\r
76 * @throws NullPointerException ロケール引数がnull
\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
86 * 任意の言語コードに関連付けられた文字列の登録。
\r
87 * @param code639 ISO639言語コード
\r
88 * @param seq 文字列。nullの場合は削除動作
\r
89 * @throws NullPointerException 言語コードがnull
\r
91 public void setText(String code639, CharSequence seq)
\r
92 throws NullPointerException{
\r
93 if(code639 == null) throw new NullPointerException();
\r
96 String text = seq.toString();
\r
97 this.nameMap.put(code639, text);
\r
99 this.nameMap.remove(code639);
\r
107 * @param code639 ISO639言語コード
\r
108 * @return 文字列。見つからなければnullを返す。
\r
109 * @throws NullPointerException 引数がnull
\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
119 * @param locale ロケール
\r
120 * @return 文字列。見つからなければnullを返す。
\r
121 * @throws NullPointerException 引数がnull
\r
123 public String getText(Locale locale) throws NullPointerException{
\r
124 String code639 = locale.getLanguage();
\r
125 String result = getText(code639);
\r
131 * @return 文字列。見つからなければnullを返す。
\r
133 public String getPrimaryText(){
\r
134 String result = getText(CODE639_PRIMARY);
\r
140 * @return 文字列。見つからなければnullを返す。
\r
142 public String getGlobalText(){
\r
143 String result = getText(CODE639_GLOBAL);
\r
149 * 見つからなければグローバル文字列を返す。
\r
150 * それでも見つからなければ空文字列を返す。
\r
153 public String getText(){
\r
156 result = getPrimaryText();
\r
158 if(result == null){
\r
159 result = getGlobalText();
\r
162 if(result == null){
\r
170 * 実行環境のデフォルトロケールに応じた文字列を返す。
\r
171 * 見つからなければグローバル文字列、プライマリ文字列の順に返す。
\r
172 * それでも見つからなければ適当な言語コードの文字列を返す。
\r
173 * それでも見つからなければ空文字列を返す。
\r
174 * デフォルトロケールの確認はその都度行われる。
\r
177 public String getLocalizedText(){
\r
178 Locale locale = Locale.getDefault();
\r
179 String langCode = locale.getLanguage();
\r
183 result = this.nameMap.get(langCode);
\r
185 if(result == null){
\r
186 result = this.nameMap.get(CODE639_GLOBAL);
\r
189 if(result == null){
\r
190 result = this.nameMap.get(CODE639_PRIMARY);
\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
203 if(result == null){
\r
213 public void removeAllText(){
\r
214 this.nameMap.clear();
\r
219 * 登録済みの全ISO639言語コードリストを返す。
\r
220 * 優先度はプライマリ、グローバル、その他の順。
\r
221 * @return 全ISO639言語コード
\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
227 for(String lang : set){
\r
228 if(lang.equals(CODE639_PRIMARY)) result.add(lang);
\r
231 for(String lang : set){
\r
232 if(lang.equals(CODE639_GLOBAL)) result.add(lang);
\r
235 for(String lang : set){
\r
236 if(lang.equals(CODE639_PRIMARY)) continue;
\r
237 if(lang.equals(CODE639_GLOBAL)) continue;
\r
245 * プライマリ文字列が登録されているか判定する。
\r
246 * @return 登録されていればtrue
\r
248 public boolean hasPrimaryText(){
\r
249 boolean result = this.nameMap.containsKey(CODE639_PRIMARY);
\r
254 * グローバル文字列が登録されているか判定する。
\r
255 * @return 登録されていればtrue
\r
257 public boolean hasGlobalText(){
\r
258 boolean result = this.nameMap.containsKey(CODE639_GLOBAL);
\r
264 * {@link #getText()}に準ずる。
\r
265 * @param index {@inheritDoc}
\r
266 * @return {@inheritDoc}
\r
268 public char charAt(int index){
\r
269 String text = getText();
\r
270 char result = text.charAt(index);
\r
276 * {@link #getText()}に準ずる。
\r
277 * @return {@inheritDoc}
\r
279 public int length(){
\r
280 String text = getText();
\r
281 int result = text.length();
\r
287 * {@link #getText()}に準ずる。
\r
288 * @param start {@inheritDoc}
\r
289 * @param end {@inheritDoc}
\r
290 * @return {@inheritDoc}
\r
292 public CharSequence subSequence(int start, int end){
\r
293 String text = getText();
\r
294 CharSequence result = text.subSequence(start, end);
\r
300 * {@link #getText()}に準ずる。
\r
301 * @return {@inheritDoc}
\r
304 public String toString(){
\r