Coverage Report - org.vostokframework.application.monitoring.monitors.CompositeLoadingMonitor
 
Classes in this File Line Coverage Branch Coverage Complexity
CompositeLoadingMonitor
85%
126/147
N/A
0
 
 1  
 /*
 2  
  * Licensed under the MIT License
 3  
  * 
 4  
  * Copyright 2011 (c) Flávio Silva, 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  1
 package org.vostokframework.application.monitoring.monitors
 30  
 {
 31  
         import org.as3collections.IIterator;
 32  
         import org.as3collections.IList;
 33  
         import org.as3collections.IMap;
 34  
         import org.as3collections.lists.ArrayList;
 35  
         import org.as3collections.lists.TypedList;
 36  
         import org.as3collections.maps.HashMap;
 37  
         import org.as3collections.maps.TypedMap;
 38  
         import org.vostokframework.VostokIdentification;
 39  
         import org.vostokframework.application.monitoring.ILoadingMonitor;
 40  
         import org.vostokframework.domain.loading.ILoader;
 41  
         import org.vostokframework.domain.loading.errors.DuplicateLoadingMonitorError;
 42  
         import org.vostokframework.domain.loading.errors.LoadingMonitorNotFoundError;
 43  
 
 44  
         import flash.events.TimerEvent;
 45  
         import flash.utils.Timer;
 46  
 
 47  
         /**
 48  
          * @author Flavio
 49  
          * @version 1.0
 50  
          * @created 14-mai-2011 12:02:52
 51  
          */
 52  
         public class CompositeLoadingMonitor extends LoadingMonitor
 53  
         {
 54  
                 /**
 55  
                  * @private
 56  
                  */
 57  
                 private var _isFirstProgressDispatch:Boolean;
 58  
                 private var _lastPercent:int;
 59  
                 private var _monitors:IMap;
 60  
                 private var _monitorsListeners:IList;
 61  
                 private var _progressTimer:Timer;
 62  
                 private var _progressTimerDelay:int;
 63  
                 
 64  
                 /**
 65  
                  * 
 66  
                  * @param loader
 67  
                  */
 68  
                 public function CompositeLoadingMonitor(loader:ILoader, dispatcher:LoadingMonitorDispatcher)
 69  
                 {
 70  1
                         super(loader, dispatcher);
 71  
                         
 72  1
                         _monitors = new TypedMap(new HashMap(), String, ILoadingMonitor);
 73  1
                         _monitorsListeners = new TypedList(new ArrayList(), EventListener);
 74  1
                         _progressTimerDelay = 50;
 75  1
                         _progressTimer = new Timer(_progressTimerDelay);
 76  1
                         _isFirstProgressDispatch = true;
 77  
                         
 78  1
                         addTimerListener();
 79  1
                 }
 80  
                 
 81  
                 override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
 82  
                 {
 83  1
                         validateDisposal();
 84  
                         
 85  1
                         if (!dispatcher.typeBelongs(type))
 86  
                         {
 87  1
                                 var eventListener:EventListener = new EventListener(type, listener, useCapture, priority, useWeakReference);
 88  1
                                 _monitorsListeners.add(eventListener);
 89  
                                 
 90  1
                                 addListenersOnMonitors();
 91  1
                                 return;
 92  
                         }
 93  
                         
 94  1
                         super.addEventListener(type, listener, useCapture, priority, useWeakReference);
 95  1
                 }
 96  
                 
 97  
                 override public function addChild(child:ILoadingMonitor):void
 98  
                 {
 99  1
                         validateDisposal();
 100  
                         
 101  1
                         if (!child) throw new ArgumentError("Argument <child> must not be null.");
 102  1
                         if (containsChild(child.loader.identification)) throw new DuplicateLoadingMonitorError("There is already an ILoadingMonitor object stored for a ILoader object with identification:\n<" + child.loader.identification + ">");
 103  
                         
 104  1
                         _monitors.put(child.loader.identification.toString(), child);
 105  1
                         addListenersOnMonitors();
 106  1
                 }
 107  
                 
 108  
                 override public function addChildren(children:IList):void
 109  
                 {
 110  1
                         validateDisposal();
 111  
                         
 112  1
                         if (!children) throw new ArgumentError("Argument <children> must not be null.");
 113  1
                         if (children.isEmpty()) return;
 114  
                         
 115  1
                         var it:IIterator = children.iterator();
 116  
                         var child:ILoadingMonitor;
 117  
                         
 118  1
                         while (it.hasNext())
 119  
                         {
 120  1
                                 child = it.next();
 121  1
                                 addChild(child);
 122  
                         }
 123  1
                 }
 124  
                 
 125  
                 override public function containsChild(identification:VostokIdentification):Boolean
 126  
                 {
 127  1
                         if (_monitors.isEmpty()) return false;
 128  
                         
 129  1
                         if (_monitors.containsKey(identification.toString()))
 130  
                         {
 131  1
                                 return true;
 132  
                         }
 133  
                         
 134  1
                         var it:IIterator = _monitors.iterator();
 135  
                         var child:ILoadingMonitor;
 136  
                         
 137  1
                         while (it.hasNext())
 138  
                         {
 139  1
                                 child = it.next();
 140  1
                                 if (child.containsChild(identification)) return true;
 141  
                         }
 142  
                         
 143  1
                         return false;
 144  
                 }
 145  
                 
 146  
                 override public function getChild(identification:VostokIdentification):ILoadingMonitor
 147  
                 {
 148  1
                         validateDisposal();
 149  
                         
 150  1
                         if (_monitors.containsKey(identification.toString()))
 151  
                         {
 152  1
                                 return _monitors.getValue(identification.toString());
 153  
                         }
 154  
                         else
 155  
                         {
 156  1
                                 var it:IIterator = _monitors.iterator();
 157  
                                 var child:ILoadingMonitor;
 158  
                                 
 159  1
                                 while (it.hasNext())
 160  
                                 {
 161  1
                                         child = it.next();
 162  1
                                         if (child.containsChild(identification)) return child.getChild(identification);
 163  
                                 }
 164  
                                 
 165  0
                                 var message:String = "There is no ILoadingMonitor object stored with identification:\n";
 166  0
                                 message += "<" + identification + ">";
 167  0
                                 throw new LoadingMonitorNotFoundError(message);
 168  
                         }
 169  
                 }
 170  
                 
 171  
                 override public function hasEventListener(type:String):Boolean
 172  
                 {
 173  1
                         validateDisposal();
 174  
                         
 175  1
                         if (!dispatcher.typeBelongs(type))
 176  
                         {
 177  1
                                 return monitorsHasEventListener(type);
 178  
                         }
 179  
                         
 180  0
                         return super.hasEventListener(type);
 181  
                 }
 182  
                 
 183  
                 override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
 184  
                 {
 185  1
                         validateDisposal();
 186  
                         
 187  1
                         if (!dispatcher.typeBelongs(type))
 188  
                         {
 189  1
                                 removeListenerOnMonitors(type, listener, useCapture);
 190  1
                                 return;
 191  
                         }
 192  
                         
 193  1
                         super.removeEventListener(type, listener, useCapture);
 194  1
                 }
 195  
                 
 196  
                 override public function removeChild(identification:VostokIdentification):void
 197  
                 {
 198  1
                         validateDisposal();
 199  
                         
 200  1
                         if (_monitors.containsKey(identification.toString()))
 201  
                         {
 202  1
                                 var monitor:ILoadingMonitor = _monitors.getValue(identification.toString());
 203  1
                                 monitor.dispose();
 204  
                                 
 205  1
                                 _monitors.remove(identification.toString());
 206  
                         }
 207  
                         else
 208  
                         {
 209  0
                                 var it:IIterator = _monitors.iterator();
 210  
                                 var child:ILoadingMonitor;
 211  
                                 
 212  0
                                 while (it.hasNext())
 213  
                                 {
 214  0
                                         child = it.next();
 215  0
                                         if (child.containsChild(identification))
 216  
                                         {
 217  0
                                                 child.removeChild(identification);
 218  0
                                                 return;
 219  
                                         }
 220  
                                 }
 221  
                                 
 222  0
                                 var message:String = "There is no ILoadingMonitor object stored with identification:\n";
 223  0
                                 message += "<" + identification + ">";
 224  0
                                 throw new LoadingMonitorNotFoundError(message);
 225  
                         }
 226  1
                 }
 227  
                 
 228  
                 override public function willTrigger(type:String):Boolean
 229  
                 {
 230  0
                         validateDisposal();
 231  
                         
 232  0
                         if (!dispatcher.typeBelongs(type))
 233  
                         {
 234  0
                                 return monitorsWillTrigger(type);
 235  
                         }
 236  
                         
 237  0
                         return super.willTrigger(type);
 238  
                 }
 239  
                 
 240  
                 override protected function doDispose():void
 241  
                 {
 242  1
                         removeListenersOnMonitors();
 243  1
                         removeTimerListener();
 244  1
                         _progressTimer.stop();
 245  1
                         _monitors.clear();
 246  1
                         _monitorsListeners.clear();
 247  
                         
 248  1
                         _monitors = null;
 249  1
                         _monitorsListeners = null;
 250  1
                         _progressTimer = null;
 251  1
                 }
 252  
                 
 253  
                 override protected function loadingComplete():void
 254  
                 {
 255  1
                         _progressTimer.stop();
 256  1
                         _progressTimer.reset();
 257  1
                 }
 258  
                 
 259  
                 override protected function loadingStarted():void
 260  
                 {
 261  1
                         _progressTimer.start();
 262  1
                 }
 263  
                 
 264  
                 private function addListenersOnMonitors():void
 265  
                 {
 266  1
                         var itMonitors:IIterator = _monitors.iterator();
 267  
                         var itListeners:IIterator;
 268  
                         var monitor:ILoadingMonitor;
 269  
                         var eventListener:EventListener;
 270  
                         
 271  1
                         while (itMonitors.hasNext())
 272  
                         {
 273  1
                                 monitor = itMonitors.next();
 274  1
                                 itListeners = _monitorsListeners.iterator();
 275  
                                 
 276  1
                                 while (itListeners.hasNext())
 277  
                                 {
 278  1
                                         eventListener = itListeners.next();
 279  1
                                         monitor.addEventListener(eventListener.type, eventListener.listener, eventListener.useCapture, eventListener.priority, eventListener.useWeakReference);
 280  
                                 }
 281  
                         }
 282  1
                 }
 283  
                 
 284  
                 private function addTimerListener():void
 285  
                 {
 286  1
                         _progressTimer.addEventListener(TimerEvent.TIMER, progressTimerEventHandler, false, 0, true);
 287  1
                 }
 288  
                 
 289  
                 private function monitorsHasEventListener(type:String):Boolean
 290  
                 {
 291  1
                         if (_monitorsListeners.isEmpty()) return false;
 292  
                         
 293  1
                         var it:IIterator = _monitorsListeners.iterator();
 294  
                         var eventListener:EventListener;
 295  
                         
 296  1
                         while (it.hasNext())
 297  
                         {
 298  1
                                 eventListener = it.next();
 299  1
                                 if (eventListener.type == type) return true;
 300  
                         }
 301  
                         
 302  0
                         return false;
 303  
                 }
 304  
                 
 305  
                 private function monitorsWillTrigger(type:String):Boolean
 306  
                 {
 307  0
                         if (_monitors.isEmpty()) return false;
 308  
                         
 309  0
                         var monitor:ILoadingMonitor = _monitors.iterator().next();
 310  0
                         return monitor.willTrigger(type);
 311  
                 }
 312  
                 
 313  
                 private function progress():void
 314  
                 {
 315  1
                         validateDisposal();
 316  
                         
 317  1
                         var it:IIterator = _monitors.iterator();
 318  
                         var monitor:ILoadingMonitor;
 319  
                         
 320  
                         var bytesLoaded:int;
 321  
                         var bytesTotal:int;
 322  
                         var totalLoadersHasBytesTotal:int;
 323  
                         var totalLoadersHasNotBytesTotal:int;
 324  
                         
 325  1
                         while (it.hasNext())
 326  
                         {
 327  1
                                 monitor = it.next();
 328  
                                 
 329  1
                                 if (monitor.monitoring && monitor.monitoring.bytesTotal > 0)
 330  
                                 {
 331  1
                                          totalLoadersHasBytesTotal++;
 332  1
                                          bytesTotal += monitor.monitoring.bytesTotal;
 333  1
                                          bytesLoaded += monitor.monitoring.bytesLoaded;
 334  
                                 }
 335  
                         }
 336  
                         
 337  1
                         totalLoadersHasNotBytesTotal = _monitors.size() - totalLoadersHasBytesTotal;
 338  
                         
 339  1
                         if (totalLoadersHasNotBytesTotal > 0)
 340  
                         {
 341  1
                                 var fakeBytes:int = bytesTotal / totalLoadersHasBytesTotal;
 342  1
                                 bytesTotal += fakeBytes * totalLoadersHasNotBytesTotal;
 343  
                         }
 344  
                         
 345  1
                         _lastPercent = monitoring.percent;
 346  1
                         updateMonitoring(bytesTotal, bytesLoaded);
 347  
                         
 348  1
                         if (monitoring.percent != _lastPercent || _isFirstProgressDispatch) dispatcher.dispatchProgressEvent(monitoring);
 349  
                         
 350  1
                         _isFirstProgressDispatch = false;
 351  1
                 }
 352  
                 
 353  
                 private function removeListenerOnMonitors(type:String, listener:Function, useCapture:Boolean = false):void
 354  
                 {
 355  1
                         var it:IIterator = _monitors.iterator();
 356  
                         var monitor:ILoadingMonitor;
 357  
                         
 358  1
                         while (it.hasNext())
 359  
                         {
 360  1
                                 monitor = it.next();
 361  1
                                 monitor.removeEventListener(type, listener, useCapture);
 362  
                         }
 363  
                         
 364  1
                         var eventListener:EventListener = new EventListener(type, listener, useCapture);
 365  1
                         _monitorsListeners.remove(eventListener);
 366  1
                 }
 367  
                 
 368  
                 private function removeListenersOnMonitors():void
 369  
                 {
 370  1
                         var itMonitors:IIterator = _monitors.iterator();
 371  
                         var itListeners:IIterator;
 372  
                         var monitor:ILoadingMonitor;
 373  
                         var eventListener:EventListener;
 374  
                         
 375  1
                         while (itMonitors.hasNext())
 376  
                         {
 377  1
                                 monitor = itMonitors.next();
 378  1
                                 itListeners = _monitorsListeners.iterator();
 379  
                                 
 380  1
                                 while (itListeners.hasNext())
 381  
                                 {
 382  1
                                         eventListener = itListeners.next();
 383  1
                                         monitor.removeEventListener(eventListener.type, eventListener.listener, eventListener.useCapture);
 384  
                                 }
 385  
                         }
 386  1
                 }
 387  
                 
 388  
                 private function removeTimerListener():void
 389  
                 {
 390  1
                         _progressTimer.removeEventListener(TimerEvent.TIMER, progressTimerEventHandler, false);
 391  1
                 }
 392  
                 
 393  
                 private function progressTimerEventHandler(event:TimerEvent):void
 394  
                 {
 395  1
                         progress();
 396  1
                 }
 397  
                 
 398  
         }
 399  
 
 400  
 }