blob: 9b56beecce268c838aece8a8c43c35751c4fb62b [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// 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.
*
* <p>A single instance of this class manages all localized resources
* for a Flex application.</p>
*
* @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;
inFrame1 = true;
SystemManagerGlobals.topLevelSystemManagers[0].
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
}
var info:Object = SystemManagerGlobals.info;
// Falcon injects this property and it is always false
// We ignore missing bundles because Falcon doesn't
// generate fallback bundles like MXMLC;
if (!inFrame1)
ignoreMissingBundles = info && info.hasOwnProperty("isMXMLC");
if (info)
processInfo(info, false);
ignoreMissingBundles = info && info.hasOwnProperty("isMXMLC");
if (SystemManagerGlobals.topLevelSystemManagers.length)
SystemManagerGlobals.topLevelSystemManagers[0].
addEventListener(FlexEvent.NEW_CHILD_APPLICATION, newChildApplicationHandler);
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
*
* Whether or ignoreMissingBundles was set in frame 1
*/
private var inFrame1:Boolean = false;
/**
* @private
*
* Whether or not to throw an error.
*/
private var ignoreMissingBundles:Boolean = false;
/**
* @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 a proxy
var proxy:ResourceBundleProxy = new ResourceBundleProxy();
proxy.bundleClass = bundleClass;
proxy.useWeakReference = useWeakReference;
// 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.
proxy.locale = locale;
proxy.bundleName = bundleName;
// Add that resource bundle instance to the ResourceManager.
resourceBundle = proxy;
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";
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)
{
if (obj is ResourceBundleProxy)
bundle = loadResourceBundleProxy(ResourceBundleProxy(obj));
else
bundle = obj as IResourceBundle;
break;
}
}
}
else if (bundleObject is ResourceBundleProxy)
{
bundle = loadResourceBundleProxy(ResourceBundleProxy(bundleObject));
}
else
{
bundle = bundleObject as IResourceBundle;
}
return bundle;
}
private function loadResourceBundleProxy(proxy:ResourceBundleProxy):ResourceBundle {
var proxyClass:Class = proxy.bundleClass;
var resourceBundle:ResourceBundle = ResourceBundle(new proxyClass());
resourceBundle._locale = proxy.locale;
resourceBundle._bundleName = proxy.bundleName;
addResourceBundle(resourceBundle, proxy.useWeakReference);
return resourceBundle;
}
/**
* @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)
{
if (obj is ResourceBundleProxy)
bundle = loadResourceBundleProxy(ResourceBundleProxy(obj));
else
bundle = obj as IResourceBundle;
break;
}
}
}
else if (bundleObject is ResourceBundleProxy)
{
bundle = loadResourceBundleProxy(ResourceBundleProxy(bundleObject));
}
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)
{
inFrame1 = false;
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.IResourceBundle;
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);
}
}
////////////////////////////////////////////////////////////////////////////////
//
// Helper class: ResourceBundleProxy
//
////////////////////////////////////////////////////////////////////////////////
/**
* @private
*/
class ResourceBundleProxy implements IResourceBundle
{
public var bundleClass:Class;
public var useWeakReference:Boolean;
private var _bundleName:String;
private var _locale:String;
public function ResourceBundleProxy()
{
}
public function get bundleName():String {
return _bundleName;
}
public function set bundleName(value:String):void {
_bundleName = value;
}
public function get content():Object {
return null;
}
public function get locale():String {
return _locale;
}
public function set locale(value:String):void {
_locale = value;
}
}