Java tutorial
package act.i18n; /*- * #%L * ACT Framework * %% * Copyright (C) 2014 - 2017 ActFramework * %% * 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. * #L% */ import act.apidoc.Description; import act.app.ActionContext; import act.conf.AppConfig; import act.controller.Controller; import org.joda.time.DateTime; import org.osgl.http.H; import org.osgl.mvc.annotation.PostAction; import org.osgl.util.S; import java.util.Locale; import javax.inject.Inject; /** * Responsible for setting up client Locale for the context * <p> * The client locale info is resolved in the following sequence: * 1. check the request parameter by configured name * 2. check the session variable * 3. check the cookie value * 4. check the `Accept-Language` header * 5. use the server locale */ public class LocaleResolver { private static final String KEY = "__locale__"; private static final int COOKIE_TTL = 60 * 60 * 24 * 7; private ActionContext context; private AppConfig config; private boolean enabled; private Locale locale; private boolean reset; private boolean resolvedFromParam; @Description("Set locale to the session. The parameter name is configured with default value act_locale, it must be put as a query parameter instead of form field") @PostAction("i18n/locale") public static void updateLocale(H.Request request) { // there is no logic needed as locale has been processed built-in logic already String s = request.header(H.Header.Names.REFERER); if (S.notBlank(s)) { throw Controller.Util.redirect(s); } } @Inject public LocaleResolver(ActionContext context) { AppConfig config = context.config(); this.enabled = config.i18nEnabled(); if (!this.enabled) { return; } this.context = context; this.config = config; } public void resolve() { if (!enabled) { return; } Locale locale = resolveFromParam(); if (!reset && null == locale) { locale = resolveFromSessionOrCookie(); } if (null == locale) { locale = resolveFromHeader(); } if (null == locale) { locale = resolveFromServer(); } context.locale(locale); this.locale = locale; } public void dissolve() { if (!shouldWriteLocaleCookie()) { return; } String cookieName = config.localeCookieName(); Locale locale = context.locale(); if (null == locale) { locale = this.locale; } String localeStr = locale.toString(); H.Session session = context.session(); if (null != session) { if (reset) { session.remove(KEY); } else { session.put(KEY, localeStr); } } H.Cookie cookie = new H.Cookie(cookieName, localeStr); cookie.domain(config.cookieDomain()); cookie.path("/"); // in case we have resolved locale from cookie and we shouldn't write cookie anymore, we need to clear it cookie.maxAge(reset ? -1 : COOKIE_TTL); if (reset) { cookie.expires(DateTime.now().minusDays(1).toDate()); } context.resp().addCookie(cookie); } private boolean shouldWriteLocaleCookie() { /* * 1. i18n must be enabled * 2. anyone of the following condition is true * 2.1 resolved from param * 2.2 the current locale does not match the locale resolved originally (meaning programmatically updated locale) * 2.3 reset is true (meaning session and cookie should be cleared) */ return enabled && (reset || resolvedFromParam || locale != context.locale()); } private Locale resolveFromSessionOrCookie() { Locale locale = null; H.Session session = context.session(); if (null != session) { locale = parseStr(session.get(KEY)); } if (null == locale) { H.Cookie cookie = context.cookie(config.localeCookieName()); locale = null == cookie ? null : parseStr(cookie.value()); } return locale; } private Locale resolveFromParam() { String s = context.paramValwithoutBodyParsing(config.localeParamName()); Locale locale = parseStr(s); if (null != locale) { resolvedFromParam = true; } return locale; } private Locale resolveFromHeader() { return context.req().locale(); } private Locale resolveFromServer() { return config.locale(); } private Locale parseStr(String val) { if (null == val) { return null; } if ("default".equals(val)) { reset = true; return null; } String[] sa = val.trim().split("[-_]"); int len = sa.length; switch (len) { case 3: return new Locale(sa[0], sa[1], sa[2]); case 2: return new Locale(sa[0], sa[1]); default: return new Locale(sa[0]); } } public static void main(String[] args) { System.out.println(Locale.US.toLanguageTag()); } }