Thursday June 28, 2007 | Just my 2¢ Naoto Sato's Weblog |
|
All Languages |
English Only |
日本語のみ JDKのアプリケーションで通貨に関連したことを行おうとした場合、通常はjava.util.Currencyクラスを使います。このクラスを使うと、ある国で使われている通貨や、その通貨のローカライズされたシンボルがなんであるかを調べることが出来ます。このような情報を提供するためにJDKは内部にISO 4217標準に基づいた通貨のデータを持っています。ところがこのISO 4217のデータ、いろんな理由(たとえばデノミネーションとか)でしばしば管理機関によってアップデートがかかるんですが、JDKで持っている通貨のデータを常にこのISO 4217のデータに合わせておくことは通貨を扱うアプリケーションには非常に重要です。もし実際の通貨とJDKの通貨データに整合性がない場合、これらの金融アプリケーションのトランザクションに重大な問題が生じるからです。(前に書いたトルコのお菓子のエントリーが良い例(すいませんが英語です)かも) さて、現在のJDKの通貨サポートの問題点の一つに「通貨データが"lib/rt.jar"の中にクラスファイルとして存在している」というのがあります。なぜこれが問題か。というのもISO 4217のデータに変更があった場合(例えばスロベニアがユーロに移行したとか)、常にrt.jarをアップデートしなければなりません。この事実はたとえばお客さんが通貨データだけをアップデートしたい時でも、常にJDK全体をアップグレードしなければならない事を示しています。TimeZoneのデータも同様な位置づけにあるんですが、TimeZoneのデータは既に隔離されていて、個別にアップデート可能になっています。 で、このブログエントリー、何を言いたいかというとJDK7ではこの問題はもう起こらなくなります。というのも必要な変更のチェックインをつい最近完了したんで、もうしばらくするとOpenJDK経由でアクセスできるようになるはずです。変更後では通貨データは"<JAVA_HOME>/lib"の下に"currency.data"というバイナリファイルとして個別に置かれます。なのでJDKアップデートリリースとは別のサイクルでこの通貨データをアップデートすることが可能になるはずです。さらにボーナス機能として、ユーザーがプロパティファイルでこの通貨データの内容を上書きすることも出来ます。"<JAVA_HOME>/lib/currency.properties"というファイルを作って、その中に"key=value"というペア("key"はISO 3166国コード、"value"は3文字通貨コード、3桁数値コード、それにマイナー・ユニットをカンマで区切った物)を書いておけば、"key"で指定した国の通貨のデータを上書きできます。たとえば"JP=JPZ,999,2"というエントリーは、日本の通貨データを上書きします。 この通貨の拡張に加えて、いくつかのAPIも実装しました。まず初めはJDKで定義されているすべてのCurrencyインスタンスを列挙する機能: public static Set<Currency> getAvailableCurrencies() それからISO 4217の数値通貨コードを取得する機能: public int getNumericCode() 最後にCurrencyインスタンスのディスプレイ用の名称取得機能。例えば日本の通貨は、getSymbol()すると「¥」ですが、このAPIは「日本円」を返します(ロケールが日本の場合)。 public String getDisplayName() public String getDisplayName(Locale displayLocale) このAPIの最初の実装は英語、フランス語、ドイツ語、イタリア語、日本語、韓国語、中国語(簡体字)、スペイン語、スウェーデン語、それに中国語(繁体字)の10のロケール用にローカライズされた通貨のディスプレイ用名称を返すことが出来ます。 さらにこれに応じてjava.util.spi.CurrencyNameProviderにも新たなSPIを追加しました。上記10言語以外に対応したい場合に、このSPIを実装することでどんな言語にもローカライズ可能です。
以上が今回実装した拡張の概要です。これで開発者の皆さんの苦労が少しでも減ると良いんですけどね。今回実はデモも一緒に載せたかったんですが、さすがにまだ出回ってないビルド用のデモは載せられないんでパスです。あしからず。 (2007-06-28 15:55:11.0) PermalinkIn the JDK, applications can use java.util.Currency class to deal with currencies. They can query what currency is used in a given country, or what localized symbol is used for that currency in a particular locale. To provide applications with those currency information, the JDK contains the currency data that is based on the ISO 4217 standard. From time to time, due to a variety of reasons, the ISO 4217 data are often updated by the maintenance agency. Keeping up with these updates in the JDK is critical for applications that deal with currencies, such as a banking application. Otherwise, those applications would result in a wrong financial transaction (cf. see my old entry regarding the Turkish pastry story here) Now, one of the issues in the current JDK's currency support is that the currency data is embedded in "lib/rt.jar" as a class file. So every time the ISO 4217 maintenance agency releases a currency update, such as Slovenia switching to Euro currency, the rt.jar file needs to be updated. This makes it impossible for customers to replace just the currency data portion when needed, without upgrading the whole JDK. This issue is analogous to the TimeZone data being separated from the JDK class files, and they can be upgraded separately. The purpose of this blog entry is to announce that this will no longer be an issue in the JDK7, as I have just checked-in the necessary changes for this issue (woohoo!), which will soon be public in the OpenJDK build. In the new structure, the currency data is separately placed in "<JAVA_HOME>/lib" directory as a binary file "currency.data", which can be replaced not in sync with the JDK update release schedule. One added feature to this is that you could even provide your own properties file to override the contents in the currency data file. If you create a properties file as "<JAVA_HOME>/lib/currency.properties", which contains "key=value" pairs where the "key" is a ISO 3166 country code, and the "value" consists of three-letter currency code, three-digit numeric code, and the minor unit (separeted by a comma), it would override the currency data for that country designated by the "key". For example if it has "JP=JPZ,999,2", this would override the Japanese currency data. Also, along with this Currency enhancement, I added a couple of new APIs. First one is to acquire all the available currencies in the JDK as follows: public static Set<Currency> getAvailableCurrencies() Next one is to return a numeric ISO 4217 code for a Currency instance: public int getNumericCode() The last one is to return the display name for a Currency instance. Instead of getSymbol() returning "$" for the US Dollar ("USD"), this API returns "US Dollar" in the "US" locale. public String getDisplayName() public String getDisplayName(Locale displayLocale) The initial release of this API contains localized currency names for 10 locales, i.e., English, French, German, Italian, Japanese, Korean, Simplified Chinese, Spanish, Swedish, and Traditional Chinese. I also added an SPI in java.util.spi.CurrencyNameProvider for the languages other than the above, so that one could provide localized display names in any language:
These are the changes that I have checked in, and I hope this is useful for developers. I would have liked to provide a working demo, but it's not possible to do it with a yet released build :-) (2007-06-28 14:55:06.0) Permalink Comments [15] |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||