/** * Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jfinal.i18n; import com.jfinal.aop.Interceptor; import com.jfinal.aop.Invocation; import com.jfinal.core.Const; import com.jfinal.core.Controller; import com.jfinal.kit.StrKit; import com.jfinal.render.Render; /** * I18nInterceptor is used to change the locale by request para, * and it is also switch the view or pass Res object to the view. * * you can extends I18nInterceptor and override the getLocaleParaName() and getResName() * to customize configuration for your own i18n Interceptor */ public class I18nInterceptor implements Interceptor { private String localeParaName = "_locale"; private String resName = "_res"; private boolean isSwitchView = false; public I18nInterceptor() { } public I18nInterceptor(String localeParaName, String resName) { if (StrKit.isBlank(localeParaName)) { throw new IllegalArgumentException("localeParaName can not be blank."); } if (StrKit.isBlank(resName)) { throw new IllegalArgumentException("resName can not be blank."); } this.localeParaName = localeParaName; this.resName = resName; } public I18nInterceptor(String localeParaName, String resName, boolean isSwitchView) { this(localeParaName, resName); this.isSwitchView = isSwitchView; } public I18nInterceptor(boolean isSwitchView) { this.isSwitchView = isSwitchView; } /** * Return the localeParaName, which is used as para name to get locale from the request para and the cookie. */ protected String getLocaleParaName() { return localeParaName; } /** * Return the resName, which is used as attribute name to pass the Res object to the view. */ protected String getResName() { return resName; } /** * Return the baseName, which is used as base name of the i18n resource file. */ protected String getBaseName() { return I18n.defaultBaseName; } /** * 1: use the locale from request para if exists. change the locale write to the cookie * 2: use the locale from cookie para if exists. * 3: use the default locale * 4: use setAttr(resName, resObject) pass Res object to the view. */ public void intercept(Invocation inv) { Controller c = inv.getController(); String localeParaName = getLocaleParaName(); String locale = c.getPara(localeParaName); if (StrKit.notBlank(locale)) { // change locale, write cookie c.setCookie(localeParaName, locale, Const.DEFAULT_I18N_MAX_AGE_OF_COOKIE); } else { // get locale from cookie and use the default locale if it is null locale = c.getCookie(localeParaName); if (StrKit.isBlank(locale)) locale = I18n.defaultLocale; } inv.invoke(); if (isSwitchView) { switchView(locale, c); } else { Res res = I18n.use(getBaseName(), locale); c.setAttr(getResName(), res); } } /** * 在有些 web 系统中,页面需要国际化的文本过多,并且 css 以及 html 也因为际化而大不相同, * 对于这种应用场景先直接制做多套同名称的国际化视图,并将这些视图以 locale 为子目录分类存放, * 最后使用本拦截器根据 locale 动态切换视图,而不必对视图中的文本逐个进行国际化切换,省时省力。 */ public void switchView(String locale, Controller c) { Render render = c.getRender(); if (render != null) { String view = render.getView(); if (view != null) { if (view.startsWith("/")) { view = "/" + locale + view; } else { view = locale + "/" + view; } render.setView(view); } } } }