All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nablarch.common.web.handler.threadcontext.HttpLanguageAttribute Maven / Gradle / Ivy

The newest version!
package nablarch.common.web.handler.threadcontext;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Pattern;

import nablarch.common.handler.threadcontext.LanguageAttribute;
import nablarch.core.util.StringUtil;
import nablarch.fw.ExecutionContext;
import nablarch.fw.Request;
import nablarch.fw.web.HttpRequest;
import nablarch.fw.web.servlet.ServletExecutionContext;

/**
 * スレッドコンテキストに保持する言語属性をHTTPヘッダ(Accept-Language)から取得するクラス。
 * @author Kiyohito Itoh
 */
public class HttpLanguageAttribute extends LanguageAttribute {
    
    /** サポート対象の言語 */
    private Set supportedLanguages;
    
    /**
     * サポート対象の言語を設定する。
     * @param supportedLanguages サポート対象の言語
     */
    public void setSupportedLanguages(String... supportedLanguages) {
        this.supportedLanguages = new HashSet(Arrays.asList(supportedLanguages));
    }
    
    /**
     * コンテキストスレッドに格納するこのプロパティの値を返す。 
     * 

* {@link #getLocale(HttpRequest, ServletExecutionContext)}に処理を委譲する。 * @param req リクエスト * @param ctx 実行コンテキスト * @return サポート対象の言語 */ public Object getValue(Request req, ExecutionContext ctx) { return getLocale((HttpRequest) req, (ServletExecutionContext) ctx); } /** * スレッドコンテキストに保持する言語属性を返す。 *

     * このクラスの実装では以下の処理を行う。
     *   
     * 1.Accept-Languageヘッダから言語の取得を試みる。
     *   ({@link #getAcceptLanguage(HttpRequest, ServletExecutionContext)})
     * 
     *   サポート対象の言語が取得できた場合は取得できた言語を返す。
     *   サポート対象の言語が取得できない場合は2.に進む。
     * 
     * 2.デフォルトの言語を返す。
     *   ({@link LanguageAttribute#getValue(Request, ExecutionContext)})
     * 
     * 
* @param req リクエスト * @param ctx 実行コンテキスト * @return サポート対象の言語 */ protected Locale getLocale(HttpRequest req, ServletExecutionContext ctx) { String acceptLanguage = getAcceptLanguage(req, ctx); if (acceptLanguage != null) { return new Locale(acceptLanguage); } return (Locale) super.getValue(req, ctx); } /** カンマを表す正規表現のパターン */ private static final Pattern COMMA_PATTERN = Pattern.compile(","); /** * "Accept-Language"ヘッダをパースし、一番優先度が高いサポート対象の言語を返す。 * @param req リクエスト * @param ctx 実行コンテキスト * @return サポート対象の言語。サポート対象の言語が取得できない場合はnull。 */ protected String getAcceptLanguage(HttpRequest req, ServletExecutionContext ctx) { String acceptLanguages = ctx.getServletRequest().getHeader("Accept-Language"); if (StringUtil.isNullOrEmpty(acceptLanguages)) { // "Accept-Language"ヘッダが存在しない場合。 return null; } // "Accept-Language"ヘッダをパースし、一番優先度が高い言語を探す。 String language = null; double qualityValue = -1; for (String acceptLanguage : COMMA_PATTERN.split(acceptLanguages)) { String candidateLanguage; // レンジ指定に応じて言語タグを取得する。 int languageRangeIndex = acceptLanguage.indexOf(";q="); if (languageRangeIndex == -1) { candidateLanguage = acceptLanguage; } else { candidateLanguage = acceptLanguage.substring(0, languageRangeIndex); } // 言語タグからISO-639(2桁の言語)以外を捨てる。 candidateLanguage = candidateLanguage.trim(); int subTagIndex = candidateLanguage.indexOf("-"); if (subTagIndex != -1) { candidateLanguage = candidateLanguage.substring(0, subTagIndex); } if (!isSupportedLanguage(candidateLanguage)) { // サポート対象外の言語は飛ばす。 continue; } // レンジ指定に応じて品質値(優先度、最小値=0、最大値=1)を取得する。 double candidateQualityValue; if (languageRangeIndex == -1) { // 品質値の規定は1。 candidateQualityValue = 1.0; } else { try { candidateQualityValue = Double.parseDouble(acceptLanguage.substring(languageRangeIndex + 3).trim()); } catch (NumberFormatException e) { // 品質値(重み)の指定が不正なため飛ばす。 // HTTPヘッダーの値は不正値が指定されてくる可能性があるため、 // 不正な値の場合でも障害とせずに読み飛ばす。 continue; } } if (candidateQualityValue == 1.0) { // 品質値の最大値は1のため決まり。 return candidateLanguage; } else if (qualityValue < candidateQualityValue) { // 品質値が高い場合のみ入れ替え。 // 品質値が等しい場合、記述順とするため入れ替えなし。 language = candidateLanguage; qualityValue = candidateQualityValue; } } // 一番優先度が高いものを返す。 return language != null ? language : null; } /** * サポート対象の言語か否かを判定する。 * @param language 言語 * @return サポート対象の言語の場合はtrue */ protected boolean isSupportedLanguage(String language) { return supportedLanguages.contains(language); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy