daily pastebin goal
59%
SHARE
TWEET

Untitled

a guest Jul 12th, 2018 52 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
 
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  ADOBE SYSTEMS INCORPORATED
  4. //  Copyright 2005-2007 Adobe Systems Incorporated
  5. //  All Rights Reserved.
  6. //
  7. //  NOTICE: Adobe permits you to use, modify, and distribute this file
  8. //  in accordance with the terms of the license agreement accompanying it.
  9. //
  10. ////////////////////////////////////////////////////////////////////////////////
  11.  
  12. package mx.collections
  13. {
  14.    
  15. import flash.events.EventDispatcher;
  16. import flash.events.IEventDispatcher;
  17. import flash.utils.IDataInput;
  18. import flash.utils.IDataOutput;
  19. import flash.utils.IExternalizable;
  20. import flash.utils.getQualifiedClassName;
  21. import mx.core.IPropertyChangeNotifier;
  22. import mx.core.mx_internal;
  23. import mx.events.CollectionEvent;
  24. import mx.events.CollectionEventKind;
  25. import mx.events.PropertyChangeEvent;
  26. import mx.events.PropertyChangeEventKind;
  27. import mx.managers.ISystemManager;
  28. import mx.managers.SystemManager;
  29. import mx.resources.IResourceManager;
  30. import mx.resources.ResourceManager;
  31. import mx.utils.ArrayUtil;
  32. import mx.utils.UIDUtil;
  33.  
  34. //--------------------------------------
  35. //  Events
  36. //--------------------------------------
  37.  
  38. /**
  39.  *  Dispatched when the IList has been updated in some way.
  40.  *  
  41.  *  @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
  42.  */
  43. [Event(name="collectionChange", type="mx.events.CollectionEvent")]
  44.  
  45. //--------------------------------------
  46. //  Other metadata
  47. //--------------------------------------
  48.  
  49. [ExcludeClass]
  50.  
  51. [RemoteClass(alias="flex.messaging.io.ArrayList")]
  52.  
  53. [ResourceBundle("collections")]
  54.  
  55. /**
  56.  *  @private
  57.  *  A simple implementation of IList that uses a backing Array.
  58.  *  This base class will not throw ItemPendingErrors but it
  59.  *  is possible that a subclass might.
  60.  */
  61. public class ArrayList extends EventDispatcher
  62.        implements IList, IExternalizable, IPropertyChangeNotifier
  63. {
  64.     include "../core/Version.as";
  65.  
  66.     //--------------------------------------------------------------------------
  67.     //
  68.     // Constructor
  69.     //
  70.     //--------------------------------------------------------------------------
  71.  
  72.     /**
  73.      *  Construct a new ArrayList using the specified array as its source.
  74.      *  If no source is specified an empty array will be used.
  75.      */
  76.     public function ArrayList(source:Array = null)
  77.     {
  78.         super();
  79.  
  80.         disableEvents();
  81.         this.source = source;
  82.         enableEvents();
  83.         _uid = UIDUtil.createUID();
  84.     }
  85.    
  86.     //--------------------------------------------------------------------------
  87.     //
  88.     // Variables
  89.     //
  90.     //--------------------------------------------------------------------------
  91.  
  92.     /**
  93.      *  @private
  94.      *  Used for accessing localized Error messages.
  95.      */
  96.     private var resourceManager:IResourceManager =
  97.                                     ResourceManager.getInstance();
  98.  
  99.     //--------------------------------------------------------------------------
  100.     //
  101.     // Properties
  102.     //
  103.     //--------------------------------------------------------------------------
  104.    
  105.     //----------------------------------
  106.     // length
  107.     //----------------------------------
  108.  
  109.     /**
  110.      *  Get the number of items in the list.  An ArrayList should always
  111.      *  know its length so it shouldn't return -1, though a subclass may
  112.      *  override that behavior.
  113.      *
  114.      *  @return int representing the length of the source.
  115.      */
  116.     public function get length():int
  117.     {
  118.         if (source)
  119.             return source.length;
  120.         else
  121.             return 0;
  122.     }
  123.    
  124.     //----------------------------------
  125.     // source
  126.     //----------------------------------
  127.    
  128.     /**
  129.      *  The source array for this ArrayList.  
  130.      *  Any changes done through the IList interface will be reflected in the
  131.      *  source array.  
  132.      *  If no source array was supplied the ArrayList will create one internally.
  133.      *  Changes made directly to the underlying Array (e.g., calling
  134.      *  <code>theList.source.pop()</code> will not cause <code>CollectionEvents</code>
  135.      *  to be dispatched.
  136.      *
  137.      *  @return An Array that represents the underlying source.
  138.      */
  139.     public function get source():Array
  140.     {
  141.         return _source;
  142.     }
  143.    
  144.     public function set source(s:Array):void
  145.     {
  146.         var i:int;
  147.         var len:int;
  148.         if (_source && _source.length)
  149.         {
  150.             len = _source.length;
  151.             for (i = 0; i < len; i++)
  152.             {
  153.                 stopTrackUpdates(_source[i]);
  154.             }
  155.         }
  156.         _source  = s ? s : [];
  157.         len = _source.length;
  158.         for (i = 0; i < len; i++)
  159.         {
  160.             startTrackUpdates(_source[i]);
  161.         }
  162.        
  163.         if (_dispatchEvents == 0)
  164.         {
  165.            var event:CollectionEvent =
  166.             new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
  167.            event.kind = CollectionEventKind.RESET;
  168.            dispatchEvent(event);
  169.         }
  170.     }
  171.    
  172.     //----------------------------------
  173.     // uid -- mx.core.IPropertyChangeNotifier
  174.     //----------------------------------
  175.    
  176.     /**
  177.      *  Provides access to the unique id for this list.
  178.      *  
  179.      *  @return String representing the internal uid.
  180.      */  
  181.     public function get uid():String
  182.     {
  183.         return _uid;
  184.     }
  185.    
  186.     public function set uid(value:String):void
  187.     {
  188.         _uid = value;
  189.     }
  190.  
  191.     //--------------------------------------------------------------------------
  192.     //
  193.     // Methods
  194.     //
  195.     //--------------------------------------------------------------------------
  196.  
  197.     /**
  198.      *  Get the item at the specified index.
  199.      *
  200.      *  @param  index the index in the list from which to retrieve the item
  201.      *  @param  prefetch int indicating both the direction and amount of items
  202.      *          to fetch during the request should the item not be local.
  203.      *  @return the item at that index, null if there is none
  204.      *  @throws ItemPendingError if the data for that index needs to be
  205.      *                           loaded from a remote location
  206.      *  @throws RangeError if the index < 0 or index >= length
  207.      */
  208.     public function getItemAt(index:int, prefetch:int = 0):Object
  209.     {
  210.         if (index < 0 || index >= length)
  211.         {
  212.             var message:String = resourceManager.getString(
  213.                 "collections", "outOfBounds", [ index ]);
  214.             throw new RangeError(message);
  215.         }
  216.            
  217.         return source[index];
  218.     }
  219.    
  220.     /**
  221.      *  Place the item at the specified index.  
  222.      *  If an item was already at that index the new item will replace it and it
  223.      *  will be returned.
  224.      *
  225.      *  @param  item the new value for the index
  226.      *  @param  index the index at which to place the item
  227.      *  @return the item that was replaced, null if none
  228.      *  @throws RangeError if index is less than 0 or greater than or equal to length
  229.      */
  230.     public function setItemAt(item:Object, index:int):Object
  231.     {
  232.         if (index < 0 || index >= length)
  233.         {
  234.             var message:String = resourceManager.getString(
  235.                 "collections", "outOfBounds", [ index ]);
  236.             throw new RangeError(message);
  237.         }
  238.        
  239.         var oldItem:Object = source[index];
  240.         source[index] = item;
  241.         stopTrackUpdates(oldItem);
  242.         startTrackUpdates(item);
  243.        
  244.         //dispatch the appropriate events
  245.         if (_dispatchEvents == 0)
  246.         {
  247.             var hasCollectionListener:Boolean =
  248.                 hasEventListener(CollectionEvent.COLLECTION_CHANGE);
  249.             var hasPropertyListener:Boolean =
  250.                 hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE);
  251.             var updateInfo:PropertyChangeEvent;
  252.            
  253.             if (hasCollectionListener || hasPropertyListener)
  254.             {
  255.                 updateInfo = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
  256.                 updateInfo.kind = PropertyChangeEventKind.UPDATE;
  257.                 updateInfo.oldValue = oldItem;
  258.                 updateInfo.newValue = item;
  259.                 updateInfo.property = index;
  260.             }
  261.            
  262.             if (hasCollectionListener)
  263.             {
  264.                 var event:CollectionEvent =
  265.                     new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
  266.                 event.kind = CollectionEventKind.REPLACE;
  267.                 event.location = index;
  268.                 event.items.push(updateInfo);
  269.                 dispatchEvent(event);
  270.             }
  271.            
  272.             if (hasPropertyListener)
  273.             {
  274.                 dispatchEvent(updateInfo);
  275.             }
  276.         }
  277.         return oldItem;    
  278.     }
  279.    
  280.     /**
  281.      *  Add the specified item to the end of the list.
  282.      *  Equivalent to addItemAt(item, length);
  283.      *
  284.      *  @param item the item to add
  285.      */
  286.     public function addItem(item:Object):void
  287.     {
  288.         addItemAt(item, length);
  289.     }
  290.    
  291.     /**
  292.      *  Add the item at the specified index.  
  293.      *  Any item that was after this index is moved out by one.  
  294.      *
  295.      *  @param item the item to place at the index
  296.      *  @param index the index at which to place the item
  297.      *  @throws RangeError if index is less than 0 or greater than the length
  298.      */
  299.     public function addItemAt(item:Object, index:int):void
  300.     {
  301.         if (index < 0 || index > length)
  302.         {
  303.             var message:String = resourceManager.getString(
  304.                 "collections", "outOfBounds", [ index ]);
  305.             throw new RangeError(message);
  306.         }
  307.            
  308.         source.splice(index, 0, item);
  309.  
  310.         startTrackUpdates(item);
  311.         internalDispatchEvent(CollectionEventKind.ADD, item, index);
  312.     }
  313.    
  314.     /**
  315.      *  Return the index of the item if it is in the list such that
  316.      *  getItemAt(index) == item.  
  317.      *  Note that in this implementation the search is linear and is therefore
  318.      *  O(n).
  319.      *
  320.      *  @param item the item to find
  321.      *  @return the index of the item, -1 if the item is not in the list.
  322.      */
  323.     public function getItemIndex(item:Object):int
  324.     {
  325.         return ArrayUtil.getItemIndex(item, source);
  326.     }
  327.    
  328.     /**
  329.      *  Removes the specified item from this list, should it exist.
  330.      *
  331.      *  @param  item Object reference to the item that should be removed.
  332.      *  @return Boolean indicating if the item was removed.
  333.      */
  334.     public function removeItem(item:Object):Boolean
  335.     {
  336.         var index:int = getItemIndex(item);
  337.         var result:Boolean = index >= 0;
  338.         if (result)
  339.             removeItemAt(index);
  340.  
  341.         return result;
  342.     }
  343.    
  344.     /**
  345.      *  Remove the item at the specified index and return it.  
  346.      *  Any items that were after this index are now one index earlier.
  347.      *
  348.      *  @param index the index from which to remove the item
  349.      *  @return the item that was removed
  350.      *  @throws RangeError is index < 0 or index >= length
  351.      */
  352.     public function removeItemAt(index:int):Object
  353.     {
  354.         if (index < 0 || index >= length)
  355.         {
  356.             var message:String = resourceManager.getString(
  357.                 "collections", "outOfBounds", [ index ]);
  358.             throw new RangeError(message);
  359.         }
  360.  
  361.         var removed:Object = source.splice(index, 1)[0];
  362.         stopTrackUpdates(removed);
  363.         internalDispatchEvent(CollectionEventKind.REMOVE, removed, index);
  364.         return removed;
  365.     }
  366.    
  367.     /**
  368.      *  Remove all items from the list.
  369.      */
  370.     public function removeAll():void
  371.     {
  372.         if (length > 0)
  373.         {
  374.             var len:int = length;
  375.             for (var i:int = 0; i < len; i++)
  376.             {
  377.                 stopTrackUpdates(source[i]);
  378.             }
  379.  
  380.             source.splice(0, length);
  381.             internalDispatchEvent(CollectionEventKind.RESET);
  382.         }    
  383.     }
  384.    
  385.     /**
  386.      *  Notify the view that an item has been updated.  
  387.      *  This is useful if the contents of the view do not implement
  388.      *  <code>IEventDispatcher</code>.  
  389.      *  If a property is specified the view may be able to optimize its
  390.      *  notification mechanism.
  391.      *  Otherwise it may choose to simply refresh the whole view.
  392.      *
  393.      *  @param item The item within the view that was updated.
  394.      *
  395.      *  @param property A String, QName, or int
  396.      *  specifying the property that was updated.
  397.      *
  398.      *  @param oldValue The old value of that property.
  399.      *  (If property was null, this can be the old value of the item.)
  400.      *
  401.      *  @param newValue The new value of that property.
  402.      *  (If property was null, there's no need to specify this
  403.      *  as the item is assumed to be the new value.)
  404.      *
  405.      *  @see mx.events.CollectionEvent
  406.      *  @see mx.core.IPropertyChangeNotifier
  407.      *  @see mx.events.PropertyChangeEvent
  408.      */
  409.      public function itemUpdated(item:Object, property:Object = null,
  410.                                  oldValue:Object = null,
  411.                                  newValue:Object = null):void
  412.     {
  413.         var event:PropertyChangeEvent =
  414.             new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
  415.        
  416.         event.kind = PropertyChangeEventKind.UPDATE;
  417.         event.source = item;
  418.         event.property = property;
  419.         event.oldValue = oldValue;
  420.         event.newValue = newValue;
  421.        
  422.         itemUpdateHandler(event);        
  423.     }    
  424.    
  425.     /**
  426.      *  Return an Array that is populated in the same order as the IList
  427.      *  implementation.  
  428.      *
  429.      *  @throws ItemPendingError if the data is not yet completely loaded
  430.      *  from a remote location
  431.      */
  432.     public function toArray():Array
  433.     {
  434.         return source.concat();
  435.     }
  436.    
  437.     /**
  438.      *  Ensures that only the source property is seralized.
  439.      *  @private
  440.      */
  441.     public function readExternal(input:IDataInput):void
  442.     {
  443.         source = input.readObject();
  444.     }
  445.    
  446.     /**
  447.      *  Ensures that only the source property is serialized.
  448.      *  @private
  449.      */
  450.     public function writeExternal(output:IDataOutput):void
  451.     {
  452.         output.writeObject(_source);
  453.     }
  454.  
  455.     /**
  456.      *  Pretty prints the contents of this ArrayList to a string and returns it.
  457.      */
  458.     override public function toString():String
  459.     {
  460.         if (source)
  461.             return source.toString();
  462.         else
  463.             return getQualifiedClassName(this);
  464.     }  
  465.    
  466.     //--------------------------------------------------------------------------
  467.     //
  468.     // Internal Methods
  469.     //
  470.     //--------------------------------------------------------------------------
  471.  
  472.     /**
  473.      *  Enables event dispatch for this list.
  474.      */
  475.     private function enableEvents():void
  476.     {
  477.         _dispatchEvents++;
  478.         if (_dispatchEvents > 0)
  479.             _dispatchEvents = 0;
  480.     }
  481.    
  482.     /**
  483.      *  Disables event dispatch for this list.
  484.      *  To re-enable events call enableEvents(), enableEvents() must be called
  485.      *  a matching number of times as disableEvents().
  486.      */
  487.     private function disableEvents():void
  488.     {
  489.         _dispatchEvents--;
  490.     }
  491.    
  492.     /**
  493.      *  Dispatches a collection event with the specified information.
  494.      *
  495.      *  @param kind String indicates what the kind property of the event should be
  496.      *  @param item Object reference to the item that was added or removed
  497.      *  @param location int indicating where in the source the item was added.
  498.      */
  499.     private function internalDispatchEvent(kind:String, item:Object = null, location:int = -1):void
  500.     {
  501.         if (_dispatchEvents == 0)
  502.         {
  503.             if (hasEventListener(CollectionEvent.COLLECTION_CHANGE))
  504.             {
  505.                 var event:CollectionEvent =
  506.                     new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
  507.                 event.kind = kind;
  508.                 event.items.push(item);
  509.                 event.location = location;
  510.                 dispatchEvent(event);
  511.             }
  512.  
  513.             // now dispatch a complementary PropertyChangeEvent
  514.             if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE) &&
  515.                (kind == CollectionEventKind.ADD || kind == CollectionEventKind.REMOVE))
  516.             {
  517.                 var objEvent:PropertyChangeEvent =
  518.                     new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
  519.                 objEvent.property = location;
  520.                 if (kind == CollectionEventKind.ADD)
  521.                     objEvent.newValue = item;
  522.                 else
  523.                     objEvent.oldValue = item;
  524.                 dispatchEvent(objEvent);
  525.             }
  526.         }
  527.     }
  528.    
  529.     /**
  530.      *  Called whenever any of the contained items in the list fire an
  531.      *  ObjectChange event.  
  532.      *  Wraps it in a CollectionEventKind.UPDATE.
  533.      */    
  534.     protected function itemUpdateHandler(event:PropertyChangeEvent):void
  535.     {
  536.         internalDispatchEvent(CollectionEventKind.UPDATE, event);
  537.         // need to dispatch object event now
  538.         if (_dispatchEvents == 0 && hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
  539.         {
  540.             var objEvent:PropertyChangeEvent = PropertyChangeEvent(event.clone());
  541.             var index:uint = getItemIndex(event.target);
  542.             objEvent.property = index.toString() + "." + event.property;
  543.             dispatchEvent(objEvent);
  544.         }
  545.     }
  546.    
  547.     /**
  548.      *  If the item is an IEventDispatcher watch it for updates.  
  549.      *  This is called by addItemAt and when the source is initially
  550.      *  assigned.
  551.      */
  552.     protected function startTrackUpdates(item:Object):void
  553.     {
  554.         if (item && (item is IEventDispatcher))
  555.         {
  556.             IEventDispatcher(item).addEventListener(
  557.                                         PropertyChangeEvent.PROPERTY_CHANGE,
  558.                                         itemUpdateHandler, false, 0, true);
  559.         }
  560.     }
  561.    
  562.     /**
  563.      *  If the item is an IEventDispatcher stop watching it for updates.
  564.      *  This is called by removeItemAt, removeAll, and before a new
  565.      *  source is assigned.
  566.      */
  567.     protected function stopTrackUpdates(item:Object):void
  568.     {
  569.         if (item && item is IEventDispatcher)
  570.         {
  571.             IEventDispatcher(item).removeEventListener(
  572.                                         PropertyChangeEvent.PROPERTY_CHANGE,
  573.                                         itemUpdateHandler);    
  574.         }
  575.     }
  576.    
  577.     //--------------------------------------------------------------------------
  578.     //
  579.     // Variables
  580.     //
  581.     //--------------------------------------------------------------------------
  582.  
  583.     /**
  584.      *  indicates if events should be dispatched.
  585.      *  calls to enableEvents() and disableEvents() effect the value when == 0
  586.      *  events should be dispatched.
  587.      */
  588.     private var _dispatchEvents:int = 0;
  589.     private var _source:Array;
  590.     private var _uid:String;
  591. }
  592.  
  593. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top