SeamFramework.orgCommunity Documentation

第16章 国際化と地域化およびテーマ

16.1. アプリケーションを国際化する
16.1.1. アプリケーションサーバーの設定
16.1.2. 翻訳されたアプリケーション文字列
16.1.3. その他のエンコーディング設定
16.2. ロケール
16.3. ラベル
16.3.1. ラベルを定義する
16.3.2. ラベルを表示する
16.3.3. Faces メッセージ
16.4. タイムゾーン
16.5. テーマ
16.6. ロケールとテーマ設定のクッキーによる永続化

Seam では容易に国際化されたアプリケーションを作成できます。 まず、 アプリケーションの国際化および地域化に必要とされるすべての段階について見ていきます。 そのあと Seam が同梱するコンポーネントの説明をします。

JEE アプリケーションは数多くのコンポーネントから構成され、 それらのコンポーネントすべてがローカライズを行うアプリケーションに対して正しく設定されていなければなりません。

最初から始めることにします。 1 番目の手順としてデータベースのサーバーとクライアントが使用するロケールに対応する正しい文字エンコーディングを使用していることを確認します。 UTF-8 を使用するのが全般的には多くなります。 この方法については本チュートリアルの範囲外となります。

アプリケーションのすべての メッセージ にも翻訳された文字列が必要となります (例、 ビューのフィールドラベルなど)。 まず、 リソースバンドルが目的の文字エンコーディングを使ってコード化されることを確認する必要があります。 デフォルトでは ASCII が使用されます。 ASCII は多くの言語に十分対応しますが、 すべての言語の文字を提供しているわけではありません。

リソースバンドルは ASCII で作成されなければなりません。 あるいは Unicode 文字の表示に Unicode エスケープのコードを使用します。 バイトコードに対してプロパティファイルをコンパイルしないため使用にセットする文字を JVM に伝える方法がありません。 このため、 ASCII 文字または ASCII 文字にはないエスケープ文字を使用しなければなりません。 \uXXXX を使用するといずれの Java ファイルでも Unicode 文字を表すことができます。 XXXX はその文字を表す 16 進数です。

ネイティブエンコーディングでメッセージのリソースバンドルにラベル (<xlink>ラベル</xlink>) の翻訳を書き込みそのファイルの内容を JDK で提供される native2ascii ツールでエスケープ形式に変換することができます。 このツールはネイティブエンコーディングで記述されたファイルを Unicode エスケープ配列として非 ASCII 文字で表すものに変換します。

このツールの使い方は Java 5 の場合はここ または Java 6 の場合はここ に記載されています。 たとえば、 あるファイルを UTF-8 から変換するには次のようにします。

$ native2ascii -encoding UTF-8 messages_cs.properties > messages_cs_escaped.properties

各ユーザーログインのセッションは、 java.util.Locale インスタンスと関連しています (アプリケーションでは、 locale という名前のコンポーネントとして扱えます)。 通常の環境では、 ロケールのための特別な設定は不要です。 Seam ではアクティブなロケールの決定は単純に JSF に委譲しています。

Seam 設定プロパティの org.jboss.seam.international.localeSelector.languageorg.jboss.seam.international.localeSelector.country そして org.jboss.seam.international.localeSelector.variant によりマニュアルでのロケール設定が 可能 ですが、 これを行う妥当な理由は考え付きません。

しかし、アプリケーションユーザーインタフェースを通じて、 ユーザーにマニュアルでロケール設定を可能とさせることは有用です。 Seam は上記のアルゴリズムによって決定されるロケールをオーバライドする組み込み機能も提供しています。 すべきことは、JSP または、Facelet ページのフォームに以下の断片を追加するだけです。


<h:selectOneMenu value="#{localeSelector.language}">
    <f:selectItem itemLabel="English" itemValue="en"/>
    <f:selectItem itemLabel="Deutsch" itemValue="de"/>
    <f:selectItem itemLabel="Francais" itemValue="fr"/>
</h:selectOneMenu>
<h:commandButton action="#{localeSelector.select}"
    value="#{messages['ChangeLanguage']}"/>

あるいは、faces-config.xml に対応されたすべてのロケールの組み合わせが欲しければ、 以下を使ってください。


<h:selectOneMenu value="#{localeSelector.localeString}">
    <f:selectItems value="#{localeSelector.supportedLocales}"/>
</h:selectOneMenu>
<h:commandButton action="#{localeSelector.select}"
    value="#{messages['ChangeLanguage']}"/>

ユーザーがドロップダウンからアイテムを選択してコマンドボタンをクリックすると、 その後のセッションに対して Seam と JSF のロケールはオーバライドされます。

これにより対応ロケールはどこで定義するのだろうかという疑問が湧いてきます。 一般的には JSF 設定ファイル (/META-INF/faces-config.xml) の <locale-config> エレメントでリソースバンドルに一致するロケール一覧を与えます。 ただし、 Seam のコンポーネント設定のメカニズムは Java EE 提供のそれよりずっとパワフルであることを学んできました。 こうした理由から org.jboss.seam.international.localeConfig という名前の組み込みコンポーネントを使用して対応ロケールおよびサーバーのデフォルトロケールを設定することができます。 これを使うにはまず Seam コンポーネント記述子で Seam の国際パッケージ用の XML 名前空間を宣言します。 次にデフォルトのロケールと対応ロケールを次のように定義します。


