Coverage Report - org.as3collections.queues.SortedQueue
 
Classes in this File Line Coverage Branch Coverage Complexity
SortedQueue
100%
41/41
N/A
0
 
 1  
 /*
 2  
  * Licensed under the MIT License
 3  
  * 
 4  
  * Copyright 2010 (c) Flávio Silva, http://flsilva.com
 5  
  *
 6  
  * Permission is hereby granted, free of charge, to any person
 7  
  * obtaining a copy of this software and associated documentation
 8  
  * files (the "Software"), to deal in the Software without
 9  
  * restriction, including without limitation the rights to use,
 10  
  * copy, modify, merge, publish, distribute, sublicense, and/or sell
 11  
  * copies of the Software, and to permit persons to whom the
 12  
  * Software is furnished to do so, subject to the following
 13  
  * conditions:
 14  
  *
 15  
  * The above copyright notice and this permission notice shall be
 16  
  * included in all copies or substantial portions of the Software.
 17  
  *
 18  
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 19  
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 20  
  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 21  
  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 22  
  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 23  
  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 24  
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 25  
  * OTHER DEALINGS IN THE SOFTWARE.
 26  
  * 
 27  
  * http://www.opensource.org/licenses/mit-license.php
 28  
  */
 29  
 
 30  1
 package org.as3collections.queues
 31  
 {
 32  
         import org.as3collections.ICollection;
 33  
         import org.as3collections.ISortedQueue;
 34  
         import org.as3coreaddendum.system.IComparator;
 35  
         import org.as3utils.ReflectionUtil;
 36  
 
 37  
         /**
 38  
          * A queue that provides a <em>total ordering</em> on its elements.
 39  
          * The queue is ordered according to the <em>natural ordering</em> of its elements, by a <em>IComparator</em> typically provided at sorted queue creation time, or by the arguments provided to the <code>sort</code> or <code>sortOn</code> methods.
 40  
          * <p>For each change that occurs the queue is automatically ordered using the <code>comparator</code> and <code>options</code>.
 41  
          * If none was provided the default behavior of the <code>sort</code> method is used.</p>
 42  
          * <p>The user of this queue may change their order at any time by calling the <code>sort</code> or <code>sortOn</code> method and imposing others arguments to change the sort behaviour.</p>
 43  
          * <p>It's possible to create unique sorted queues, typed sorted queues and even unique typed sorted queues.
 44  
          * You just sends the <code>SortedQueue</code> object to the wrappers <code>UniqueQueue</code> or <code>TypedQueue</code> or uses the <code>QueueUtil.getUniqueTypedQueue</code>.
 45  
          * But there's a problem here: the return type will be <code>UniqueQueue</code> or <code>TypedQueue</code>.
 46  
          * Thus you will can no longer use the <code>sort</code> and <code>sortOn</code> methods directly.
 47  
          * The wrapped <code>SortedQueue</code> will be only automatically ordered, with the provided <code>comparator</code> and <code>options</code> constructor's arguments.
 48  
          * Check the examples at the bottom of the page.</p>
 49  
          * 
 50  
          * @example
 51  
          * 
 52  
          * <listing version="3.0">
 53  
          * import org.as3collections.ISortedQueue;
 54  
          * import org.as3collections.queues.SortedQueue;
 55  
          * 
 56  
          * var queue1:ISortedQueue = new SortedQueue([3, 5, 1, 7], null, Array.NUMERIC | Array.DESCENDING);
 57  
          * 
 58  
          * queue1                      // [7,5,3,1]
 59  
          * queue1.size()               // 4
 60  
          * 
 61  
          * queue1.add(-1)              // true
 62  
          * queue1                      // [7,5,3,1,-1]
 63  
          * queue1.size()               // 5
 64  
          * 
 65  
          * queue1.add(4)               // true
 66  
          * queue1                      // [7,5,4,3,1,-1]
 67  
          * queue1.size()               // 6
 68  
          * 
 69  
          * queue1.add(5)               // true
 70  
          * queue1                      // [7,5,5,4,3,1,-1]
 71  
          * queue1.size()               // 7
 72  
          * 
 73  
          * queue1.poll()               // 7
 74  
          * queue1                      // [5,5,4,3,1,-1]
 75  
          * queue1.size()               // 6
 76  
          * 
 77  
          * queue1.sort(null, Array.NUMERIC)
 78  
          * queue1                      // [-1,1,3,4,5,5]
 79  
          * 
 80  
          * queue1.poll()               // -1
 81  
          * queue1                      // [5,5,4,3,1]
 82  
          * queue1.size()               // 5
 83  
          * 
 84  
          * queue1.add(2)               // true
 85  
          * queue1                      // [5,5,4,3,2,1]
 86  
          * queue1.size()               // 6
 87  
          * 
 88  
          * queue1.add(10)              // true
 89  
          * queue1                      // [10,5,5,4,3,2,1]
 90  
          * </listing>
 91  
          * 
 92  
          * @author Flávio Silva
 93  
          */
 94  
         public class SortedQueue extends LinearQueue implements ISortedQueue
 95  
         {
 96  
                 private var _comparator: IComparator;
 97  
                 private var _options: uint;
 98  
 
 99  
                 /**
 100  
                  * Defines the comparator object to be used automatically to sort.
 101  
                  * <p>If this value change the queue is automatically reordered with the new value.</p>
 102  
                  */
 103  
                 public function get comparator(): IComparator { return _comparator; }
 104  
 
 105  
                 public function set comparator(value:IComparator): void
 106  
                 {
 107  1
                         _comparator = value;
 108  1
                         _sort();
 109  1
                 }
 110  
 
 111  
                 /**
 112  
                  * Defines the options to be used automatically to sort.
 113  
                  * <p>If this value change the queue is automatically reordered with the new value.</p>
 114  
                  */
 115  
                 public function get options(): uint { return _options; }
 116  
 
 117  
                 public function set options(value:uint): void
 118  
                 {
 119  1
                         _options = value;
 120  1
                         _sort();
 121  1
                 }
 122  
 
 123  
                 /**
 124  
                  * Constructor, creates a new <code>SortedQueue</code> object.
 125  
                  * 
 126  
                  * @param         source                 an array to fill the queue.
 127  
                  * @param         comparator         the comparator object to be used internally to sort.
 128  
                  * @param         options         the options to be used internally to sort.
 129  
                  */
 130  
                 public function SortedQueue(source:Array = null, comparator:IComparator = null, options:uint = 0)
 131  
                 {
 132  1
                         super(source);
 133  
                         
 134  1
                         _comparator = comparator;
 135  1
                         _options = options;
 136  1
                         _sort();
 137  1
                 }
 138  
 
 139  
                 /**
 140  
                  * Creates and return a new <code>SortedQueue</code> object containing all elements in this queue (in the same order).
 141  
                  * 
 142  
                  * @return         a new <code>SortedQueue</code> object containing all elements in this queue (in the same order).
 143  
                   */
 144  
                 override public function clone(): *
 145  
                 {
 146  1
                         return new SortedQueue(data, _comparator, _options);
 147  
                 }
 148  
                 
 149  
                 /**
 150  
                  * Performs an arbitrary, specific evaluation of equality between this object and the <code>other</code> object.
 151  
                  * <p>This implementation considers two differente objects equal if:</p>
 152  
                  * <p>
 153  
                  * <ul><li>object A and object B are instances of the same class (i.e. if they have <b>exactly</b> the same type)</li>
 154  
                  * <li>object A contains all elements of object B</li>
 155  
                  * <li>object B contains all elements of object A</li>
 156  
                  * <li>elements have exactly the same order</li>
 157  
                  * <li>object A and object B has the same type of comparator</li>
 158  
                  * <li>object A and object B has the same options</li>
 159  
                  * </ul></p>
 160  
                  * <p>This implementation takes care of the order of the elements in the queue.
 161  
                  * So, for two queues are equal the order of elements returned by the iterator object must be equal.</p>
 162  
                  * 
 163  
                  * @param          other         the object to be compared for equality.
 164  
                  * @return         <code>true</code> if the arbitrary evaluation considers the objects equal.
 165  
                  */
 166  
                 override public function equals(other:*): Boolean
 167  
                 {
 168  1
                         if (this == other) return true;
 169  
                         
 170  1
                         if (!ReflectionUtil.classPathEquals(this, other)) return false;
 171  
                         
 172  1
                         var l:ISortedQueue = other as ISortedQueue;
 173  
                         
 174  1
                         if (_options != l.options) return false;
 175  1
                         if (!_comparator && l.comparator) return false;
 176  1
                         if (_comparator && !l.comparator) return false;
 177  1
                         if (!ReflectionUtil.classPathEquals(_comparator, l.comparator)) return false;
 178  
                         
 179  1
                         return super.equals(other);
 180  
                 }
 181  
                 
 182  
                 /**
 183  
                  * Inserts the specified element into this queue if it is possible to do so immediately without violating restrictions.
 184  
                  * When using a restricted queue (like <code>TypedQueue</code> and <code>UniqueQueue</code>), this method is generally preferable to <code>add</code>, which can fail to insert an element only by throwing an error. 
 185  
                  * <p>Before returning, the queue is reordered.</p>
 186  
                  * 
 187  
                  * @param          element         the element to add.
 188  
                  * @return         <code>true</code> if the element was added to this queue, else <code>false</code>. 
 189  
                  */
 190  
                 override public function offer(element:*): Boolean
 191  
                 {
 192  1
                         var b:Boolean = super.offer(element);
 193  1
                         if (b) _sort();
 194  1
                         return b;
 195  
                 }
 196  
 
 197  
                 /**
 198  
                  * Retrieves and removes the head of this queue, or returns <code>null</code> if this queue is empty. 
 199  
                  * <p>Before returning, the queue is reordered.</p>
 200  
                  * 
 201  
                  * @return         the head of this queue, or <code>null</code> if this queue is empty.
 202  
                   */
 203  
                 override public function poll(): *
 204  
                 {
 205  1
                         var e:* = super.poll();
 206  1
                         if (e) _sort();
 207  1
                         return e;
 208  
                 }
 209  
 
 210  
                 /**
 211  
                  * Removes a single instance (only one occurrence) of the specified object from this queue, if it is present.
 212  
                  * <p>Before returning, the queue is reordered.</p>
 213  
                  * 
 214  
                  * @param          o         the object to be removed from this collection, if present.
 215  
                  * @return         <code>true</code> if an object was removed as a result of this call.
 216  
                  */
 217  
                 override public function remove(o:*): Boolean
 218  
                 {
 219  1
                         var b:Boolean = super.remove(o);
 220  1
                         if (b) _sort();
 221  1
                         return b;
 222  
                 }
 223  
 
 224  
                 /**
 225  
                  * Removes all of this queue's elements that are also contained in the specified collection. After this call returns, this queue will contain no elements in common with the specified collection.
 226  
                  * <p>Before returning, the queue is reordered.</p>
 227  
                  * 
 228  
                  * @param          collection         the collection containing elements to be removed from this queue.
 229  
                  * @return         <code>true</code> if this queue changed as a result of the call.
 230  
                  */
 231  
                 override public function removeAll(collection:ICollection): Boolean
 232  
                 {
 233  1
                         var b:Boolean = super.removeAll(collection);
 234  1
                         if (b) _sort();
 235  1
                         return b;
 236  
                 }
 237  
 
 238  
                 /**
 239  
                  * Sorts the objects within this class.
 240  
                  * <p>For more info see <code>org.as3coreaddendum.system.ISortable.sort()</code> in the link below.</p>
 241  
                  * 
 242  
                  * @param compare
 243  
                  * @param options
 244  
                  * @return
 245  
                  */
 246  
                 public function sort(compare:Function = null, options:uint = 0): Array
 247  
                 {
 248  1
                         if (compare != null)
 249  
                         { 
 250  1
                                 return data.sort(compare, options);
 251  
                         }
 252  
                         else
 253  
                         {
 254  1
                                 return data.sort(options);
 255  
                         }
 256  
                 }
 257  
 
 258  
                 /**
 259  
                  * @inheritDoc
 260  
                  * 
 261  
                  * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#sortOn()
 262  
                  */
 263  
                 public function sortOn(fieldName:*, options:* = null): Array
 264  
                 {
 265  1
                         return data.sortOn(fieldName, options);
 266  
                 }
 267  
 
 268  
                 /**
 269  
                  * @private
 270  
                  */
 271  
                 protected function _sort(): void
 272  
                 {
 273  1
                         if (_comparator)
 274  
                         {
 275  1
                                 sort(_comparator.compare, _options);
 276  
                         }
 277  
                         else
 278  
                         {
 279  1
                                 sort(null, _options);
 280  
                         }
 281  1
                 }
 282  
 
 283  
         }
 284  
 
 285  
 }