Return-Path: X-Original-To: apmail-flex-commits-archive@www.apache.org Delivered-To: apmail-flex-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 16958176FE for ; Sun, 1 Mar 2015 07:03:35 +0000 (UTC) Received: (qmail 6351 invoked by uid 500); 1 Mar 2015 07:03:30 -0000 Delivered-To: apmail-flex-commits-archive@flex.apache.org Received: (qmail 6324 invoked by uid 500); 1 Mar 2015 07:03:29 -0000 Mailing-List: contact commits-help@flex.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@flex.apache.org Delivered-To: mailing list commits@flex.apache.org Received: (qmail 6316 invoked by uid 99); 1 Mar 2015 07:03:29 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 01 Mar 2015 07:03:29 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 6E0E5E0B41; Sun, 1 Mar 2015 07:03:29 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: aharui@apache.org To: commits@flex.apache.org Message-Id: <6a0d8f388d9647d696a804f162e62f7d@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: git commit: [flex-sdk] [refs/heads/develop] - Falcon caught a duplicate variable Date: Sun, 1 Mar 2015 07:03:29 +0000 (UTC) Repository: flex-sdk Updated Branches: refs/heads/develop ca3287102 -> 3c40976eb Falcon caught a duplicate variable Project: http://git-wip-us.apache.org/repos/asf/flex-sdk/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-sdk/commit/3c40976e Tree: http://git-wip-us.apache.org/repos/asf/flex-sdk/tree/3c40976e Diff: http://git-wip-us.apache.org/repos/asf/flex-sdk/diff/3c40976e Branch: refs/heads/develop Commit: 3c40976eb0b3a73d2bb7180cc22400917f719fc4 Parents: ca32871 Author: Alex Harui Authored: Sat Feb 28 23:03:24 2015 -0800 Committer: Alex Harui Committed: Sat Feb 28 23:03:24 2015 -0800 ---------------------------------------------------------------------- .../org/apache/flex/collections/ArrayList.as | 1678 +++++++++--------- 1 file changed, 839 insertions(+), 839 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-sdk/blob/3c40976e/frameworks/projects/apache/src/org/apache/flex/collections/ArrayList.as ---------------------------------------------------------------------- diff --git a/frameworks/projects/apache/src/org/apache/flex/collections/ArrayList.as b/frameworks/projects/apache/src/org/apache/flex/collections/ArrayList.as index a1ea7b4..853f812 100644 --- a/frameworks/projects/apache/src/org/apache/flex/collections/ArrayList.as +++ b/frameworks/projects/apache/src/org/apache/flex/collections/ArrayList.as @@ -1,839 +1,839 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// 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 org.apache.flex.collections -{ - -import flash.events.EventDispatcher; -import flash.events.IEventDispatcher; -import flash.utils.IDataInput; -import flash.utils.IDataOutput; -import flash.utils.IExternalizable; -import flash.utils.getQualifiedClassName; - -import mx.collections.ICollectionView; -import mx.collections.IList; -import mx.core.IPropertyChangeNotifier; -import mx.events.CollectionEvent; -import mx.events.CollectionEventKind; -import mx.events.PropertyChangeEvent; -import mx.events.PropertyChangeEventKind; -import mx.resources.IResourceManager; -import mx.resources.ResourceManager; -import mx.utils.ArrayUtil; -import mx.utils.UIDUtil; - -//-------------------------------------- -// Events -//-------------------------------------- - -/** - * Dispatched when the IList has been updated in some way. - * - * @eventType mx.events.CollectionEvent.COLLECTION_CHANGE - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ -[Event(name="collectionChange", type="mx.events.CollectionEvent")] - -//-------------------------------------- -// Other metadata -//-------------------------------------- - -[RemoteClass(alias="flex.messaging.io.ArrayList")] - -[ResourceBundle("collections")] - -[DefaultProperty("source")] - -/** - * The ArrayList class is a simple implementation of IList - * that uses a backing Array as the source of the data. - * - * Items in the backing Array can be accessed and manipulated - * using the methods and properties of the IList - * interface. Operations on an ArrayList instance modify the - * data source; for example, if you use the removeItemAt() - * method on an ArrayList, you remove the item from the underlying - * Array. - * - * This base class will not throw ItemPendingErrors but it - * is possible that a subclass might. - * - *
- *  <mx:ArrayList
- *  Properties
- *  source="null"
- *  />
- *  
- * - * @langversion 3.0 - * @playerversion Flash 10 - * @playerversion AIR 1.5 - * @productversion Flex 4 - */ -public class ArrayList extends EventDispatcher - implements IList, IExternalizable, IPropertyChangeNotifier -{ - //include "../core/Version.as"; - - //-------------------------------------------------------------------------- - // - // Constructor - // - //-------------------------------------------------------------------------- - - /** - * Construct a new ArrayList using the specified array as its source. - * If no source is specified an empty array will be used. - * - * @param source The Array to use as a source for the ArrayList. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function ArrayList(source:Array = null) - { - super(); - - disableEvents(); - this.source = source; - enableEvents(); - } - - //-------------------------------------------------------------------------- - // - // Variables - // - //-------------------------------------------------------------------------- - - /** - * @private - * Used for accessing localized Error messages. - */ - private var resourceManager:IResourceManager = - ResourceManager.getInstance(); - - /** - * @private - * Indicates if events should be dispatched. - * calls to enableEvents() and disableEvents() effect the value when == 0 - * events should be dispatched. - */ - private var _dispatchEvents:int = 0; - - //-------------------------------------------------------------------------- - // - // Properties - // - //-------------------------------------------------------------------------- - - //---------------------------------- - // length - //---------------------------------- - - [Bindable("collectionChange")] - - /** - * Get the number of items in the list. An ArrayList should always - * know its length so it shouldn't return -1, though a subclass may - * override that behavior. - * - * @return int representing the length of the source. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function get length():int - { - if (source) - return source.length; - else - return 0; - } - - //---------------------------------- - // source - //---------------------------------- - - /** - * @private - * Storage for the source Array. - */ - private var _source:Array; - - /** - * The source array for this ArrayList. - * Any changes done through the IList interface will be reflected in the - * source array. - * If no source array was supplied the ArrayList will create one internally. - * Changes made directly to the underlying Array (e.g., calling - * theList.source.pop() will not cause CollectionEvents - * to be dispatched. - * - * @return An Array that represents the underlying source. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function get source():Array - { - return _source; - } - - public function set source(s:Array):void - { - var i:int; - var len:int; - if (_source && _source.length) - { - len = _source.length; - for (i = 0; i < len; i++) - { - stopTrackUpdates(_source[i]); - } - } - _source = s ? s : []; - len = _source.length; - for (i = 0; i < len; i++) - { - startTrackUpdates(_source[i]); - } - - if (_dispatchEvents == 0) - { - var event:CollectionEvent = - new CollectionEvent(CollectionEvent.COLLECTION_CHANGE); - event.kind = CollectionEventKind.RESET; - dispatchEvent(event); - } - } - - //---------------------------------- - // uid -- mx.core.IPropertyChangeNotifier - //---------------------------------- - - /** - * @private - * Storage for the UID String. - */ - private var _uid:String; - - /** - * Provides access to the unique id for this list. - * - * @return String representing the internal uid. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function get uid():String - { - if (!_uid) { - _uid = UIDUtil.createUID(); - } - return _uid; - } - - public function set uid(value:String):void - { - _uid = value; - } - - //-------------------------------------------------------------------------- - // - // Methods - // - //-------------------------------------------------------------------------- - - /** - * Get the item at the specified index. - * - * @param index the index in the list from which to retrieve the item - * @param prefetch int indicating both the direction and amount of items - * to fetch during the request should the item not be local. - * @return the item at that index, null if there is none - * @throws ItemPendingError if the data for that index needs to be - * loaded from a remote location - * @throws RangeError if the index < 0 or index >= length - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function getItemAt(index:int, prefetch:int = 0):Object - { - if (index < 0 || index >= length) - { - var message:String = resourceManager.getString( - "collections", "outOfBounds", [ index ]); - throw new RangeError(message); - } - - return source[index]; - } - - /** - * Place the item at the specified index. - * If an item was already at that index the new item will replace it and it - * will be returned. - * - * @param item the new value for the index - * @param index the index at which to place the item - * @return the item that was replaced, null if none - * @throws RangeError if index is less than 0 or greater than or equal to length - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function setItemAt(item:Object, index:int):Object - { - if (index < 0 || index >= length) - { - var message:String = resourceManager.getString( - "collections", "outOfBounds", [ index ]); - throw new RangeError(message); - } - - var oldItem:Object = source[index]; - source[index] = item; - stopTrackUpdates(oldItem); - startTrackUpdates(item); - - //dispatch the appropriate events - if (_dispatchEvents == 0) - { - var hasCollectionListener:Boolean = - hasEventListener(CollectionEvent.COLLECTION_CHANGE); - var hasPropertyListener:Boolean = - hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE); - var updateInfo:PropertyChangeEvent; - - if (hasCollectionListener || hasPropertyListener) - { - updateInfo = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE); - updateInfo.kind = PropertyChangeEventKind.UPDATE; - updateInfo.oldValue = oldItem; - updateInfo.newValue = item; - updateInfo.property = index; - } - - if (hasCollectionListener) - { - var event:CollectionEvent = - new CollectionEvent(CollectionEvent.COLLECTION_CHANGE); - event.kind = CollectionEventKind.REPLACE; - event.location = index; - event.items.push(updateInfo); - dispatchEvent(event); - } - - if (hasPropertyListener) - { - dispatchEvent(updateInfo); - } - } - return oldItem; - } - - /** - * Add the specified item to the end of the list. - * Equivalent to addItemAt(item, length); - * - * @param item the item to add - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function addItem(item:Object):void - { - addItemAt(item, length); - } - - /** - * Add the item at the specified index. - * Any item that was after this index is moved out by one. - * - * @param item the item to place at the index - * @param index the index at which to place the item - * @throws RangeError if index is less than 0 or greater than the length - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function addItemAt(item:Object, index:int):void - { - const spliceUpperBound:int = length; - - if (index < spliceUpperBound && index > 0) - { - source.splice(index, 0, item); - } - else if (index == spliceUpperBound) - { - source.push(item); - } - else if (index == 0) - { - source.unshift(item); - } - else - { - var message:String = resourceManager.getString( - "collections", "outOfBounds", [ index ]); - throw new RangeError(message); - } - - startTrackUpdates(item); - internalDispatchEvent(CollectionEventKind.ADD, item, index); - } - - /** - * @copy mx.collections.ListCollectionView#addAll() - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function addAll(addList:IList):void - { - addAllAt(addList, length); - } - - /** - * @copy mx.collections.ListCollectionView#addAllAt() - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function addAllAt(addList:IList, index:int):void - { - var length:int = addList.length; - for (var i:int = 0; i < length; i++) - { - this.addItemAt(addList.getItemAt(i), i+index); - } - } - - /** - * Return the index of the item if it is in the list such that - * getItemAt(index) == item. - * Note that in this implementation the search is linear and is therefore - * O(n). - * - * @param item the item to find - * @return the index of the item, -1 if the item is not in the list. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function getItemIndex(item:Object):int - { - return ArrayUtil.getItemIndex(item, source); - } - - /** - * Removes the specified item from this list, should it exist. - * - * @param item Object reference to the item that should be removed. - * @return Boolean indicating if the item was removed. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function removeItem(item:Object):Boolean - { - var index:int = getItemIndex(item); - var result:Boolean = index >= 0; - if (result) - removeItemAt(index); - - return result; - } - - /** - * Remove the item at the specified index and return it. - * Any items that were after this index are now one index earlier. - * - * @param index The index from which to remove the item. - * @return The item that was removed. - * @throws RangeError if index < 0 or index >= length. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function removeItemAt(index:int):Object - { - const spliceUpperBound:int = length - 1; - var removed:Object; - - if (index > 0 && index < spliceUpperBound) - { - removed = source.splice(index, 1)[0]; - } - else if (index == spliceUpperBound) - { - removed = source.pop(); - } - else if (index == 0) - { - removed = source.shift(); - } - else - { - var message:String = resourceManager.getString( - "collections", "outOfBounds", [ index ]); - throw new RangeError(message); - } - - var removed:Object = source.splice(index, 1)[0]; - stopTrackUpdates(removed); - internalDispatchEvent(CollectionEventKind.REMOVE, removed, index); - return removed; - } - - /** - * Remove all items from the list. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function removeAll():void - { - if (length > 0) - { - var len:int = length; - for (var i:int = 0; i < len; i++) - { - stopTrackUpdates(source[i]); - } - - source.splice(0, length); - internalDispatchEvent(CollectionEventKind.RESET); - } - } - - /** - * Notify the view that an item has been updated. - * This is useful if the contents of the view do not implement - * IEventDispatcher. - * If a property is specified the view may be able to optimize its - * notification mechanism. - * Otherwise it may choose to simply refresh the whole view. - * - * @param item The item within the view that was updated. - * - * @param property A String, QName, or int - * specifying the property that was updated. - * - * @param oldValue The old value of that property. - * (If property was null, this can be the old value of the item.) - * - * @param newValue The new value of that property. - * (If property was null, there's no need to specify this - * as the item is assumed to be the new value.) - * - * @see mx.events.CollectionEvent - * @see mx.core.IPropertyChangeNotifier - * @see mx.events.PropertyChangeEvent - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function itemUpdated(item:Object, property:Object = null, - oldValue:Object = null, - newValue:Object = null):void - { - var event:PropertyChangeEvent = - new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE); - - event.kind = PropertyChangeEventKind.UPDATE; - event.source = item; - event.property = property; - event.oldValue = oldValue; - event.newValue = newValue; - - //This handler was intended to handle events from child objects, not to be called directly - //itemUpdateHandler(event); - - internalDispatchEvent(CollectionEventKind.UPDATE, event); - - // need to dispatch object event now - if (_dispatchEvents == 0 && hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE)) - { - dispatchPropertyChangeEventClone( event, item ); - } - } - - /** - * Return an Array that is populated in the same order as the IList - * implementation. - * - * @return An Array populated in the same order as the IList - * implementation. - * - * @throws ItemPendingError if the data is not yet completely loaded - * from a remote location - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - public function toArray():Array - { - return source.concat(); - } - - /** - * Ensures that only the source property is seralized. - * @private - */ - public function readExternal(input:IDataInput):void - { - source = input.readObject(); - } - - /** - * Ensures that only the source property is serialized. - * @private - */ - public function writeExternal(output:IDataOutput):void - { - output.writeObject(_source); - } - - /** - * Pretty prints the contents of this ArrayList to a string and returns it. - * - * @return A String containing the contents of the ArrayList. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - override public function toString():String - { - if (source) - return source.toString(); - else - return getQualifiedClassName(this); - } - - //-------------------------------------------------------------------------- - // - // Internal Methods - // - //-------------------------------------------------------------------------- - - /** - * Dispatches a PropertyChangeEvent clone either from a child object whose event needs to be redispatched - * or when a PropertyChangeEvent is faked inside of this class for the purposes of informing the view - * of an update to underlying data. - * - * @param event The PropertyChangeEvent to be cloned and dispatched - * @param item The item within the view that was updated. - * - * @see mx.core.IPropertyChangeNotifier - * @see mx.events.PropertyChangeEvent - */ - - private function dispatchPropertyChangeEventClone( event:PropertyChangeEvent, item:Object ):void { - var objEvent:PropertyChangeEvent = PropertyChangeEvent(event.clone()); - - var index:int = getItemIndex( item ); - objEvent.property = index.toString() + "." + event.property; - dispatchEvent(objEvent); - } - - /** - * Enables event dispatch for this list. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - private function enableEvents():void - { - _dispatchEvents++; - if (_dispatchEvents > 0) - _dispatchEvents = 0; - } - - /** - * Disables event dispatch for this list. - * To re-enable events call enableEvents(), enableEvents() must be called - * a matching number of times as disableEvents(). - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - private function disableEvents():void - { - _dispatchEvents--; - } - - /** - * Dispatches a collection event with the specified information. - * - * @param kind String indicates what the kind property of the event should be - * @param item Object reference to the item that was added or removed - * @param location int indicating where in the source the item was added. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - private function internalDispatchEvent(kind:String, item:Object = null, location:int = -1):void - { - if (_dispatchEvents == 0) - { - if (hasEventListener(CollectionEvent.COLLECTION_CHANGE)) - { - var event:CollectionEvent = - new CollectionEvent(CollectionEvent.COLLECTION_CHANGE); - event.kind = kind; - event.items.push(item); - event.location = location; - dispatchEvent(event); - } - - // now dispatch a complementary PropertyChangeEvent - if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE) && - (kind == CollectionEventKind.ADD || kind == CollectionEventKind.REMOVE)) - { - var objEvent:PropertyChangeEvent = - new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE); - objEvent.property = location; - if (kind == CollectionEventKind.ADD) - objEvent.newValue = item; - else - objEvent.oldValue = item; - dispatchEvent(objEvent); - } - } - } - - /** - * Called when any of the contained items in the list dispatch an - * ObjectChange event. - * Wraps it in a CollectionEventKind.UPDATE object. - * - * @param event The event object for the ObjectChange event. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - protected function itemUpdateHandler(event:PropertyChangeEvent):void - { - internalDispatchEvent(CollectionEventKind.UPDATE, event); - - // need to dispatch object event now - if (_dispatchEvents == 0 && hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE)) - { - dispatchPropertyChangeEventClone( event, event.target ); - } - } - - /** - * If the item is an IEventDispatcher, watch it for updates. - * This method is called by the addItemAt() method, - * and when the source is initially assigned. - * - * @param item The item passed to the addItemAt() method. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - protected function startTrackUpdates(item:Object):void - { - if (item && (item is IEventDispatcher)) - { - IEventDispatcher(item).addEventListener( - PropertyChangeEvent.PROPERTY_CHANGE, - itemUpdateHandler, false, 0, true); - } - } - - /** - * If the item is an IEventDispatcher, stop watching it for updates. - * This method is called by the removeItemAt() and - * removeAll() methods, and before a new - * source is assigned. - * - * @param item The item passed to the removeItemAt() method. - * - * @langversion 3.0 - * @playerversion Flash 9 - * @playerversion AIR 1.1 - * @productversion Flex 3 - */ - protected function stopTrackUpdates(item:Object):void - { - if (item && item is IEventDispatcher) - { - IEventDispatcher(item).removeEventListener( - PropertyChangeEvent.PROPERTY_CHANGE, - itemUpdateHandler); - } - } - -} - -} +//////////////////////////////////////////////////////////////////////////////// +// +// 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 org.apache.flex.collections +{ + +import flash.events.EventDispatcher; +import flash.events.IEventDispatcher; +import flash.utils.IDataInput; +import flash.utils.IDataOutput; +import flash.utils.IExternalizable; +import flash.utils.getQualifiedClassName; + +import mx.collections.ICollectionView; +import mx.collections.IList; +import mx.core.IPropertyChangeNotifier; +import mx.events.CollectionEvent; +import mx.events.CollectionEventKind; +import mx.events.PropertyChangeEvent; +import mx.events.PropertyChangeEventKind; +import mx.resources.IResourceManager; +import mx.resources.ResourceManager; +import mx.utils.ArrayUtil; +import mx.utils.UIDUtil; + +//-------------------------------------- +// Events +//-------------------------------------- + +/** + * Dispatched when the IList has been updated in some way. + * + * @eventType mx.events.CollectionEvent.COLLECTION_CHANGE + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ +[Event(name="collectionChange", type="mx.events.CollectionEvent")] + +//-------------------------------------- +// Other metadata +//-------------------------------------- + +[RemoteClass(alias="flex.messaging.io.ArrayList")] + +[ResourceBundle("collections")] + +[DefaultProperty("source")] + +/** + * The ArrayList class is a simple implementation of IList + * that uses a backing Array as the source of the data. + * + * Items in the backing Array can be accessed and manipulated + * using the methods and properties of the IList + * interface. Operations on an ArrayList instance modify the + * data source; for example, if you use the removeItemAt() + * method on an ArrayList, you remove the item from the underlying + * Array. + * + * This base class will not throw ItemPendingErrors but it + * is possible that a subclass might. + * + *
+ *  <mx:ArrayList
+ *  Properties
+ *  source="null"
+ *  />
+ *  
+ * + * @langversion 3.0 + * @playerversion Flash 10 + * @playerversion AIR 1.5 + * @productversion Flex 4 + */ +public class ArrayList extends EventDispatcher + implements IList, IExternalizable, IPropertyChangeNotifier +{ + //include "../core/Version.as"; + + //-------------------------------------------------------------------------- + // + // Constructor + // + //-------------------------------------------------------------------------- + + /** + * Construct a new ArrayList using the specified array as its source. + * If no source is specified an empty array will be used. + * + * @param source The Array to use as a source for the ArrayList. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function ArrayList(source:Array = null) + { + super(); + + disableEvents(); + this.source = source; + enableEvents(); + } + + //-------------------------------------------------------------------------- + // + // Variables + // + //-------------------------------------------------------------------------- + + /** + * @private + * Used for accessing localized Error messages. + */ + private var resourceManager:IResourceManager = + ResourceManager.getInstance(); + + /** + * @private + * Indicates if events should be dispatched. + * calls to enableEvents() and disableEvents() effect the value when == 0 + * events should be dispatched. + */ + private var _dispatchEvents:int = 0; + + //-------------------------------------------------------------------------- + // + // Properties + // + //-------------------------------------------------------------------------- + + //---------------------------------- + // length + //---------------------------------- + + [Bindable("collectionChange")] + + /** + * Get the number of items in the list. An ArrayList should always + * know its length so it shouldn't return -1, though a subclass may + * override that behavior. + * + * @return int representing the length of the source. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function get length():int + { + if (source) + return source.length; + else + return 0; + } + + //---------------------------------- + // source + //---------------------------------- + + /** + * @private + * Storage for the source Array. + */ + private var _source:Array; + + /** + * The source array for this ArrayList. + * Any changes done through the IList interface will be reflected in the + * source array. + * If no source array was supplied the ArrayList will create one internally. + * Changes made directly to the underlying Array (e.g., calling + * theList.source.pop() will not cause CollectionEvents + * to be dispatched. + * + * @return An Array that represents the underlying source. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function get source():Array + { + return _source; + } + + public function set source(s:Array):void + { + var i:int; + var len:int; + if (_source && _source.length) + { + len = _source.length; + for (i = 0; i < len; i++) + { + stopTrackUpdates(_source[i]); + } + } + _source = s ? s : []; + len = _source.length; + for (i = 0; i < len; i++) + { + startTrackUpdates(_source[i]); + } + + if (_dispatchEvents == 0) + { + var event:CollectionEvent = + new CollectionEvent(CollectionEvent.COLLECTION_CHANGE); + event.kind = CollectionEventKind.RESET; + dispatchEvent(event); + } + } + + //---------------------------------- + // uid -- mx.core.IPropertyChangeNotifier + //---------------------------------- + + /** + * @private + * Storage for the UID String. + */ + private var _uid:String; + + /** + * Provides access to the unique id for this list. + * + * @return String representing the internal uid. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function get uid():String + { + if (!_uid) { + _uid = UIDUtil.createUID(); + } + return _uid; + } + + public function set uid(value:String):void + { + _uid = value; + } + + //-------------------------------------------------------------------------- + // + // Methods + // + //-------------------------------------------------------------------------- + + /** + * Get the item at the specified index. + * + * @param index the index in the list from which to retrieve the item + * @param prefetch int indicating both the direction and amount of items + * to fetch during the request should the item not be local. + * @return the item at that index, null if there is none + * @throws ItemPendingError if the data for that index needs to be + * loaded from a remote location + * @throws RangeError if the index < 0 or index >= length + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function getItemAt(index:int, prefetch:int = 0):Object + { + if (index < 0 || index >= length) + { + var message:String = resourceManager.getString( + "collections", "outOfBounds", [ index ]); + throw new RangeError(message); + } + + return source[index]; + } + + /** + * Place the item at the specified index. + * If an item was already at that index the new item will replace it and it + * will be returned. + * + * @param item the new value for the index + * @param index the index at which to place the item + * @return the item that was replaced, null if none + * @throws RangeError if index is less than 0 or greater than or equal to length + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function setItemAt(item:Object, index:int):Object + { + if (index < 0 || index >= length) + { + var message:String = resourceManager.getString( + "collections", "outOfBounds", [ index ]); + throw new RangeError(message); + } + + var oldItem:Object = source[index]; + source[index] = item; + stopTrackUpdates(oldItem); + startTrackUpdates(item); + + //dispatch the appropriate events + if (_dispatchEvents == 0) + { + var hasCollectionListener:Boolean = + hasEventListener(CollectionEvent.COLLECTION_CHANGE); + var hasPropertyListener:Boolean = + hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE); + var updateInfo:PropertyChangeEvent; + + if (hasCollectionListener || hasPropertyListener) + { + updateInfo = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE); + updateInfo.kind = PropertyChangeEventKind.UPDATE; + updateInfo.oldValue = oldItem; + updateInfo.newValue = item; + updateInfo.property = index; + } + + if (hasCollectionListener) + { + var event:CollectionEvent = + new CollectionEvent(CollectionEvent.COLLECTION_CHANGE); + event.kind = CollectionEventKind.REPLACE; + event.location = index; + event.items.push(updateInfo); + dispatchEvent(event); + } + + if (hasPropertyListener) + { + dispatchEvent(updateInfo); + } + } + return oldItem; + } + + /** + * Add the specified item to the end of the list. + * Equivalent to addItemAt(item, length); + * + * @param item the item to add + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function addItem(item:Object):void + { + addItemAt(item, length); + } + + /** + * Add the item at the specified index. + * Any item that was after this index is moved out by one. + * + * @param item the item to place at the index + * @param index the index at which to place the item + * @throws RangeError if index is less than 0 or greater than the length + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function addItemAt(item:Object, index:int):void + { + const spliceUpperBound:int = length; + + if (index < spliceUpperBound && index > 0) + { + source.splice(index, 0, item); + } + else if (index == spliceUpperBound) + { + source.push(item); + } + else if (index == 0) + { + source.unshift(item); + } + else + { + var message:String = resourceManager.getString( + "collections", "outOfBounds", [ index ]); + throw new RangeError(message); + } + + startTrackUpdates(item); + internalDispatchEvent(CollectionEventKind.ADD, item, index); + } + + /** + * @copy mx.collections.ListCollectionView#addAll() + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function addAll(addList:IList):void + { + addAllAt(addList, length); + } + + /** + * @copy mx.collections.ListCollectionView#addAllAt() + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function addAllAt(addList:IList, index:int):void + { + var length:int = addList.length; + for (var i:int = 0; i < length; i++) + { + this.addItemAt(addList.getItemAt(i), i+index); + } + } + + /** + * Return the index of the item if it is in the list such that + * getItemAt(index) == item. + * Note that in this implementation the search is linear and is therefore + * O(n). + * + * @param item the item to find + * @return the index of the item, -1 if the item is not in the list. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function getItemIndex(item:Object):int + { + return ArrayUtil.getItemIndex(item, source); + } + + /** + * Removes the specified item from this list, should it exist. + * + * @param item Object reference to the item that should be removed. + * @return Boolean indicating if the item was removed. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function removeItem(item:Object):Boolean + { + var index:int = getItemIndex(item); + var result:Boolean = index >= 0; + if (result) + removeItemAt(index); + + return result; + } + + /** + * Remove the item at the specified index and return it. + * Any items that were after this index are now one index earlier. + * + * @param index The index from which to remove the item. + * @return The item that was removed. + * @throws RangeError if index < 0 or index >= length. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function removeItemAt(index:int):Object + { + const spliceUpperBound:int = length - 1; + var removed:Object; + + if (index > 0 && index < spliceUpperBound) + { + removed = source.splice(index, 1)[0]; + } + else if (index == spliceUpperBound) + { + removed = source.pop(); + } + else if (index == 0) + { + removed = source.shift(); + } + else + { + var message:String = resourceManager.getString( + "collections", "outOfBounds", [ index ]); + throw new RangeError(message); + } + + removed = source.splice(index, 1)[0]; + stopTrackUpdates(removed); + internalDispatchEvent(CollectionEventKind.REMOVE, removed, index); + return removed; + } + + /** + * Remove all items from the list. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function removeAll():void + { + if (length > 0) + { + var len:int = length; + for (var i:int = 0; i < len; i++) + { + stopTrackUpdates(source[i]); + } + + source.splice(0, length); + internalDispatchEvent(CollectionEventKind.RESET); + } + } + + /** + * Notify the view that an item has been updated. + * This is useful if the contents of the view do not implement + * IEventDispatcher. + * If a property is specified the view may be able to optimize its + * notification mechanism. + * Otherwise it may choose to simply refresh the whole view. + * + * @param item The item within the view that was updated. + * + * @param property A String, QName, or int + * specifying the property that was updated. + * + * @param oldValue The old value of that property. + * (If property was null, this can be the old value of the item.) + * + * @param newValue The new value of that property. + * (If property was null, there's no need to specify this + * as the item is assumed to be the new value.) + * + * @see mx.events.CollectionEvent + * @see mx.core.IPropertyChangeNotifier + * @see mx.events.PropertyChangeEvent + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function itemUpdated(item:Object, property:Object = null, + oldValue:Object = null, + newValue:Object = null):void + { + var event:PropertyChangeEvent = + new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE); + + event.kind = PropertyChangeEventKind.UPDATE; + event.source = item; + event.property = property; + event.oldValue = oldValue; + event.newValue = newValue; + + //This handler was intended to handle events from child objects, not to be called directly + //itemUpdateHandler(event); + + internalDispatchEvent(CollectionEventKind.UPDATE, event); + + // need to dispatch object event now + if (_dispatchEvents == 0 && hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE)) + { + dispatchPropertyChangeEventClone( event, item ); + } + } + + /** + * Return an Array that is populated in the same order as the IList + * implementation. + * + * @return An Array populated in the same order as the IList + * implementation. + * + * @throws ItemPendingError if the data is not yet completely loaded + * from a remote location + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + public function toArray():Array + { + return source.concat(); + } + + /** + * Ensures that only the source property is seralized. + * @private + */ + public function readExternal(input:IDataInput):void + { + source = input.readObject(); + } + + /** + * Ensures that only the source property is serialized. + * @private + */ + public function writeExternal(output:IDataOutput):void + { + output.writeObject(_source); + } + + /** + * Pretty prints the contents of this ArrayList to a string and returns it. + * + * @return A String containing the contents of the ArrayList. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + override public function toString():String + { + if (source) + return source.toString(); + else + return getQualifiedClassName(this); + } + + //-------------------------------------------------------------------------- + // + // Internal Methods + // + //-------------------------------------------------------------------------- + + /** + * Dispatches a PropertyChangeEvent clone either from a child object whose event needs to be redispatched + * or when a PropertyChangeEvent is faked inside of this class for the purposes of informing the view + * of an update to underlying data. + * + * @param event The PropertyChangeEvent to be cloned and dispatched + * @param item The item within the view that was updated. + * + * @see mx.core.IPropertyChangeNotifier + * @see mx.events.PropertyChangeEvent + */ + + private function dispatchPropertyChangeEventClone( event:PropertyChangeEvent, item:Object ):void { + var objEvent:PropertyChangeEvent = PropertyChangeEvent(event.clone()); + + var index:int = getItemIndex( item ); + objEvent.property = index.toString() + "." + event.property; + dispatchEvent(objEvent); + } + + /** + * Enables event dispatch for this list. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + private function enableEvents():void + { + _dispatchEvents++; + if (_dispatchEvents > 0) + _dispatchEvents = 0; + } + + /** + * Disables event dispatch for this list. + * To re-enable events call enableEvents(), enableEvents() must be called + * a matching number of times as disableEvents(). + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + private function disableEvents():void + { + _dispatchEvents--; + } + + /** + * Dispatches a collection event with the specified information. + * + * @param kind String indicates what the kind property of the event should be + * @param item Object reference to the item that was added or removed + * @param location int indicating where in the source the item was added. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + private function internalDispatchEvent(kind:String, item:Object = null, location:int = -1):void + { + if (_dispatchEvents == 0) + { + if (hasEventListener(CollectionEvent.COLLECTION_CHANGE)) + { + var event:CollectionEvent = + new CollectionEvent(CollectionEvent.COLLECTION_CHANGE); + event.kind = kind; + event.items.push(item); + event.location = location; + dispatchEvent(event); + } + + // now dispatch a complementary PropertyChangeEvent + if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE) && + (kind == CollectionEventKind.ADD || kind == CollectionEventKind.REMOVE)) + { + var objEvent:PropertyChangeEvent = + new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE); + objEvent.property = location; + if (kind == CollectionEventKind.ADD) + objEvent.newValue = item; + else + objEvent.oldValue = item; + dispatchEvent(objEvent); + } + } + } + + /** + * Called when any of the contained items in the list dispatch an + * ObjectChange event. + * Wraps it in a CollectionEventKind.UPDATE object. + * + * @param event The event object for the ObjectChange event. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + protected function itemUpdateHandler(event:PropertyChangeEvent):void + { + internalDispatchEvent(CollectionEventKind.UPDATE, event); + + // need to dispatch object event now + if (_dispatchEvents == 0 && hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE)) + { + dispatchPropertyChangeEventClone( event, event.target ); + } + } + + /** + * If the item is an IEventDispatcher, watch it for updates. + * This method is called by the addItemAt() method, + * and when the source is initially assigned. + * + * @param item The item passed to the addItemAt() method. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + protected function startTrackUpdates(item:Object):void + { + if (item && (item is IEventDispatcher)) + { + IEventDispatcher(item).addEventListener( + PropertyChangeEvent.PROPERTY_CHANGE, + itemUpdateHandler, false, 0, true); + } + } + + /** + * If the item is an IEventDispatcher, stop watching it for updates. + * This method is called by the removeItemAt() and + * removeAll() methods, and before a new + * source is assigned. + * + * @param item The item passed to the removeItemAt() method. + * + * @langversion 3.0 + * @playerversion Flash 9 + * @playerversion AIR 1.1 + * @productversion Flex 3 + */ + protected function stopTrackUpdates(item:Object):void + { + if (item && item is IEventDispatcher) + { + IEventDispatcher(item).removeEventListener( + PropertyChangeEvent.PROPERTY_CHANGE, + itemUpdateHandler); + } + } + +} + +}