July 28, 2013

java.util.ResourceBundle

Internationalization Programming အား ရေးသားရာတွင် မဖြစ်မနေ ကြုံတွေ့ရမည့် ပြဿနာ တစ်ခုသည်၊ User Interface များတွင် အသုံးပြုထားသည့် စာများ၊ အသုံးပြုသည့် Unit များ၊ Format များပင်ဖြစ်သည်။ နေရာဒေသ Locale အပေါ်မှုတည်၍ အသုံးပြုသည့် ဘာသာစကားများအပြင်၊ Unit များ Format များမှာ ကွဲခြားသောကြောင့် ဖြစ်သည်။ ယခင်တစ်ခေါက် Locale ဘလောဂ်တွင် ဖော်ပြခဲ့သည့် အတိုင်း မြန်မာ Locale အား လက်ရှိ Java ဘာသာရပ်တွင် Support လုပ်ထားခြင်း မရှိသေးပါ။ ResourceBundle ဆိုသည်မှာ Locale အပေါ်မှုတည်၍ ပြောင်းလည်းတတ်သော Object များ Management ပြုလုပ်ပေးနိုင်သော API ဖြစ်ပါသည်။

Java SE 6 အရောက်တွင် ResourceBundle အား အတော်လေးပင် ပြုပြင်ပြောင်းလည်း လာခဲ့ပါသည်။

ResourceBundle အား အသုံးပြုပုံ


ResourceBundle Class ၏ အသုံးပြုပုံမှာ အတော်လေးပင် လွယ်ကူလှပါသည်။ သို့ရာတွင် လက်တွေ့အလုပ်လုပ်ပုံကို နားလည်ထားခြင်းမရှိပါက၊ ထင်မထားသည့် ResourceBundle အား သွားခေါ်တတ်ပါသဖြင့် သတိပြုသင့်ပါသည်။ နမှုနာ တစ်ခုကို ရေးသားကြည့်ပါမည်။
    public static void main(String[] args) {
        ResourceBundle rb = ResourceBundle.getBundle("com.dtc.rb.resource");
        System.out.println(rb.getString("sample"));
    }
အထက်ပါနာ့မှုနာထဲတွင် ResourceBundle Object အား ResourceBundel Class ၏ static Method getBundle ဖြင့် ခေါ်ဆိုနိုင်ပါသည်။ Locale အား သတ်မှတ်ထားခြင်း မရှိပါက Default Locale တွင် အသုံးပြုသော Resource အား ခေါ်ယူမည် ဖြစ်သည်။ Argument တွင် အသုံးပြုသော String သည် Resource ၏ Family Name ဖြစ်၏။ Package အတွင်း တွင်ရှိပါက Package အား ရေးသား၍ Family Name အား ရေးသားရပါသည်။ အထက်နမှုနာတွင် com.dtc.rb သည် Package ဖြစ်ပြီး၊ resource သည် Family Name ဖြစ်ပါသည်။

ResourceBundle အတွင်းတွင် Resurce များအား Key နှင့် Value အားတွဲကာ သိမ်းဆည်းထားပြီး၊ တန်ဖိုးအား ရယူလိုသည့်အခါတွင် getString, getObject နှင့် getStringArray Method တို့ကို အသုံးပြုနိုင်ပါသည်။ အဆိုပါ Method များတွင် String type Parameter အား အသုံးပြုရန် လိုအပ်ပြီး၊ ၎င်းမှာ Resource အား တွဲ၍ သိမ်းဆည်းထားသော Key ဖြစ်ပါသည်။

Resource များအား အသုံးပြုပုံ


Resource များအား ရေးသားရာတွင် အဓိကအားဖြင့် ၂မျိုး ရေးသားနိုင်ပါသည်။ ပဋ္ဌမနည်းမှာ Class အဖြစ်ရေးသားနည်း ဖြစ်ပြီး၊ ဒုတိယနည်းမှာ Properties ဖိုင်တွင် ရေးသားနိုင်ပါသည်။ Class အဖြစ်ရေးသားရာတွင် java.util.ListResourceBundle ၏ Sub Class အနေဖြင့် ရေးသားရန် လိုအပ်ပါသည်။

အထက်ပါနမှုနာတွင် ရေးသာထားသည့် Resource အား Classပုံစံဖြင့် ရေးသားကြည့်ပါမည်။
package com.dtc.rb;

import java.util.ListResourceBundle;

public class resource extends ListResourceBundle {
 
    static Object [][] resource = {
        {"sample","Hello Resource Bundle"}
    };

