You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ah...@apache.org on 2018/10/02 04:30:15 UTC
[royale-asjs] 02/02: first cut at ResourceManager
This is an automated email from the ASF dual-hosted git repository.
aharui pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git
commit 688a1faca5b78cf3929f7f39ea398e67c051d7a2
Author: Alex Harui <ah...@apache.org>
AuthorDate: Mon Oct 1 21:29:50 2018 -0700
first cut at ResourceManager
---
.../src/main/royale/mx/core/UIComponent.as | 35 +
.../src/main/royale/mx/events/ResourceEvent.as | 224 ++++
.../main/royale/mx/resources/IResourceBundle.as | 256 ++++
.../main/royale/mx/resources/IResourceManager.as | 824 ++++++++++++
.../src/main/royale/mx/resources/Locale.as | 236 ++++
.../src/main/royale/mx/resources/LocaleSorter.as | 1084 +++++++++++++++
.../src/main/royale/mx/resources/ResourceBundle.as | 249 ++++
.../main/royale/mx/resources/ResourceManager.as | 130 ++
.../royale/mx/resources/ResourceManagerImpl.as | 1408 ++++++++++++++++++++
9 files changed, 4446 insertions(+)
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
index 141ffbe..bf36c66 100644
--- a/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/core/UIComponent.as
@@ -50,6 +50,8 @@ import mx.managers.ICursorManager;
import mx.managers.IFocusManager;
import mx.managers.IFocusManagerContainer;
import mx.managers.ISystemManager;
+import mx.resources.IResourceManager;
+import mx.resources.ResourceManager;
import mx.styles.IStyleManager2;
import mx.styles.StyleManager;
@@ -1414,6 +1416,39 @@ public class UIComponent extends UIBase
}
//----------------------------------
+ // resourceManager
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the resourceManager property.
+ */
+ private var _resourceManager:IResourceManager = ResourceManager.getInstance();
+
+ /**
+ * @private
+ * This metadata suppresses a trace() in PropertyWatcher:
+ * "warning: unable to bind to property 'resourceManager' ..."
+ */
+ [Bindable("unused")]
+
+ /**
+ * A reference to the object which manages
+ * all of the application's localized resources.
+ * This is a singleton instance which implements
+ * the IResourceManager interface.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function get resourceManager():IResourceManager
+ {
+ return _resourceManager;
+ }
+
+ //----------------------------------
// styleManager
//----------------------------------
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/events/ResourceEvent.as b/frameworks/projects/MXRoyale/src/main/royale/mx/events/ResourceEvent.as
new file mode 100644
index 0000000..2b16cf6
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/events/ResourceEvent.as
@@ -0,0 +1,224 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.events
+{
+
+import org.apache.royale.events.Event;
+import mx.events.ProgressEvent;
+
+/**
+ * The ResourceEvent class represents an Event object that is dispatched
+ * when the ResourceManager loads the resource bundles in a resource module
+ * by calling the <code>loadResourceModule()</code> method.
+ *
+ * @see mx.resources.ResourceManager
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class ResourceEvent extends ProgressEvent
+{
+// include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Dispatched when the resource module SWF file has finished loading.
+ * The ResourceEvent.COMPLETE constant defines the value of the
+ * <code>type</code> property of the event object for a <code>complete</code> event.
+ *
+ * <p>The properties of the event object have the following values:</p>
+ * <table class="innertable">
+ * <tr><th>Property</th><th>Value</th></tr>
+ * <tr><td><code>bubbles</code></td><td><code>false</code></td></tr>
+ * <tr><td><code>cancelable</code></td><td><code>false</code></td></tr>
+ * <tr><td><code>currentTarget</code></td><td>The object that defines the
+ * event listener that handles the event. For example, if you use
+ * <code>myButton.addEventListener()</code> to register an event listener,
+ * <code>myButton</code> is the value of <code>currentTarget</code>. </td></tr>
+ * <tr><td><code>errorText</code></td><td>Empty</td></tr>
+ * <tr><td><code>target</code></td><td>The object that dispatched the event;
+ * it is not always the object listening for the event.
+ * Use the <code>currentTarget</code> property to always access the
+ * object that listens for the event.</td></tr>
+ * </table>
+ *
+ * @eventType complete
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const COMPLETE:String = "complete";
+
+ /**
+ * Dispatched when there is an error loading the resource module SWF file.
+ * The ResourceEvent.ERROR constant defines the value of the
+ * <code>type</code> property of the event object for a <code>error</code> event.
+ *
+ * <p>The properties of the event object have the following values:</p>
+ * <table class="innertable">
+ * <tr><th>Property</th><th>Value</th></tr>
+ * <tr><td><code>bubbles</code></td><td><code>false</code></td></tr>
+ * <tr><td><code>bytesLoaded</code></td><td>Empty</td></tr>
+ * <tr><td><code>bytesTotal</code></td><td>Empty</td></tr>
+ * <tr><td><code>cancelable</code></td><td>false</td></tr>
+ * <tr><td><code>currentTarget</code></td><td>The object that defines the
+ * event listener that handles the event. For example, if you use the
+ * <code>myButton.addEventListener()</code> method to register an event listener,
+ * <code>myButton</code> is the value of <code>currentTarget</code>. </td></tr>
+ * <tr><td><code>errorText</code></td>An error message.<td></td></tr>
+ * <tr><td><code>target</code></td><td>The object that dispatched the event;
+ * it is not always the object that is listening for the event.
+ * Use the <code>currentTarget</code> property to always access the
+ * object that listens for the event.</td></tr>
+ * </table>
+ *
+ * @eventType error
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const ERROR:String = "error";
+
+ /**
+ * Dispatched when the resource module SWF file is loading.
+ * The ResourceEvent.PROGRESS constant defines the value of the
+ * <code>type</code> property of the event object for a <code>progress</code> event.
+ *
+ * <p>The properties of the event object have the following values:</p>
+ * <table class="innertable">
+ * <tr><th>Property</th><th>Value</th></tr>
+ * <tr><td><code>bubbles</code></td><td><code>false</code></td></tr>
+ * <tr><td><code>bytesLoaded</code></td><td>The number of bytes loaded.</td></tr>
+ * <tr><td><code>bytesTotal</code></td><td>The total number of bytes to load.</td></tr>
+ * <tr><td><code>cancelable</code></td><td><code>false</code></td></tr>
+ * <tr><td><code>currentTarget</code></td><td>The object that defines the
+ * event listener that handles the event. For example, if you use the
+ * <code>myButton.addEventListener()</code> method to register an event listener,
+ * <code>myButton</code> is the value of <code>currentTarget</code>.</td></tr>
+ * <tr><td><code>errorText</code></td>Empty<td></td></tr>
+ * <tr><td><code>target</code></td><td>The object that dispatched the event;
+ * it is not always the object that listens for the event.
+ * Use the <code>currentTarget</code> property to always access the
+ * object that is listening for the event.</td></tr>
+ * </table>
+ *
+ * @eventType progress
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static const PROGRESS:String = "progress";
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @param type The value of the <code>type</code> property of the event object. Possible values are:
+ * <ul>
+ * <li><code>"progress"</code> (<code>ResourceEvent.PROGRESS</code>)</li>
+ * <li><code>"complete"</code> (<code>ResourceEvent.COMPLETE</code>)</li>
+ * <li><code>"error"</code> (<code>ResourceEvent.ERROR</code>)</li>
+ * </ul>
+ *
+ * @param bubbles Determines whether the Event object
+ * participates in the bubbling stage of the event flow.
+ *
+ * @param cancelable Determines whether the Event object can be cancelled.
+ *
+ * @param bytesLoaded The number of bytes loaded
+ * at the time the listener processes the event.
+ *
+ * @param bytesTotal The total number of bytes
+ * that will ultimately be loaded if the loading process succeeds.
+ *
+ * @param errorText The error message of the error
+ * when <code>type</code> is <code>ResourceEvent.ERROR</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function ResourceEvent(type:String, bubbles:Boolean = false,
+ cancelable:Boolean = false,
+ bytesLoaded:uint = 0, bytesTotal:uint = 0,
+ errorText:String = null)
+ {
+ super(type, bubbles, cancelable, bytesLoaded, bytesTotal);
+
+ this.errorText = errorText;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // errorText
+ //----------------------------------
+
+ /**
+ * The error message if the <code>type</code> is <code>ERROR</code>;
+ * otherwise, it is <code>null</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public var errorText:String;
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden properties: Event
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ override public function clone():Event
+ {
+ return new ResourceEvent(type, bubbles, cancelable,
+ bytesLoaded, bytesTotal, errorText);
+ }
+}
+
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/resources/IResourceBundle.as b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/IResourceBundle.as
new file mode 100644
index 0000000..74c0304
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/IResourceBundle.as
@@ -0,0 +1,256 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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
+{
+
+/**
+ * The IResourceBundle and IResourceManager interfaces work together
+ * to provide localization support for Flex applications.
+ *
+ * <p>There are three main concepts involved in localization:
+ * locales, resources, and resource bundles.</p>
+ *
+ * <p>A locale specifies a language and a country
+ * for which your application has been localized.
+ * For example, the locale <code>"en_US"</code>
+ * specifies English as spoken in the United States.
+ * (See the mx.resources.Locale class for more information.)</p>
+ *
+ * <p>A resource is a named value that is locale-dependent.
+ * For example, your application might have a resource
+ * whose name is <code>"OPEN"</code>
+ * and whose value for an English locale is <code>"Open"</code>
+ * but whose value for a French locale is <code>"Ouvrir"</code>.</p>
+ *
+ * <p>A resource bundle is a named group of resources
+ * whose values have been localized for a particular locale.
+ * A resource bundle is identified by the combination of its
+ * <code>bundleName</code> and its <code>locale</code>,
+ * and has a <code>content</code> Object that contains
+ * the name-value pairs for the bundle's resources.</p>
+ *
+ * <p>The IResourceBundle interface represents a specific resource bundle.
+ * However, most applications will only need to use IResourceManager.
+ * A single ResourceManager object implementing this interface
+ * manages multiple resource bundles, possibly for multiple locales,
+ * and provides access to the resources that they contain.
+ * For example, you can retrieve a specific resource as a String by calling
+ * <code>resourceManager.getString(bundleName, resourceName)</code>.
+ * By changing the <code>localeChain</code> property of the ResourceManager,
+ * you can change which resource bundles are searched for resource values.</p>
+ *
+ * <p>Generally, you do not create resource bundles yourself;
+ * instead, they are usually compiled from ~~.properties files.
+ * A properties file named MyResources.properties
+ * produces a resource bundle with <code>"MyResources"</code>
+ * for its <code>bundleName</code>.
+ * You generally produce multiple versions of each properties file,
+ * one for each locale that your application supports.</p>
+ *
+ * <p>Flex properties files are similar to Java properties files,
+ * except that they also support MXML's <code>Embed()</code>
+ * and <code>ClassReference()</code> directives.
+ * These directives work the same way in a properties file
+ * as they do in a CSS file, producing class references.
+ * Also, the encoding for Flex properties files
+ * is always assumed to be UTF-8.</p>
+ *
+ * <p>The Flex framework's resources have been localized
+ * for U.S. English (the <code>"en_US"</code> locale) and
+ * for Japanese (the <code>"ja_JP"</code> locale).
+ * The framework resources are organized into multiple bundles
+ * corresponding to framework packages; for example, the "formatters"
+ * bundle is used by classes in the mx.formatters package.
+ * (There is also a "SharedResources" bundle for resources used by
+ * multiple packages.)</p>
+ *
+ * <p>The properties files for the framework resources,
+ * such as formatters.properties, can be found in the
+ * frameworks/projects/framework/bundles/{locale}/src directories
+ * of the Flex SDK.
+ * Your applications normally link against the Flex framework
+ * as a precompiled library, framework.swc,
+ * in the frameworks/libs directory.
+ * This library has no resources in it.
+ * Instead, the framework resources have been compiled into separate
+ * resource bundle libraries such as framework_rb.swc.
+ * These are located in the frameworks/locales/{locale} directories
+ * and your application must also link in one or more of these.</p>
+ *
+ * <p>You are free to organize your application's own resources
+ * into whatever bundles you find convenient.
+ * If you localize your application for locales
+ * other than <code>"en_US"</code> and <code>"ja_JP"</code>,
+ * you should localize the framework's properties files for those locales
+ * as well and compile additional resource bundle libaries for them.</p>
+ *
+ * <p>When your application starts, the ResourceManager is automatically
+ * populated with whatever resource bundles were compiled
+ * into the application.
+ * If you create a code module, by default the resources that its classes
+ * need are compiled into the module.
+ * When the module is loaded into an application, any bundles that the
+ * application does not already have are added to the ResourceManager.</p>
+ *
+ * <p>You can compile "resource modules" that have only resources in them,
+ * and load them with the <code>loadResourceModule()</code> method
+ * of the ResourceManager.
+ * With resource modules, you can support multiple locales by loading
+ * the resources you need at run time rather than compiling them into
+ * your application.</p>
+ *
+ * <p>Although the ResourceManager is normally populated with resource bundles
+ * that were compiled into your application or loaded from modules,
+ * you can also programmatically create resource bundles and add them
+ * to the ResourceManager yourself with the <code>addResourceBundle()</code>
+ * method.</p>
+ *
+ * @see mx.resources.ResourceBundle
+ * @see mx.resources.IResourceManager
+ * @see mx.resources.ResourceManager
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public interface IResourceBundle
+{
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // bundleName
+ //----------------------------------
+
+ /**
+ * A name that identifies this resource bundle,
+ * such as <code>"MyResources"</code>.
+ *
+ * <p>This read-only property is set
+ * when a resource bundle is constructed.</p>
+ *
+ * <p>Resource bundles that are automatically created from compiled
+ * properties files have bundle names based on the names of those files.
+ * For example, a properties file named MyResources.properties
+ * will produce a resource bundle whose <code>bundleName</code>
+ * is <code>"MyResources"</code>.</p>
+ *
+ * <p>The ResourceManager can manage multiple bundles with the same
+ * <code>bundleName</code> as long as they have different values
+ * for their <code>locale</code> property.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function get bundleName():String;
+
+ //----------------------------------
+ // content
+ //----------------------------------
+
+ /**
+ * An object containing key-value pairs for the resources
+ * in this resource bundle.
+ *
+ * <p>In general, you should access resources by using IResourceManager
+ * methods such as <code>getString()</code>, rather than directly
+ * accessing them in a resource bundle.
+ * However, if you are programmatically creating your own
+ * resource bundles, you can initialize them with resources,
+ * as follows:</p>
+ *
+ * <pre>
+ * var rb:IResourceBundle = new ResourceBundle("fr_FR", "MyResources");
+ * rb.content["LANGUAGE"] = "Francais";
+ * rb.content["GREETING"] = "Bonjour";
+ * </pre>
+ *
+ * <p>When a resource bundle is produced by compiling a properties
+ * file, its resource values are either of type String or Class.
+ * For example, if the properties file contains</p>
+ *
+ * <pre>
+ * LANGUAGE=English
+ * MINIMUM_AGE=18
+ * ENABLED=true
+ * LOGO=Embed("logo.png")
+ * </pre>
+ *
+ * <p>then the value of the <code>LANGUAGE</code> resource
+ * is the String <code>"English"</code>,
+ * the value of the <code>MINIMUM_AGE</code> resource
+ * is the String <code>"18"</code>,
+ * the value of the <code>ENABLED</code> resource
+ * is the String <code>"true"</code>,
+ * and the value of the <code>LOGO</code> resource
+ * is a Class that represents the embedded PNG file.</p>
+ *
+ * <p>You can use IResourceManager methods such as <code>getInt()</code>
+ * and <code>getBoolean()</code> to convert resource strings like
+ * <code>"18"</code> and <code>"true"</code> into the type
+ * that your code expects.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function get content():Object;
+
+ //----------------------------------
+ // locale
+ //----------------------------------
+
+ /**
+ * The locale for which this bundle's resources have been localized.
+ * This is a String such as <code>"en_US"</code> for U.S. English.
+ *
+ * <p>This read-only property is set
+ * when a resource bundle is constructed.</p>
+ *
+ * <p>Resource bundles that are automatically created from compiled
+ * properties files have locales based on the
+ * <code>-compiler.locale</code> option of the mxmlc or compc compilers.
+ * For example, suppose that you compile your application with the option
+ * <code>-compiler.locale=en_US,ja_JP</code> and that you have specified
+ * <code>-compiler.source-path=resources/{locale}</code> so that
+ * your application's resources, located in
+ * resources/en_US/MyResources.properties and
+ * resources/ja_JP/MyResources.properties, are found.
+ * Then your application will have two resource bundles
+ * whose <code>bundleName</code> is <code>"MyResources"</code>,
+ * one whose <code>locale</code> is <code>"en_US"</code>
+ * and one whose <code>locale</code> is <code>"ja_JP"</code>.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function get locale():String;
+}
+
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/resources/IResourceManager.as b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/IResourceManager.as
new file mode 100644
index 0000000..110f30e
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/IResourceManager.as
@@ -0,0 +1,824 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 org.apache.royale.events.IEventDispatcher;
+
+/**
+ * The APIs of the IResourceManager interface
+ * provide localization support for Flex applications.
+ *
+ * <p>There are three main concepts involved in localization:
+ * locales, resources, and resource bundles.</p>
+ *
+ * <p>A locale specifies a language and a country
+ * for which your application has been localized.
+ * For example, the locale <code>"en_US"</code>
+ * specifies English as spoken in the United States.
+ * (See the mx.resources.Locale class for more information.)</p>
+ *
+ * <p>A resource is a named value that is locale-dependent.
+ * For example, your application might have a resource
+ * whose name is <code>"OPEN"</code>
+ * and whose value for an English locale is <code>"Open"</code>
+ * but whose value for a French locale is <code>"Ouvrir"</code>.</p>
+ *
+ * <p>A resource bundle is a named group of resources
+ * whose values have been localized for a particular locale.
+ * A resource bundle is identified by the combination of its
+ * <code>bundleName</code> and its <code>locale</code>,
+ * and has a <code>content</code> object that contains
+ * the name-value pairs for the bundle's resources.
+ * See the documentation for mx.resources.IResourceBundle
+ * for information about how you typically create resource
+ * bundles from properties files.</p>
+ *
+ * <p>A single ResourceManager object implementing the IResourceManager
+ * interface manages multiple resource bundles, possibly for multiple
+ * locales, and provides access to the resources that they contain.
+ * For example, you can retrieve a specific resource as a String by calling
+ * <code>resourceManager.getString(bundleName, resourceName)</code>.</p>
+ *
+ * <p>All classes that extend UIComponent, Formatter, or Validator
+ * have a <code>resourceManager</code> property
+ * that provides a reference to the object implementing this interface.
+ * Other classes can call <code>ResourceManager.getInstance()</code>
+ * to obtain this object.</p>
+ *
+ * <p>Resource retrieval methods such as <code>getString()</code>
+ * search for resources in the locales specified
+ * by the <code>localeChain</code> property.
+ * By changing this property, you can make your application
+ * suddenly use, for example, Japanese rather than English resources.</p>
+ *
+ * <p>When your application starts, the ResourceManager is automatically
+ * populated with whatever resource bundles were compiled
+ * into the application.
+ * If you create a code module, by default the resources that its classes
+ * need are compiled into the module.
+ * When the module is loaded into an application, any bundles that the
+ * application does not already have are added to the ResourceManager.</p>
+ *
+ * <p>You can compile "resource modules" which have only resources in them,
+ * and load them with the <code>loadResourceModule()</code> method
+ * of IResourceManager.
+ * With resource modules, you can support multiple locales by loading
+ * the resources you need at run time rather than compiling them into
+ * your application.</p>
+ *
+ * <p>Although the ResourceManager is normally populated with resource bundles
+ * that were compiled into your application or loaded from modules,
+ * you can also programmatically create resource bundles and add them
+ * to the ResourceManager yourself with the <code>addResourceBundle()</code>
+ * method.</p>
+ *
+ * @see mx.resources.ResourceManager
+ * @see mx.resources.IResourceBundle
+ * @see mx.resources.ResourceBundle
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public interface IResourceManager extends IEventDispatcher
+{
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // localeChain
+ //----------------------------------
+
+ /**
+ * An Array of locale Strings, such as <code>[ "en_US" ]</code>,
+ * which specifies one or more locales to be searched for resources.
+ *
+ * <p>When you call the ResourceManager methods <code>getObject()</code>,
+ * <code>getString()</code>, <code>getStringArray()</code>,
+ * <code>getNumber()</code>, <code>getInt()</code>,
+ * <code>getUint()</code>, <code>getBoolean()</code>, or
+ * <code>getClass()</code> to get the value of a resource,
+ * you specify a bundle name and a resource name,
+ * but not a locale.
+ * The ResourceManager starts with the first locale in the
+ * <code>localeChain</code> and looks for a ResourceBundle
+ * with the specified bundle name for that locale.
+ * If such a ResourceBundle exists, and the specified resource
+ * exists in it, then the value of that resource is returned.
+ * Otherwise, the ResourceManager proceeds on to the other
+ * locales in the <code>localeChain</code>.</p>
+ *
+ * <p>This scheme makes it possible to have locales that do not
+ * necessarily contain a complete set of localized resources.
+ * For example, if you are localizing your application for
+ * Indian English rather than U.S. English, you need only
+ * supply resources for the <code>en_IN</code> locale in which the
+ * Indian spelling or usage differs from that in the U.S.,
+ * and then set the <code>localeChain</code> property
+ * to <code>[ "en_IN", "en_US" ]</code>.</p>
+ *
+ * <p>Many framework classes assume that they can always
+ * obtain, from some locale, the resources that they expect,
+ * and they will throw errors if they cannot do so.
+ * Therefore, you must ensure that the <code>localeChain</code>
+ * always contains a complete set of resources.
+ * Unless you have done a complete localization of all the
+ * framework's resources as well as your own application's
+ * resources, you can keep the <code>"en_US"</code> locale
+ * at the end of your <code>localeChain</code> to ensure this.</p>
+ *
+ * <p>Setting this property causes the ResourceManager to dispatch
+ * a <code>"change"</code> Event.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function get localeChain():Array /* of String */;
+
+ /**
+ * @private
+ */
+ function set localeChain(value:Array /* of String */):void;
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Begins loading a resource module containing resource bundles.
+ *
+ * <p>Each call to this method returns a new event-dispatching object
+ * that you can use to learn how the loading is progressing
+ * and whether it completes successfully or results in an error.
+ * This object dispatches <code>ResourceEvent.PROGRESS</code>,
+ * <code>ResourceEvent.COMPLETE</code>, and
+ * <code>ResourceEvent.ERROR</code> events.</p>
+ *
+ * <p>When the module has been loaded, the resource bundles
+ * are added to the ResourceManager, but the <code>localeChain</code>
+ * is left unchanged.
+ * If the <code>update</code> parameter is <code>true</code>,
+ * the <code>update()</code> method will be called.</p>
+ *
+ * @param url The URL from which to load the resource module.
+ *
+ * @param update Whether to call
+ * the <code>update()</code> method when the module finishes loading.
+ *
+ * @param applicationDomain The ApplicationDomain passed to the
+ * <code>load()</code> method of the IModuleInfo class
+ * that loads the resource module.
+ * This parameter is optional and defaults to <code>null</code>.
+ *
+ * @param securityDomain The SecurityDomain passed to the
+ * <code>load()</code> method of the IModuleInfo class
+ * that loads the resource module.
+ * This parameter is optional and defaults to <code>null</code>.
+ *
+ * @return An object that is associated with this particular load operation
+ * that dispatches <code>ResourceEvent.PROGRESS</code>,
+ * <code>ResourceEvent.COMPLETE</code>, and
+ * <code>ResourceEvent.ERROR</code> events.
+ *
+ * @see mx.events.ResourceEvent
+ * @see mx.resources.IResourceManager#update()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ function loadResourceModule(url:String, update:Boolean = true,
+ applicationDomain:ApplicationDomain = null,
+ securityDomain:SecurityDomain = null):
+ IEventDispatcher;
+ */
+
+ /**
+ * Begins unloading a loaded resource module.
+ *
+ * <p>When the module is unloaded, its resource bundles
+ * are removed from the ResourceManager, but the <code>localeChain</code>
+ * is left unchanged.
+ * If the <code>update</code> parameter is <code>true</code>,
+ * the <code>update()</code> method will be called.</p>
+ *
+ * @param url The URL that was used to load the resource module.
+ *
+ * @param update Whether to call
+ * the <code>update()</code> method when the module finishes unloading.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ function unloadResourceModule(url:String, update:Boolean = true):void;
+ */
+
+ /**
+ * Adds the specified ResourceBundle to the ResourceManager
+ * so that its resources can be accessed by ResourceManager
+ * methods such as <code>getString()</code>.
+ *
+ * @param resourceBundle The resource bundle to be added.
+ * @param useWeakReference Determines if the ResourceManager
+ * keeps a weak reference to the resource bundle.
+ * If <code>useWeakReference</code> is <code>true</code> then the ResourceManager
+ * provides a weak reference to the resource bundle. When the
+ * caller chooses to use a weak reference it becomes the
+ * caller's responsibility to keep a hard reference the resource bundle
+ * so it is not garbaged collected prematurely. If <code>useWeakReference</code> is
+ * <code>false</code>, the ResourceManager keeps a hard reference to the resource
+ * bundle so it will not be garbage collected.
+ *
+ * <p>When a Flex sub-application or module automatically adds its compiled
+ * resource bundles to the ResourceManager, it calls the <code>addResourceBundle()</code>
+ * with <code>useWeakReference</code> set to <code>true</code>, to avoid becoming pinned in memory.
+ * If you create resource bundles at runtime in a sub-application or
+ * module, you should do the same. You then need to hold on to these
+ * resource bundles with a hard reference to prevent them from being
+ * garbage collected.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function addResourceBundle(resourceBundle:IResourceBundle,
+ useWeakReference:Boolean = false):void;
+
+ /**
+ * Removes the specified ResourceBundle from the ResourceManager
+ * so that its resources can no longer be accessed by ResourceManager
+ * methods such as <code>getString()</code>.
+ *
+ * @param locale A locale string such as <code>"en_US"</code>.
+ *
+ * @param bundleName A bundle name such as <code>"MyResources"</code>.
+ *
+ * @see mx.resources.IResourceBundle
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function removeResourceBundle(locale:String, bundleName:String):void;
+
+ /**
+ * Removes all ResourceBundles for the specified locale
+ * from the ResourceManager so that their resources
+ * can no longer be accessed by ResourceManager methods
+ * such as <code>getString()</code>.
+ *
+ * @param locale A locale string such as <code>"en_US"</code>.
+ *
+ * @see mx.resources.IResourceBundle
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function removeResourceBundlesForLocale(locale:String):void;
+
+ /**
+ * Dispatches a <code>change</code> event from the
+ * ResourceManager.
+ *
+ * <p>This causes binding expressions to re-evaluate
+ * if they involve the ResourceManager methods
+ * <code>getObject()</code>, <code>getString()</code>,
+ * <code>getStringArray()</code>, <code>getNumber()</code>,
+ * <code>getInt()</code>, <code>getUint()</code>,
+ * <code>getBoolean()</code>, or <code>getClass()</code>.</p>
+ *
+ * <p>This also causes the <code>resourcesChanged()</code> method
+ * of a UIComponent, Formatter, or Validator to execute.
+ * Many components implement this method to update
+ * their state based on the latest resources.</p>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function update():void;
+
+ /**
+ * Returns an Array of Strings specifying all locales for which
+ * ResourceBundle objects exist in the ResourceManager.
+ *
+ * <p>The order of locales in this array is not specified.</p>
+ *
+ * @return An Array of locale Strings.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getLocales():Array /* of String */;
+
+ /**
+ * Returns an Array of Strings specifying all locales for which
+ * ResourceBundle objects exist in the ResourceManager,
+ * ordered using user preferences as reported by
+ * <code>Capabilities.language</code> or
+ * <code>Capabilities.languages</code>.
+ *
+ * @return An Array of locale Strings.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getPreferredLocaleChain():Array /* of String */;
+
+ /**
+ * Returns an Array of Strings specifying the bundle names
+ * for all ResourceBundle objects that exist in the ResourceManager
+ * and that belong to the specified locale.
+ *
+ * <p>The order of bundle names in this Array is not specified.</p>
+ *
+ * @param locale A locale string such as <code>"en_US"</code>.
+ *
+ * @return An Array of bundle names.
+ *
+ * @see mx.resources.IResourceBundle
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getBundleNamesForLocale(locale:String):Array /* of String */;
+
+ /**
+ * Returns a ResourceBundle with the specified <code>locale</code>
+ * and <code>bundleName</code> that has been previously added
+ * to the ResourceManager with <code>addResourceBundle()</code>.
+ * If no such ResourceBundle exists, this method returns <code>null</code>.
+ *
+ * @param locale A locale string such as <code>"en_US"</code>.
+ *
+ * @param bundleName A bundle name such as <code>"MyResources"</code>.
+ *
+ * @return The ResourceBundle with the specified <code>locale</code>
+ * and <code>bundleName</code> if one exists; otherwise <code>null</code>.
+ *
+ * @see mx.resources.IResourceBundle
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getResourceBundle(locale:String,
+ bundleName:String):IResourceBundle;
+
+ /**
+ * Searches the locales in the <code>localeChain</code>
+ * for the specified resource and returns
+ * the first resource bundle in which it is found.
+ * If the resource isn't found, this method returns <code>null</code>.
+ *
+ * @param bundleName A bundle name such as <code>"MyResources"</code>.
+ *
+ * @param resourceName The name of a resource in the resource bundle.
+ *
+ * @return The first ResourceBundle in the <code>localeChain</code>
+ * that contains the specified resource, or <code>null</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function findResourceBundleWithResource(
+ bundleName:String,
+ resourceName:String):IResourceBundle;
+
+ [Bindable("change")]
+
+ /**
+ * Gets the value of a specified resource as an Object.
+ *
+ * <p>The value is returned exactly as it is stored
+ * in the <code>content</code> Object of the ResourceBundle,
+ * with no conversion.
+ * If the resource was compiled from a properties files,
+ * the resource value in the <code>content</code> Object
+ * is always a String unless you used the <code>Embed()</code>
+ * or <code>ClassReference()</code> directive, in which case
+ * it is a Class.
+ * Use the <code>getString()</code>, <code>getStringArray()</code>,
+ * <code>getNumber()</code>, <code>getInt()</code>
+ * <code>getUint()</code>, <code>getBoolean()</code>, and
+ * <code>getClass()</code> methods to convert the value
+ * to more specific types.</p>
+ *
+ * <p>If the specified resource is not found,
+ * this method returns <code>undefined</code>.</p>
+ *
+ * @param bundleName The name of a resource bundle.
+ *
+ * @param resourceName The name of a resource in the resource bundle.
+ *
+ * @param locale A specific locale to be used for the lookup,
+ * or <code>null</code> to search all locales
+ * in the <code>localeChain</code>.
+ * This parameter is optional and defaults to <code>null</code>;
+ * you should seldom need to specify it.
+ *
+ * @return The resource value, exactly as it is stored
+ * in the <code>content</code> Object,
+ * or <code>undefined</code> if the resource is not found.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getObject(bundleName:String, resourceName:String,
+ locale:String = null):*;
+
+ [Bindable("change")]
+
+ /**
+ * Gets the value of a specified resource as a String,
+ * after substituting specified values for placeholders.
+ *
+ * <p>This method calls <code>getObject()</code>
+ * and then casts the result to a String.</p>
+ *
+ * <p>If a <code>parameters</code> Array is passed to this method,
+ * the parameters in it are converted to Strings
+ * and then substituted, in order, for the placeholders
+ * <code>"{0}"</code>, <code>"{1}"</code>, and so on, in the String
+ * before it is returned.</p>
+ *
+ * <p>If the specified resource is not found,
+ * this method returns <code>null</code>.</p>
+ *
+ * @param bundleName The name of a resource bundle.
+ *
+ * @param resourceName The name of a resource in the resource bundle.
+ *
+ * @param parameters An Array of parameters that are
+ * substituted for the placeholders.
+ * Each parameter is converted to a String with the <code>toString()</code> method
+ * before being substituted.
+ *
+ * @param locale A specific locale to be used for the lookup,
+ * or <code>null</code> to search all locales
+ * in the <code>localeChain</code>.
+ * This parameter is optional and defaults to <code>null</code>;
+ * you should seldom need to specify it.
+ *
+ * @return The resource value, as a String,
+ * or <code>null</code> if it is not found.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getString(bundleName:String, resourceName:String,
+ parameters:Array = null,
+ locale:String = null):String;
+
+ [Bindable("change")]
+
+ /**
+ * Gets the value of a specified resource as an Array of Strings.
+ *
+ * <p>This method assumes that the resource value is a String
+ * containing a comma-separated list of items.
+ * It calls the <code>getString()</code> method, splits the String
+ * into items at the commas, and trims white space
+ * before and after each item.
+ * It is useful if you have written a line such as:</p>
+ *
+ * <pre>
+ * COUNTRIES=India, China, Japan
+ * </pre>
+ *
+ * <p>in a properties file and you want to obtain the value
+ * <code>[ "India", "China", "Japan" ]</code>
+ * rather than the value <code>"India, China, Japan"</code>.</p>
+ *
+ * <p>If the specified resource is not found,
+ * this method returns <code>null</code>.</p>
+ *
+ * @param bundleName The name of a resource bundle.
+ *
+ * @param resourceName The name of a resource in the resource bundle.
+ *
+ * @param locale A specific locale to be used for the lookup,
+ * or <code>null</code> to search all locales
+ * in the <code>localeChain</code>.
+ * This parameter is optional and defaults to <code>null</code>;
+ * you should seldom need to specify it.
+ *
+ * @return The resource value, as an Array of Strings,
+ * or <code>null</code> if it is not found.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getStringArray(bundleName:String,
+ resourceName:String,
+ locale:String = null):Array /* of String */;
+
+ [Bindable("change")]
+
+ /**
+ * Gets the value of a specified resource as a Number.
+ *
+ * <p>This method calls <code>getObject()</code>
+ * and casts the result to a Number.
+ * It is useful if you have written a line such as:</p>
+ *
+ * <pre>
+ * LONGITUDE=170.3
+ * </pre>
+ *
+ * <p>in a properties file and want to obtain the value
+ * 170.3 rather than <code>"170.3"</code>.</p>
+ *
+ * <p>If the specified resource is not found,
+ * this method returns <code>NaN</code>.</p>
+ *
+ * @param bundleName The name of a resource bundle.
+ *
+ * @param resourceName The name of a resource in the resource bundle.
+ *
+ * @param locale A specific locale to be used for the lookup,
+ * or <code>null</code> to search all locales
+ * in the <code>localeChain</code>.
+ * This parameter is optional and defaults to <code>null</code>;
+ * you should seldom need to specify it.
+ *
+ * @return The resource value, as a Number,
+ * or <code>NaN</code> if it is not found.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getNumber(bundleName:String, resourceName:String,
+ locale:String = null):Number;
+
+ [Bindable("change")]
+
+ /**
+ * Gets the value of a specified resource as an int.
+ *
+ * <p>This method calls <code>getObject()</code>
+ * and casts the result to an int.
+ * It is useful if you have written a line such as:</p>
+ *
+ * <pre>
+ * MINIMUM=5
+ * </pre>
+ *
+ * <p>in a properties file and want to obtain the value
+ * 5 rather than <code>"5"</code>.</p>
+ *
+ * <p>If the specified resource is not found,
+ * this method returns 0.</p>
+ *
+ * @param bundleName The name of a resource bundle.
+ *
+ * @param resourceName The name of a resource in the resource bundle.
+ *
+ * @param locale A specific locale to be used for the lookup,
+ * or <code>null</code> to search all locales
+ * in the <code>localeChain</code>.
+ * This parameter is optional and defaults to <code>null</code>;
+ * you should seldom need to specify it.
+ *
+ * @return The resource value, as an int,
+ * or 0 if it is not found.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getInt(bundleName:String, resourceName:String,
+ locale:String = null):int;
+
+ [Bindable("change")]
+
+ /**
+ * Gets the value of a specified resource as a uint.
+ *
+ * <p>This method calls the <code>getObject()</code> method
+ * and casts the result to a uint.
+ * It is useful if you have written a line such as:</p>
+ *
+ * <pre>
+ * MINIMUM=5
+ * </pre>
+ *
+ * <p>in a properties file and want to obtain the value
+ * 5 rather than <code>"5"</code>.</p>
+ *
+ * <p>If the specified resource is not found,
+ * this method returns 0.</p>
+ *
+ * @param bundleName The name of a resource bundle.
+ *
+ * @param resourceName The name of a resource in the resource bundle.
+ *
+ * @param locale A specific locale to be used for the lookup,
+ * or <code>null</code> to search all locales
+ * in the <code>localeChain</code>.
+ * This parameter is optional and defaults to <code>null</code>;
+ * you should seldom need to specify it.
+ *
+ * @return The resource value, as a uint,
+ * or 0 if it is not found.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getUint(bundleName:String, resourceName:String,
+ locale:String = null):uint;
+
+ [Bindable("change")]
+
+ /**
+ * Gets the value of a specified resource as a Boolean.
+ *
+ * <p>This method first calls <code>getString()</code>
+ * and converts the result to lowercase.
+ * It then returns <code>true</code>
+ * if the result was <code>"true"</code>.
+ * and <code>false</code> otherwise.</p>
+ *
+ * <p>If the specified resource is not found,
+ * this method returns <code>false</code>.</p>
+ *
+ * @param bundleName The name of a resource bundle.
+ *
+ * @param resourceName The name of a resource in the resource bundle.
+ *
+ * @param locale A specific locale to be used for the lookup,
+ * or <code>null</code> to search all locales
+ * in the <code>localeChain</code>.
+ * This parameter is optional and defaults to <code>null</code>;
+ * you should seldom need to specify it.
+ *
+ * @return The resource value, as a Boolean,
+ * or <code>false</code> if it is not found.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getBoolean(bundleName:String, resourceName:String,
+ locale:String = null):Boolean;
+
+ [Bindable("change")]
+
+ /**
+ * Gets the value of a specified resource as a Class.
+ *
+ * <p>This method calls <code>getObject()</code>
+ * and coerces it to type Class using the <code>as</code> operator.
+ * The result will be <code>null</code> if the resource value
+ * was not a class reference.
+ * It is useful if you have written a lines such as</p>
+ *
+ * <pre>
+ * IMAGE=Embed("image.jpg")
+ * BUTTON_SKIN=ClassReference("skins.ButtonSkin_en_US")
+ * </pre>
+ *
+ * <p>in a properties file and want to obtain
+ * the Class that the <code>Embed()</code>
+ * or <code>ClassReference()</code> directive produced.</p>
+ *
+ * <p>If the specified resource is not found,
+ * this method returns <code>null</code>.</p>
+ *
+ * @param bundleName The name of a resource bundle.
+ *
+ * @param resourceName The name of a resource in the resource bundle.
+ *
+ * @param locale A specific locale to be used for the lookup,
+ * or <code>null</code> to search all locales
+ * in the <code>localeChain</code>.
+ * This parameter is optional and defaults to <code>null</code>;
+ * you should seldom need to specify it.
+ *
+ * @return The resource value, as a <code>Class</code>,
+ * or <code>null</code> if it is not found.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function getClass(bundleName:String, resourceName:String,
+ locale:String = null):Class;
+
+ /**
+ * Creates instances of all ResourceBundle subclasses that were compiled into the SWF
+ * and adds them to the ResourceManager.
+ *
+ * <p>For example, if the <code>locales</code> parameter is [ "en_US", "ja_JP" ]
+ * and the <code>bundleNames</code> parameter is [ "core", "controls" ],
+ * then four resource bundles will be installed.</p>
+ *
+ * <p>This method is used only by classes that implement the IFlexModuleFactory interface.</p>
+ *
+ * @param applicationDomain The ApplicationDomain that is used to look up the resource bundle
+ * classes by name.
+ *
+ * @param locales An Array of Strings that specify the locales for which the SWF was compiled.
+ *
+ * @param bundleNames An Array of Strings that specify the names of the resource bundles
+ * that were compiled into the SWF.
+ *
+ * @param useWeakReference A flag that specifyies whether the resource bundles should be
+ * intalled into the ResourceManager using a weak reference.
+ *
+ * @return An Array of the ResourceBundle instances that were created
+ * and added to the ResourceManager.
+ *
+ * @see mx.core.IFlexModuleFactory
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function installCompiledResourceBundles(
+ /*applicationDomain:ApplicationDomain,*/
+ locales:Array /* of String */,
+ bundleNames:Array /* of String */,
+ useWeakReference:Boolean = false):Array;
+
+ /**
+ * Initializes the <code>localeChain</code> property of the ResourceManager
+ * using an algorithm that compares the operating system's list of user-preferred
+ * locales with the list of locales available in the SWF.
+ *
+ * <p>For example, if the user has indicated in the operating system that she
+ * prefers French, and the SWF was compiled for the locales en_US, fr_FR, and de_DE,
+ * then the <code>localeChain</code> will be set so that the first locale in it
+ * is fr_FR.</p>
+ *
+ * <p>This method is used only by classes that implement the IFlexModuleFactory interface.</p>
+ *
+ * @param compiledLocales An Array of Strings specifying the locales
+ * for which the SWF was compiled.
+ *
+ * @see mx.core.IFlexModuleFactory
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ function initializeLocaleChain(compiledLocales:Array):void;
+}
+
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/resources/Locale.as b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/Locale.as
new file mode 100644
index 0000000..63a1a4a
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/Locale.as
@@ -0,0 +1,236 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 mx.managers.ISystemManager;
+
+/**
+ * The Locale class can be used to parse a locale String such as <code>"en_US_MAC"</code>
+ * into its three parts: a language code, a country code, and a variant.
+ *
+ * <p>The localization APIs in the IResourceManager and IResourceBundle
+ * interfaces use locale Strings rather than Locale instances,
+ * so this class is seldom used in an application.</p>
+ *
+ * @see mx.resources.IResourceBundle
+ * @see mx.resources.IResourceManager
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class Locale
+{
+// include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private static var currentLocale:Locale;
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @param localeString A 1-, 2-, or 3-part locale String,
+ * such as <code>"en"</code>, <code>"en_US"</code>, or <code>"en_US_MAC"</code>.
+ * The parts are separated by underscore characters.
+ * The first part is a two-letter lowercase language code
+ * as defined by ISO-639, such as <code>"en"</code> for English.
+ * The second part is a two-letter uppercase country code
+ * as defined by ISO-3166, such as <code>"US"</code> for the United States.
+ * The third part is a variant String, which can be used
+ * to optionally distinguish multiple locales for the same language and country.
+ * It is sometimes used to indicate the operating system
+ * that the locale should be used with, such as <code>"MAC"</code>, <code>"WIN"</code>, or <code>"UNIX"</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function Locale(localeString:String)
+ {
+ super();
+
+ this.localeString = localeString;
+
+ var parts:Array = localeString.split("_");
+
+ if (parts.length > 0)
+ _language = parts[0];
+
+ if (parts.length > 1)
+ _country = parts[1];
+
+ if (parts.length > 2)
+ _variant = parts.slice(2).join("_");
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private var localeString:String;
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // language
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the language property.
+ */
+ private var _language:String;
+
+ [Inspectable(category="General", defaultValue="null")]
+
+ /**
+ * The language code of this Locale instance. [Read-Only]
+ *
+ * <pre>
+ * var locale:Locale = new Locale("en_US_MAC");
+ * trace(locale.language); // outputs "en"
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get language():String
+ {
+ return _language;
+ }
+
+ //----------------------------------
+ // country
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the country property.
+ */
+ private var _country:String;
+
+ [Inspectable(category="General", defaultValue="null")]
+
+ /**
+ * The country code of this Locale instance. [Read-Only]
+ *
+ * <pre>
+ * var locale:Locale = new Locale("en_US_MAC");
+ * trace(locale.country); // outputs "US"
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get country():String
+ {
+ return _country
+ }
+
+ //----------------------------------
+ // variant
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the variant property.
+ */
+ private var _variant:String;
+
+ [Inspectable(category="General", defaultValue="null")]
+
+ /**
+ * The variant part of this Locale instance. [Read-Only]
+ *
+ * <pre>
+ * var locale:Locale = new Locale("en_US_MAC");
+ * trace(locale.variant); // outputs "MAC"
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get variant():String
+ {
+ return _variant;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Returns the locale String that was used to construct
+ * this Locale instance. For example:
+ *
+ * <pre>
+ * var locale:Locale = new Locale("en_US_MAC");
+ * trace(locale.toString()); // outputs "en_US_MAC"
+ * </pre>
+ *
+ * @return Returns the locale String that was used to
+ * construct this Locale instance.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function toString():String
+ {
+ return localeString;
+ }
+}
+
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/resources/LocaleSorter.as b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/LocaleSorter.as
new file mode 100644
index 0000000..bd23e98
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/LocaleSorter.as
@@ -0,0 +1,1084 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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
+{
+
+[ExcludeClass]
+
+/**
+ * @private
+ * The APIs of the LocaleSorter class provides the sorting functionality
+ * of application locales against system preferences.
+ */
+public class LocaleSorter
+{
+// include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Sorts a list of locales using the order specified
+ * by the user preferences.
+ *
+ * @param appLocales An Array of locales supported by the application.
+ *
+ * @param systemPreferences The locale chain of user-preferred locales.
+ *
+ * @param ultimateFallbackLocale The ultimate fallback locale
+ * that will be used when no locale from systemPreference matches
+ * a locale from application supported locale list.
+ *
+ * @param addAll When true, adds all the non-matching locales
+ * at the end of the result list preserving the given order.
+ *
+ * @return A locale chain that matches user preferences order.
+ */
+ public static function sortLocalesByPreference(
+ appLocales:Array, systemPreferences:Array,
+ ultimateFallbackLocale:String = null,
+ addAll:Boolean = false):Array
+ {
+ var result:Array = [];
+
+ var hasLocale:Object = {};
+
+ var i:int;
+ var j:int;
+
+ var locales:Array = trimAndNormalize(appLocales);
+ var preferenceLocales:Array = trimAndNormalize(systemPreferences);
+
+ addUltimateFallbackLocale(preferenceLocales, ultimateFallbackLocale);
+
+ var noLocales:int = locales.length;
+ var noPreferenceLocales:int = preferenceLocales.length;
+
+ // For better performance, save the locales in a lookup table.
+ for (j = 0; j < noLocales; j++)
+ {
+ hasLocale[locales[j]] = j;
+ }
+
+ function promote(locale:String):void
+ {
+ if (typeof hasLocale[locale] != "undefined")
+ {
+ result.push(appLocales[hasLocale[locale]]);
+ delete hasLocale[locale];
+ }
+ }
+
+ var preferenceLocalesID:Vector.<LocaleID> = new Vector.<LocaleID>(noPreferenceLocales);
+ for (i = 0; i < noPreferenceLocales; i++)
+ {
+ preferenceLocalesID[i] = LocaleID.fromString(preferenceLocales[i]);
+ }
+
+ var localesID:Vector.<LocaleID> = new Vector.<LocaleID>(noLocales);
+ for (i = 0; i < noLocales; i++)
+ {
+ localesID[i] = LocaleID.fromString(locales[i]);
+ }
+
+ for (i = 0; i < noPreferenceLocales; i++)
+ {
+ var plocale:LocaleID = preferenceLocalesID[i].clone();
+
+ // Step 1: Promote the perfect match.
+ promote(preferenceLocales[i]);
+
+ promote(plocale.toString());
+
+ // Step 2: Promote the parent chain.
+ while (plocale.transformToParent())
+ {
+ promote(plocale.toString());
+ }
+
+ // Parse it again.
+ plocale = preferenceLocalesID[i].clone();
+
+ // Step 3: Promote the order of siblings from preferenceLocales.
+ for (j = 0; j < noPreferenceLocales; j++)
+ {
+ if (plocale.isSiblingOf(preferenceLocalesID[j]))
+ promote(preferenceLocales[j]);
+ }
+
+ // Step 4: Promote all remaining siblings
+ // (aka not in preferenceLocales)
+ // eg. push en_UK after en_US and en if the user
+ // doesn't have en_UK in the preference list
+ for (j = 0; j < noLocales; j++)
+ {
+ if (plocale.isSiblingOf(localesID[j]))
+ promote(locales[j]);
+ }
+ }
+
+ if (addAll)
+ {
+ // Check what locales are not already loaded
+ // and push them preserving the order.
+ for (j = 0; j < noLocales; j++)
+ {
+ promote(locales[j]);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * @private
+ */
+ private static function trimAndNormalize(list:Array):Array
+ {
+ var resultList:Array = [];
+
+ for (var i:int = 0; i < list.length; i++)
+ {
+ resultList.push(normalizeLocale(list[i]));
+ }
+
+ return resultList;
+ }
+
+ /**
+ * @private
+ */
+ private static function normalizeLocale(locale:String):String
+ {
+ return locale.toLowerCase().replace(/-/g, "_");
+ }
+
+ /**
+ * @private
+ */
+ private static function addUltimateFallbackLocale(
+ preferenceLocales:Array,
+ ultimateFallbackLocale:String):void
+ {
+ if (ultimateFallbackLocale != null && ultimateFallbackLocale != "")
+ {
+ var locale:String = normalizeLocale(ultimateFallbackLocale);
+
+ if (preferenceLocales.indexOf(locale) == -1)
+ {
+ // Add the locale to the end of the chain.
+ preferenceLocales.push(locale);
+ }
+ }
+ }
+}
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Helper class: LocaleID
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @private
+ * The APIs of the internal LocaleID class parse a locale string
+ * according to:
+ * RFC 4646: http://www.ietf.org/rfc/rfc4646.txt
+ * RFC 4647: http://www.ietf.org/rfc/rfc4647.txt
+ * IANA Language Subtag Registry:
+ * http://www.iana.org/assignments/language-subtag-registry
+ */
+class LocaleID
+{
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ public static const STATE_PRIMARY_LANGUAGE:int = 0;
+
+ /**
+ * @private
+ */
+ public static const STATE_EXTENDED_LANGUAGES:int = 1;
+
+ /**
+ * @private
+ */
+ public static const STATE_SCRIPT:int = 2;
+
+ /**
+ * @private
+ */
+ public static const STATE_REGION:int = 3;
+
+ /**
+ * @private
+ */
+ public static const STATE_VARIANTS:int = 4;
+
+ /**
+ * @private
+ */
+ public static const STATE_EXTENSIONS:int = 5;
+
+ /**
+ * @private
+ */
+ public static const STATE_PRIVATES:int = 6;
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private static function appendElements(dest:Array, src:Array):void
+ {
+ for (var i:uint = 0, argc:uint = src.length; i < argc; i++)
+ {
+ dest.push(src[i]);
+ }
+ }
+
+ /**
+ * @private
+ */
+ public static function fromString(str:String):LocaleID
+ {
+ var localeID:LocaleID = new LocaleID();
+
+ var state:int = STATE_PRIMARY_LANGUAGE;
+ var subtags:Array = str.replace(/-/g, '_').split('_');
+
+ var last_extension:Array;
+
+ for (var i:int = 0, l:int = subtags.length; i < l; i++)
+ {
+ var subtag:String = subtags[i].toLowerCase();
+
+ if (state == STATE_PRIMARY_LANGUAGE)
+ {
+ if (subtag == "x")
+ {
+ localeID.privateLangs = true;
+ // not used in our implementation,
+ // but makes the tag private
+ }
+ else if (subtag == "i")
+ {
+ localeID.lang += "i-";
+ // and wait the next subtag
+ // to complete the language name
+ }
+ else
+ {
+ localeID.lang += subtag;
+ state = STATE_EXTENDED_LANGUAGES;
+ }
+ }
+ else
+ {
+ // looking for:
+ // an extended language - 3 chars
+ // a script - 4 chars
+ // a region - 2-3 chars
+ // a variant - alpha with at least 5 chars
+ // or numeric with at least 4 chars
+ // an extension/private singleton - 1 char
+
+ var subtag_length:int = subtag.length;
+ if (subtag_length == 0)
+ continue; // skip zero-lengthed subtags
+
+ var firstChar:String = subtag.charAt(0).toLowerCase();
+
+ if (state <= STATE_EXTENDED_LANGUAGES &&
+ subtag_length == 3)
+ {
+ localeID.extended_langs.push(subtag);
+ if (localeID.extended_langs.length == 3)
+ {
+ // Allow a maximum of 3 extended langs.
+ state = STATE_SCRIPT;
+ }
+ }
+ else if (state <= STATE_SCRIPT &&
+ subtag_length == 4)
+ {
+ localeID.script = subtag;
+ state = STATE_REGION;
+ }
+ else if (state <= STATE_REGION &&
+ (subtag_length == 2 || subtag_length == 3))
+ {
+ localeID.region = subtag;
+ state = STATE_VARIANTS;
+ }
+ else if (state <= STATE_VARIANTS &&
+ ((firstChar >= "a" && firstChar <= "z" &&
+ subtag_length >= 5) ||
+ (firstChar >= "0" && firstChar <= "9" &&
+ subtag_length >= 4)))
+ {
+ // variant
+ localeID.variants.push(subtag);
+ state = STATE_VARIANTS;
+ }
+ else if (state < STATE_PRIVATES &&
+ subtag_length == 1)
+ {
+ // singleton
+ if (subtag == "x")
+ {
+ state = STATE_PRIVATES;
+ last_extension = localeID.privates;
+ }
+ else
+ {
+ state = STATE_EXTENSIONS;
+ last_extension = localeID.extensions[subtag] || [];
+ localeID.extensions[subtag] = last_extension;
+ }
+ }
+ else if (state >= STATE_EXTENSIONS)
+ {
+ last_extension.push(subtag);
+ }
+ }
+ }
+
+ localeID.canonicalize();
+
+ return localeID;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function LocaleID()
+ {
+ super();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private var lang:String = "";
+
+ /**
+ * @private
+ */
+ private var script:String = "";
+
+ /**
+ * @private
+ */
+ private var region:String = "";
+
+ /**
+ * @private
+ */
+ private var extended_langs:Array = [];
+
+ /**
+ * @private
+ */
+ private var variants:Array = [];
+
+ /**
+ * @private
+ */
+ private var extensions:Object = {};
+
+ /**
+ * @private
+ */
+ private var privates:Array = [];
+
+ /**
+ * @private
+ */
+ private var privateLangs:Boolean = false;
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ public function clone():LocaleID {
+
+ var copy:LocaleID = new LocaleID();
+ copy.lang = lang;
+ copy.script = script;
+ copy.region = region;
+ copy.extended_langs = extended_langs.concat();
+ copy.variants = variants.concat();
+ copy.extensions = {};
+ for (var i:String in extensions)
+ {
+ if (extensions.hasOwnProperty(i))
+ {
+ copy.extensions[i] = extensions[i].concat();
+ }
+ }
+
+ copy.privates = privates.concat();
+ copy.privateLangs = privateLangs;
+
+ return copy;
+ }
+
+ /**
+ * @private
+ */
+ public function canonicalize():void
+ {
+ for (var i:String in extensions)
+ {
+ if (extensions.hasOwnProperty(i))
+ {
+ // Also clear zero length extensions.
+ if (extensions[i].length == 0)
+ delete extensions[i];
+ else
+ extensions[i] = extensions[i].sort();
+ }
+ }
+
+ extended_langs = extended_langs.sort();
+ variants = variants.sort();
+ privates = privates.sort();
+
+ if (script == "")
+ script = LocaleRegistry.getScriptByLang(lang);
+
+ // Still no script, check the region.
+ if (script == "" && region != "")
+ script = LocaleRegistry.getScriptByLangAndRegion(lang, region);
+
+ if (region == "" && script != "")
+ {
+ region = LocaleRegistry.getDefaultRegionForLangAndScript(
+ lang, script);
+ }
+ }
+
+ /**
+ * @private
+ */
+ public function toString():String
+ {
+ var stack:Array = [ lang ];
+
+ appendElements(stack, extended_langs);
+
+ if (script != "")
+ stack.push(script);
+
+ if (region != "")
+ stack.push(region);
+
+ appendElements(stack, variants);
+
+ for (var i:String in extensions)
+ {
+ if (extensions.hasOwnProperty(i))
+ {
+ stack.push(i);
+ appendElements(stack, extensions[i]);
+ }
+ }
+
+ if (privates.length > 0)
+ {
+ stack.push("x");
+ appendElements(stack, privates);
+ }
+
+ return stack.join("_");
+ }
+
+ /**
+ * @private
+ */
+ public function equals(locale:LocaleID):Boolean
+ {
+ return toString() == locale.toString();
+ }
+
+ /**
+ * @private
+ */
+ public function isSiblingOf(other:LocaleID):Boolean
+ {
+ return lang == other.lang && script == other.script;
+ }
+
+ /**
+ * @private
+ */
+ public function transformToParent():Boolean
+ {
+ if (privates.length > 0)
+ {
+ privates.splice(privates.length - 1, 1);
+ return true;
+ }
+
+ var lastExtensionName:String = null;
+ for (var i:String in extensions)
+ {
+ if (extensions.hasOwnProperty(i))
+ lastExtensionName = i;
+ }
+
+ if (lastExtensionName)
+ {
+ var lastExtension:Array = extensions[lastExtensionName];
+ if (lastExtension.length == 1)
+ {
+ delete extensions[lastExtensionName];
+ return true;
+ }
+ lastExtension.splice(lastExtension.length - 1, 1);
+ return true;
+ }
+
+ if (variants.length > 0)
+ {
+ variants.splice(variants.length - 1, 1);
+ return true;
+ }
+
+ if (script != "")
+ {
+ // Check if we can suppress the script.
+ if (LocaleRegistry.getScriptByLang(lang) != "")
+ {
+ script = "";
+ return true;
+ }
+ else if (region == "")
+ {
+ // Maybe the default region can suppress the script.
+ var defaultRegion:String =
+ LocaleRegistry.getDefaultRegionForLangAndScript(
+ lang, script);
+ if (defaultRegion != "")
+ {
+ region = defaultRegion;
+ script = "";
+ return true;
+ }
+ }
+ }
+
+ if (region != "")
+ {
+ if (!(script == "" && LocaleRegistry.getScriptByLang(lang) == ""))
+ {
+ region = "";
+ return true;
+ }
+ }
+
+ if (extended_langs.length > 0)
+ {
+ extended_langs.splice(extended_langs.length - 1, 1);
+ return true;
+ }
+
+ return false;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Helper class: LocaleRegistry
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * @private
+ */
+class LocaleRegistry
+{
+ //--------------------------------------------------------------------------
+ //
+ // Class constants
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * A list of codes representing writing systems, in arbitrary order.
+ * For example, "latn" represents the Latin alphabet, used for
+ * writing languages such as English, French, Indonesian, and Swahili,
+ * and "arab" represents the Arabic script, used for writing
+ * Arabic, Persian, Pashto, and Urdu.
+ */
+ private static const SCRIPTS:Array =
+ [
+ "", // 0
+ "latn", // 1 Latin
+ "ethi", // 2 Ethiopian
+ "arab", // 3 Arabic
+ "beng", // 4 Bengali
+ "cyrl", // 5 Cyrillic
+ "thaa", // 6 Thaana
+ "tibt", // 7 Tibetan
+ "grek", // 8 Greek
+ "gujr", // 9 Gujarati
+ "hebr", // 10 Hebrew
+ "deva", // 11 Devanagari
+ "armn", // 12 Armenian
+ "jpan", // 13 Japanese
+ "geor", // 14 Georgian
+ "khmr", // 15 Khmer
+ "knda", // 16 Kannada
+ "kore", // 17 Korean
+ "laoo", // 18 Lao
+ "mlym", // 19 Malayalam
+ "mymr", // 20 Burmese
+ "orya", // 21 Oriya
+ "guru", // 22 Punjabi
+ "sinh", // 23 Sinhalese
+ "taml", // 24 Tamil
+ "telu", // 25 Telugu
+ "thai", // 26 Thai
+ "nkoo", // 27 N'Ko
+ "blis", // 28 Bliss
+ "hans", // 29 Simplified Chinese
+ "hant", // 30 Traditional Chinese
+ "mong", // 31 Mongolian
+ "syrc" // 32 Syriac
+ ];
+
+ /**
+ * @private
+ * The inverse of the SCRIPT Array.
+ * Maps a script code (like "jpan" for Japanese)
+ * to its index in the SCRIPT Array.
+ */
+ private static const SCRIPT_BY_ID:Object =
+ {
+ latn: 1,
+ ethi: 2,
+ arab: 3,
+ beng: 4,
+ cyrl: 5,
+ thaa: 6,
+ tibt: 7,
+ grek: 8,
+ gujr: 9,
+ hebr: 10,
+ deva: 11,
+ armn: 12,
+ jpan: 13,
+ geor: 14,
+ khmr: 15,
+ knda: 16,
+ kore: 17,
+ laoo: 18,
+ mlym: 19,
+ mymr: 20,
+ orya: 21,
+ guru: 22,
+ sinh: 23,
+ taml: 24,
+ telu: 25,
+ thai: 26,
+ nkoo: 27,
+ blis: 28,
+ hans: 29,
+ hant: 30,
+ mong: 31,
+ syrc: 32
+ };
+
+ /**
+ * @private
+ * This table maps a language and a script to the most
+ * prominent region where that combination is used.
+ *
+ * Note: "is" must be quoted because it is a reserved word.
+ */
+ private static const DEFAULT_REGION_BY_LANG_AND_SCRIPT:Object =
+ {
+ bg: { 5: "bg" }, // Bulgarian / Cyrillic -> Bulgaria
+ ca: { 1: "es" }, // Catalan / Latin -> Spain
+ zh: { 30: "tw", 29: "cn" }, // Chinese / Traditional Chinese -> Taiwan
+ // Chinese / Simplified Chinese -> China
+ cs: { 1: "cz" }, // Czech / Latin -> Czech Republic
+ da: { 1: "dk" }, // Danish / Latin -> Denmark
+ de: { 1: "de" }, // German / Latin -> Germany
+ el: { 8: "gr" }, // Greek / Greek -> Greece
+ en: { 1: "us" }, // English / Latin -> United States
+ es: { 1: "es" }, // Spanish / Latin -> Spain
+ fi: { 1: "fi" }, // Finnish / Latin -> Finland
+ fr: { 1: "fr" }, // French / Latin -> France
+ he: { 10: "il" }, // Hebrew / Hebrew -> Israel
+ hu: { 1: "hu" }, // Hungarian / Latin -> Hungary
+ "is": { 1: "is" }, // Icelandic / Latin -> Iceland
+ it: { 1: "it" }, // Italian / Latin -> Italy
+ ja: { 13: "jp" }, // Japanese / Japanese -> Japan
+ ko: { 17: "kr" }, // Korean / Korean -> Korea
+ nl: { 1: "nl" }, // Dutch / Latin -> Netherlands
+ nb: { 1: "no" }, // Norwegian Bokmaal / Latin -> Norway
+ pl: { 1: "pl" }, // Polish / Latin -> Poland
+ pt: { 1: "br" }, // Portuguese / Latin -> Brazil
+ ro: { 1: "ro" }, // Romanian / Latin -> Romania
+ ru: { 5: "ru" }, // Russian / Cyrillic -> Russia
+ hr: { 1: "hr" }, // Croatian / Latin -> Croatia
+ sk: { 1: "sk" }, // Slovak / Latin -> Slovakia
+ sq: { 1: "al" }, // Albanian / Latin -> Albania
+ sv: { 1: "se" }, // Swedish / Latin -> Sweden
+ th: { 26: "th" }, // Thai / Thai -> Thailand
+ tr: { 1: "tr" }, // Turkish / Latin -> Turkey
+ ur: { 3: "pk" }, // Urdu / Arabic -> Pakistan
+ id: { 1: "id" }, // Indonesian / Latin -> Indonesia
+ uk: { 5: "ua" }, // Ukrainian / Cyrillic -> Ukraine
+ be: { 5: "by" }, // Byelorussian / Cyrillic -> Belarus
+ sl: { 1: "si" }, // Slovenian / Latin -> Slovenia
+ et: { 1: "ee" }, // Estonian / Latin -> Estonia
+ lv: { 1: "lv" }, // Latvian / Latin -> Latvia
+ lt: { 1: "lt" }, // Lithuanian / Latin -> Lithuania
+ fa: { 3: "ir" }, // Persian / Arabic -> Iran
+ vi: { 1: "vn" }, // Vietnamese / Latin -> Vietnam
+ hy: { 12: "am"}, // Armenian / Armenian -> Armenia
+ az: { 1: "az", 5: "az" }, // Azerbaijani / Latin -> Azerbaijan
+ // Azerbaijani / Cyrillic -> Azerbaijan
+ eu: { 1: "es" }, // Basque / Latin -> Spain
+ mk: { 5: "mk" }, // Macedonian / Cyrillic -> Macedonia
+ af: { 1: "za" }, // Afrikaans / Latin -> South Africa
+ ka: { 14: "ge" }, // Georgian / Georgian -> Georgia
+ fo: { 1: "fo" }, // Faeroese / Latin -> Faroe Islands
+ hi: { 11: "in" }, // Hindi / Devanagari -> India
+ ms: { 1: "my" }, // Malay / Latin -> Malaysia
+ kk: { 5: "kz" }, // Kazakh / Cyrillic -> Kazakhstan
+ ky: { 5: "kg" }, // Kirghiz / Cyrillic -> Kyrgyzstan
+ sw: { 1: "ke" }, // Swahili / Latin -> Kenya
+ uz: { 1: "uz", 5: "uz" }, // Uzbek / Latin -> Uzbekistan
+ // Uzbek / Cyrillic -> Uzbekistan
+ tt: { 5: "ru" }, // Tatar / Cyrillic -> Russia
+ pa: { 22: "in" }, // Punjabi / Punjabi -> India
+ gu: { 9: "in" }, // Gujarati / Gujarati -> India
+ ta: { 24: "in" }, // Tamil / Tamil -> India
+ te: { 25: "in" }, // Telugu / Telugu -> India
+ kn: { 16: "in" }, // Kannada / Kannada -> India
+ mr: { 11: "in" }, // Marathi / Devanagari -> India
+ sa: { 11: "in" }, // Sanskrit / Devanagari -> India
+ mn: { 5: "mn" }, // Mongolian / Cyrillic -> Mongolia
+ gl: { 1: "es" }, // Galician / Latin -> Spain
+ kok: { 11: "in" }, // Konkani / Devanagari -> India
+ syr: { 32: "sy" }, // Syriac / Syriac -> Syria
+ dv: { 6: "mv" }, // Dhivehi / Thaana -> Maldives
+ nn: { 1: "no" }, // Norwegian Nynorsk / Latin -> Norway
+ sr: { 1: "cs", 5: "cs" }, // Serbian / Latin -> Serbia
+ // Serbian / Cyrillic -> Serbia
+ cy: { 1: "gb" }, // Welsh / Latin -> United Kingdom
+ mi: { 1: "nz" }, // Maori / Latin -> New Zealand
+ mt: { 1: "mt" }, // Maltese / Latin -> Malta
+ quz: { 1: "bo" }, // Quechua / Latin -> Bolivia
+ tn: { 1: "za" }, // Tswana / Latin -> South Africa
+ xh: { 1: "za" }, // Xhosa / Latin -> South Africa
+ zu: { 1: "za" }, // Zulu / Latin -> South Africa
+ nso: { 1: "za" }, // Northern Sotho / Latin -> South Africa
+ se: { 1: "no" }, // Northern Saami / Latin -> Norway
+ smj: { 1: "no" }, // Lule Saami / Latin -> Norway
+ sma: { 1: "no" }, // Southern Saami / Latin -> Norway
+ sms: { 1: "fi" }, // Skolt Saami / Latin -> Finland
+ smn: { 1: "fi" }, // Inari Saami / Latin -> Finland
+ bs: { 1: "ba" } // Bosnia / Latin -> Bosnia
+ };
+
+ /**
+ * @private
+ * This table maps a language to a script.
+ * It was derived from the entries at
+ * http://www.iana.org/assignments/language-subtag-registry
+ * which have a Suppress-Script property.
+ *
+ * Note: "as", "in", and "is" must be quoted
+ * because they are reserved words.
+ */
+ private static const SCRIPT_ID_BY_LANG:Object =
+ {
+ ab: 5, // Abkhazian -> Cyrillic
+ af: 1, // Afrikaans -> Latin
+ am: 2, // Amharic -> Ethiopian
+ ar: 3, // Arabic -> Arabic
+ "as": 4, // Assamese -> Bengali
+ ay: 1, // Aymara -> Latin
+ be: 5, // Belarusian -> Cyrillic
+ bg: 5, // Bulgarian -> Cyrillic
+ bn: 4, // Bengali -> Bengali
+ bs: 1, // Bosnian -> Latin
+ ca: 1, // Catalan / Valencian -> Latin
+ ch: 1, // Chamorro -> Latin
+ cs: 1, // Czech -> Latin
+ cy: 1, // Welsh -> Latin
+ da: 1, // Danish -> Latin
+ de: 1, // German -> Latin
+ dv: 6, // Dhivehi / Maldivian -> Thaana
+ dz: 7, // Dzongkha -> Tibetan
+ el: 8, // Modern Greek -> Greek
+ en: 1, // English -> Latin
+ eo: 1, // Esperanto -> Latin
+ es: 1, // Spanish / Castilian -> Latin
+ et: 1, // Estonian -> Latin
+ eu: 1, // Basque -> Latin
+ fa: 3, // Persian -> Arabic
+ fi: 1, // Finnish -> Latin
+ fj: 1, // Fijian -> Latin
+ fo: 1, // Faroese -> Latin
+ fr: 1, // French -> Latin
+ frr: 1, // Northern Frisian -> Latin
+ fy: 1, // Western Frisian -> Latin
+ ga: 1, // Irish -> Latin
+ gl: 1, // Galician -> Latin
+ gn: 1, // Guarani -> Latin
+ gu: 9, // Gujarati -> Gujarati
+ gv: 1, // Manx -> Latin
+ he: 10, // Hebrew -> Hebrew
+ hi: 11, // Hindi -> Devanagari
+ hr: 1, // Croatian -> Latin
+ ht: 1, // Haitian Creole -> Latin
+ hu: 1, // Hungarian -> Latin
+ hy: 12, // Armenian -> Armenian
+ id: 1, // Indonesian -> Latin
+ "in": 1, // Indonesian -> Latin
+ "is": 1, // Icelandic -> Latin
+ it: 1, // Italian -> Latin
+ iw: 10, // Hebrew -> Hebrew
+ ja: 13, // Japanese -> Japanese
+ ka: 14, // Georgian -> Georgian
+ kk: 5, // Kazakh -> Cyrillic
+ kl: 1, // Kalaallisut / Greenlandic -> Latin
+ km: 15, // Central Khmer -> Khmer
+ kn: 16, // Kannada -> Kannada
+ ko: 17, // Korean -> Korean
+ la: 1, // Latin -> Latin
+ lb: 1, // Luxembourgish -> Latin
+ ln: 1, // Lingala -> Latin
+ lo: 18, // Lao -> Lao
+ lt: 1, // Lithuanian -> Latin
+ lv: 1, // Latvian -> Latin
+ mg: 1, // Malagasy -> Latin
+ mh: 1, // Marshallese -> Latin
+ mk: 5, // Macedonian -> Cyrillic
+ ml: 19, // Malayalam -> Malayalam
+ mo: 1, // Moldavian -> Latin
+ mr: 11, // Marathi -> Devanagari
+ ms: 1, // Malay -> Latin
+ mt: 1, // Maltese -> Latin
+ my: 20, // Burmese -> Burmese
+ na: 1, // Nauru -> Latin
+ nb: 1, // Norwegian Bokmaal -> Latin
+ nd: 1, // North Ndebele -> Latin
+ ne: 11, // Nepali -> Devanagari
+ nl: 1, // Dutch / Flemish -> Latin
+ nn: 1, // Norwegian Nynorsk -> Latin
+ no: 1, // Norwegian -> Latin
+ nr: 1, // South Ndebele -> Latin
+ ny: 1, // Chichewa / Chewa / Nyanja -> Latin
+ om: 1, // Oromo -> Latin
+ or: 21, // Oriya -> Oriya
+ pa: 22, // Punjabi -> Punjabi
+ pl: 1, // Polish -> Latin
+ ps: 3, // Pashto -> Arabic
+ pt: 1, // Portuguese -> Latin
+ qu: 1, // Quechua -> Latin
+ rn: 1, // Rundi -> Latin
+ ro: 1, // Romanian -> Latin
+ ru: 5, // Russian -> Cyrillic
+ rw: 1, // Kinyarwanda -> Latin
+ sg: 1, // Sango -> Latin
+ si: 23, // Sinhalese -> Sinhalese
+ sk: 1, // Slovak -> Latin
+ sl: 1, // Slovenian -> Latin
+ sm: 1, // Samoan -> Latin
+ so: 1, // Somali -> Latin
+ sq: 1, // Albanian -> Latin
+ ss: 1, // Swati -> Latin
+ st: 1, // Southern Sotho -> Latin
+ sv: 1, // Swedish -> Latin
+ sw: 1, // Swahili -> Latin
+ ta: 24, // Tamil -> Tamil
+ te: 25, // Telugu -> Telugu
+ th: 26, // Thai -> Thai
+ ti: 2, // Tigrinya -> Ethiopian
+ tl: 1, // Tagalog -> Latin
+ tn: 1, // Tswana -> Latin
+ to: 1, // Tonga -> Latin
+ tr: 1, // Turkish -> Latin
+ ts: 1, // Tsonga -> Latin
+ uk: 5, // Ukrainian -> Cyrillic
+ ur: 3, // Urdu -> Arabic
+ ve: 1, // Venda -> Latin
+ vi: 1, // Vietnamese -> Latin
+ wo: 1, // Wolof -> Latin
+ xh: 1, // Xhosa -> Latin
+ yi: 10, // Yiddish -> Hebrew
+ zu: 1, // Zulu -> Latin
+ cpe: 1, // Creoles and pidgins -> Latin
+ dsb: 1, // Lower Sorbian -> Latin
+ frs: 1, // Eastern Frisian -> Latin
+ gsw: 1, // Swiss German / Alemaanic / Alsatian -> Latin
+ hsb: 1, // Upper Sorbian -> Latin
+ kok: 11, // Konkana -> Devanagari
+ mai: 11, // Maithili -> Devanagari
+ men: 1, // Mende -> Latin
+ nds: 1, // Low German -> Latin
+ niu: 1, // Niuean -> Latin
+ nqo: 27, // N'Ko -> N'Ko
+ nso: 1, // Northern Sotho / Pedi / Sepedi -> Latin
+ son: 1, // Songhai -> Latin
+ tem: 1, // Timne -> Latin
+ tkl: 1, // Tokelau -> Latin
+ tmh: 1, // Tamashek -> Latin
+ tpi: 1, // Tok Pisin -> Latin
+ tvl: 1, // Tuvalu -> Latin
+ zbl: 28 // Bliss -> Bliss
+ };
+
+ /**
+ * @private
+ * This table maps a language-as-spoken-in-a-region
+ * to the script used to write it.
+ *
+ * Chinese in China -> Simplified Chinese
+ * Chinese in Singapore -> Simplified Chinese
+ * Chinese in Taiwan -> Traditional Chinese
+ * Chinese in Hong Kong -> Traditional Chinese
+ * Chinese in Macao -> Traditional Chinese
+ * Mongolian in China -> Mongolian
+ * Mongolian in Singapore -> Cyrillic
+ * Punjabi in Pakistan -> Arabic
+ * Punjabi in India -> Punjabi
+ * Hausa in Ghana -> Latin
+ * Hausa in Niger -> Latin
+ */
+ private static const SCRIPT_ID_BY_LANG_AND_REGION:Object =
+ {
+ zh: { cn: 29, sg: 29, tw: 30, hk: 30, mo: 30 },
+ mn: { cn: 31, sg: 5 },
+ pa: { pk: 3, "in": 22 }, // "in" is reserved word
+ ha: { gh: 1, ne: 1 }
+ };
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Given a language and a region, returns the script system
+ * used to write the language there.
+ *
+ * Examples:
+ * lang zh (Chinese), region cn (China) -> hans (Simplified Chinese)
+ * lang zh (Chinese), region tw (Taiwan) -> hast (Traditional Chinese)
+ */
+ public static function getScriptByLangAndRegion(
+ lang:String, region:String):String
+ {
+ var langRegions:Object = SCRIPT_ID_BY_LANG_AND_REGION[lang];
+ if (langRegions == null)
+ return "";
+
+ var scriptID:Object = langRegions[region];
+ if (scriptID == null)
+ return "";
+
+ return SCRIPTS[int(scriptID)].toLowerCase();
+ }
+
+ /**
+ * @private
+ * Given a language, returns the script generally used to write it.
+ *
+ * Examples:
+ * lang bg (Bulgarian) -> cyrl (Cyrillic)
+ */
+ public static function getScriptByLang(lang:String):String
+ {
+ var scriptID:Object = SCRIPT_ID_BY_LANG[lang];
+ if (scriptID == null)
+ return "";
+
+ return SCRIPTS[int(scriptID)].toLowerCase();
+ }
+
+ /**
+ * @private
+ * Given a language and a script used for writing it,
+ * returns the most prominent region where that combination is used.
+ *
+ * Examples:
+ */
+ public static function getDefaultRegionForLangAndScript(
+ lang:String, script:String):String
+ {
+ var langObj:Object = DEFAULT_REGION_BY_LANG_AND_SCRIPT[lang];
+ var scriptID:Object = SCRIPT_BY_ID[script];
+ if (langObj == null || scriptID == null)
+ return "";
+
+ return langObj[int(scriptID)] || "";
+ }
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/resources/ResourceBundle.as b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/ResourceBundle.as
new file mode 100644
index 0000000..320271d
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/ResourceBundle.as
@@ -0,0 +1,249 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.system.ApplicationDomain;
+
+import mx.core.mx_internal;
+import mx.utils.StringUtil;
+
+use namespace mx_internal;
+
+/**
+ * Provides an implementation of the IResourceBundle interface.
+ * The IResourceManager and IResourceBundle interfaces work together
+ * to provide internationalization support for Flex applications.
+ *
+ * <p>A Flex application typically has multiple instances of this class,
+ * all managed by a single instance of the ResourceManager class.
+ * It is possible to have ResourceBundle instances for multiple locales,
+ * one for each locale. There can be multiple ResourceBundle instances with
+ * different bundle names.</p>
+ *
+ * @see mx.resources.IResourceBundle
+ * @see mx.resources.IResourceManager
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class ResourceBundle implements IResourceBundle
+{
+// include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Set by SystemManager constructor in order to make the deprecated
+ * getResourceBundle() method work with the new resource scheme
+ * in the single-locale case.
+ */
+ mx_internal static var locale:String;
+
+ /**
+ * @private
+ * Set by bootstrap loaders
+ * to allow for alternate search paths for resources
+ */
+// mx_internal static var backupApplicationDomain:ApplicationDomain;
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ private static function getClassByName(name:String,
+ domain:ApplicationDomain):Class
+ {
+ var c:Class;
+
+ if (domain.hasDefinition(name))
+ c = domain.getDefinition(name) as Class;
+
+ return c;
+ }
+ */
+
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Constructor.
+ *
+ * @param locale A locale string, such as <code>"en_US"</code>.
+ *
+ * @param bundleName A name that identifies this bundle,
+ * such as <code>"MyResources"</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function ResourceBundle(locale:String = null,
+ bundleName:String = null)
+ {
+ // The only reason that the arguments are optional is so that
+ // Flex 3 applications can link against Flex 2 resource SWCs.
+ // In Flex 2, the constructor had no arguments at all
+ // and the autogenerated ResourceBundle subclasses
+ // therefore called super() with no arguments.
+ // If, in Flex 3, the constructor has required arguments,
+ // this causes a VerifyError.
+
+ super();
+
+ _locale = locale;
+ _bundleName = bundleName;
+
+ _content = getContent();
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // bundleName
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the bundleName property.
+ */
+ mx_internal var _bundleName:String;
+
+ /**
+ * @copy mx.resources.IResourceBundle#bundleName
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get bundleName():String
+ {
+ return _bundleName;
+ }
+
+ //----------------------------------
+ // content
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the content property.
+ */
+ private var _content:Object = {};
+
+ /**
+ * @copy mx.resources.IResourceBundle#content
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get content():Object
+ {
+ return _content;
+ }
+
+ //----------------------------------
+ // locale
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the locale property.
+ */
+ mx_internal var _locale:String;
+
+ /**
+ * @copy mx.resources.IResourceBundle#locale
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get locale():String
+ {
+ return _locale;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * When a properties file is compiled into a resource bundle,
+ * the MXML compiler autogenerates a subclass of ResourceBundle.
+ * The subclass overrides this method to return an Object
+ * that contains key-value pairs for the bundle's resources.
+ *
+ * <p>If you create your own ResourceBundle instances,
+ * you can set the key-value pairs on the <code>content</code> object.</p>
+ *
+ * @return The Object that contains key-value pairs for the bundle's resources.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function getContent():Object
+ {
+ return {};
+ }
+
+ /**
+ * @private
+ */
+ private function _getObject(key:String):Object
+ {
+ var value:Object = content[key];
+ if (!value)
+ {
+ throw new Error("Key " + key +
+ " was not found in resource bundle " + bundleName);
+ }
+ return value;
+ }
+}
+
+}
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/resources/ResourceManager.as b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/ResourceManager.as
new file mode 100644
index 0000000..4a00afe
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/ResourceManager.as
@@ -0,0 +1,130 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 org.apache.royale.events.Event;
+import org.apache.royale.events.EventDispatcher;
+import org.apache.royale.events.IEventDispatcher;
+
+import mx.core.IFlexModuleFactory;
+import mx.core.mx_internal;
+//import mx.core.Singleton;
+//import mx.events.ModuleEvent;
+import mx.events.ResourceEvent;
+import mx.modules.IModuleInfo;
+import mx.modules.ModuleManager;
+import mx.utils.StringUtil;
+
+/**
+ * This class is used to get a single instance of the IResourceManager
+ * implementation.
+ * The IResourceManager and IResourceBundle interfaces work together
+ * to provide internationalization support for Flex applications.
+ *
+ * <p>A single instance of an IResourceManager implementation
+ * manages all localized resources
+ * for a Flex application.</p>
+ *
+ * @see mx.resources.IResourceManager
+ * @see mx.resources.IResourceBundle
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class ResourceManager
+{
+// include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * Linker dependency on implementation class.
+ */
+ private static var implClassDependency:ResourceManagerImpl;
+
+ /**
+ * @private
+ * The sole instance of the ResourceManager.
+ */
+ private static var instance:IResourceManager;
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Gets the single instance of the ResourceManager 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)
+ {
+ /*
+ if (!Singleton.getClass("mx.resources::IResourceManager"))
+ // install ResourceManagerImpl if not registered already
+ Singleton.registerClass("mx.resources::IResourceManager",
+ Class(getDefinitionByName("mx.resources::ResourceManagerImpl")));
+
+
+ try
+ {
+ instance = IResourceManager(
+ Singleton.getInstance("mx.resources::IResourceManager"));
+ }
+ catch(e:Error)
+ {
+ // In non-Flex apps and modules, the Singleton manager
+ // won't have been initialized by SystemManager
+ // or FlexModuleFactory (since these don't get linked in)
+ // so the above call to getInstance() will throw an exception.
+ }
+
+ // In this situation, the ResourceManager simply creates
+ // its own ResourceManagerImpl.
+ */
+ if (!instance)
+ instance = new ResourceManagerImpl();
+
+ }
+
+ return instance;
+ }
+
+}
+
+}
\ No newline at end of file
diff --git a/frameworks/projects/MXRoyale/src/main/royale/mx/resources/ResourceManagerImpl.as b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/ResourceManagerImpl.as
new file mode 100644
index 0000000..19126e6
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/resources/ResourceManagerImpl.as
@@ -0,0 +1,1408 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 org.apache.royale.events.Event;
+import org.apache.royale.events.EventDispatcher;
+import org.apache.royale.events.IEventDispatcher;
+import org.apache.royale.utils.LocaleUtils;
+import org.apache.royale.reflection.getDefinitionByName;
+/*
+import flash.events.FocusEvent;
+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="org.apache.royale.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;
+ /* figure this out later, if needed
+ 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
+ * @royaleignorecoercion Class
+ */
+ 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;
+ bundleClass = getDefinitionByName(resourceBundleClassName) as Class;
+
+ if (!bundleClass)
+ {
+ resourceBundleClassName = bundleName;
+ bundleClass = getDefinitionByName(resourceBundleClassName) as Class;
+ }
+
+ // In case we linked against a Flex 2 SWC, look for the old
+ // class name.
+ if (!bundleClass)
+ {
+ resourceBundleClassName = bundleName + "_properties";
+ bundleClass = getDefinitionByName(resourceBundleClassName) as Class;
+ }
+
+ 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;
+
+ if(!(resourceName in resourceBundle.content))
+ 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 ];
+ */
+ systemPreferences = [ LocaleUtils.getLocale() ];
+
+ 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 org.apache.royale.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;
+ }
+}