//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You 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 mx.resources { import flash.events.Event; import flash.events.EventDispatcher; import flash.events.FocusEvent; import flash.events.IEventDispatcher; import flash.events.TimerEvent; import flash.system.ApplicationDomain; import flash.system.Capabilities; import flash.system.SecurityDomain; import flash.utils.Dictionary; import flash.utils.Timer; import mx.core.IFlexModuleFactory; import mx.core.mx_internal; import mx.core.Singleton; import mx.events.FlexEvent; import mx.events.ModuleEvent; import mx.events.ResourceEvent; import mx.managers.SystemManagerGlobals; import mx.modules.IModuleInfo; import mx.modules.ModuleManager; import mx.utils.StringUtil; use namespace mx_internal; /** * @copy mx.resources.IResourceManager#change * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="change", type="flash.events.Event")] [ExcludeClass] /** * @private * This class provides an implementation of the IResourceManager interface. * The IResourceManager and IResourceBundle interfaces work together * to provide internationalization support for Flex applications. * *

A single instance of this class manages all localized resources * for a Flex application.

* * @see mx.resources.IResourceManager * @see mx.resources.IResourceBundle */ public class ResourceManagerImpl extends EventDispatcher implements IResourceManager { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Class variables // //-------------------------------------------------------------------------- /** * @private * The sole instance of the ResourceManager. */ private static var instance:IResourceManager; //-------------------------------------------------------------------------- // // Class methods // //-------------------------------------------------------------------------- /** * Gets the single instance of the ResourceManagerImpl class. * This object manages all localized resources for a Flex application. * * @return An object implementing IResourceManager. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public static function getInstance():IResourceManager { if (!instance) instance = new ResourceManagerImpl(); return instance; } //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function ResourceManagerImpl() { super(); if (SystemManagerGlobals.topLevelSystemManagers.length) { if (SystemManagerGlobals.topLevelSystemManagers[0].currentFrame == 1) { ignoreMissingBundles = true; SystemManagerGlobals.topLevelSystemManagers[0]. addEventListener(Event.ENTER_FRAME, enterFrameHandler); } } var info:Object = SystemManagerGlobals.info; if (info) processInfo(info, false); ignoreMissingBundles = false; if (SystemManagerGlobals.topLevelSystemManagers.length) SystemManagerGlobals.topLevelSystemManagers[0]. addEventListener(FlexEvent.NEW_CHILD_APPLICATION, newChildApplicationHandler); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private * * Whether or not to throw an error. */ private var ignoreMissingBundles:Boolean; /** * @private * * The dictionary to hold all of the weak reference resource bundles. */ private var bundleDictionary:Dictionary; /** * @private * A map whose keys are locale strings like "en_US" * and whose values are "bundle maps". * A bundle map is a map whose keys are bundle names * like "SharedResources" and whose values are ResourceBundle instances. * You can get to an individual resource value like this: * localeMap["en_US"]["SharedResources"].content["currencySymbol"] */ private var localeMap:Object = {}; /** * @private * A map whose keys are URLs for resource modules that have been loaded * and whose values are ResourceModuleInfo instances for those modules. */ private var resourceModules:Object = {}; /** * @private */ private var initializedForNonFrameworkApp:Boolean = false; //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // localeChain //---------------------------------- /** * @private * Storage for the localeChain property. */ private var _localeChain:Array /* of String */; /** * @copy mx.resources.IResourceManager#localeChain * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get localeChain():Array /* of String */ { return _localeChain; } /** * @private */ public function set localeChain(value:Array /* of String */):void { _localeChain = value; update(); } //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * @private * This method is called by the SystemManager class of an Application * when the application starts. * It is also called by the FlexModuleFactory class of a code module * when that module gets loaded. * * The MXML compiler autogenerated code which set the * "compiledLocales" and "compiledResourceBundleNames" properties * of the info() Object required by the IFlexModuleFactory * interface that these classes implement. * These two properties together indicate which resource bundle * classes the MXML compiler autogenerated and linked into the * application or module. * * The "compiledLocales" property has been set to the locales * which were specified at compile time using the -locale option. * For example, if you compile with -locale=en_US,ja_JP * then the "compiledLocales" property is the array [ "en_US", "ja_JP" ]. * * The "compiledResourceBundleNames" property has been set * to the names of the resource bundles which are used by * the application or module, as determined by the compiler * from [ResourceBundle] metadata and ~~Resource() directives. * For example, if the classes in the application or module * declare that they use resource bundles named "core" and "MyApp", * then the "compiledResourceBundleNames" property is the array * [ "core", "MyApp" ]. * * The compiler autogenerated a ResourceBundle subclass for each * (locale, bundle name) pair. * For example, with the above locales and bundle names, * there would be four classes: * en_US$core_properties * en_US$MyApp_properties * ja_JP$core_properties * ja_JP$MyApp_properties * * This method creates one instance of each such class * and installs it into the ResourceManager with addResourceBundle(). * If a bundle for a given locale and bundle name already exists * in the ResourceManager already exists, it does not get replaced. * This can happen when a code module gets loaded into an application. * * When sub-applications and modules install their resource bundles * they set useWeakReference = true. Any new resource bundles they * create will be weak referenced by the ResourceManager. The * sub-application or module will then provide a hard reference * to the returned Array of resource bundles to keep them from * being garbage collected. */ public function installCompiledResourceBundles( applicationDomain:ApplicationDomain, locales:Array /* of String */, bundleNames:Array /* of String */, useWeakReference:Boolean = false):Array { //trace("locales", locales); //trace("bundleNames", bundleNames); var bundles:Array = []; var bundleCount:uint = 0; var n:int = locales ? locales.length : 0; var m:int = bundleNames ? bundleNames.length : 0; // Loop over the locales. for (var i:int = 0; i < n; i++) { var locale:String = locales[i]; // Loop over the bundle names. for (var j:int = 0; j < m; j++) { var bundleName:String = bundleNames[j]; var bundle:IResourceBundle = installCompiledResourceBundle( applicationDomain, locale, bundleName, useWeakReference); if (bundle) bundles[bundleCount++] = bundle; } } return bundles; } /** * @private */ private function installCompiledResourceBundle( applicationDomain:ApplicationDomain, locale:String, bundleName:String, useWeakReference:Boolean = false):IResourceBundle { var packageName:String = null; var localName:String = bundleName; var colonIndex:int = bundleName.indexOf(":"); if (colonIndex != -1) { packageName = bundleName.substring(0, colonIndex); localName = bundleName.substring(colonIndex + 1); } // If a bundle with that locale and bundle name already exists // in the ResourceManager, don't replace it. // If we want to install a weakReferenceDictionary then don't rely on // a weak reference dictionary because it may go way when the // application goes away. var resourceBundle:IResourceBundle = getResourceBundleInternal(locale, bundleName, useWeakReference); if (resourceBundle) return resourceBundle; // The autogenerated resource bundle classes produced by the // mxmlc and compc compilers have names that incorporate // the locale and bundle name, such as "en_US$core_properties". var resourceBundleClassName:String = locale + "$" + localName + "_properties"; if (packageName != null) resourceBundleClassName = packageName + "." + resourceBundleClassName; // Find the bundle class by its name. // We do a hasDefinition() check before calling getDefinition() // because getDefinition() will throw an RTE // if the class doesn't exist. var bundleClass:Class = null; if (applicationDomain.hasDefinition(resourceBundleClassName)) { bundleClass = Class(applicationDomain.getDefinition( resourceBundleClassName)); } if (!bundleClass) { resourceBundleClassName = bundleName; if (applicationDomain.hasDefinition(resourceBundleClassName)) { bundleClass = Class(applicationDomain.getDefinition( resourceBundleClassName)); } } // In case we linked against a Flex 2 SWC, look for the old // class name. if (!bundleClass) { resourceBundleClassName = bundleName + "_properties"; if (applicationDomain.hasDefinition(resourceBundleClassName)) { bundleClass = Class(applicationDomain.getDefinition( resourceBundleClassName)); } } if (!bundleClass) { if (ignoreMissingBundles) return null; throw new Error( "Could not find compiled resource bundle '" + bundleName + "' for locale '" + locale + "'."); } // Create an instance of the bundle class. resourceBundle = ResourceBundle(new bundleClass()); // In case we just created a ResourceBundle from a Flex 2 SWC, // set its locale and bundleName, because the old constructor // didn't used to do this. ResourceBundle(resourceBundle)._locale = locale; ResourceBundle(resourceBundle)._bundleName = bundleName; // Add that resource bundle instance to the ResourceManager. addResourceBundle(resourceBundle, useWeakReference); return resourceBundle; } // FocusEvent is used just so we can add a relatedObject private function newChildApplicationHandler(event:FocusEvent):void { var info:Object = event.relatedObject["info"](); var weakReference:Boolean = false; if ("_resourceBundles" in event.relatedObject) weakReference = true; // If the application has a "_resourceBundles" object for us to put // the bundles into then we will. Otherwise have the ResourceManager // create a hard reference to the resources. var bundles:Array = processInfo(info, weakReference); if (weakReference) event.relatedObject["_resourceBundles"] = bundles; } private function processInfo(info:Object, useWeakReference:Boolean):Array { var compiledLocales:Array = info["compiledLocales"]; ResourceBundle.locale = compiledLocales != null && compiledLocales.length > 0 ? compiledLocales[0] : "en_US"; // The FlashVars of the SWF's HTML wrapper, // or the query parameters of the SWF URL, // can specify the ResourceManager's localeChain. var localeChainList:String = SystemManagerGlobals.parameters["localeChain"]; if (localeChainList != null && localeChainList != "") localeChain = localeChainList.split(","); var applicationDomain:ApplicationDomain = info["currentDomain"]; var compiledResourceBundleNames:Array /* of String */ = info["compiledResourceBundleNames"]; var bundles:Array = installCompiledResourceBundles( applicationDomain, compiledLocales, compiledResourceBundleNames, useWeakReference); // If the localeChain wasn't specified in the FlashVars of the SWF's // HTML wrapper, or in the query parameters of the SWF URL, // then initialize it to the list of compiled locales, // sorted according to the system's preferred locales as reported by // Capabilities.languages or Capabilities.language. // For example, if the applications was compiled with, say, // -locale=en_US,ja_JP and Capabilities.languages reports [ "ja-JP" ], // set the localeChain to [ "ja_JP" "en_US" ]. if (!localeChain) initializeLocaleChain(compiledLocales); return bundles; } /** * @copy mx.resources.IResourceManager#initializeLocaleChain() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function initializeLocaleChain(compiledLocales:Array):void { localeChain = LocaleSorter.sortLocalesByPreference( compiledLocales, getSystemPreferredLocales(), null, true); } /** * @copy mx.resources.IResourceManager#loadResourceModule() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function loadResourceModule(url:String, updateFlag:Boolean = true, applicationDomain:ApplicationDomain = null, securityDomain:SecurityDomain = null): IEventDispatcher { var moduleInfo:IModuleInfo = ModuleManager.getModule(url); // Create the per-load IEventDispatcher that we'll return. var resourceEventDispatcher:ResourceEventDispatcher = new ResourceEventDispatcher(moduleInfo); // Set up a handler for the "ready" event from the module. // We use a local Function rather than a method // so that it can access the 'update' argument. var readyHandler:Function = function(event:ModuleEvent):void { //trace("readyHandler"); var resourceModule:* = // IResourceModule event.module.factory.create(); //dumpResourceModule(resourceModule); resourceModules[event.module.url].resourceModule = resourceModule; if (updateFlag) update(); } moduleInfo.addEventListener(ModuleEvent.READY, readyHandler, false, 0, true); // Set up a handler for the "error" event from the module. // We use a local Function rather than a method // for symmetry with the readyHandler. var errorHandler:Function = function(event:ModuleEvent):void { var message:String = "Unable to load resource module from " + url; if (resourceEventDispatcher.willTrigger(ResourceEvent.ERROR)) { var resourceEvent:ResourceEvent = new ResourceEvent( ResourceEvent.ERROR, event.bubbles, event.cancelable); resourceEvent.bytesLoaded = 0; resourceEvent.bytesTotal = 0; resourceEvent.errorText = message; resourceEventDispatcher.dispatchEvent(resourceEvent); } else { throw new Error(message); } } moduleInfo.addEventListener(ModuleEvent.ERROR, errorHandler, false, 0, true); resourceModules[url] = new ResourceModuleInfo(moduleInfo, readyHandler, errorHandler); // This Timer gives the loadResourceModules() caller a chance // to add event listeners to the return value, before the module // is loaded. // We use a local Function for the timerHandler rather than a method // so that it can access the 'moduleInfo' local var. var timer:Timer = new Timer(0); var timerHandler:Function = function(event:TimerEvent):void { timer.removeEventListener(TimerEvent.TIMER, timerHandler); timer.stop(); //trace("loading"); // Start loading the module. moduleInfo.load(applicationDomain, securityDomain); } timer.addEventListener(TimerEvent.TIMER, timerHandler, false, 0, true); timer.start(); return resourceEventDispatcher; } /** * @copy mx.resources.IResourceManager#unloadResourceModule() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function unloadResourceModule(url:String, update:Boolean = true):void { // Get the resource module info. var rmi:ResourceModuleInfo = resourceModules[url]; if (!rmi) return; if (rmi.resourceModule) { // Get the bundles in this module. var bundles:Array = rmi.resourceModule.resourceBundles; if (bundles) { var n:int = bundles.length; for (var i:int = 0; i < n; i++) { // Remove each bundle. var locale:String = bundles[i].locale; var bundleName:String = bundles[i].bundleName; removeResourceBundle(locale, bundleName); } } } // Remove all links to the module. resourceModules[url] = null; delete resourceModules[url]; // Unload the module. rmi.moduleInfo.unload(); // Update if necessary. if (update) this.update(); } /** * @copy mx.resources.IResourceManager#addResourceBundle() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function addResourceBundle(resourceBundle:IResourceBundle, useWeakReference:Boolean = false):void { var locale:String = resourceBundle.locale; var bundleName:String = resourceBundle.bundleName; if (!localeMap[locale]) localeMap[locale] = {}; if (useWeakReference) { if (!bundleDictionary) { bundleDictionary = new Dictionary(true); } bundleDictionary[resourceBundle] = locale + bundleName; localeMap[locale][bundleName] = bundleDictionary; } else { localeMap[locale][bundleName] = resourceBundle; } } /** * @copy mx.resources.IResourceManager#getResourceBundle() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getResourceBundle(locale:String, bundleName:String):IResourceBundle { return getResourceBundleInternal(locale, bundleName, false); } /** * @private * * @param ignoreWeakReferenceBundles if true, do not search weak * reference bundles. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ private function getResourceBundleInternal(locale:String, bundleName:String, ignoreWeakReferenceBundles:Boolean):IResourceBundle { var bundleMap:Object = localeMap[locale]; if (!bundleMap) return null; var bundle:IResourceBundle = null; var bundleObject:Object = bundleMap[bundleName]; if (bundleObject is Dictionary) { if (ignoreWeakReferenceBundles) return null; var localeBundleNameString:String = locale + bundleName; for (var obj:Object in bundleObject) { if (bundleObject[obj] == localeBundleNameString) { bundle = obj as IResourceBundle; break; } } } else { bundle = bundleObject as IResourceBundle; } return bundle; } /** * @copy mx.resources.IResourceManager#removeResourceBundle() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function removeResourceBundle(locale:String, bundleName:String):void { // Remove the specified bundle. delete localeMap[locale][bundleName]; // If that leaves a locale node with no bundles, // delete the locale node. if (getBundleNamesForLocale(locale).length == 0) delete localeMap[locale]; } /** * @copy mx.resources.IResourceManager#removeResourceBundlesForLocale() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function removeResourceBundlesForLocale(locale:String):void { delete localeMap[locale]; } /** * @copy mx.resources.IResourceManager#update() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function update():void { dispatchEvent(new Event(Event.CHANGE)); } /** * @copy mx.resources.IResourceManager#getLocales() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getLocales():Array /* of String */ { var locales:Array = []; for (var p:String in localeMap) { locales.push(p); } return locales; } /** * @copy mx.resources.IResourceManager#getPreferredLocaleChain() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getPreferredLocaleChain():Array /* of String */ { return LocaleSorter.sortLocalesByPreference( getLocales(), getSystemPreferredLocales(), null, true); } /** * @copy mx.resources.IResourceManager#getBundleNamesForLocale() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getBundleNamesForLocale(locale:String):Array /* of String */ { var bundleNames:Array = []; for (var p:String in localeMap[locale]) { bundleNames.push(p); } return bundleNames; } /** * @copy mx.resources.findResourceBundleWithResource * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function findResourceBundleWithResource( bundleName:String, resourceName:String):IResourceBundle { if (!_localeChain) return null; var n:int = _localeChain.length; for (var i:int = 0; i < n; i++) { var locale:String = localeChain[i]; var bundleMap:Object = localeMap[locale]; if (!bundleMap) continue; var bundleObject:Object = bundleMap[bundleName]; if (!bundleObject) continue; var bundle:IResourceBundle = null; if (bundleObject is Dictionary) { var localeBundleNameString:String = locale + bundleName; for (var obj:Object in bundleObject) { if (bundleObject[obj] == localeBundleNameString) { bundle = obj as IResourceBundle; break; } } } else { bundle = bundleObject as IResourceBundle; } if (bundle && resourceName in bundle.content) return bundle; } return null; } [Bindable("change")] /** * @copy mx.resources.IResourceManager#getObject() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getObject(bundleName:String, resourceName:String, locale:String = null):* { var resourceBundle:IResourceBundle = findBundle(bundleName, resourceName, locale); if (!resourceBundle) return undefined; return resourceBundle.content[resourceName]; } [Bindable("change")] /** * @copy mx.resources.IResourceManager#getString() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getString(bundleName:String, resourceName:String, parameters:Array = null, locale:String = null):String { var resourceBundle:IResourceBundle = findBundle(bundleName, resourceName, locale); if (!resourceBundle) return null; var value:String = String(resourceBundle.content[resourceName]); if (parameters) value = StringUtil.substitute(value, parameters); return value; } [Bindable("change")] /** * @copy mx.resources.IResourceManager#getStringArray() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getStringArray(bundleName:String, resourceName:String, locale:String = null):Array /* of String */ { var resourceBundle:IResourceBundle = findBundle(bundleName, resourceName, locale); if (!resourceBundle) return null; var value:* = resourceBundle.content[resourceName]; var array:Array = String(value).split(","); var n:int = array.length; for (var i:int = 0; i < n; i++) { array[i] = StringUtil.trim(array[i]); } return array; } [Bindable("change")] /** * @copy mx.resources.IResourceManager#getNumber() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getNumber(bundleName:String, resourceName:String, locale:String = null):Number { var resourceBundle:IResourceBundle = findBundle(bundleName, resourceName, locale); if (!resourceBundle) return NaN; var value:* = resourceBundle.content[resourceName]; return Number(value); } [Bindable("change")] /** * @copy mx.resources.IResourceManager#getInt() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getInt(bundleName:String, resourceName:String, locale:String = null):int { var resourceBundle:IResourceBundle = findBundle(bundleName, resourceName, locale); if (!resourceBundle) return 0; var value:* = resourceBundle.content[resourceName]; return int(value); } [Bindable("change")] /** * @copy mx.resources.IResourceManager#getUint() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getUint(bundleName:String, resourceName:String, locale:String = null):uint { var resourceBundle:IResourceBundle = findBundle(bundleName, resourceName, locale); if (!resourceBundle) return 0; var value:* = resourceBundle.content[resourceName]; return uint(value); } [Bindable("change")] /** * @copy mx.resources.IResourceManager#getBoolean() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getBoolean(bundleName:String, resourceName:String, locale:String = null):Boolean { var resourceBundle:IResourceBundle = findBundle(bundleName, resourceName, locale); if (!resourceBundle) return false; var value:* = resourceBundle.content[resourceName]; return String(value).toLowerCase() == "true"; } [Bindable("change")] /** * @copy mx.resources.IResourceManager#getClass() * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function getClass(bundleName:String, resourceName:String, locale:String = null):Class { var resourceBundle:IResourceBundle = findBundle(bundleName, resourceName, locale); if (!resourceBundle) return null; var value:* = resourceBundle.content[resourceName]; return value as Class; } /** * @private. */ private function findBundle(bundleName:String, resourceName:String, locale:String):IResourceBundle { supportNonFrameworkApps(); return locale != null ? getResourceBundle(locale, bundleName) : findResourceBundleWithResource(bundleName, resourceName); } /** * @private. */ private function supportNonFrameworkApps():void { if (initializedForNonFrameworkApp) return; initializedForNonFrameworkApp = true; if (getLocales().length > 0) return; var applicationDomain:ApplicationDomain = ApplicationDomain.currentDomain; if (!applicationDomain.hasDefinition("_CompiledResourceBundleInfo")) return; var c:Class = Class(applicationDomain.getDefinition( "_CompiledResourceBundleInfo")); var locales:Array /* of String */ = c.compiledLocales; var bundleNames:Array /* of String */ = c.compiledResourceBundleNames; installCompiledResourceBundles( applicationDomain, locales, bundleNames); localeChain = locales; } /** * @private */ private function getSystemPreferredLocales():Array /* of String */ { var systemPreferences:Array; // Capabilities.languages was added in AIR 1.1, // so this API may not exist. if (Capabilities["languages"]) systemPreferences = Capabilities["languages"]; else systemPreferences = [ Capabilities.language ]; return systemPreferences; } /** * @private. */ private function dumpResourceModule(resourceModule:*):void { for each (var bundle:ResourceBundle in resourceModule.resourceBundles) { trace(bundle.locale, bundle.bundleName); for (var p:String in bundle.content) { //trace(p, bundle.getObject(p)); } } } /** * @private */ private function enterFrameHandler(event:Event):void { if (SystemManagerGlobals.topLevelSystemManagers.length) { if (SystemManagerGlobals.topLevelSystemManagers[0].currentFrame == 2) { SystemManagerGlobals.topLevelSystemManagers[0]. removeEventListener(Event.ENTER_FRAME, enterFrameHandler); } else return; } var info:Object = SystemManagerGlobals.info; if (info) processInfo(info, false); } } } import flash.events.EventDispatcher; import mx.events.ModuleEvent; import mx.events.ResourceEvent; import mx.modules.IModuleInfo; import mx.resources.IResourceModule; //////////////////////////////////////////////////////////////////////////////// // // Helper class: ResourceModuleInfo // //////////////////////////////////////////////////////////////////////////////// /** * @private */ class ResourceModuleInfo { //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function ResourceModuleInfo(moduleInfo:IModuleInfo, readyHandler:Function, errorHandler:Function) { super(); this.moduleInfo = moduleInfo; this.readyHandler = readyHandler; this.errorHandler = errorHandler; } //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // errorHandler //---------------------------------- /** * @private */ public var errorHandler:Function; //---------------------------------- // moduleInfo //---------------------------------- /** * @private */ public var moduleInfo:IModuleInfo //---------------------------------- // readyHandler //---------------------------------- /** * @private */ public var readyHandler:Function; //---------------------------------- // resourceModule //---------------------------------- /** * @private */ public var resourceModule:IResourceModule; } //////////////////////////////////////////////////////////////////////////////// // // Helper class: ResourceEventDispatcher // //////////////////////////////////////////////////////////////////////////////// /** * @private */ class ResourceEventDispatcher extends EventDispatcher { //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function ResourceEventDispatcher(moduleInfo:IModuleInfo) { super(); moduleInfo.addEventListener( ModuleEvent.ERROR, moduleInfo_errorHandler, false, 0, true); moduleInfo.addEventListener( ModuleEvent.PROGRESS, moduleInfo_progressHandler, false, 0, true); moduleInfo.addEventListener( ModuleEvent.READY, moduleInfo_readyHandler, false, 0, true); } //-------------------------------------------------------------------------- // // Event handlers // //-------------------------------------------------------------------------- /** * @private */ private function moduleInfo_errorHandler(event:ModuleEvent):void { var resourceEvent:ResourceEvent = new ResourceEvent( ResourceEvent.ERROR, event.bubbles, event.cancelable); resourceEvent.bytesLoaded = event.bytesLoaded; resourceEvent.bytesTotal = event.bytesTotal; resourceEvent.errorText = event.errorText; dispatchEvent(resourceEvent); } /** * @private */ private function moduleInfo_progressHandler(event:ModuleEvent):void { var resourceEvent:ResourceEvent = new ResourceEvent( ResourceEvent.PROGRESS, event.bubbles, event.cancelable); resourceEvent.bytesLoaded = event.bytesLoaded; resourceEvent.bytesTotal = event.bytesTotal; dispatchEvent(resourceEvent); } /** * @private */ private function moduleInfo_readyHandler(event:ModuleEvent):void { var resourceEvent:ResourceEvent = new ResourceEvent(ResourceEvent.COMPLETE); dispatchEvent(resourceEvent); } }