    @Override
    protected Object[][] getContents() {
        return resource;
    }
}
ListResourceBundle Class အား Extends ပြုလုပ်ရာတွင် getContents Method အား Override ပြုလုပ်ရန်လိုအပ်ပြီး၊ ၎င်း Method အတွင်းမှာ အသုံးပြုမည့် Key နှင့် Value အား တွဲ၍ထားသော Array အား Return လုပ်ရန် လိုအပ်ပါသည်။ အထက်ပါ နမှုနာတွင် sample သည် Key ဖြစ်၍ Hello Resource Bundle သည် တန်ဖိုးဖြစ်ပါသည်။

အခြား Locale တစ်ခုကို ပြောင်း၍ စမ်းသပ်ကြည့်ပါဦးမည်။ မြန်မာ Locale သည် လက်ရှိ Java အပေါ်တွင် မရှိသေးပါသောကြောင့် ဂျပန် Locale ကို သာအသုံးပြု၍ စမ်းသပ်ကြည့်ပါမည်။ အထက်ပါ Class Name အား resource မှ Resource_ja_JP.properties ဟု ပြောင်းကြည့်ပါမည်။ အတွင်းတွင် ရေးသားထားသော စာများအားလည်း ဂျပန်စာဖြင့်ပြောင်းရေးကြည့်ပါမည်။ Properties ဖိုင်အား UTF-8 ပုံစံဖြင့် သိမ်းပါမည်။

Resource_ja_JP.properties
name:高田
age:48
work:プロレスラー

Properties ဖိုင်များသည် ASCII ဖြင့်သာ အသုံးပြုနိုင်သောကြောင့် ဂျပန်စာကို အသုံးပြုနိုင်ရန်အတွက် စာလုံးများအား Unicode အဖြစ်ပြောင်းရန် လိုအပ်ပါသည်။ သို့မဟုတ်ပါက UTF-8 အဖြစ်သိမ်းဆည်းထားပြီး File Reader တွင် Encoding ကို သတ်မှတ်ရန် လိုအပ်ပါသည်။ ဆိုလိုသည်မှာ ResourceBundle#getBundle ၏ တတိယ ပါရာမီတာဖြစ်သော java.util.ResourceBundle.Control အား Unicode အား ဖတ်နိုင်သော Control အဖြစ်ပြောင်း၍ အသုံးပြုရန်လိုအပ်ပါသည်။

UTFControle
package com.dtc.resource;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.ResourceBundle.Control;

public class UTFControle extends Control {

    @Override
    public ResourceBundle newBundle(String baseName, Locale locale,
            String format, ClassLoader loader, boolean reload)
            throws IllegalAccessException, InstantiationException, IOException {

        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, "properties");
        ResourceBundle bundle = null;
        InputStream stream = null;

        if (reload) {
            URL url = loader.getResource(resourceName);
            if (url != null) {
                URLConnection connection = url.openConnection();
                if (connection != null) {
                    connection.setUseCaches(false);
                    stream = connection.getInputStream();
                }
            }
        } else {
            stream = loader.getResourceAsStream(resourceName);
        }
        if (stream != null) {
            try {
                bundle = new PropertyResourceBundle(new InputStreamReader(
                        stream, "UTF-8"));
            } finally {
                stream.close();
            }
        }
        return bundle;
    }

}

ဂျပန် Resource Bundle အား ခေါ်ယူ အသုံးပြုနေသည်မှာ အောက်ပါအတိုင်းဖြစ်ပါသည်။

ResourceTest
package com.dtc.resource;

import java.util.Enumeration;
import java.util.Locale;
import java.util.ResourceBundle;

public class ResourceTest {

    public static void main(String[] args) {
        Locale locale = Locale.JAPAN;
        ResourceBundle bundle = ResourceBundle.getBundle("Resource", locale,
                new UTFControle());

        Enumeration<String> enu = bundle.getKeys();
        while (enu.hasMoreElements()) {
            String key = enu.nextElement();
            System.out.println(key + " : " + bundle.getString(key));
        }
    }
}
အထက် ဖော်ပြပါအတိုင်း Locale.JAPAN အား အသုံးပြု၍ Resource အမည်ရသော Resource အား ရှာဖွေရာတွင် Resource_ja_JP.properties ဖိုင်အား မှန်ကန်စွာ ရှာ ဖွေတွေ့ရှိနိုင်သည်ကို တွေ့ရပါသည်။ ဤနည်းအားဖြင့် အပြည်ပြည်ဆိုင်ရာတွင် အသုံးပြုမည့် အပလီကေးရှင်းများအား ရေးသားရာတွင် Resource များကို နိုင်ငံအလိုက်ပြင်ဆင်ထားခြင်း အားဖြင့် ရေးသားနိုင်မည်ဖြစ်ပါသည်။

ဆက်ပါဦးမည်။ လေးစားစွာဖြင့်။
မင်းလွင်

No comments:

Post a Comment