You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2016/06/16 22:59:43 UTC
[26/50] [abbrv] git commit: [flex-asjs] [refs/heads/spark] - Merge
branch 'develop' into spark
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/utils/LoaderUtil.as
----------------------------------------------------------------------
diff --cc frameworks/projects/MX/src/main/flex/mx/utils/LoaderUtil.as
index 26f2e4e,0000000..94166ac
mode 100644,000000..100644
--- a/frameworks/projects/MX/src/main/flex/mx/utils/LoaderUtil.as
+++ b/frameworks/projects/MX/src/main/flex/mx/utils/LoaderUtil.as
@@@ -1,679 -1,0 +1,679 @@@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.utils
+{
- COMPILE::AS3
++COMPILE::SWF
+{
+import flash.display.DisplayObject;
+import flash.display.Loader;
+import flash.display.LoaderInfo;
+import flash.events.IEventDispatcher;
+import flash.system.Capabilities;
+import flash.utils.Dictionary;
+}
+COMPILE::JS
+{
+}
+COMPILE::LATER
+{
+import mx.core.ApplicationDomainTarget;
+import mx.core.RSLData;
+}
+import mx.core.IFlexModuleFactory;
+import mx.core.mx_internal;
+import mx.events.Request;
+import mx.managers.SystemManagerGlobals;
+import mx.utils.Platform;
+
+use namespace mx_internal;
+
+ /**
+ * The LoaderUtil class defines utility methods for use with Flex RSLs and
+ * generic Loader instances.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public class LoaderUtil
+ {
+
+ include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ *
+ * An array of search strings and filters. These are used in the normalizeURL
+ * method. normalizeURL is used to remove special Flash Player markup from
+ * urls, but the array could be appended to by the user to modify urls in other
+ * ways.
+ *
+ * Each object in the array has two fields:
+ *
+ * 1. searchString - the string to search the url
+ * 2. filterFunction - a function that accepts an url and an index to the first
+ * occurrence of the search string in the url. The function may modify the url
+ * and return a new url. A filterFunction is only called once, for the first
+ * occurrence of where the searchString was found. If there
+ * are multiple strings in the url that need to be processed the filterFunction
+ * should handle all of them on the call. A filter function should
+ * be defined as follows:
+ *
+ * @param url the url to process.
+ * @param index the index of the first occurrence of the seachString in the url.
+ * @return the new url.
+ *
+ * function filterFunction(url:String, index:int):String
+ *
+ */
+ mx_internal static var urlFilters:Array =
+ [
+ { searchString: "/[[DYNAMIC]]/", filterFunction: dynamicURLFilter},
+ { searchString: "/[[IMPORT]]/", filterFunction: importURLFilter}
+ ];
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * The root URL of a cross-domain RSL contains special text
+ * appended to the end of the URL.
+ * This method normalizes the URL specified in the specified LoaderInfo instance
+ * to remove the appended text, if present.
+ * Classes accessing <code>LoaderInfo.url</code> should call this method
+ * to normalize the URL before using it.
+ * This method also encodes the url by calling the encodeURI() method
+ * on it. If you want the unencoded url, you must call unencodeURI() on
+ * the results.
+ *
+ * @param loaderInfo A LoaderInfo instance or url string.
+ *
+ * @return A normalized <code>LoaderInfo.url</code> property.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function normalizeURL(loaderInfo:Object):String
+ {
+ var url:String;
- COMPILE::AS3
++ COMPILE::SWF
+ {
+ if (loaderInfo is LoaderInfo)
+ url = loaderInfo.url;
+ else
+ url = loaderInfo.toString();
+ }
+ COMPILE::JS
+ {
+ url = loaderInfo.toString();
+ }
+ var index:int;
+ var searchString:String;
+ var urlFilter:Function;
+ var n:uint = LoaderUtil.urlFilters.length;
+
+ for (var i:uint = 0; i < n; i++)
+ {
+ searchString = LoaderUtil.urlFilters[i].searchString;
+ if ((index = url.indexOf(searchString)) != -1)
+ {
+ urlFilter = LoaderUtil.urlFilters[i].filterFunction;
+ url = urlFilter(url, index);
+ }
+ }
+
+ // On the mac, the player doesn't like filenames with high-ascii
+ // characters. Calling encodeURI fixes this problem. We restrict
+ // this call to mac-only since it causes problems on Windows.
+ if (Platform.isMac)
+ return encodeURI(url);
+
+ return url;
+ }
+
+ /**
+ * @private
+ *
+ * Use this method when you want to load resources with relative URLs.
+ *
+ * Combine a root url with a possibly relative url to get a absolute url.
+ * Use this method to convert a relative url to an absolute URL that is
+ * relative to a root URL.
+ *
+ * @param rootURL An url that will form the root of the absolute url.
+ * If the <code>rootURL</code> does not specify a file name it must be
+ * terminated with a slash. For example, "http://a.com" is incorrect, it
+ * should be terminated with a slash, "http://a.com/". If the rootURL is
+ * taken from loaderInfo, it must be passed thru <code>normalizeURL</code>
+ * before being passed to this function.
+ *
+ * When loading resources relative to an application, the rootURL is
+ * typically the loaderInfo.url of the application.
+ *
+ * @param url The url of the resource to load (may be relative).
+ *
+ * @return If <code>url</code> is already an absolute URL, then it is
+ * returned as is. If <code>url</code> is relative, then an absolute URL is
+ * returned where <code>url</code> is relative to <code>rootURL</code>.
+ */
+ public static function createAbsoluteURL(rootURL:String, url:String):String
+ {
+ var absoluteURL:String = url;
+
+ // make relative paths relative to the SWF loading it, not the top-level SWF
+ if (rootURL &&
+ !(url.indexOf(":") > -1 || url.indexOf("/") == 0 || url.indexOf("\\") == 0))
+ {
+ // First strip off the search string and then any url fragments.
+ var index:int;
+
+ if ((index = rootURL.indexOf("?")) != -1 )
+ rootURL = rootURL.substring(0, index);
+
+ if ((index = rootURL.indexOf("#")) != -1 )
+ rootURL = rootURL.substring(0, index);
+
+ // If the url starts from the current directory, then just skip
+ // over the "./".
+ // If the url start from the parent directory, the we need to
+ // modify the rootURL.
+ var lastIndex:int = Math.max(rootURL.lastIndexOf("\\"), rootURL.lastIndexOf("/"));
+ if (url.indexOf("./") == 0)
+ {
+ url = url.substring(2);
+ }
+ else
+ {
+ while (url.indexOf("../") == 0)
+ {
+ url = url.substring(3);
+ lastIndex = Math.max(rootURL.lastIndexOf("\\", lastIndex - 1),
+ rootURL.lastIndexOf("/", lastIndex - 1));
+ }
+ }
+
+ if (lastIndex != -1)
+ absoluteURL = rootURL.substr(0, lastIndex + 1) + url;
+ }
+
+ return absoluteURL;
+ }
+
+ /**
+ * @private
+ *
+ * Takes a list of required rsls and determines:
+ * - which RSLs have not been loaded
+ * - the application domain and IModuleFactory where the
+ * RSL should be loaded
+ *
+ * @param moduleFactory The module factory of the application or module
+ * to get load information for. If the moduleFactory has not loaded the
+ * module, then its parent is asked for load information. Each successive
+ * parent is asked until the load information is found or there are no
+ * more parents to ask. Only parents in parent ApplicationDomains are
+ * searched. Applications in different security domains or sibling
+ * ApplicationDomains do not share RSLs.
+ *
+ * @param rsls An array of RSLs that are required for
+ * <code>moduleFactory</code>. Each RSL is in an array of RSLData where
+ * the first element is the primary RSL and the remaining elements are
+ * failover RSLs.
+ * @return Array of RSLData that represents the RSLs to load. RSLs that are
+ * already loaded are not in the listed.
+ */
+ COMPILE::LATER
+ mx_internal static function processRequiredRSLs(moduleFactory:IFlexModuleFactory,
+ rsls:Array):Array
+ {
+ var rslsToLoad:Array = []; // of Array, where each element is an array
+ // of RSLData (primary and failover), return value
+ var topLevelModuleFactory:IFlexModuleFactory = SystemManagerGlobals.topLevelSystemManagers[0];
+ var currentModuleFactory:IFlexModuleFactory = topLevelModuleFactory;
+ var parentModuleFactory:IFlexModuleFactory = null;
+ var loaded:Dictionary = new Dictionary(); // contains rsls that are loaded
+ var loadedLength:int = 0;
+ var resolved:Dictionary = new Dictionary(); // contains rsls that have the app domain resolved
+ var resolvedLength:int = 0;
+ var moduleFactories:Array = null;
+
+ // Start at the top level module factory and work our way down the
+ // module factory chain checking if the any of the rsls are loaded
+ // and resolving application domain targets.
+ // We start at the top level module factory because the default rsls
+ // will all be loaded here and we won't often have to check other
+ // module factories.
+ while (currentModuleFactory != moduleFactory)
+ {
+ // Need to loop over all the rsls, to see which one are loaded
+ // and resolve application domains.
+ var n:int = rsls.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ var rsl:Array = rsls[i];
+
+ // Check if the RSL has already been loaded.
+ if (!loaded[rsl])
+ {
+ if (isRSLLoaded(currentModuleFactory, rsl[0].digest))
+ {
+ loaded[rsl] = 1;
+ loadedLength++;
+
+ // We may find an rsl loaded in a module factory as we work
+ // our way down the module factory list. If we find one then
+ // remove it.
+ if (currentModuleFactory != topLevelModuleFactory)
+ {
+ var index:int = rslsToLoad.indexOf(rsl);
+ if (index != -1)
+ rslsToLoad.splice(index, 1);
+ }
+ }
+ else if (rslsToLoad.indexOf(rsl) == -1)
+ {
+ rslsToLoad.push(rsl); // assume we have to load it
+ }
+ }
+
+ // If the rsl is already loaded or already resolved then
+ // skip resolving it.
+ if (!loaded[rsl] && resolved[rsl] == null)
+ {
+ // Get the parent module factory if we are going to need to
+ // resolve the application domain target.
+ if (!parentModuleFactory &&
+ RSLData(rsl[0]).applicationDomainTarget == ApplicationDomainTarget.PARENT)
+ {
+ parentModuleFactory = getParentModuleFactory(moduleFactory);
+ }
+
+ // Resolve the application domain target.
+ if (resolveApplicationDomainTarget(rsl,
+ moduleFactory,
+ currentModuleFactory,
+ parentModuleFactory,
+ topLevelModuleFactory))
+ {
+ resolved[rsl] = 1;
+ resolvedLength++;
+ }
+ }
+ }
+
+ // If process all rsls then get out.
+ if (loadedLength + resolvedLength >= rsls.length)
+ break;
+
+ // If we didn't find everything in the top level module factory then work
+ // down towards the rsl's owning module factory.
+ // Build up the module factory parent chain so we can traverse it.
+ if (!moduleFactories)
+ {
+ moduleFactories = [moduleFactory];
+ currentModuleFactory = moduleFactory;
+ while (currentModuleFactory != topLevelModuleFactory)
+ {
+
+ currentModuleFactory = getParentModuleFactory(currentModuleFactory);
+
+ // If we couldn't get the parent module factory, then we
+ // will have to load into the highest application domain
+ // that is available. We won't be able to get a parent
+ // if a module was loaded without specifying a parent
+ // module factory.
+ if (!currentModuleFactory)
+ break;
+
+ if (currentModuleFactory != topLevelModuleFactory)
+ moduleFactories.push(currentModuleFactory);
+
+ if (!parentModuleFactory)
+ parentModuleFactory = currentModuleFactory;
+ }
+ }
+
+ currentModuleFactory = moduleFactories.pop();
+ }
+
+ return rslsToLoad;
+ }
+
+ /**
+ * @private
+ * Test whether a url is on the local filesystem. We can only
+ * really tell this with URLs that begin with "file:" or a
+ * Windows-style drive notation such as "C:". This fails some
+ * cases like the "/" notation on Mac/Unix.
+ *
+ * @param url
+ * the url to check against
+ *
+ * @return
+ * true if url is local, false if not or unable to determine
+ **/
+ mx_internal static function isLocal(url:String):Boolean
+ {
+ return (url.indexOf("file:") == 0 || url.indexOf(":") == 1);
+ }
+
+ /**
+ * @private
+ * Currently (FP 10.x) the ActiveX player (Explorer on Windows) does not
+ * handle encoded URIs containing UTF-8 on the local filesystem, but
+ * it does handle those same URIs unencoded. The plug-in requires
+ * encoded URIs.
+ *
+ * @param url
+ * url to properly encode, may be fully or partially encoded with encodeURI
+ *
+ * @param local
+ * true indicates the url is on the local filesystem
+ *
+ * @return
+ * encoded url that may be loaded with a URLRequest
+ **/
- COMPILE::AS3
++ COMPILE::SWF
+ mx_internal static function OSToPlayerURI(url:String, local:Boolean):String
+ {
+
+ // First strip off the search string and any url fragments so
+ // they will not be decoded/encoded.
+ // Next decode the url.
+ // Before returning the decoded or encoded string add the search
+ // string and url fragment back.
+ var searchStringIndex:int;
+ var fragmentUrlIndex:int;
+ var decoded:String = url;
+
+ if ((searchStringIndex = decoded.indexOf("?")) != -1 )
+ {
+ decoded = decoded.substring(0, searchStringIndex);
+ }
+
+ if ((fragmentUrlIndex = decoded.indexOf("#")) != -1 )
+ decoded = decoded.substring(0, fragmentUrlIndex);
+
+ try
+ {
+ // decode the url
+ decoded = decodeURI(decoded);
+ }
+ catch (e:Error)
+ {
+ // malformed url, but some are legal on the file system
+ }
+
+ // create the string to hold the the search string url fragments.
+ var extraString:String = null;
+ if (searchStringIndex != -1 || fragmentUrlIndex != -1)
+ {
+ var index:int = searchStringIndex;
+
+ if (searchStringIndex == -1 ||
+ (fragmentUrlIndex != -1 && fragmentUrlIndex < searchStringIndex))
+ {
+ index = fragmentUrlIndex;
+ }
+
+ extraString = url.substr(index);
+ }
+
+ if (local && flash.system.Capabilities.playerType == "ActiveX")
+ {
+ if (extraString)
+ return decoded + extraString;
+ else
+ return decoded;
+ }
+
+ if (extraString)
+ return encodeURI(decoded) + extraString;
+ else
+ return encodeURI(decoded);
+ }
+
+ /**
+ * @private
+ * Get the parent module factory.
+ *
+ * @param moduleFactory The module factory to get the parent of.
+ *
+ * @return the parent module factory if available, null otherwise.
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ private static function getParentModuleFactory(moduleFactory:IFlexModuleFactory):IFlexModuleFactory
+ {
+ var request:Request = new Request(Request.GET_PARENT_FLEX_MODULE_FACTORY_REQUEST);
+ DisplayObject(moduleFactory).dispatchEvent(request);
+ return request.value as IFlexModuleFactory;
+ }
+
+ /**
+ * @private
+ * Resolve the application domain target.
+ *
+ * @param rsl to resolve.
+ * @param moduleFactory The module factory loading the RSLs.
+ * @param currentModuleFactory The module factory to search for placeholders.
+ * @param parentModuleFactory The rsl's parent module factory.
+ * @param topLevelModuleFactory The top-level module factory.
+ *
+ * @return true if the application domain target was resolved,
+ * false otherwise.
+ */
+ COMPILE::LATER
+ private static function resolveApplicationDomainTarget(rsl:Array,
+ moduleFactory:IFlexModuleFactory,
+ currentModuleFactory:IFlexModuleFactory,
+ parentModuleFactory:IFlexModuleFactory,
+ topLevelModuleFactory:IFlexModuleFactory):Boolean
+ {
+ var resolvedRSL:Boolean = false;
+ var targetModuleFactory:IFlexModuleFactory = null;
+
+ var applicationDomainTarget:String = rsl[0].applicationDomainTarget;
+ if (isLoadedIntoTopLevelApplicationDomain(moduleFactory))
+ {
+ targetModuleFactory = topLevelModuleFactory;
+ }
+ else if (applicationDomainTarget == ApplicationDomainTarget.DEFAULT)
+ {
+ if (hasPlaceholderRSL(currentModuleFactory, rsl[0].digest))
+ {
+ targetModuleFactory = currentModuleFactory;
+ }
+ }
+ else if (applicationDomainTarget == ApplicationDomainTarget.TOP_LEVEL)
+ {
+ targetModuleFactory = topLevelModuleFactory;
+ }
+ else if (applicationDomainTarget == ApplicationDomainTarget.CURRENT)
+ {
+ resolvedRSL = true;
+ }
+ else if (applicationDomainTarget == ApplicationDomainTarget.PARENT)
+ {
+ // If there is no parent, ignore the target and load into the current
+ // app domain.
+ targetModuleFactory = parentModuleFactory;
+ }
+ else
+ {
+ resolvedRSL = true; // bogus target, load into current application domain
+ }
+
+ if (resolvedRSL || targetModuleFactory)
+ {
+ if (targetModuleFactory)
+ updateRSLModuleFactory(rsl, targetModuleFactory);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @private
+ * Determine if the moduleFactory has loaded an rsl that matches the
+ * specified digest.
+ *
+ * @param moduleFactory The module factory to search.
+ * @param digest The digest to search for.
+ * @return true if a loaded rsl matching the digest was found.
+ */
+ COMPILE::LATER
+ private static function isRSLLoaded(moduleFactory:IFlexModuleFactory, digest:String):Boolean
+ {
+ var preloadedRSLs:Dictionary = moduleFactory.preloadedRSLs;
+
+ if (preloadedRSLs)
+ {
+ // loop over the rsls to find a matching digest
+ for each (var rsl:Vector.<RSLData> in preloadedRSLs)
+ {
+ var n:int = rsl.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ if (rsl[i].digest == digest)
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @private
+ *
+ * Determine if the moduleFactory has a placeholder rsl that matches the
+ * specified digest.
+ *
+ * @param moduleFactory The module factory to search.
+ * @param digest The digest to search for.
+ * @return true if a placeholder rsl matching the digest was found.
+ */
+ private static function hasPlaceholderRSL(moduleFactory:IFlexModuleFactory, digest:String):Boolean
+ {
+ var phRSLs:Array = moduleFactory.info()["placeholderRsls"];
+
+ if (phRSLs)
+ {
+ // loop over the rsls to find a matching digest
+ var n:int = phRSLs.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ var rsl:Object = phRSLs[i];
+ var m:int = rsl.length;
+ for (var j:int = 0; j < m; j++)
+ {
+ if (rsl[j].digest == digest)
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @private
+ * Test if a module factory has been loaded into the top-level application domain.
+ *
+ * @return true if loaded into the top-level application domain, false otherwise.
+ */
+ COMPILE::LATER
+ private static function isLoadedIntoTopLevelApplicationDomain(moduleFactory:IFlexModuleFactory):Boolean
+ {
+ if (moduleFactory is DisplayObject)
+ {
+ var displayObject:DisplayObject = DisplayObject(moduleFactory);
+ var loaderInfo:LoaderInfo = displayObject.loaderInfo;
+ if (loaderInfo && loaderInfo.applicationDomain &&
+ loaderInfo.applicationDomain.parentDomain == null)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @private
+ *
+ * Update the module factory of an rsl, both the primary rsl and all
+ * failover rsls.
+ *
+ * @param rsl One RSL represented by an array of RSLData. The
+ * first element in the array is the primary rsl, the others are failovers.
+ * @param moduleFactory The moduleFactory to set in the primary and
+ * failover rsls.
+ */
+ COMPILE::LATER
+ private static function updateRSLModuleFactory(rsl:Array, moduleFactory:IFlexModuleFactory):void
+ {
+ var n:int = rsl.length;
+ for (var i:int = 0; i < n; i++)
+ {
+ rsl[i].moduleFactory = moduleFactory;
+ }
+ }
+
+ /**
+ * @private
+ *
+ * Strip off the DYNAMIC string(s) appended to the url.
+ */
+ private static function dynamicURLFilter(url:String, index:int):String
+ {
+ return url.substring(0, index);
+ }
+
+ /**
+ * @private
+ *
+ * Add together the protocol plus everything after "/[[IMPORT]]/".
+ */
+ private static function importURLFilter(url:String, index:int):String
+ {
+ var protocolIndex:int = url.indexOf("://");
+ return url.substring(0,protocolIndex + 3) + url.substring(index + 12);
+ }
+
+ }
- }
++}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/utils/NameUtil.as
----------------------------------------------------------------------
diff --cc frameworks/projects/MX/src/main/flex/mx/utils/NameUtil.as
index 4f8f53d,0000000..7782458
mode 100644,000000..100644
--- a/frameworks/projects/MX/src/main/flex/mx/utils/NameUtil.as
+++ b/frameworks/projects/MX/src/main/flex/mx/utils/NameUtil.as
@@@ -1,195 -1,0 +1,195 @@@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.utils
+{
+
+import org.apache.flex.reflection.getQualifiedClassName;
+
+import mx.core.IRepeaterClient;
+import mx.core.IUIComponent;
+
+/**
+ * The NameUtil utility class defines static methods for
+ * creating names for Flex objects.
+ * You do not create instances of NameUtil;
+ * instead you call static methods of the class, such as
+ * the <code>NameUtil.createName()</code> method.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public class NameUtil
+{
+ include "../core/Version.as";
+
+ //--------------------------------------------------------------------------
+ //
+ // Class variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ */
+ private static var counter:int = 0;
+
+ //--------------------------------------------------------------------------
+ //
+ // Class methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Creates a unique name for any Object instance, such as "Button12", by
+ * combining the unqualified class name with an incrementing counter.
+ *
+ * @param object Object requiring a name.
+ *
+ * @return String containing the unique name.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function createUniqueName(object:Object):String
+ {
+ if (!object)
+ return null;
+
+ var name:String = getQualifiedClassName(object);
+
+ // If there is a package name, strip it off.
+ var index:int = name.indexOf("::");
+ if (index != -1)
+ name = name.substr(index + 2);
+
+ // If the class name ends with a digit (which some autogenerated
+ // classes do), then append an underscore before appending
+ // the counter.
+ var charCode:int = name.charCodeAt(name.length - 1);
+ if (charCode >= 48 && charCode <= 57)
+ name += "_";
+
+ return name + counter++;
+ }
+
+ /**
+ * Returns a string, such as
+ * "MyApplication0.addressForm.lastName.TextField17",
+ * for a DisplayObject object that indicates its position in the
+ * hierarchy of DisplayObject objects in an application.
+ *
+ * @param displayObject A DisplayObject object whose hierarchy in the application
+ * is desired.
+ *
+ * @return String containing the position of <code>displayObject</code>
+ * in the hierarchy of DisplayObject objects in an application.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ *
+ * @flexjsignorecoercion mx.core.IUIComponent
+ */
+ public static function displayObjectToString(
+ displayObject:IUIComponent):String
+ {
+ var result:String;
+
+ // Start at the specified object and walk up the parent chain
+ // to build up the string to return.
+ try
+ {
+ for (var o:IUIComponent = displayObject;
+ o != null;
+ o = o.parent as IUIComponent)
+ {
+ // If this object is in the display tree,
+ // stop after we've prepended the topmost Application instance.
+ if (o.parent && o.topOfDisplayList && o.parent == o.topOfDisplayList)
+ break;
+
+ // Prefer id over name if specified.
+ var s:String = "id" in o && o["id"] ? o["id"] : o.name;
+
+ if (o is IRepeaterClient)
+ {
+ var indices:Array = IRepeaterClient(o).instanceIndices;
+ if (indices)
+ s += "[" + indices.join("][") + "]";
+ }
+
+ result = result == null ? s : s + "." + result;
+ }
+ }
+ catch (e:Error)
+ {
- COMPILE::AS3
++ COMPILE::SWF
+ {
+ if (!(e is SecurityError))
+ throw e;
+ }
+ // Ignore error and continue with what we have.
+ // We may not have access to our parent if we are loaded into a sandbox.
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the name of the specified object's class,
+ * such as <code>"Button"</code>
+ *
+ * <p>This string does not include the package name.
+ * If you need the package name as well, call the
+ * <code>getQualifiedClassName()</code> method in the flash.utils package.
+ * It will return a string such as <code>"mx.controls::Button"</code>.</p>
+ *
+ * @param object The object.
+ *
+ * @return The name of the specified object's class.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public static function getUnqualifiedClassName(object:Object):String
+ {
+ var name:String;
+ if (object is String)
+ name = object as String;
+ else
+ name = getQualifiedClassName(object);
+
+ // If there is a package name, strip it off.
+ var index:int = name.indexOf("::");
+ if (index != -1)
+ name = name.substr(index + 2);
+
+ return name;
+ }
+}
+
+}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/77148f4a/frameworks/projects/MX/src/main/flex/mx/utils/ObjectProxy.as
----------------------------------------------------------------------
diff --cc frameworks/projects/MX/src/main/flex/mx/utils/ObjectProxy.as
index a6f1591,0000000..2d0e0ee
mode 100644,000000..100644
--- a/frameworks/projects/MX/src/main/flex/mx/utils/ObjectProxy.as
+++ b/frameworks/projects/MX/src/main/flex/mx/utils/ObjectProxy.as
@@@ -1,946 -1,0 +1,946 @@@
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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.utils
+{
+
+import org.apache.flex.events.EventDispatcher;
+import org.apache.flex.reflection.getQualifiedClassName;
- COMPILE::AS3
++COMPILE::SWF
+{
+import flash.events.Event;
+import flash.utils.IDataInput;
+import flash.utils.IDataOutput;
+import flash.utils.IExternalizable;
+import flash.utils.flash_proxy;
+}
+COMPILE::JS
+{
+ import org.apache.flex.events.Event;
+ import flex.utils.IExternalizable;
+}
+import org.apache.flex.utils.Proxy;
+import mx.core.IPropertyChangeNotifier;
+import mx.events.PropertyChangeEvent;
+import mx.events.PropertyChangeEventKind;
+
- COMPILE::AS3
++COMPILE::SWF
+{
+use namespace flash_proxy;
+use namespace object_proxy;
+}
+
+[Bindable("propertyChange")]
+[RemoteClass(alias="flex.messaging.io.ObjectProxy")]
+
+/**
+ * This class provides the ability to track changes to an item
+ * managed by this proxy.
+ * Any number of objects can "listen" for changes on this
+ * object, by using the <code>addEventListener()</code> method.
+ *
+ * @example
+ * <pre>
+ * import mx.events.PropertyChangeEvent;
+ * import mx.utils.ObjectUtil;
+ * import mx.utils.ObjectProxy;
+ * import mx.utils.StringUtil;
+ *
+ * var a:Object = { name: "Tyler", age: 5, ssnum: "555-55-5555" };
+ * var p:ObjectProxy = new ObjectProxy(a);
+ * p.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, updateHandler);
+ * p.name = "Jacey";
+ * p.age = 2;
+ * delete p.ssnum;
+ *
+ * // handler function
+ * function updateHandler(event:ChangeEvent):void
+ * {
+ * trace(StringUtil.substitute("updateHandler('{0}', {1}, {2}, {3}, '{4}')",
+ * event.kind,
+ * event.property,
+ * event.oldValue,
+ * event.newValue,
+ * event.target.object_proxy::UUID));
+ * }
+ *
+ * // The trace output appears as:
+ * // updateHandler('opUpdate', name, Tyler, Jacey, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+ * // updateHandler('opUpdate', age, 5, 2, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+ * // updateHandler('opDelete', ssnum, 555-55-5555, null, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+public dynamic class ObjectProxy extends Proxy
+ implements IExternalizable,
+ IPropertyChangeNotifier
+{
+ //--------------------------------------------------------------------------
+ //
+ // Constructor
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Initializes this proxy with the specified object, id and proxy depth.
+ *
+ * @param item Object to proxy.
+ * If no item is specified, an anonymous object will be constructed
+ * and assigned.
+ *
+ * @param uid String containing the unique id
+ * for this object instance.
+ * Required for IPropertyChangeNotifier compliance as every object must
+ * provide a unique way of identifying it.
+ * If no value is specified, a random id will be assigned.
+ *
+ * @param proxyDepth An integer indicating how many levels in a complex
+ * object graph should have a proxy created during property access.
+ * The default is -1, meaning "proxy to infinite depth".
+ *
+ * @example
+ *
+ * <pre>
+ * import mx.events.PropertyChangeEvent;
+ * import mx.utils.ObjectUtil;
+ * import mx.utils.ObjectProxy;
+ * import mx.utils.StringUtil;
+ *
+ * var a:Object = { name: "Tyler", age: 5, ssnum: "555-55-5555" };
+ * var p:ObjectProxy = new ObjectProxy(a);
+ * p.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, updateHandler);
+ * p.name = "Jacey";
+ * p.age = 2;
+ * delete p.ssnum;
+ *
+ * // handler function
+ * function updateHandler(event:PropertyChangeEvent):void
+ * {
+ * trace(StringUtil.substitute("updateHandler('{0}', {1}, {2}, {3}, '{4}')",
+ * event.kind,
+ * event.property,
+ * event.oldValue,
+ * event.newValue,
+ * event.target.uid));
+ * }
+ *
+ * // trace output
+ * updateHandler('opUpdate', name, Jacey, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+ * updateHandler('opUpdate', age, 2, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+ * updateHandler('opDelete', ssnum, null, '698AF8CB-B3D9-21A3-1AFFDGHT89075CD2')
+ * </pre>
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function ObjectProxy(item:Object = null, uid:String = null,
+ proxyDepth:int = -1)
+ {
+ super();
+
+ if (!item)
+ item = {};
+ _item = item;
+
+ _proxyLevel = proxyDepth;
+
+ notifiers = {};
+
+ dispatcher = new EventDispatcher(this);
+
+ // If we got an id, use it. Otherwise the UID is lazily
+ // created in the getter for UID.
+ if (uid)
+ _id = uid;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Variables
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * A reference to the EventDispatcher for this proxy.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected var dispatcher:EventDispatcher;
+
+ /**
+ * A hashmap of property change notifiers that this proxy is
+ * listening for changes from; the key of the map is the property name.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected var notifiers:Object;
+
+ /**
+ * Indicates what kind of proxy to create
+ * when proxying complex properties.
+ * Subclasses should assign this value appropriately.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected var proxyClass:Class = ObjectProxy;
+
+ /**
+ * Contains a list of all of the property names for the proxied object.
+ * Descendants need to fill this list by overriding the
+ * <code>setupPropertyList()</code> method.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected var propertyList:Array;
+
+ /**
+ * Indicates how deep proxying should be performed.
+ * If -1 (default), always proxy;
+ * if this value is zero, no proxying will be performed.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private var _proxyLevel:int;
+
+ //--------------------------------------------------------------------------
+ //
+ // Properties
+ //
+ //--------------------------------------------------------------------------
+
+ //----------------------------------
+ // object
+ //----------------------------------
+
+ /**
+ * Storage for the object property.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ private var _item:Object;
+
+ /**
+ * The object being proxied.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ COMPILE::LATER
+ object_proxy function get object():Object
+ {
+ return _item;
+ }
+
+ //----------------------------------
+ // type
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the qualified type name.
+ */
+ COMPILE::LATER
+ private var _type:QName;
+
+ /**
+ * The qualified type name associated with this object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ COMPILE::LATER
+ object_proxy function get type():QName
+ {
+ return _type;
+ }
+
+ /**
+ * @private
+ */
+ COMPILE::LATER
+ object_proxy function set type(value:QName):void
+ {
+ _type = value;
+ }
+
+ //----------------------------------
+ // uid
+ //----------------------------------
+
+ /**
+ * @private
+ * Storage for the uid property.
+ */
+ private var _id:String;
+
+ /**
+ * The unique identifier for this object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function get uid():String
+ {
+ if (_id === null)
+ _id = UIDUtil.createUID();
+
+ return _id;
+ }
+
+ /**
+ * @private
+ */
+ public function set uid(value:String):void
+ {
+ _id = value;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Overridden methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Returns the specified property value of the proxied object.
+ *
+ * @param name Typically a string containing the name of the property,
+ * or possibly a QName where the property name is found by
+ * inspecting the <code>localName</code> property.
+ *
+ * @return The value of the property.
+ * In some instances this value may be an instance of
+ * <code>ObjectProxy</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ override flash_proxy function getProperty(name:*):*
+ {
+ // if we have a data proxy for this then
+ var result:*;
+
+ if (notifiers[name.toString()])
+ return notifiers[name];
+
+ result = _item[name];
+
+ if (result)
+ {
+ if (_proxyLevel == 0 || ObjectUtil.isSimple(result))
+ {
+ return result;
+ }
+ else
+ {
+ result = object_proxy::getComplexProperty(name, result);
+ } // if we are proxying
+ }
+
+ return result;
+ }
+ COMPILE::JS
+ override public function getProperty(name:String):*
+ {
+ // if we have a data proxy for this then
+ var result:*;
+
+ if (notifiers[name.toString()])
+ return notifiers[name];
+
+ result = _item[name];
+
+ if (result)
+ {
+ if (_proxyLevel == 0 || ObjectUtil.isSimple(result))
+ {
+ return result;
+ }
+ else
+ {
+ result = object_proxy::getComplexProperty(name, result);
+ } // if we are proxying
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the value of the proxied object's method with the specified name.
+ *
+ * @param name The name of the method being invoked.
+ *
+ * @param rest An array specifying the arguments to the
+ * called method.
+ *
+ * @return The return value of the called method.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ override flash_proxy function callProperty(name:*, ... rest):*
+ {
+ return _item[name].apply(_item, rest)
+ }
+
+ /**
+ * Deletes the specified property on the proxied object and
+ * sends notification of the delete to the handler.
+ *
+ * @param name Typically a string containing the name of the property,
+ * or possibly a QName where the property name is found by
+ * inspecting the <code>localName</code> property.
+ *
+ * @return A Boolean indicating if the property was deleted.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ override flash_proxy function deleteProperty(name:*):Boolean
+ {
+ var notifier:IPropertyChangeNotifier = IPropertyChangeNotifier(notifiers[name]);
+ if (notifier)
+ {
+ notifier.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
+ propertyChangeHandler);
+ delete notifiers[name];
+ }
+
+ var oldVal:* = _item[name];
+ var deleted:Boolean = delete _item[name];
+
+ if (dispatcher.hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
+ {
+ var event:PropertyChangeEvent = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
+ event.kind = PropertyChangeEventKind.DELETE;
+ event.property = name;
+ event.oldValue = oldVal;
+ event.source = this;
+ dispatcher.dispatchEvent(event);
+ }
+
+ return deleted;
+ }
+ COMPILE::JS
+ override public function deleteProperty(name:String):Boolean
+ {
+ var notifier:IPropertyChangeNotifier = IPropertyChangeNotifier(notifiers[name]);
+ if (notifier)
+ {
+ notifier.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
+ propertyChangeHandler);
+ delete notifiers[name];
+ }
+
+ var oldVal:* = _item[name];
+ var deleted:Boolean = delete _item[name];
+
+ if (dispatcher.hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
+ {
+ var event:PropertyChangeEvent = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
+ event.kind = PropertyChangeEventKind.DELETE;
+ event.property = name;
+ event.oldValue = oldVal;
+ event.source = this;
+ dispatcher.dispatchEvent(event);
+ }
+
+ return deleted;
+ }
+
+ /**
+ * @private
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ override flash_proxy function hasProperty(name:*):Boolean
+ {
+ return(name in _item);
+ }
+ COMPILE::JS
+ override public function hasProperty(name:String):Boolean
+ {
+ return(name in _item);
+ }
+
+ /**
+ * @private
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ override flash_proxy function nextName(index:int):String
+ {
+ return propertyList[index -1];
+ }
+
+ /**
+ * @private
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ override flash_proxy function nextNameIndex(index:int):int
+ {
+ if (index == 0)
+ {
+ setupPropertyList();
+ }
+
+ if (index < propertyList.length)
+ {
+ return index + 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ /**
+ * @private
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ override flash_proxy function nextValue(index:int):*
+ {
+ return _item[propertyList[index -1]];
+ }
+
+ /**
+ * Updates the specified property on the proxied object
+ * and sends notification of the update to the handler.
+ *
+ * @param name Object containing the name of the property that
+ * should be updated on the proxied object.
+ *
+ * @param value Value that should be set on the proxied object.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ override flash_proxy function setProperty(name:*, value:*):void
+ {
+ var oldVal:* = _item[name];
+ if (oldVal !== value)
+ {
+ // Update item.
+ _item[name] = value;
+
+ // Stop listening for events on old item if we currently are.
+ var notifier:IPropertyChangeNotifier =
+ IPropertyChangeNotifier(notifiers[name]);
+ if (notifier)
+ {
+ notifier.removeEventListener(
+ PropertyChangeEvent.PROPERTY_CHANGE,
+ propertyChangeHandler);
+ delete notifiers[name];
+ }
+
+ // Notify anyone interested.
+ if (dispatcher.hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
+ {
+ if (name is QName)
+ name = QName(name).localName;
+ var event:PropertyChangeEvent =
+ PropertyChangeEvent.createUpdateEvent(
+ this, name.toString(), oldVal, value);
+ dispatcher.dispatchEvent(event);
+ }
+ }
+ }
+ COMPILE::JS
+ override public function setProperty(name:String, value:*):void
+ {
+ var oldVal:* = _item[name];
+ if (oldVal !== value)
+ {
+ // Update item.
+ _item[name] = value;
+
+ // Stop listening for events on old item if we currently are.
+ var notifier:IPropertyChangeNotifier =
+ IPropertyChangeNotifier(notifiers[name]);
+ if (notifier)
+ {
+ notifier.removeEventListener(
+ PropertyChangeEvent.PROPERTY_CHANGE,
+ propertyChangeHandler);
+ delete notifiers[name];
+ }
+
+ // Notify anyone interested.
+ if (dispatcher.hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
+ {
+ COMPILE::LATER
+ {
+ if (name is QName)
+ name = QName(name).localName;
+ }
+ var event:PropertyChangeEvent =
+ PropertyChangeEvent.createUpdateEvent(
+ this, name.toString(), oldVal, value);
+ dispatcher.dispatchEvent(event);
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // object_proxy methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Provides a place for subclasses to override how a complex property that
+ * needs to be either proxied or daisy chained for event bubbling is managed.
+ *
+ * @param name Typically a string containing the name of the property,
+ * or possibly a QName where the property name is found by
+ * inspecting the <code>localName</code> property.
+ *
+ * @param value The property value.
+ *
+ * @return The property value or an instance of <code>ObjectProxy</code>.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ object_proxy function getComplexProperty(name:*, value:*):*
+ {
+ if (value is IPropertyChangeNotifier)
+ {
+ value.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
+ propertyChangeHandler);
+ notifiers[name] = value;
+ return value;
+ }
+
+ if (getQualifiedClassName(value) == "Object")
+ {
+ value = new proxyClass(_item[name], null,
+ _proxyLevel > 0 ? _proxyLevel - 1 : _proxyLevel);
+ value.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,
+ propertyChangeHandler);
+ notifiers[name] = value;
+ return value;
+ }
+
+ return value;
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // IExternalizable Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Since Flex only uses ObjectProxy to wrap anonymous objects,
+ * the server flex.messaging.io.ObjectProxy instance serializes itself
+ * as a Map that will be returned as a plain ActionScript object.
+ * You can then set the object_proxy object property to this value.
+ *
+ * @param input The source object from which the ObjectProxy is
+ * deserialized.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ public function readExternal(input:IDataInput):void
+ {
+ var value:Object = input.readObject();
+ _item = value;
+ }
+
+ /**
+ * Since Flex only serializes the inner ActionScript object that it wraps,
+ * the server flex.messaging.io.ObjectProxy populates itself
+ * with this anonymous object's contents and appears to the user
+ * as a Map.
+ *
+ * @param output The source object from which the ObjectProxy is
+ * deserialized.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ public function writeExternal(output:IDataOutput):void
+ {
+ output.writeObject(_item);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * Registers an event listener object
+ * so that the listener receives notification of an event.
+ * For more information, including descriptions of the parameters see
+ * <code>addEventListener()</code> in the
+ * flash.events.EventDispatcher class.
+ *
+ * @param type The type of event.
+ *
+ * @param listener The listener function that processes the event. This function must accept
+ * an Event object as its only parameter and must return nothing.
+ *
+ * @param useCapture Determines whether the listener works in the capture phase or the
+ * target and bubbling phases. If <code>useCapture</code> is set to <code>true</code>,
+ * the listener processes the event only during the capture phase and not in the
+ * target or bubbling phase. If <code>useCapture</code> is <code>false</code>, the
+ * listener processes the event only during the target or bubbling phase. To listen for
+ * the event in all three phases, call <code>addEventListener</code> twice, once with
+ * <code>useCapture</code> set to <code>true</code>, then again with
+ * <code>useCapture</code> set to <code>false</code>.
+ *
+ * @param priority The priority level of the event listener.
+ *
+ * @param useWeakReference Determines whether the reference to the listener is strong or
+ * weak. A strong reference (the default) prevents your listener from being garbage-collected.
+ * A weak reference does not.
+ *
+ * @see flash.events.EventDispatcher#addEventListener()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ public function addEventListener(type:String, listener:Function,
+ useCapture:Boolean = false,
+ priority:int = 0,
+ useWeakReference:Boolean = false):void
+ {
+ dispatcher.addEventListener(type, listener, useCapture,
+ priority, useWeakReference);
+ }
+
+ /**
+ * Removes an event listener.
+ * If there is no matching listener registered with the EventDispatcher object,
+ * a call to this method has no effect.
+ * For more information, see
+ * the flash.events.EventDispatcher class.
+ *
+ * @param type The type of event.
+ *
+ * @param listener The listener object to remove.
+ *
+ * @param useCapture Specifies whether the listener was registered for the capture
+ * phase or the target and bubbling phases. If the listener was registered for both
+ * the capture phase and the target and bubbling phases, two calls to
+ * <code>removeEventListener()</code> are required to remove both, one call with
+ * <code>useCapture</code>
+ * set to <code>true</code>, and another call with <code>useCapture</code>
+ * set to <code>false</code>.
+ *
+ * @see flash.events.EventDispatcher#removeEventListener()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ public function removeEventListener(type:String, listener:Function,
+ useCapture:Boolean = false):void
+ {
+ dispatcher.removeEventListener(type, listener, useCapture);
+ }
+
+ /**
+ * Dispatches an event into the event flow.
+ * For more information, see
+ * the flash.events.EventDispatcher class.
+ *
+ * @param event The Event object that is dispatched into the event flow. If the
+ * event is being redispatched, a clone of the event is created automatically.
+ * After an event is dispatched, its target property cannot be changed, so you
+ * must create a new copy of the event for redispatching to work.
+ *
+ * @return Returns <code>true</code> if the event was successfully dispatched.
+ * A value
+ * of <code>false</code> indicates failure or that <code>preventDefault()</code>
+ * was called on the event.
+ *
+ * @see flash.events.EventDispatcher#dispatchEvent()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ public function dispatchEvent(event:Event):Boolean
+ {
+ return dispatcher.dispatchEvent(event);
+ }
+
+ /**
+ * Checks whether there are any event listeners registered
+ * for a specific type of event.
+ * This allows you to determine where an object has altered handling
+ * of an event type in the event flow hierarchy.
+ * For more information, see
+ * the flash.events.EventDispatcher class.
+ *
+ * @param type The type of event
+ *
+ * @return Returns <code>true</code> if a listener of the specified type is
+ * registered; <code>false</code> otherwise.
+ *
+ * @see flash.events.EventDispatcher#hasEventListener()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ public function hasEventListener(type:String):Boolean
+ {
+ return dispatcher.hasEventListener(type);
+ }
+
+ /**
+ * Checks whether an event listener is registered with this object
+ * or any of its ancestors for the specified event type.
+ * This method returns <code>true</code> if an event listener is triggered
+ * during any phase of the event flow when an event of the specified
+ * type is dispatched to this object or any of its descendants.
+ * For more information, see the flash.events.EventDispatcher class.
+ *
+ * @param type The type of event.
+ *
+ * @return Returns <code>true</code> if a listener of the specified type will
+ * be triggered; <code>false</code> otherwise.
+ *
+ * @see flash.events.EventDispatcher#willTrigger()
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
- COMPILE::AS3
++ COMPILE::SWF
+ public function willTrigger(type:String):Boolean
+ {
+ return dispatcher.willTrigger(type);
+ }
+
+ /**
+ * Called when a complex property is updated.
+ *
+ * @param event An event object that has changed.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ public function propertyChangeHandler(event:PropertyChangeEvent):void
+ {
+ dispatcher.dispatchEvent(event);
+ }
+
+ //--------------------------------------------------------------------------
+ //
+ // Protected Methods
+ //
+ //--------------------------------------------------------------------------
+
+ /**
+ * This method creates an array of all of the property names for the
+ * proxied object.
+ * Descendants must override this method if they wish to add more
+ * properties to this list.
+ * Be sure to call <code>super.setupPropertyList</code> before making any
+ * changes to the <code>propertyList</code> property.
+ *
+ * @langversion 3.0
+ * @playerversion Flash 9
+ * @playerversion AIR 1.1
+ * @productversion Flex 3
+ */
+ protected function setupPropertyList():void
+ {
+ if (getQualifiedClassName(_item) == "Object")
+ {
+ propertyList = [];
+ for (var prop:String in _item)
+ propertyList.push(prop);
+ }
+ else
+ {
+ propertyList = ObjectUtil.getClassInfo(_item, null, {includeReadOnly:true, uris:["*"]}).properties;
+ }
+ }
+}
+
+}