<international:locale-config default-locale="fr_CA" supported-locales="en fr_CA fr_FR"/>

必然的にロケールをサポートすることを宣言する場合、 一致するリソースバンドルを与えた方がよいでしょう。 次は言語固有のラベルの定義方法について説明します。

JSF は、ユーザーインタフェースのラベルや説明用テキストの国際化を、 <f:loadBundle /> を使用することによって対応しています。 Seam アプリケーションでもこのアプローチが使用可能です。 代わりに、組み込みの EL 式を利用したテンプレート化ラベルの表示に、 Seam messages コンポーネントを利用することも可能です。

Seam は java.util.ResourceBundle を提供しています (アプリケーションでは org.jboss.seam.core.resourceBundle として利用可能)。 この特殊リソースバンドルを通じて国際化されたラベルを使用可能にする必要があります。 デフォルトでは、 Seam で使用されるリソースバンドルは messages の名称なので messages.propertiesmessages_en.propertiesmessages_en_AU.properties などの名称のファイルにラベルを定義する必要があります。 これらのファイルは通常 WEB-INF/classes ディレクトリに属します。

従って、messages_en.properties では、

Hello=Hello

そして、messages_en_AU.properties では、

Hello=G'day

org.jboss.seam.core.resourceLoader.bundleNames と呼ばれる Seam 設定プロパティによって、 リソースバンドルとして異なる名前を選択することが可能です。 リソースバンドル名の一覧を指定してメッセージの検索をさせる (深さ優先) こともできます。


<core:resource-loader>
    <core:bundle-names>
        <value>mycompany_messages</value>
        <value>standard_messages</value>       
    </core:bundle-names>
</core:resource-loader>

特定のページだけにメッセージを定義したいのであれば、 そのJSFビューIDと同じ名前でリソースバンドルに指定します。 このときIDの最初の / と最後の拡張子を除去します。 つまり /welcome/hello.jsp にのみメッセージを表示したいのであれば、 表示させるメッセージを welcome/hello_en.properties に配置します。

pages.xml に明示的なバンドル名を指定することもできます。


<page view-id="/welcome/hello.jsp" bundle="HelloMessages"/>

これで HelloMessages.properties に定義されたメッセージを /welcome/hello.jsp で使うことができます。

java.util.Timezone のセッションスコープのインスタンス、 名称はorg.jboss.seam.international.timezone とタイムゾーンを変更する Seam コンポーネント、 名称は org.jboss.seam.international.timezoneSelector もあります。 デフォルトでは、タイムゾーンはサーバのデフォルトタイムゾーンです。 タイムゾーンが <f:convertDateTime> を使用して明示的に指定されない限り、 残念ながら JSF 仕様ではすべての日付と時間は UTC を前提としており、UTC として表示されます。 非常に不便なデフォルト動作となります。

Seamはこの動作をオーバーライドし、すべての日付と時刻をデフォルトでSeamタイムゾーンにします。 さらにSeamは、Seamタイムゾーンでの変換を常に行う <s:convertDateTime> タグを提供します。

Seamアプリケーションはまた、とても簡単にスキン変更ができます。 テーマAPIはローカライゼーションAPIにとても似ていますが、 もちろんこれら二つの関心事は直交しており、 ローカライゼーションとテーマの両方をサポートするアプリケーションもあります。

まず、サポートされるテーマのセットを設定します:


<theme:theme-selector cookie-enabled="true">
    <theme:available-themes>
        <value>default</value>
        <value>accessible</value>
        <value>printable</value>
    </theme:available-themes>
</theme:theme-selector>

最初にリストされたテーマがデフォルトテーマであることに注意してください。

テーマは、そのテーマと同じ名前でプロパティファイルに定義されます。 例えば、 default テーマは default.properties に一連のエントリとして定義されます。 例えば、default.properties は以下のように定義します。

css ../screen.css
template /template.xhtml

通常、 テーマリソースバンドルのエントリは CSS スタイルや画像へのパスや facelet テンプレートの名前になるでしょう (通常はテキストであるローカライゼーションリソースバンドルとは違って)。

これでJSPやfaceletページにおいてこれらのエントリを使えます。 例えば、faceletページでスタイルシートを適用するには:


<link href="#{theme.css}" rel="stylesheet" type="text/css" />

あるいは、サブディレクトリにページ定義が存在している場合は次のようになります。


<link href="#{facesContext.externalContext.requestContextPath}#{theme.css}" 
    rel="stylesheet" type="text/css" />

最も強力な使い方として、 faceletでは <ui:composition> によってテンプレートを適用できます。


<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    template="#{theme.template}">

ちょうどロケールセレクタのように、 ユーザーが自由にテーマを変更できるよう、組み込みのテーマセレクタがあります。


<h:selectOneMenu value="#{themeSelector.theme}">
    <f:selectItems value="#{themeSelector.themes}"/>
</h:selectOneMenu>
<h:commandButton action="#{themeSelector.select}" value="Select Theme"/>

ロケールセレクタ、テーマセレクタ、タイムゾーンセレクタはすべて、 ロケールとテーマ設定をクッキーに永続化することをサポートしています。 単純に components.xmlcookie-enabled プロパティを設定します。


<theme:theme-selector cookie-enabled="true">
    <theme:available-themes>
        <value>default</value>
        <value>accessible</value>
        <value>printable</value>
    </theme:available-themes>
</theme:theme-selector>

<international:locale-selector cookie-enabled="true"/>