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

joo.ResourceBundleAwareClassLoader.as Maven / Gradle / Ivy

There is a newer version: 4.1.8
Show newest version
/*
 * Copyright 2009 CoreMedia AG
 *
 * 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 joo {


/**
 * A class loader that provides special treatment of resource bundle classes.
 * It maintains a current locale and loads a locale-specific subclass of any
 * class ending with _properties.
 * 

The locale is saved in and retrieved from a Cookie whose name, path, and domain * can be configured.

*

In your JavaScript code, after including the Jangaroo Runtime, activate * locale-specific resource bundle class loading as follows:

*
 * new joo.ResourceBundleAwareClassLoader(["en", "de"]);
 * 
*

You can create resource bundle classes by creating *_locale.properties * files below the src/main/joo directory. These files are translated to AS3 * code by the Jangaroo properties compiler (Maven goal: properties). * Each resource bundle must consist of properties files for each supported locale, where * the default locale is suppressed. * For example for supported locales ["en", "de"] (which makes "en" * the default locale), you need properties files My.properties and My_de.properties.

*

To change the locale, your application code must call

*
 * joo.ResourceBundleAwareClassLoader.INSTANCE.setLocale(newLocale);
 * 
* * @see #ResourceBundleAwareClassLoader * @see #getLocale * @see #setLocale * * @author Manuel Ohlendorf * @author Frank Wienberg */ public class ResourceBundleAwareClassLoader extends DynamicClassLoader { private static const DAYS_TILL_LOCALE_COOKIE_EXPIRY:int = 10*356; /** * The ResourceBundleAwareClassLoader singleton, which is created or overwritten * by invoking the constructor. * @see #ResourceBundleAwareClassLoader */ public static var INSTANCE:ResourceBundleAwareClassLoader; private var supportedLocales:Array; private var localeCookieName:String; private var localeCookiePath:String; /** * Set before any resource bundle is loaded. * @see #getLocale */ public var localeCookieDomain:String = null; private var preferredLocales:Array; private var locale:String; /** * Create a new ResourceBundleAwareClassLoader with the given supported locales, default locale, * and locale Cookie name, and set it as the default Jangaroo class loader (joo.classLoader) * and as the singleton ResourceBundleAwareClassLoader (INSTANCE). * @param supportedLocales (default: ["en"]) An Array of supported locales (String). * The current locale is guaranteed to be an item of this list. * The first element of this list is used as the default locale to use when all other attempts to determine * a locale fail. * @param localeCookieName (default: "joo.locale") The name of the Cookie to load and store locale * information on the client. * @param localeCookiePath (default: window.location.pathname) The path of the Cookie to load and * store locale information on the client. * @param localeCookieDomain (default: null) The domain of the Cookie to load and store locale * information on the client. * @param preferredLocales the locales preferred by the current user, in order of preference, which will be used * to determine the best supported locale if no locale Cookie is set. * @see joo.classLoader * @see #INSTANCE * @see #getLocale */ public function ResourceBundleAwareClassLoader(supportedLocales:Array = undefined, localeCookieName:String = undefined, localeCookiePath:String = undefined, localeCookieDomain:String = undefined, preferredLocales:Array = undefined) { INSTANCE = this; super(); this.preferredLocales = preferredLocales || localization.preferredLocales || []; this.supportedLocales = supportedLocales || localization.supportedLocales || ["en"]; this.localeCookieName = localeCookieName || localization.localeCookieName || "joo.locale"; this.localeCookiePath = localeCookiePath || localization.localeCookiePath || getQualifiedObject("location.pathname"); this.localeCookieDomain = localeCookieDomain || localization.localeCookieDomain || null; } //noinspection JSUnusedGlobalSymbols public function getSupportedLocales():Array { return supportedLocales.concat(); } public function getDefaultLocale():String { return supportedLocales[0]; } override protected function createClassDeclaration(packageDef:String, metadata:Object, classDef:String, inheritanceLevel:int, memberFactory:Function, publicStaticMethodNames:Array, dependencies:Array):JooClassDeclaration { var cd : JooClassDeclaration = JooClassDeclaration(super.createClassDeclaration(packageDef, metadata, classDef, inheritanceLevel, memberFactory, publicStaticMethodNames, dependencies)); if (cd.fullClassName.match(NativeClassDeclaration.RESOURCE_BUNDLE_PATTERN)) { cd.getDependencies().push(getLocalizedResourceClassName(cd)); } return cd; } //noinspection JSUnusedGlobalSymbols /** * Used internally by code generated by the properties compiler. * In case your want to implement a custom resource bundle, use the following code to * generate a locale-specific instance of your bundle class: *
   * public static const INSTANCE:My_properties = My_properties(ResourceBundleAwareClassLoader.INSTANCE.createSingleton(My_properties));
   * 
* @param resourceBundle the resource bundle class for which the subclass corresponding to the current locale * is to be instantiated. * @return Object an instance of the resource bundle class or the subclass corresponding to the current locale * @see #getLocale */ public function createSingleton(resourceBundle:Class):Object { var cd:NativeClassDeclaration = NativeClassDeclaration(resourceBundle['$class']); var fullLocalizedClassName:String = getLocalizedResourceClassName(cd); var LocalizedResourceBundle:Class = getQualifiedObject(fullLocalizedClassName); return new LocalizedResourceBundle(); } private function readLocaleFromCookie():String { return findSupportedLocale(getCookie(localeCookieName)); } private static function escape(s:String):String { return s.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1"); } private static function getCookie(name:String):String { var cookieKey:String = escape(name); var document:* = getQualifiedObject("document"); var match:Array = document.cookie.match("(?:^|;)\\s*" + cookieKey + "=([^;]*)"); return match ? decodeURIComponent(match[1]) : null; } private static function setCookie(name:String, value:String, path:String = null, expires:Date = null, domain:String = null, secure:Boolean = false):void { var document:* = getQualifiedObject("document"); document.cookie = name + "=" + encodeURIComponent(value || "") + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + (secure ? "; secure" : ""); } private static function getLocaleCookieExpiry():Date { var date:Date = new Date(); date.setTime(date.getTime() + (DAYS_TILL_LOCALE_COOKIE_EXPIRY * 24 * 60 * 60 * 1000)); return date; } private function getLocaleFromPreferredLocales():String { for (var i:int = 0; i < preferredLocales.length; i++) { var preferredLocale:String = findSupportedLocale(preferredLocales[i]); if (preferredLocale) { return preferredLocale; } } return null; } private function readLocaleFromNavigator():String { var navigator:* = getQualifiedObject("navigator"); if (navigator) { var locale:String = navigator['language'] || navigator['browserLanguage'] || navigator['systemLanguage'] || navigator['userLanguage']; if (locale) { return findSupportedLocale(locale.replace(/-/g, "_")); } } return null; } /** * Sets the current locale to the given locale or, if the given locale is not supported, * to the longest match in the supported locales, or the default locale if there is no match. * @param newLocale the locale to use for resource bundle class loading * @return String the supported locale that has actually been set * @see #ResourceBundleAwareClassLoader */ public function setLocale(newLocale:String):String { locale = findSupportedLocale(newLocale); // either create, update or remove (if locale===null) the Cookie: setCookie(localeCookieName, locale, localeCookiePath, locale ? getLocaleCookieExpiry() : Date(0), localeCookieDomain); return getLocale(); // use getter to re-compute fallback logic for locale==null and cache the result } public function findSupportedLocale(locale:String):String { if (!locale) { return null; } // find longest match of locale in supported locales var longestMatch:String = ""; for (var i:int = 0; i < supportedLocales.length; i++) { if (locale.indexOf(supportedLocales[i]) === 0 && supportedLocales[i].length > longestMatch.length) { longestMatch = supportedLocales[i]; } } return longestMatch ? longestMatch : null; } /** * Return the locale currently used for resource bundle class loading. * On the first call of this method, the locale is read from the Cookie given by * localeCookieName (default "joo.locale"), localeCookiePath * (window.location.pathname) and localeCookieDomain * (null). * If there is no such Cookie, the browser's navigator object is asked for its * language. If the locale still is not determined, the defaultLocale is used. * This value if stored using setLocale(). * * @return the locale currently used for resource bundle class loading. * * @see #ResourceBundleAwareClassLoader * @see #setLocale */ public function getLocale():String { if (!locale) { locale = readLocaleFromCookie() || getLocaleFromPreferredLocales() || readLocaleFromNavigator() || getDefaultLocale(); } return locale; } private function getLocalizedResourceClassName(cd:NativeClassDeclaration):String { var localizedResourceClassName:String = cd.fullClassName; var locale:String = getLocale(); if (locale !== getDefaultLocale()) { localizedResourceClassName += "_" + locale; } return localizedResourceClassName; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy