Transferred from the Adobe Open Source Subversion Repository

Revision: 3035
Author:   jvroom@adobe.com
Date:     2008-08-29T06:18:11.275196Z

Log Message:
-----------
* Added HTTPMultiService component - refactored the guts of HTTPService into a new
class AbstractOperation which HTTPService now wraps.

* Moved concurrency and showBusyCursor classes up to the mx.rpc level from mx.rpc.mxml.
Partly this improves consistency and partly because it is awkward to implement them
with the wrapping design in the subclass.  This does introduce a new dependency on
CursorManager in mx.rpc.HTTPService, though I think that should turn into a "runtime binding"
so we remove the compile time binding altogether.

* Added managers, operationManager, resultType, resultElementType, properties to the
AbstractService and AbstractInvoker classes.  These are used to improve the metadata information
on these operations for better tooling in the future, and to allow management services to
tie into the service infrastructure.

* AsyncToken gets a default parameter for its constructor so it can be used in MXML.

* Moved endpoint property up from the MXML to the regular mx.rpc version to improve consistency

The blazeds RPC tests passed unfortunately I had problems getting the RPC tests in the sdk branch
to build and run so let me know if you see any problems on those.

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/remoting/mxml/RemoteObject.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/AbstractOperation.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/AbstractService.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/remoting/Operation.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/HTTPMultiService.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/mxml/HTTPService.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/AbstractInvoker.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/SerializationFilter.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/soap/Operation.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/AbstractOperation.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/manifest.xml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/remoting/RemoteObject.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/soap/mxml/WebService.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/AsyncToken.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/HTTPService.as</path>
<path kind="file" action="A">/flex/sdk/trunk/frameworks/projects/rpc/src/mx/rpc/http/Operation.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1274157 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/rpc/src/mx/rpc/http/AbstractOperation.as
+++ frameworks/projects/rpc/src/mx/rpc/http/AbstractOperation.as
@@ -0,0 +1,956 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2005-2007 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.rpc.http
+{
+
+import flash.utils.getQualifiedClassName;
+import flash.xml.XMLDocument;
+import flash.xml.XMLNode;
+
+import mx.collections.ArrayCollection;
+import mx.core.mx_internal;
+import mx.logging.ILogger;
+import mx.logging.Log;
+import mx.managers.CursorManager;
+import mx.messaging.ChannelSet;
+import mx.messaging.channels.DirectHTTPChannel;
+import mx.messaging.config.LoaderConfig;
+import mx.messaging.events.MessageEvent;
+import mx.messaging.messages.AsyncMessage;
+import mx.messaging.messages.HTTPRequestMessage;
+import mx.messaging.messages.IMessage;
+import mx.resources.IResourceManager;
+import mx.resources.ResourceManager;
+import mx.rpc.AbstractService;
+import mx.rpc.AsyncDispatcher;
+import mx.rpc.AsyncToken;
+import mx.rpc.Fault;
+import mx.rpc.events.FaultEvent;
+import mx.rpc.mxml.Concurrency;
+import mx.rpc.xml.SimpleXMLDecoder;
+import mx.rpc.xml.SimpleXMLEncoder;
+import mx.utils.ObjectProxy;
+import mx.utils.ObjectUtil;
+import mx.utils.StringUtil;
+import mx.utils.URLUtil;
+
+use namespace mx_internal;
+
+/**
+ * An Operation used specifically by HTTPService or HTTPMultiService.  An Operation is an
+ * individual operation on a service usually corresponding to a single operation on the server
+ * side.  An Operation can be called either by invoking the
+ * function of the same name on the service or by accessing the Operation as a property on the service and
+ * calling the send(param1, param2) method.  HTTP services also support a sendBody
+ * method which allows you to directly specify the body of the HTTP response.  If you use the
+ * send(param1, param2) method, the body is typically formed by combining the argumentNames
+ * property of the operation with the parameters sent.  An Object is created which uses the
+ * argumentNames[i] as the key and the corresponding parameter as the value.
+ *

+ * The exact way in which the HTTP operation arguments is put into the HTTP body is determined
+ * by the serializationFilter used.
+ */
+public class AbstractOperation extends mx.rpc.AbstractOperation
+{
+    //---------------------------------
+    // Constructor
+    //---------------------------------
+
+    /**
+     * Creates a new Operation.
+     */
+    public function AbstractOperation(service:AbstractService=null, name:String=null)
+    {
+        super(service, name);
+
+        argumentNames = [];
+
+        _log = Log.getLogger("mx.rpc.http.HTTPService");
+
+        showBusyCursor = false;
+        concurrency = Concurrency.MULTIPLE;
+    }
+
+    /**
+     * This is a hook to register additional user specified properties for your operation.
+     */
+    public var properties:Object;
+
+    /**
+     *  The result format "e4x" specifies that the value returned is an XML instance, which can be accessed using ECMAScript for XML (E4X) expressions.
+     */
+    mx_internal static const RESULT_FORMAT_E4X:String = "e4x";
+
+    /**
+     *  The result format "flashvars" specifies that the value returned is text containing name=value pairs
+     *  separated by ampersands, which is parsed into an ActionScript object.
+     */
+    mx_internal static const RESULT_FORMAT_FLASHVARS:String = "flashvars";
+
+    /**
+     *  The result format "object" specifies that the value returned is XML but is parsed as a tree of ActionScript objects. This is the default.
+     */
+    mx_internal static const RESULT_FORMAT_OBJECT:String = "object";
+
+    /**
+     *  The result format "array" is similar to "object" however the value returned is always an Array such
+     *  that if the result returned from result format "object" is not an Array already the item will be
+     *  added as the first item to a new Array.
+     */
+    mx_internal static const RESULT_FORMAT_ARRAY:String = "array";
+
+    /**
+     *  The result format "text" specifies that the HTTPService result text should be an unprocessed String.
+     */
+    mx_internal static const RESULT_FORMAT_TEXT:String = "text";
+
+    /**
+     *  The result format "xml" specifies that results should be returned as an flash.xml.XMLNode instance pointing to
+     *  the first child of the parent flash.xml.XMLDocument.
+     */
+    mx_internal static const RESULT_FORMAT_XML:String = "xml";
+
+    /**
+     *  Indicates that the data being sent by the HTTP service is encoded as application/xml.
+     */
+    mx_internal static const CONTENT_TYPE_XML:String = "application/xml";
+
+    /**
+     *  Indicates that the data being sent by the HTTP service is encoded as application/x-www-form-urlencoded.
+     */
+    mx_internal static const CONTENT_TYPE_FORM:String = "application/x-www-form-urlencoded";
+
+    // Constants for error codes
+    /**
+     *  Indicates that the useProxy property was set to false but a url was not provided.
+     */
+    private static const ERROR_URL_REQUIRED:String = "Client.URLRequired";
+
+    /**
+     *  Indicates that an XML formatted result could not be parsed into an XML instance
+     *  or decoded into an Object.
+     */
+    private static const ERROR_DECODING:String = "Client.CouldNotDecode";
+
+    /**
+     *  Indicates that an input parameter could not be encoded as XML.
+     */
+    private static const ERROR_ENCODING:String = "Client.CouldNotEncode";
+
+    //---------------------------------
+    // Properties
+    //---------------------------------
+
+    /**
+     * An ordered list of the names of the arguments to pass to a method invocation.  Since the arguments object is
+     * a hashmap with no guaranteed ordering, this array helps put everything together correctly.
+     * It will be set automatically by the MXML compiler, if necessary, when the Operation is used in tag form.
+     */
+    public var argumentNames:Array;
+
+    //----------------------------------
+    //  method
+    //----------------------------------
+
+    [Inspectable(enumeration="GET,get,POST,post,HEAD,head,OPTIONS,options,PUT,put,TRACE,trace,DELETE,delete", defaultValue="GET", category="General")]
+    /**
+     *  HTTP method for sending the request. Permitted values are GET, POST, HEAD,
+     *  OPTIONS, PUT, TRACE and DELETE.
+     *  Lowercase letters are converted to uppercase letters. The default value is GET.
+     */
+    public var method:String = HTTPRequestMessage.GET_METHOD;
+
+    [Inspectable(enumeration="multiple,single,last", defaultValue="multiple", category="General")]
+    /**
+     * Value that indicates how to handle multiple calls to the same service. The default
+     * value is multiple. The following values are permitted:
+     *

+     *
multiple Existing requests are not cancelled, and the developer is
+     * responsible for ensuring the consistency of returned data by carefully
+     * managing the event stream. This is the default value.

+     *
single Only a single request at a time is allowed on the operation;
+     * multiple requests generate a fault.

+     *
last Making a request cancels any existing request.

+     *

+     */
+    public function get concurrency():String
+    {
+        return _concurrency;
+    }
+
+    /**
+     *  @private
+     */
+    public function set concurrency(c:String):void
+    {
+        _concurrency = c;
+    }
+
+    /**
+     *  @private
+     */
+    private var _resultFormat:String = null;
+
+    [Inspectable(enumeration="object,array,xml,flashvars,text,e4x", category="General")]
+    /**
+     *  Value that indicates how you want to deserialize the result
+     *  returned by the HTTP call. The value for this is based on the following:
+     *

+     *
Whether you are returning XML or name/value pairs.

+     *
How you want to access the results; you can access results as an object,
+     *    text, or XML.

+     *

+     *
+     *
The default value is object. The following values are permitted:

+     *

+     *
object The value returned is XML and is parsed as a tree of ActionScript
+     *    objects. This is the default.

+     *
array The value returned is XML and is parsed as a tree of ActionScript
+     *    objects however if the top level object is not an Array, a new Array is created and the result
+     *    set as the first item. If makeObjectsBindable is true then the Array
+     *    will be wrapped in an ArrayCollection.

+     *
xml The value returned is XML and is returned as literal XML in an
+     *    ActionScript XMLnode object.

+     *
flashvars The value returned is text containing
+     *    name=value pairs separated by ampersands, which
+     *  is parsed into an ActionScript object.

+     *
text The value returned is text, and is left raw.

+     *
e4x The value returned is XML and is returned as literal XML
+     *    in an ActionScript XML object, which can be accessed using ECMAScript for
+     *    XML (E4X) expressions.

+     *

+     */
+    public function get resultFormat():String
+    {
+        return _resultFormat;
+    }
+
+    /**
+     *  @private
+     */
+    public function set resultFormat(value:String):void
+    {
+        switch (value)
+        {
+            case RESULT_FORMAT_OBJECT:
+            case RESULT_FORMAT_ARRAY:
+            case RESULT_FORMAT_XML:
+            case RESULT_FORMAT_E4X:
+            case RESULT_FORMAT_TEXT:
+            case RESULT_FORMAT_FLASHVARS:
+            {
+                break;
+            }
+
+            default:
+            {
+                var sf:SerializationFilter;
+                if (value != null && (sf = SerializationFilter.filterForResultFormatTable[value]) == null)
+                {
+                    // TODO: share this code with HTTPService, HTTPMultiService?  Also
+                    // improve the error/asdoc to include discussion of the SerializationFilter
+                    // and in the error display the contents of the SerializationFilter.filterForResultFormatTable
+                    // to make it clear which SerializationFormats are available in the current
+                    // context.
+                    var message:String = resourceManager.getString(
+                        "rpc", "invalidResultFormat",
+                        [ value, RESULT_FORMAT_OBJECT, RESULT_FORMAT_ARRAY,
+                          RESULT_FORMAT_XML, RESULT_FORMAT_E4X,
+                          RESULT_FORMAT_TEXT, RESULT_FORMAT_FLASHVARS ]);
+                    throw new ArgumentError(message);
+                }
+                serializationFilter = sf;
+            }
+        }
+        _resultFormat = value;
+    }
+
+    /**
+     * A SerializationFilter can control how the arguments are formatted to form the content
+     * of the HTTP request.  It also controls how the results are converted into ActionScript
+     * objects.  It can be set either explicitly using this property or indirectly using the
+     * resultFormat property.
+     */
+    public var serializationFilter:SerializationFilter;
+
+    /** Hook for subclasses to override the serialization filter to use for a given operation */
+    protected function getSerializationFilter():SerializationFilter
+    {
+        return serializationFilter;
+    }
+
+    //----------------------------------
+    //  request
+    //----------------------------------
+
+    [Inspectable(defaultValue="undefined", category="General")]
+    /**
+     *  Object of name-value pairs used as parameters to the URL. If
+     *  the contentType property is set to application/xml, it should be an XML document.
+     */
+    public var request:Object = {};
+
+
+    //----------------------------------
+    //  url
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _url:String;
+
+    [Inspectable(defaultValue="undefined", category="General")]
+    /**
+     *  Location of the service. If you specify the url and a non-default destination,
+     *  your destination in the services-config.xml file must allow the specified URL.
+     */
+    public function get url():String
+    {
+        return _url;
+    }
+
+    /**
+     *  @private
+     */
+    public function set url(value:String):void
+    {
+        _url = value;
+    }
+
+    //----------------------------------
+    //  useProxy
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    private var _useProxy:Boolean = false;
+
+    [Inspectable(defaultValue="false", category="General")]
+    /**
+     *  Specifies whether to use the Flex proxy service. The default value is false. If you
+     *  do not specify true to proxy requests though the Flex server, you must ensure that the player
+     *  can reach the target URL. You also cannot use destinations defined in the services-config.xml file if the
+     *  useProxy property is set to false.
+     *
+     *  @default false
+     */
+    public function get useProxy():Boolean
+    {
+        return _useProxy;
+    }
+
+    /**
+     *  @private
+     */
+    public function set useProxy(value:Boolean):void
+    {
+        if (value != _useProxy)
+        {
+            _useProxy = value;
+            var dcs:ChannelSet = getDirectChannelSet();
+            if (!useProxy)
+            {
+                if (dcs != asyncRequest.channelSet)
+                    asyncRequest.channelSet = dcs;
+            }
+            else
+            {
+                if (asyncRequest.channelSet == dcs)
+                    asyncRequest.channelSet = null;
+            }
+        }
+    }
+
+    //----------------------------------
+    //  xmlDecode
+    //----------------------------------
+
+    [Inspectable(defaultValue="undefined", category="General")]
+    /**
+     *  ActionScript function used to decode a service result from XML.
+     *  When the resultFormat is an object and the xmlDecode property is set,
+     *  Flex uses the XML that the HTTPService returns to create an
+     *  Object. If it is not defined the default XMLDecoder is used
+     *  to do the work.
+     *
The function referenced by the xmlDecode property must
+     *  take a flash.xml.XMLNode object as a parameter and should return
+     *  an Object. It can return any type of object, but it must return
+     *  something. Returning null or undefined causes a fault.

+
+    The following example shows an <mx:HTTPService> tag that specifies an xmlDecode function:
+
+

+   <mx:HTTPService id="hs" xmlDecode="xmlDecoder" url="myURL" resultFormat="object" contentType="application/xml">
+        <mx:request><source/>
+            <obj>{RequestObject}</obj>
+        </mx:request>
+   </mx:HTTPService>
+

+
+
+    The following example shows an xmlDecoder function:
+

+function xmlDecoder (myXML)
+{
+ // Simplified decoding logic.
+ var myObj = {};
+ myObj.name = myXML.firstChild.nodeValue;
+ myObj.honorific = myXML.firstChild.attributes.honorific;
+ return myObj;
+}
+

+
+     */
+    public var xmlDecode:Function;
+
+    //----------------------------------
+    //  xmlEncode
+    //----------------------------------
+
+    [Inspectable(defaultValue="undefined", category="General")]
+    /**
+     *  ActionScript function used to encode a service request as XML.
+     *  When the contentType of a request is application/xml and the
+     *  request object passed in is an Object, Flex attempts to use
+     *  the function specified in the xmlEncode property to turn it
+     *  into a flash.xml.XMLNode object If the xmlEncode property is not set,
+     *  Flex uses the default
+     *  XMLEncoder to turn the object graph into a flash.xml.XMLNode object.
+     *
+     *
The xmlEncode property takes an Object and should return
+     *  a flash.xml.XMLNode object. In this case, the XMLNode object can be a flash.xml.XML object,
+     *  which is a subclass of XMLNode, or the first child of the
+     *  flash.xml.XML object, which is what you get from an <mx:XML> tag.
+     *  Returning the wrong type of object causes a fault.
+     *  The following example shows an <mx:HTTPService> tag that specifies an xmlEncode function:

+
+

+  <mx:HTTPService id="hs" xmlEncode="xmlEncoder" url="myURL" resultFormat="object" contentType="application/xml">
+        <mx:request><source/>
+            <obj>{RequestObject}</obj>
+        </mx:request>
+   </mx:HTTPService>
+

+
+
+    The following example shows an xmlEncoder function:
+

+function xmlEncoder (myObj)
+{
+  return new XML("<userencoded><attrib0>MyObj.test</attrib0>
+  <attrib1>MyObj.anotherTest</attrib1></userencoded>");
+}
+

+
+     */
+    public var xmlEncode:Function;
+
+    //----------------------------------
+    //  headers
+    //----------------------------------
+
+    [Inspectable(defaultValue="undefined", category="General")]
+    /**
+     *  Custom HTTP headers to be sent to the third party endpoint. If multiple headers need to
+     *  be sent with the same name the value should be specified as an Array.
+     */
+    public var headers:Object = {};
+
+    //----------------------------------
+    //  contentType
+    //----------------------------------
+
+    [Inspectable(enumeration="application/x-www-form-urlencoded,application/xml", defaultValue="application/x-www-form-urlencoded", category="General")]
+    /**
+     *  Type of content for service requests.
+     *  The default is application/x-www-form-urlencoded which sends requests
+     *  like a normal HTTP POST with name-value pairs. application/xml send
+     *  requests as XML.
+     */
+    public var contentType:String = CONTENT_TYPE_FORM;
+
+    //----------------------------------
+    //  showBusyCursor
+    //----------------------------------
+
+    [Inspectable(defaultValue="false", category="General")]
+    /**
+    * If true, a busy cursor is displayed while a service is executing. The default
+    * value is false.
+    */
+    public function get showBusyCursor():Boolean
+    {
+        return _showBusyCursor;
+    }
+
+    public function set showBusyCursor(sbc:Boolean):void
+    {
+        _showBusyCursor = sbc;
+    }
+
+    //----------------------------------
+    //  rootURL
+    //----------------------------------
+
+    /**
+     *  @private
+     */
+    mx_internal var _rootURL:String;
+
+    /**
+     *  The URL that the HTTPService object should use when computing relative URLs.
+     *  This property is only used when going through the proxy.
+     *  When the useProxy property is set to false, the relative URL is computed automatically
+     *  based on the location of the SWF running this application.
+     *  If not set explicitly rootURL is automatically set to the URL of
+     *  mx.messaging.config.LoaderConfig.url.
+     */
+    public function get rootURL():String
+    {
+        if (_rootURL == null)
+        {
+            _rootURL = LoaderConfig.url;
+        }
+        return _rootURL;
+    }
+
+    /**
+     *  @private
+     */
+    public function set rootURL(value:String):void
+    {
+        _rootURL = value;
+    }
+
+    //---------------------------------
+    // Methods
+    //---------------------------------
+
+    /**
+     * @private
+     */
+    override public function cancel(id:String = null):AsyncToken
+    {
+        if (showBusyCursor)
+        {
+            CursorManager.removeBusyCursor();
+        }
+        return super.cancel(id);
+    }
+
+    public function sendBody(parameters:Object):AsyncToken
+    {
+        var filter:SerializationFilter = getSerializationFilter();
+
+        var paramsToSend:Object;
+        var token:AsyncToken;
+        var fault:Fault;
+        var faultEvent:FaultEvent;
+        var msg:String;
+
+        //concurrency check
+        if (Concurrency.SINGLE == concurrency && activeCalls.hasActiveCalls())
+        {
+            token = new AsyncToken(null);
+			var m:String = resourceManager.getString(
+				"rpc", "pendingCallExists");
+            fault = new Fault("ConcurrencyError", m);
+            faultEvent = FaultEvent.createEvent(fault, token);
+            new AsyncDispatcher(dispatchRpcEvent, [faultEvent], 10);
+            return token;
+        }
+
+        var ctype:String = contentType;
+        var urlToUse:String = url;
+
+        if (filter != null)
+        {
+            // TODO: does this need to run on the array version of the parameters
+            ctype = filter.getRequestContentType(this, parameters, ctype);
+            urlToUse = filter.serializeURL(this, parameters, urlToUse);
+            parameters = filter.serializeBody(this, parameters);
+        }
+
+        if (ctype == CONTENT_TYPE_XML)
+        {
+            if (!(parameters is XMLNode) && !(parameters is XML))
+            {
+                if (xmlEncode != null)
+                {
+                    var funcEncoded:Object = xmlEncode(parameters);
+                    if (null == funcEncoded)
+                    {
+                        token = new AsyncToken(null);
+                        msg = resourceManager.getString(
+                            "rpc", "xmlEncodeReturnNull");
+                        fault = new Fault(ERROR_ENCODING, msg);
+                        faultEvent = FaultEvent.createEvent(fault, token);
+                        new AsyncDispatcher(dispatchRpcEvent, [faultEvent], 10);
+                        return token;
+                    }
+                    else if (!(funcEncoded is XMLNode))
+                    {
+                        token = new AsyncToken(null);
+                        msg = resourceManager.getString(
+                            "rpc", "xmlEncodeReturnNoXMLNode");
+                        fault = new Fault(ERROR_ENCODING, msg);
+                        faultEvent = FaultEvent.createEvent(fault, token);
+                        new AsyncDispatcher(dispatchRpcEvent, [faultEvent], 10);
+                        return token;
+                    }
+                    else
+                    {
+                        paramsToSend = XMLNode(funcEncoded).toString();
+                    }
+                }
+                else
+                {
+                    var encoder:SimpleXMLEncoder = new SimpleXMLEncoder(null);
+                    var xmlDoc:XMLDocument = new XMLDocument();
+
+                    //right now there is a wasted <encoded> wrapper tag
+                    //call.appendChild(encoder.encodeValue(parameters));
+                    var childNodes:Array = encoder.encodeValue(parameters, new QName(null, "encoded"), new XMLNode(1, "top")).childNodes.concat();
+                    for (var i:int = 0; i < childNodes.length; ++i)
+                        xmlDoc.appendChild(childNodes[i]);
+
+                    paramsToSend = xmlDoc.toString();
+                }
+            }
+            else
+            {
+                paramsToSend = XML(parameters).toXMLString();
+            }
+        }
+        else if (ctype == CONTENT_TYPE_FORM)
+        {
+            paramsToSend = {};
+            var val:Object;
+
+            //get all dynamic and all concrete properties from the parameters object
+            var classinfo:Object = ObjectUtil.getClassInfo(parameters);
+
+            for each (var p:* in classinfo.properties)
+            {
+                val = parameters[p];
+                if (val != null)
+                {
+                    if (val is Array)
+                        paramsToSend[p] = val;
+                    else
+                        paramsToSend[p] = val.toString();
+                }
+            }
+        }
+        else
+        {
+            paramsToSend = parameters;
+        }
+
+        var message:HTTPRequestMessage = new HTTPRequestMessage();
+        if (useProxy)
+        {
+            if (url && url != '')
+            {
+                message.url = URLUtil.getFullURL(rootURL, url);
+            }
+
+        }
+        else
+        {
+            if (!url)
+            {
+                token = new AsyncToken(null);
+                msg = resourceManager.getString(
+                    "rpc", "urlNotSpecified");
+                fault = new Fault(ERROR_URL_REQUIRED, msg);
+                faultEvent = FaultEvent.createEvent(fault, token);
+                new AsyncDispatcher(dispatchRpcEvent, [faultEvent], 10);
+                return token;
+            }
+
+            if (!useProxy)
+            {
+                var dcs:ChannelSet = getDirectChannelSet();
+                if (dcs != asyncRequest.channelSet)
+                    asyncRequest.channelSet = dcs;
+            }
+
+            message.url = url;
+        }
+
+        message.contentType = ctype;
+        message.method = method.toUpperCase();
+        if (ctype == CONTENT_TYPE_XML && message.method == HTTPRequestMessage.GET_METHOD)
+            message.method = HTTPRequestMessage.POST_METHOD;
+        message.body = paramsToSend;
+        message.httpHeaders = getHeaders();
+        return invoke(message);
+    }
+
+    /**
+     * Hook for subclasses to override the retrieval of the HTTP request headers.
+     */
+    protected function getHeaders():Object
+    {
+        return headers;
+    }
+
+    /**
+     *  @private
+     */
+    override mx_internal function processResult(message:IMessage, token:AsyncToken):Boolean
+    {
+        var body:Object = message.body;
+
+        _log.info("Decoding HTTPService response");
+        _log.debug("Processing HTTPService response message:\n{0}", message);
+
+        var filter:SerializationFilter = getSerializationFilter();
+
+        if (filter != null)
+            body = filter.deserializeResult(this, body);
+
+        if ((body == null) || ((body != null) && (body is String) && (StringUtil.trim(String(body)) == "")))
+        {
+            _result = body;
+            return true;
+        }
+        else if (body is String)
+        {
+            if (resultFormat == RESULT_FORMAT_XML || resultFormat == RESULT_FORMAT_OBJECT
+                    || resultFormat == RESULT_FORMAT_ARRAY)
+            {
+                //old XML style
+                var tmp:Object = new XMLDocument();
+                XMLDocument(tmp).ignoreWhite = true;
+                try
+                {
+                    XMLDocument(tmp).parseXML(String(body));
+                }
+                catch(parseError:Error)
+                {
+                    var fault:Fault = new Fault(ERROR_DECODING, parseError.message);
+                    dispatchRpcEvent(FaultEvent.createEvent(fault, token, message));
+                    return false;
+                }
+                if (resultFormat == RESULT_FORMAT_OBJECT || resultFormat == RESULT_FORMAT_ARRAY)
+                {
+                    var decoded:Object;
+                    var msg:String;
+                    if (xmlDecode != null)
+                    {
+                        decoded = xmlDecode(tmp);
+                        if (decoded == null)
+                        {
+                            msg = resourceManager.getString(
+                                "rpc", "xmlDecodeReturnNull");
+                            var fault1:Fault = new Fault(ERROR_DECODING, msg);
+                            dispatchRpcEvent(FaultEvent.createEvent(fault1, token, message));
+                        }
+                    }
+                    else
+                    {
+                        var decoder:SimpleXMLDecoder = new SimpleXMLDecoder(makeObjectsBindable);
+
+                        decoded = decoder.decodeXML(XMLNode(tmp));
+
+                        if (decoded == null)
+                        {
+                            msg = resourceManager.getString(
+                                "rpc", "defaultDecoderFailed");
+                            var fault2:Fault = new Fault(ERROR_DECODING, msg);
+                            dispatchRpcEvent(FaultEvent.createEvent(fault2, token, message));
+                        }
+                    }
+
+                    if (decoded == null)
+                    {
+                        return false;
+                    }
+
+                    if (makeObjectsBindable && (getQualifiedClassName(decoded) == "Object"))
+                    {
+                        decoded = new ObjectProxy(decoded);
+                    }
+                    else
+                    {
+                        decoded = decoded;
+                    }
+
+                    if (resultFormat == RESULT_FORMAT_ARRAY)
+                    {
+                        decoded = decodeArray(decoded);
+                    }
+
+                    _result = decoded;
+                }
+                else
+                {
+                    if (tmp.childNodes.length == 1)
+                    {
+                        tmp = tmp.firstChild;
+                    }
+                    _result = tmp;
+                }
+            }
+            else if (resultFormat == RESULT_FORMAT_E4X)
+            {
+                try
+                {
+                    _result = new XML(String(body));
+                }
+                catch(error:Error)
+                {
+                    var fault3:Fault = new Fault(ERROR_DECODING, error.message);
+                    dispatchRpcEvent(FaultEvent.createEvent(fault3, token, message));
+                    return false;
+                }
+            }
+            else if (resultFormat == RESULT_FORMAT_FLASHVARS)
+            {
+                _result = decodeParameterString(String(body));
+            }
+            else //if only we could assert(theService.resultFormat == "text")
+            {
+                _result = body;
+            }
+        }
+        else
+        {
+            if (resultFormat == RESULT_FORMAT_ARRAY)
+            {
+                body = decodeArray(body);
+            }
+
+            _result = body;
+        }
+
+        return true;
+    }
+
+    override mx_internal function invoke(message:IMessage, token:AsyncToken = null):AsyncToken
+    {
+        if (showBusyCursor)
+        {
+            CursorManager.setBusyCursor();
+        }
+
+        return super.invoke(message, token);
+    }
+
+    /*
+     * Kill the busy cursor, find the matching call object and pass it back
+     */
+    override mx_internal function preHandle(event:MessageEvent):AsyncToken
+    {
+        if (showBusyCursor)
+        {
+            CursorManager.removeBusyCursor();
+        }
+
+        var wasLastCall:Boolean = activeCalls.wasLastCall(AsyncMessage(event.message).correlationId);
+        var token:AsyncToken = super.preHandle(event);
+
+        if (Concurrency.LAST == concurrency && !wasLastCall)
+        {
+            return null;
+        }
+        //else
+        return token;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    // Private Methods
+    //
+    //--------------------------------------------------------------------------
+
+    private function decodeArray(o:Object):Object
+    {
+        var a:Array;
+
+        if (o is Array)
+        {
+            a = o as Array;
+        }
+        else if (o is ArrayCollection)
+        {
+            return o;
+        }
+        else
+        {
+            a = [];
+            a.push(o);
+        }
+
+        if (makeObjectsBindable)
+        {
+            return new ArrayCollection(a);
+        }
+        else
+        {
+            return a;
+        }
+    }
+
+    private function decodeParameterString(source:String):Object
+    {
+        var trimmed:String = StringUtil.trim(source);
+        var params:Array = trimmed.split('&');
+        var decoded:Object = {};
+        for (var i:int = 0; i<params.length; i++)
+        {
+            var param:String = params[i];
+            var equalsIndex:int = param.indexOf('=');
+            if (equalsIndex != -1)
+            {
+                var name:String = unescape(param.substr(0, equalsIndex));
+                name = name.split('+').join(' ');
+                var value:String = unescape(param.substr(equalsIndex+1));
+                value = value.split('+').join(' ');
+                decoded[name] = value;
+            }
+        }
+        return decoded;
+    }
+
+    private function getDirectChannelSet():ChannelSet
+    {
+        if (_directChannelSet == null)
+        {
+            var dcs:ChannelSet = new ChannelSet();
+            dcs.addChannel(new DirectHTTPChannel("direct_http_channel"));
+            _directChannelSet = dcs;
+        }
+        return _directChannelSet;
+    }
+
+    mx_internal var _log:ILogger;
+
+    mx_internal var resourceManager:IResourceManager =
+                                    ResourceManager.getInstance();
+    /**
+     *  @private
+     *  A shared direct Http channelset used for service instances that do not use the proxy.
+     */
+    private static var _directChannelSet:ChannelSet;
+
+    private var _concurrency:String;
+
+	private var _showBusyCursor:Boolean;
+
+}
+
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 20013
Author:   harishs@adobe.com
Date:     2011-01-31T15:32:09.255609Z

Log Message:
-----------
QE notes: Globalization changes. Full cyclone run has been done. Default locale changes and sort bug fixes since Dec 14 2010
Doc notes: ASDOC comments for all classes have been updated.
Bugs: SDK-29132 SDK-29127 SDK-28163  SDK-29075 SDK-28600 SDK-28492 SDK-28856

Reviewer: Gordon Smith, Xie Fang, Zhigang Qi
Tests run: cyclone and checkintests
Is noteworthy for integration:

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/styles/AdvancedStyleClient.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/collections/SortField.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/supportClasses/NumberValidatorBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/collections/ISort.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/supportClasses/GlobalizationValidatorBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/supportClasses/CollatorBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/formatters/NumberFormatter.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/collections/ISortField.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/formatters/CurrencyFormatter.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/collections/Sort.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/NumberValidator.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/formatters/DateTimeFormatter.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/CurrencyValidator.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/core/UIComponent.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/collections/SortField.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Group.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/supportClasses/GlobalizationBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/supportClasses/GlobalizationUtils.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/SortingCollator.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/StringTools.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/LastOperationStatus.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/collections/Sort.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/formatters/supportClasses/NumberFormatterBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/MatchingCollator.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1278165 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/collections/SortField.as
+++ frameworks/projects/spark/src/spark/collections/SortField.as
@@ -18,6 +18,7 @@

 import mx.collections.ISortField;
 import mx.collections.errors.SortError;
+import mx.core.FlexGlobals;
 import mx.core.UIComponent;
 import mx.managers.ISystemManager;
 import mx.managers.SystemManager;
@@ -52,6 +53,9 @@
 /**
  *  Provides the sorting information required to establish a sort on a field
  *  or property in a collection view.
+ *
+ *  SortField class is meant to be used with Sort class.
+ *
  *  Typically the sort is defined for collections of complex items, that
  *  is items in which the sort is performed on properties of those objects.
  *  As in the following example:
@@ -84,7 +88,7 @@
  *     col.sort = sort;
  *

  *
- *
The default comparison provided by the SortField class
+ *
The default comparison provided by the SortField class
  *  provides correct language specific
  *  sorting for strings. The language is selected by the setting the locale
  *  style on an instance of the class in one of the following ways:
@@ -95,23 +99,23 @@
  *  locale from the document that contains the declaration.
  *

  *  Example:
- *  <listing version="3.0" >
+ *

  *  <fx:Declarations>

  *         <s:SortField id="sf" />

  *  </fx:Declarations>
- *  </listing>
+ *

  *

  *  By using an MXML declaration and specifying the locale value
  *  in the list of assignments.
  *

  *  Example:
- *  <listing version="3.0" >
+ *

  *  <fx:Declarations>

  *      <s:SortField id="sf_SimplifiedChinese" locale="zh-Hans-CN" />

  *  </fx:Declarations>
- *  </listing>
+ *

  *

- *  Calling the setStyle method,
+ *  Calling the setStyle method,
  *  e.g. sf.setStyle("locale", "zh-Hans-CN")
  *

  *

@@ -249,9 +253,10 @@
     /**
      *  The function that compares two items during a sort of items for the
      *  associated collection. If you specify a compareFunction
-     *  property in an ISort object, Flex ignores any
-     *  compareFunction properties of the ISort's SortField
-     *  objects.
+     *  property in an ISort object, Flex ignores any
+     *  compareFunction properties of the ISort's
+     *  SortField objects.
+     *
      *
The compare function must have the following signature:

      *
      *
function myCompare(a:Object, b:Object):int

@@ -259,11 +264,12 @@
      *
This function must return the following values:

      *
      *

-     *
-1, if a should appear before b in
-     *        the sorted sequence

-     *
0, if a equals b

-     *
1, if a should appear after b in the
-     *        sorted sequence

+     *
-1, if the Object a should appear before the
+     *        Object b in the sorted sequence

+     *
0, if the Object a equals the
+     *        Object b

+     *
1, if the Object a should appear after the
+     *        Object b in the sorted sequence

      *

      *
      *
The default value is an internal compare function that can perform
@@ -438,6 +444,47 @@
     //--------------------------------------------------------------------------

     /**
+    *  @private
+    */
+    override public function getStyle(styleProp:String):*
+    {
+        if (styleProp != "locale")
+            return super.getStyle(styleProp);
+
+        if ((localeStyle !== undefined) && (localeStyle !== null))
+            return localeStyle;
+
+        if (styleParent)
+            return styleParent.getStyle(styleProp);
+
+        if (FlexGlobals.topLevelApplication)
+            return FlexGlobals.topLevelApplication.getStyle(styleProp);
+
+        return undefined;
+    }
+
+    /**
+     *  @private
+     *  Intercept style change for "locale".
+     *
+     *  In the case that there is no associated UI component or the
+     *  module factory of the UIComponent has not yet been intialized
+     *  style changes are only recorded but the styleChanged method
+     *  is not called.  Overriding the setStyle method allows
+     *  the class to be updated immediately when the locale style is
+     *  set directly on this class instance.
+     */
+    override public function setStyle(styleProp:String, newValue:*):void
+    {
+        super.setStyle(styleProp, newValue);
+
+        if (styleProp != "locale")
+            return;
+
+        localeChanged();
+    }
+
+    /**
      *  @private
      *  Detects changes to style properties. When any style property is set,
      *  Flex calls the styleChanged() method,
@@ -494,6 +541,8 @@
         {
             if (numeric == true)
                 _compareFunction = numericCompare;
+            else if (numeric == false)
+                _compareFunction = stringCompare;
             else
             {
                 // we need to introspect the data a little bit
@@ -599,9 +648,9 @@
     {
         if (!internalStringCollator)
         {
-            const locale:String = getStyle("locale");
-            if (!locale)
-                throw new IllegalOperationError("Undefined locale");
+            ensureStyleSource();
+            const locale:* = getStyle("locale");
+
             internalStringCollator = new SortingCollator();
             internalStringCollator.setStyle("locale", locale);
         }
@@ -614,6 +663,32 @@
     //  Private Methods
     //
     //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Ensure some style source exists for this instance of a globalization
+     *  object.
+     *
+     *  A style source is considered exist if (A) styleParent value is non-null,
+     *  or (B) localeStyle value has some useable value.
+     *  If neither is the case, this style client will be added to the
+     *  FlexGlobals.topLevelApplication as a child if possible.
+     *
+     *  As a side effect this will call the styleChanged method and if the
+     *  locale has changed will cause the createWorkingInstance method
+     *  to be called.
+     */
+    private function ensureStyleSource():void
+    {
+        if (!styleParent &&
+            ((localeStyle === undefined) || (localeStyle === null)))
+        {
+            if (FlexGlobals.topLevelApplication)
+            {
+                FlexGlobals.topLevelApplication.addStyleClient(this);
+            }
+        }
+    }

     private function nullCompare(a:Object, b:Object):int
     {
@@ -847,7 +922,7 @@
      */
     private function localeChanged():void
     {
-        const newlocaleStyle:* = getStyle("locale");
+        const newlocaleStyle:* = super.getStyle("locale");

         if (localeStyle === newlocaleStyle)
             return;


Transferred from the Adobe Open Source Subversion Repository

Revision: 17310
Author:   rfrishbe@adobe.com
Date:     2010-08-13T00:57:38.531711Z

Log Message:
-----------
Moving MobileItemRenderer to MobileTextField.  Also cleaning up MobileTextField a bit (padding's no longer respected in it and fixed a bug with isTruncated).  Also fixed up some logic in ButtonSkinBase around text truncation.

MobileItemRenderer is now the default item renderer for mobile lists.

QE notes: None
Doc notes: None
Bugs: -
Reviewer: Glenn
Tests run: checkintests
Is noteworthy for integration: No

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/supportClasses/MobileTextField.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/SparkClasses.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/MobileItemRenderer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/defaults.css</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ListSkin.mxml</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ButtonSkinBase.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1265850 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/ButtonSkinBase.as
+++ frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/ButtonSkinBase.as
@@ -401,6 +401,10 @@
             labelDisplay.y = Math.round(labelY);
             labelDisplay.height = labelHeight;
             labelDisplay.width = labelWidth;
+
+            // before truncating text, we need to reset it to its original value
+            if (hostComponent && labelDisplay.isTruncated)
+                labelDisplay.text = hostComponent.label;
             labelDisplay.truncateToFit();

             labelDisplayShadow.commitStyles();
@@ -408,7 +412,11 @@
             labelDisplayShadow.y = Math.round(labelY + 1);
             labelDisplayShadow.height = labelHeight;
             labelDisplayShadow.width = labelWidth;
-            labelDisplayShadow.truncateToFit();
+
+            // if labelDisplay is truncated, then push it down here as well.
+            // otherwise, it would have gotten pushed in the labelDisplay_valueCommitHandler()
+            if (labelDisplay.isTruncated)
+                labelDisplayShadow.text = labelDisplay.text;

             if (iconDisplay)
             {


Use utility function

Use utility function

--- lib/src_linux/com/amanitadesign/steam/FRESteamWorks.as
+++ lib/src_linux/com/amanitadesign/steam/FRESteamWorks.as
@@ -672,7 +672,7 @@

 		public function getUserPublishedItemVoteDetails(file:String):Boolean {
 			if(!callWrapper(AIRSteam_GetUserPublishedItemVoteDetails, [file])) return false;
-			return readResponse() as Boolean;
+			return readBoolResponse();
 		}

 		public function getUserPublishedItemVoteDetailsResult():UserVoteDetails {


fix DrawCall.depth getter to avoid instanciating Vector4 objects

--- src/aerys/minko/render/DrawCall.as
+++ src/aerys/minko/render/DrawCall.as
@@ -137,9 +137,12 @@

 				if (_localToWorld != null && _worldToScreen != null)
 				{
-					_localToWorld.transformVector(Vector4.ZERO, TMP_VECTOR4);
-
-					var screenSpacePosition : Vector4 = _worldToScreen.transformVector(TMP_VECTOR4, TMP_VECTOR4);
+					var worldSpacePosition 	: Vector4	= _localToWorld.transformVector(
+						Vector4.ZERO, TMP_VECTOR4
+					);
+					var screenSpacePosition : Vector4 	= _worldToScreen.transformVector(
+						worldSpacePosition, TMP_VECTOR4
+					);

 					_depth = screenSpacePosition.z / screenSpacePosition.w;
 				}


remove test of _enabled because it should now be done before calling DrawCall.apply()

--- src/aerys/minko/render/DrawCall.as
+++ src/aerys/minko/render/DrawCall.as
@@ -298,9 +298,6 @@

 		public function apply(context : Context3DResource, previous : DrawCall) : uint
 		{
-			if (!_enabled)
-				return 0;
-
 			context.setColorMask(_colorMaskR, _colorMaskG, _colorMaskB, _colorMaskA)
 				   .setProgramConstantsFromVector(PROGRAM_TYPE_VERTEX, 0, _vsConstants)
 				   .setProgramConstantsFromVector(PROGRAM_TYPE_FRAGMENT, 0, _fsConstants);


Property parentLayout made Bindable to avoid warnings

--- collect-flex/collect-flex-client/src/generated/flex/org/openforis/collect/metamodel/proxy/NodeDefinitionProxy.as
+++ collect-flex/collect-flex-client/src/generated/flex/org/openforis/collect/metamodel/proxy/NodeDefinitionProxy.as
@@ -50,6 +50,7 @@
 			return null;
 		}

+		[Bindable]
 		public function get parentLayout():String {
 			if(parent != null) {
 				return parent.layout;


Find md5s up to two-levels deep in modified checks

--- src/main/as/flump/export/BetwixtPublisher.as
+++ src/main/as/flump/export/BetwixtPublisher.as
@@ -20,12 +20,8 @@

 public class BetwixtPublisher
 {
-    public static function makeExportLocation(lib :XflLibrary, exportDir :File) :File {
-        return exportDir.resolvePath(lib.location + ".xml");
-    }
-
     public static function modified(lib :XflLibrary, exportDir :File) :Boolean {
-        const exportLoc :File = makeExportLocation(lib, exportDir);
+        const exportLoc :File = exportDir.resolvePath(lib.location + "/resources.xml");
         if (!exportLoc.exists) return true;

         const libMd5s :Map = Maps.newMapOf(String);
@@ -37,14 +33,17 @@
         export.open(exportLoc, FileMode.READ);
         var exportBytes :ByteArray = new ByteArray();
         export.readBytes(exportBytes);
-        for each (var resource :XML in bytesToXML(exportBytes).elements()) {
-            exportMd5s.put(XmlUtil.getStringAttr(resource, "name"),
-                XmlUtil.getStringAttr(resource, "md5"));
-        }
+        var xml :XML = bytesToXML(exportBytes);
+        function addMd5(el :XML) :void {
+            exportMd5s.put(XmlUtil.getStringAttr(el, "name"), XmlUtil.getStringAttr(el, "md5"));
+        };
+        // Add md5s one and two levels deep in the resource xml
+        for each (var res :XML in xml.*.(hasOwnProperty('@md5'))) addMd5(res);
+        for each (res in xml.*.*.(hasOwnProperty('@md5'))) addMd5(res);
         return !exportMd5s.equals(libMd5s);
     }

-    public static function export (lib :XflLibrary, source :File, exportDir :File) :void {
+    public static function publish (lib :XflLibrary, source :File, exportDir :File) :void {
         const packer :Packer = new Packer(lib);
         const destDir :File = exportDir.resolvePath(lib.location);
         destDir.createDirectory();


Removing event listeners before we are done needing them is a bad idea. This fixes rejoining rooms

--- src/org/jivesoftware/xiff/conference/Room.as
+++ src/org/jivesoftware/xiff/conference/Room.as
@@ -348,7 +348,6 @@
 				// Clear out the roster items
 				removeAll();
 				myConnection.removeEventListener(MessageEvent.MESSAGE, handleEvent);
-				myConnection.removeEventListener(PresenceEvent.PRESENCE, handleEvent);
 				myConnection.removeEventListener(DisconnectionEvent.DISCONNECT, handleEvent);
 			}
 		}
@@ -711,6 +710,7 @@
 								active = false;
 								e = new RoomEvent(RoomEvent.ROOM_LEAVE);
 								dispatchEvent(e);
+								myConnection.removeEventListener(PresenceEvent.PRESENCE, handleEvent);
 							}
 						}
 					}


Update frame4.as

Update frame4.as

--- as/main/frame4.as
+++ as/main/frame4.as
@@ -34,11 +34,11 @@
 	pressing = false;
 };

-var Private_lv = new LoadVars ();
+var Privat = new LoadVars ();

-Private_lv.load ("/assets/tendes.txt");
+Privat.load ("/assets/tendes.txt");

-Private_lv.onLoad = function ():Void
+Privat.onLoad = function ():Void
 {
 	this.historia_txt.htmlText = this.Privat;
 	this.play ();


Editor: bring quickmenu to front on search

--- Bin/Data/Scripts/Editor/EditorUI.as
+++ Bin/Data/Scripts/Editor/EditorUI.as
@@ -215,6 +215,7 @@

     menu.visible = limit > 0;
     menu.SetFixedHeight(limit * 16);
+    quickMenu.BringToFront();
     quickMenu.SetFixedHeight(limit*16 + 62 + (menu.visible ? 6 : 0));
 }


Camera resets by default in World's begin().

--- net/flashpunk/World.as
+++ net/flashpunk/World.as
@@ -28,7 +28,7 @@
 		 */
 		public function begin():void
 		{
-
+			FP.camera.x = FP.camera.y = 0;
 		}

 		/**


Revised select clause handling in Query
Added helper methods to Query class
Added new query methods to flare.query.methods
Updated expression test cases

git-svn-id: 6aa7ccb0a2048310a30f08a72aaff4ca39d980ed@92 91848ab2-c4ae-4e4f-8e6a-6a52ea0dccc3

--- flare.tests/flare/tests/ExpressionTests.as
+++ flare.tests/flare/tests/ExpressionTests.as
@@ -7,33 +7,41 @@
 	import flare.query.If;
 	import flare.query.Literal;
 	import flare.query.Or;
+	import flare.query.Query;
 	import flare.query.Range;
 	import flare.query.Variable;
 	import flare.query.Xor;
-	import flare.query.methods.add;
-	import flare.query.methods.and;
-	import flare.query.methods.div;
-	import flare.query.methods.eq;
-	import flare.query.methods.gt;
-	import flare.query.methods.gte;
-	import flare.query.methods.iff;
-	import flare.query.methods.lt;
-	import flare.query.methods.lte;
-	import flare.query.methods.mod;
-	import flare.query.methods.mul;
-	import flare.query.methods.neq;
-	import flare.query.methods.or;
-	import flare.query.methods.range;
-	import flare.query.methods.sub;
-	import flare.query.methods.xor;
+	import flare.query.methods.*;

 	import unitest.TestCase;

 	public class ExpressionTests extends TestCase
 	{
 		public function ExpressionTests() {
+			addTest("testParse");
 			addTest("testExpressions");
 			addTest("testExpressionMethods");
+			addTest("testQuery");
+		}
+
+		public function testParse():void
+		{
+			assertTrue(Expression.expr(true) is Literal);
+			assertTrue(Expression.expr(false) is Literal);
+			assertTrue(Expression.expr(1) is Literal);
+			assertTrue(Expression.expr(new Date()) is Literal);
+			assertTrue(Expression.expr("'a'") is Literal);
+			assertTrue(Expression.expr("a") is Variable);
+			assertTrue(Expression.expr("{a}") is Variable);
+
+			var s:String = "a";
+			assertTrue(_(s) is Literal);
+			assertEquals("a", _(s).eval());
+			assertTrue($(s) is Variable);
+			assertEquals("a", $(s).name);
+			assertTrue(Expression.expr(s) is Variable);
+			assertTrue(Expression.expr(_(s)) is Literal);
+			assertTrue(Expression.expr($(s)) is Variable);
 		}

 		// test variables
@@ -184,8 +192,8 @@

 		public function testExpressionMethods():void
 		{
-			var a:String = "[a]";
-			var b:String = "[b]";
+			var a:Variable = $("a");
+			var b:Variable = $("b");

 			_lt  = lt(a, b);
 			_gt  = gt(a, b);
@@ -208,5 +216,102 @@
 			_runTests();
 		}

+		public function testQuery():void
+		{
+			var data:Array = [
+				{val:4, cat:"a"},
+				{val:4, cat:"a"},
+				{val:4, cat:"a"},
+				{val:3, cat:"b"},
+				{val:3, cat:"b"},
+				{val:3, cat:"b"},
+				{val:2, cat:"c"},
+				{val:2, cat:"c"},
+				{val:2, cat:"c"},
+				{val:1, cat:"d"}
+			];
+
+			var r:Array;
+
+			r = select({count:count("cat")}).eval(data);
+			assertEquals(1, r.length);
+			assertEquals(10, r[0].count);
+
+			r = select({distinct:distinct("cat")}).eval(data);
+			assertEquals(1, r.length);
+			assertEquals(4, r[0].distinct);
+
+			r = select({min:min("val")}).eval(data);
+			assertEquals(1, r.length);
+			assertEquals(1, r[0].min);
+
+			r = select({max:max("val")}).eval(data);
+			assertEquals(1, r.length);
+			assertEquals(4, r[0].max);
+
+			r = select({avg:average("val")}).eval(data);
+			assertEquals(1, r.length);
+			assertEquals(2.8, r[0].avg);
+
+			r = select({sum:sum("val")}).eval(data);
+			assertEquals(1, r.length);
+			assertEquals(28, r[0].sum);
+
+			r = select({sum:sum("val")})
+				.where(eq("cat", _("a"))) // use a as literal
+				.eval(data);
+			assertEquals(1, r.length);
+			assertEquals(12, r[0].sum);
+
+			r = select({sum:sum("val")})
+				.where(eq("cat", $("a"))) // use a as variable
+				.eval(data);
+			assertEquals(0, r.length);
+
+			r = select("cat", {sum:sum("val")})
+				.groupby("cat")
+				.eval(data);
+			assertEquals( 4, r.length);
+			assertEquals(12, r[0].sum); assertEquals("a", r[0].cat);
+			assertEquals( 9, r[1].sum); assertEquals("b", r[1].cat);
+			assertEquals( 6, r[2].sum); assertEquals("c", r[2].cat);
+			assertEquals( 1, r[3].sum); assertEquals("d", r[3].cat);
+
+			var q:Query = where(or(eq("cat", _("a")),
+			                       eq("cat", _("b"))));
+			r = q.eval(data);
+			assertEquals(6, r.length);
+
+			r = q.orderby("cat", false).eval(data);
+			assertEquals(6, r.length);
+			assertEquals("b", r[0].cat);
+			assertEquals("a", r[5].cat);
+
+			// -----
+
+			data = [
+	 			{cat:"a", val:1}, {cat:"a", val:2},
+	 			{cat:"b", val:3}, {cat:"b", val:4},
+	 			{cat:"c", val:5}, {cat:"c", val:6},
+	 			{cat:"d", val:7}, {cat:"d", val:8}
+	 		];
+
+	 		r = orderby("cat", true, "val", false).eval(data);
+	 		assertEquals(8, r.length);
+	 		assertEquals(2, r[0].val); assertEquals(1, r[1].val);
+	 		assertEquals(4, r[2].val); assertEquals(3, r[3].val);
+	 		assertEquals(6, r[4].val); assertEquals(5, r[5].val);
+	 		assertEquals(8, r[6].val); assertEquals(7, r[7].val);
+
+	 		r = select("cat", {sum:sum("val")}) // category + sum of values
+	            .where(neq("cat", _("d")))      // exclude category "d"
+	            .groupby("cat")                 // group by category
+	            .eval(data);                    // evaluate with data array
+	  		assertEquals( 3, r.length);
+	  		assertEquals("a", r[0].cat); assertEquals( 3, r[0].sum);
+	  		assertEquals("b", r[1].cat); assertEquals( 7, r[1].sum);
+	  		assertEquals("c", r[2].cat); assertEquals(11, r[2].sum);
+		}
+
 	}
 }


Transferred from the Adobe Open Source Subversion Repository

Revision: 8
Author:   open-source-svn-admin@adobe.com
Date:     2007-12-15T01:49:31.087529Z

Log Message:
-----------
The beginning of the open-source Flex SDK.

Populated the flex/sdk/trunk directory with an open-source subset of files from //depot/flex/sdk/...@191097 in the Faramir Perforce server. This changelist is a bit past the 3.0rc0 build.

The Ant scripts will not successfully build yet. They need to be adapted to the open-source subset.

Modified Paths:
--------------
2532 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1258571 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/framework/src/mx/binding/utils/BindingUtils.as
+++ frameworks/projects/framework/src/mx/binding/utils/BindingUtils.as
@@ -0,0 +1,154 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2006-2007 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.binding.utils
+{
+
+import mx.binding.utils.ChangeWatcher;
+
+/**
+ *  The BindingUtils class defines utility methods
+ *  for performing data binding from ActionScript.
+ *  You can use the methods defined in this class to configure data bindings.
+ */
+public class BindingUtils
+{
+    include "../../core/Version.as";
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  Binds a public property, prop on the site
+     *  Object, to a bindable property or property chain.
+     *  If a ChangeWatcher instance is successfully created, prop
+     *  is initialized to the current value of chain.
+     *
+     *  @param site The Object defining the property to be bound
+     *  to chain.
+     *
+     *  @param prop The name of the public property defined in the
+     *  site Object to be bound.
+     *  The property will receive the current value of chain,
+     *  when the value of chain changes.
+     *
+     *  @param host The object that hosts the property or property chain
+     *  to be watched.
+     *
+     *  @param chain A value specifying the property or chain to be watched.
+     *  Legal values are:
+     *

+     *
String containing the name of a public bindable property
+     *    of the host object.

+     *
+     *
An Object in the form:
+     *    { name: property name, getter: function(host) { return host[property name] } }.
+     *    This Object must contain the name of, and a getter function for,
+     *    a public bindable property of the host object.

+     *
+     *
A non-empty Array containing a combination of the first two
+     *    options that represents a chain of bindable properties accessible
+     *    from the host.
+     *    For example, to bind the property host.a.b.c,
+     *    call the method as:
+     *    bindProperty(host, ["a","b","c"], ...).

+     *

+     *
+     *
Note: The property or properties named in the chain argument
+     *  must be public, because the describeType() method suppresses all information
+     *  about non-public properties, including the bindability metadata
+     *  that ChangeWatcher scans to find the change events that are exposed
+     *  for a given property.
+     *  However, the getter function supplied when using the { name, getter }
+     *  argument form described above can be used to associate an arbitrary
+     *  computed value with the named (public) property.

+     *
+     *  @param commitOnly Set to true if the handler
+     *  should be called only on committing change events;
+     *  set to false if the handler should be called
+     *  on both committing and non-committing change events.
+     *  Note: the presence of non-committing change events for a property
+     *  is indicated by the [NonCommittingChangeEvent(<event-name>)]
+     *  metadata tag.
+     *  Typically these tags are used to indicate fine-grained value changes,
+     *  such as modifications in a text field prior to confirmation.
+     *
+     *  @return A ChangeWatcher instance, if at least one property name has
+     *  been specified to the chain argument; null otherwise.
+     */
+    public static function bindProperty(
+                                site:Object, prop:String,
+                                host:Object, chain:Object,
+                                commitOnly:Boolean = false):ChangeWatcher
+    {
+        var w:ChangeWatcher =
+            ChangeWatcher.watch(host, chain, null, commitOnly);
+
+        if (w != null)
+        {
+            var assign:Function = function(event:*):void
+            {
+                site[prop] = w.getValue();
+            };
+            w.setHandler(assign);
+            assign(null);
+        }
+
+        return w;
+    }
+
+    /**
+     *  Binds a setter function, setter, to a bindable property
+     *  or property chain.
+     *  If a ChangeWatcher instance is successfully created,
+     *  the setter function is invoked with current value of chain.
+     *
+     *  @param setter Setter method to invoke with an argument of the current
+     *  value of chain when that value changes.
+     *
+     *  @param host The host of the property.
+     *  See the bindProperty() method for more information.
+     *
+     *  @param name The name of the property, or property chain.
+     *  See the bindProperty() method for more information.
+     *
+     *  @param commitOnly Set to true if the handler should be
+     *  called only on committing change events.
+     *  See the bindProperty() method for more information.
+     *
+     *  @return A ChangeWatcher instance, if at least one property name
+     *  has been  specified to the chain argument; null otherwise.
+     */
+    public static function bindSetter(setter:Function, host:Object,
+                                      chain:Object,
+                                      commitOnly:Boolean = false):ChangeWatcher
+    {
+        var w:ChangeWatcher =
+            ChangeWatcher.watch(host, chain, null, commitOnly);
+
+        if (w != null)
+        {
+            var invoke:Function = function(event:*):void
+            {
+                setter(w.getValue());
+            };
+            w.setHandler(invoke);
+            invoke(null);
+        }
+
+        return w;
+    }
+}
+
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 8
Author:   open-source-svn-admin@adobe.com
Date:     2007-12-15T01:49:31.087529Z

Log Message:
-----------
The beginning of the open-source Flex SDK.

Populated the flex/sdk/trunk directory with an open-source subset of files from //depot/flex/sdk/...@191097 in the Faramir Perforce server. This changelist is a bit past the 3.0rc0 build.

The Ant scripts will not successfully build yet. They need to be adapted to the open-source subset.

Modified Paths:
--------------
2532 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1263135 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/framework/src/mx/validators/StringValidator.as
+++ frameworks/projects/framework/src/mx/validators/StringValidator.as
@@ -0,0 +1,339 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2003-2007 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.validators
+{
+
+import mx.managers.ISystemManager;
+import mx.managers.SystemManager;
+import mx.utils.StringUtil;
+
+[ResourceBundle("validators")]
+
+/**
+ *  The StringValidator class validates that the length of a String
+ *  is within a specified range.
+ *
+ *  @mxml
+ *
+ *
The <mx:StringValidator> tag
+ *  inherits all of the tag attributes of its superclass,
+ *  and add the following tag attributes:

+ *
+ *

+ *  <mx:StringValidator
+ *    maxLength="NaN"
+ *    minLength="NaN"
+ *    tooLongError="This string is longer than the maximum allowed length. This must be less than {0} characters long."
+ *    tooShortError="This string is shorter than the minimum allowed length. This must be at least {0} characters long."
+ *  />
+ *

+ *
+ *  @includeExample examples/StringValidatorExample.mxml
+ */
+public class StringValidator extends Validator
+{
+	include "../core/Version.as";
+
+	//--------------------------------------------------------------------------
+	//
+	//  Class methods
+	//
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  Convenience method for calling a validator.
+	 *  Each of the standard Flex validators has a similar convenience method.
+	 *
+	 *  @param validator The StringValidator instance.
+	 *
+	 *  @param value A field to validate.
+	 *
+	 *  @param baseField Text representation of the subfield
+	 *  specified in the value parameter.
+	 *  For example, if the value parameter specifies
+	 *  value.mystring, the baseField value
+	 *  is "mystring".
+     *
+	 *  @return An Array of ValidationResult objects, with one
+	 *  ValidationResult  object for each field examined by the validator.
+	 *
+	 *  @see mx.validators.ValidationResult
+	 */
+	public static function validateString(validator:StringValidator,
+										  value:Object,
+										  baseField:String = null):Array
+	{
+		var results:Array = [];
+
+		// Resource-backed properties of the validator.
+		var maxLength:Number = Number(validator.maxLength);
+		var minLength:Number = Number(validator.minLength);
+
+		var val:String = value != null ? String(value) : "";
+
+		if (!isNaN(maxLength) && val.length > maxLength)
+		{
+			results.push(new ValidationResult(
+				true, baseField, "tooLong",
+				StringUtil.substitute(validator.tooLongError, maxLength)));
+			return results;
+		}
+
+		if (!isNaN(minLength) && val.length < minLength)
+		{
+			results.push(new ValidationResult(
+				true, baseField, "tooShort",
+				StringUtil.substitute(validator.tooShortError, minLength)));
+			return results;
+		}
+
+		return results;
+	}
+
+	//--------------------------------------------------------------------------
+	//
+	//  Constructor
+	//
+	//--------------------------------------------------------------------------
+
+	/**
+	 *  Constructor.
+	 */
+	public function StringValidator()
+	{
+		super();
+	}
+
+	//--------------------------------------------------------------------------
+	//
+	//  Properties
+	//
+	//--------------------------------------------------------------------------
+
+	//----------------------------------
+	//  maxLength
+	//----------------------------------
+
+    /**
+	 *  @private
+	 *  Storage for the maxLength property.
+	 */
+	private var _maxLength:Object;
+
+    /**
+	 *  @private
+	 */
+	private var maxLengthOverride:Object;
+
+	[Inspectable(category="General", defaultValue="null")]
+
+	/**
+	 *  Maximum length for a valid String.
+	 *  A value of NaN means this property is ignored.
+	 *
+	 *  @default NaN
+	 */
+	public function get maxLength():Object
+	{
+		return _maxLength;
+	}
+
+	/**
+	 *  @private
+	 */
+	public function set maxLength(value:Object):void
+	{
+		maxLengthOverride = value;
+
+		_maxLength = value != null ?
+					 Number(value) :
+					 resourceManager.getNumber(
+					     "validators", "maxLength");
+	}
+
+	//----------------------------------
+	//  minLength
+	//----------------------------------
+
+    /**
+	 *  @private
+	 *  Storage for the minLength property.
+	 */
+	private var _minLength:Object;
+
+    /**
+	 *  @private
+	 */
+	private var minLengthOverride:Object;
+
+	[Inspectable(category="General", defaultValue="null")]
+
+	/**
+	 *  Minimum length for a valid String.
+	 *  A value of NaN means this property is ignored.
+	 *
+	 *  @default NaN
+	 */
+	public function get minLength():Object
+	{
+		return _minLength;
+	}
+
+	/**
+	 *  @private
+	 */
+	public function set minLength(value:Object):void
+	{
+		minLengthOverride = value;
+
+		_minLength = value != null ?
+					 Number(value) :
+					 resourceManager.getNumber(
+					     "validators", "minLength");
+	}
+
+	//--------------------------------------------------------------------------
+	//
+	//  Properties: Errors
+	//
+	//--------------------------------------------------------------------------
+
+	//----------------------------------
+	//  tooLongError
+	//----------------------------------
+
+	/**
+	 *  @private
+	 *  Storage for the tooLongError property.
+	 */
+	private var _tooLongError:String;
+
+    /**
+	 *  @private
+	 */
+	private var tooLongErrorOverride:String;
+
+    [Inspectable(category="Errors", defaultValue="null")]
+
+	/**
+	 *  Error message when the String is longer
+	 *  than the maxLength property.
+	 *
+	 *  @default "This string is longer than the maximum allowed length. This must be less than {0} characters long."
+	 */
+	public function get tooLongError():String
+	{
+		return _tooLongError;
+	}
+
+	/*
+	 *  @private
+	 */
+	public function set tooLongError(value:String):void
+    {
+        tooLongErrorOverride = value;
+
+		_tooLongError = value != null ?
+						value :
+						resourceManager.getString(
+							"validators", "tooLongError");
+    }
+
+	//----------------------------------
+	//  tooShortError
+	//----------------------------------
+
+	/**
+	 *  @private
+	 *  Storage for the tooShortError property.
+	 */
+	private var _tooShortError:String;
+
+    /**
+	 *  @private
+	 */
+	private var tooShortErrorOverride:String;
+
+	[Inspectable(category="Errors", defaultValue="null")]
+
+	/**
+	 *  Error message when the string is shorter
+	 *  than the minLength property.
+	 *
+	 *  @default "This string is shorter than the minimum allowed length. This must be at least {0} characters long."
+	 */
+	public function get tooShortError():String
+	{
+		return _tooShortError;
+	}
+
+	/*
+	 *  @private
+	 */
+	public function set tooShortError(value:String):void
+    {
+        tooShortErrorOverride = value;
+
+		_tooShortError = value != null ?
+						 value :
+						 resourceManager.getString(
+						     "validators", "tooShortError");
+    }
+
+	//--------------------------------------------------------------------------
+	//
+	//  Overridden methods
+	//
+	//--------------------------------------------------------------------------
+
+    /**
+	 *  @private
+     */
+	override protected function resourcesChanged():void
+	{
+		super.resourcesChanged();
+
+		maxLength = maxLengthOverride;
+		minLength = minLengthOverride;
+
+		tooLongError = tooLongErrorOverride;
+		tooShortError = tooShortErrorOverride;
+	}
+
+	/**
+     *  Override of the base class doValidation() method
+     *  to validate a String.
+     *
+	 *
You do not call this method directly;
+	 *  Flex calls it as part of performing a validation.
+	 *  If you create a custom Validator class, you must implement this method.

+	 *
+     *  @param value Object to validate.
+     *
+	 *  @return An Array of ValidationResult objects, with one ValidationResult
+	 *  object for each field examined by the validator.
+	 */
+	override protected function doValidation(value:Object):Array
+    {
+		var results:Array = super.doValidation(value);
+
+		// Return if there are errors
+		// or if the required property is set to false and length is 0.
+		var val:String = value ? String(value) : "";
+		if (results.length > 0 || ((val.length == 0) && !required))
+			return results;
+		else
+		    return StringValidator.validateString(this, value, null);
+    }
+}
+
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 19298
Author:   mcho@adobe.com
Date:     2010-12-11T00:28:02.917663Z

Log Message:
-----------
SDK-28858 Mobile List skin doesn't allow List size to grow with content size

QE notes:
Doc notes:
Bugs: 28858
Reviewer: ryan
Tests run: checkintests
Is noteworthy for integration:

Modified Paths:
--------------
/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ListSkin.as

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1265378 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mobiletheme/src/spark/skins/mobile/ListSkin.as
+++ frameworks/projects/mobiletheme/src/spark/skins/mobile/ListSkin.as
@@ -133,7 +133,7 @@
 	override protected function measure():void
 	{
 		measuredWidth = scroller.getPreferredBoundsWidth();
-		measuredHeight = scroller.getPreferredBoundsWidth();
+		measuredHeight = scroller.getPreferredBoundsHeight();
 	}


Transferred from the Adobe Open Source Subversion Repository

Revision: 8
Author:   open-source-svn-admin@adobe.com
Date:     2007-12-15T01:49:31.087529Z

Log Message:
-----------
The beginning of the open-source Flex SDK.

Populated the flex/sdk/trunk directory with an open-source subset of files from //depot/flex/sdk/...@191097 in the Faramir Perforce server. This changelist is a bit past the 3.0rc0 build.

The Ant scripts will not successfully build yet. They need to be adapted to the open-source subset.

Modified Paths:
--------------
2532 paths were modified

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1268991 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mx/src/mx/controls/menuClasses/MenuListData.as
+++ frameworks/projects/mx/src/mx/controls/menuClasses/MenuListData.as
@@ -0,0 +1,110 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2007 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package mx.controls.menuClasses
+{
+
+import mx.controls.listClasses.ListData;
+import mx.controls.listClasses.ListBase;
+import mx.core.IUIComponent;
+
+/**
+ *  The MenuListData class defines the data type of the listData property
+ *  implemented by drop-in item renderers or drop-in item editors for the Menu and
+ *  MenuBar control.  All drop-in item renderers and drop-in item editors must implement the
+ *  IDropInListItemRenderer interface, which defines the listData property.
+ *
+ *  @see mx.controls.listClasses.IDropInListItemRenderer
+ */
+public class MenuListData extends ListData
+{
+    include "../../core/Version.as";
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+	/**
+	 *  Constructor.
+	 *
+	 *  @param text Text representation of the item data.
+	 *
+	 * 	@param icon A Class or String object representing the icon
+	 *  for the item in the List control.
+	 *
+	 *  @param labelField The name of the field of the data provider
+	 *  containing the label data of the List component.
+	 *
+	 *  @param uid A unique identifier for the item.
+	 *
+	 *  @param owner A reference to the Menu control.
+	 *
+	 *  @param rowIndex The index of the item in the data provider for the Menu control.
+	 *
+	 *  @param columnIndex The index of the column in the currently visible columns of the
+     *  control.
+	 *
+	 */
+	public function MenuListData(text:String, icon:Class, labelField:String,
+								 uid:String, owner:IUIComponent, rowIndex:int = 0,
+								 columnIndex:int = 0)
+	{
+		super(text, icon, labelField, uid, owner, rowIndex, columnIndex);
+	}
+
+    //--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    //--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  maxMeasuredIconWidth
+    //----------------------------------
+
+	/**
+	 *  The max icon width for all MenuItemListRenderers
+	 */
+	public var maxMeasuredIconWidth:Number;
+
+    //----------------------------------
+    //  maxMeasuredTypeIconWidth
+    //----------------------------------
+
+	/**
+	 *  The max type icon width for all MenuItemListRenderers
+	 */
+	public var maxMeasuredTypeIconWidth:Number;
+
+    //----------------------------------
+    //  maxMeasuredBranchIconWidth
+    //----------------------------------
+
+	/**
+	 *  The max branch icon width for all MenuItemListRenderers
+	 */
+	public var maxMeasuredBranchIconWidth:Number;
+
+	//----------------------------------
+    //  useTwoColumns
+    //----------------------------------
+
+	/**
+	 *  Whether the left icons should layout in two separate columns
+	 *  (one for icons and one for type icons, like check and radio)
+	 */
+	public var useTwoColumns:Boolean;
+
+}
+
+}


Transferred from the Adobe Open Source Subversion Repository

Revision: 4853
Author:   cframpto@adobe.com
Date:     2009-02-05T15:57:18.688275Z

Log Message:
-----------
After reading text plan, fix ASdoc for numRadioButons default and check index on getRadioButtonAt to make sure it is a valid index before using it.

QE Notes:
Doc Notes:
Bugs:
Reviewers: Darrell

Modified Paths:
--------------
/flex/sdk/trunk/frameworks/projects/flex4/src/mx/components/FxRadioButtonGroup.as

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1279954 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/RadioButtonGroup.as
+++ frameworks/projects/spark/src/spark/components/RadioButtonGroup.as
@@ -190,7 +190,7 @@
     /**
      *  The number of FxRadioButtons that belong to this FxRadioButtonGroup.
      *
-     *  @default "undefined"
+     *  @default "0"
      */
     public function get numRadioButtons():int
     {
@@ -327,11 +327,17 @@
      *  @param index The index of the  control in the
      *  FxRadioButtonGroup control, where the index of the first control is 0.
      *
-     *  @return The specified FxRadioButton control.
+     *  @return The specified FxRadioButton control if index between
+     *  0 and numRadioButtons, otherwise null.
+     *
+     *  @see numRadioButtons
      */
     public function getRadioButtonAt(index:int):FxRadioButton
     {
-        return radioButtons[index];
+        if (index >= 0 && index < numRadioButtons)
+            return radioButtons[index];
+
+        return null;
     }

     /**


Transferred from the Adobe Open Source Subversion Repository

Revision: 7783
Author:   clucier@adobe.com
Date:     2009-06-12T14:23:03.577066Z

Log Message:
-----------
Fix for the asdoc built target.  Unsure why this builds fine outside the context of the asdoc target.

Modified Paths:
--------------
/flex/sdk/trunk/frameworks/projects/flex4/src/spark/components/RadioButtonGroup.as

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1279965 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/RadioButtonGroup.as
+++ frameworks/projects/spark/src/spark/components/RadioButtonGroup.as
@@ -152,7 +152,7 @@
      *  @private
      *  Since there is no id, generate one, if needed.
      */
-    private var name:String;
+    private var _name:String;

     /**
      *  @private
@@ -404,10 +404,10 @@
      */
     mx_internal function get name():String
     {
-        if (name == null)
-            name = NameUtil.createUniqueName(this);
-
-        return name;
+        if (_name == null)
+            _name = NameUtil.createUniqueName(this);
+
+        return _name;
     }

     /**


Transferred from the Adobe Open Source Subversion Repository

Revision: 16077
Author:   cframpto@adobe.com
Date:     2010-05-12T21:32:08.367550Z

Log Message:
-----------
Merge 16076 from 4.x to trunk.  Fix for looping issues in itemRenderers which contain RET.

Modified Paths:
--------------
<path kind="dir" action="M">/flex/sdk/trunk</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/RichEditableText.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1280223 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/RichEditableText.as
+++ frameworks/projects/spark/src/spark/components/RichEditableText.as
@@ -671,7 +671,7 @@
         /**
          *  @private
          */
-        mx_internal var ignoreDamageEvent:Boolean = false;
+        private var inMeasureMethod:Boolean = false;

         /**
          *  @private
@@ -2428,9 +2428,10 @@
          */
         override protected function measure():void
         {
-            // Don't want to trigger a another remeasure when we modify the
-            // textContainerManager or compose the text.
-            ignoreDamageEvent = true;
+            // If the damage handler is called while measuring text, this means
+            // the text lines are damaged and the display needs to be updated.
+            // This flag tells the handler to invalidate just the display list.
+            inMeasureMethod = true;

             super.measure();

@@ -2544,11 +2545,9 @@
                     _textContainerManager.horizontalScrollPosition = 0;
                     _textContainerManager.verticalScrollPosition = 0;
                 }
-
-                invalidateDisplayList();
-            }
-
-            ignoreDamageEvent = false;
+            }
+
+            inMeasureMethod = false;

             //trace("measure", measuredWidth, measuredHeight, "autoSize", autoSize);
         }
@@ -4030,8 +4029,15 @@
          */
         private function textContainerManager_damageHandler(event:DamageEvent):void
         {
-            if (ignoreDamageEvent || event.damageLength == 0)
+            if (event.damageLength == 0)
                 return;
+
+            // Text that is being measured is damaged so update the display.
+            if (inMeasureMethod)
+            {
+                invalidateDisplayList();
+                return;
+            }

             //trace("damageHandler", "generation", _textFlow ? _textFlow.generation : -1, "lastGeneration", lastGeneration);


Рефакторинг

Рефакторинг

--- src/main/org/shypl/common/sound/SoundSystem.as
+++ src/main/org/shypl/common/sound/SoundSystem.as
@@ -1,66 +1,78 @@
 package org.shypl.common.sound {
 	import flash.media.Sound;
-
+
 	import org.shypl.common.collection.HashSet;
 	import org.shypl.common.collection.Set;
-
+
 	public final class SoundSystem extends AbstractSoundStream implements SoundStream {
 		private var _streams:Set = new HashSet();
-
+		private var _volumeBeforeMute:Number;
+
 		public function SoundSystem(volume:Number = 1, system:SoundSystem = null) {
 			super(system, volume);
+			_volumeBeforeMute = volume;
 			if (hasParent() && system.paused) {
 				pause();
 			}
 		}
-
-		private function hasParent():Boolean {
-			return system !== null;
+
+		public function toggleMute():void {
+			if (volume == 0) {
+				volume = _volumeBeforeMute;
+			}
+			else {
+				_volumeBeforeMute = volume;
+				volume = 0;
+			}
 		}
-
+
 		override public function get realVolume():Number {
 			return hasParent() ? super.realVolume : volume;
 		}
-
+
 		override public function stop(duration:int = 0):void {
 			stopVolumeChanger();
 			for each (var stream:SoundStream in _streams) {
 				stream.stop(duration);
 			}
 		}
-
+
 		public function play(sound:Sound, loop:Boolean = false):SoundStream {
 			return new SoundFlow(this, 1, sound, loop, 0, 0, 0, null);
 		}
-
+
 		public function prepare(sound:Sound):SoundPlayPreparer {
 			return new SoundPlayPreparer(this, sound);
 		}
-
+
 		override protected function doPause():void {
 			for each (var stream:SoundStream in _streams) {
 				stream.pause();
 			}
 		}
-
+
 		override protected function doResume():void {
 			for each (var stream:SoundStream in _streams) {
 				stream.resume();
 			}
 		}
-
+
 		override protected function applyVolume():void {
 			for each (var stream:AbstractSoundStream in _streams) {
 				stream.setVolume(volume);
 			}
 		}
-
+
 		internal function addStream(stream:AbstractSoundStream):void {
 			_streams.add(stream);
 		}
-
+
 		internal function removeStream(stream:AbstractSoundStream):void {
 			_streams.remove(stream);
 		}
+
+		private function hasParent():Boolean {
+			return system !== null;
+		}
 	}
 }