1  /*
     2   * Copyright the original author or authors.
     3   * 
     4   * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   * 
     8   *      http://www.mozilla.org/MPL/MPL-1.1.html
     9   * 
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  import org.as2lib.env.event.EventExecutionException;
    18  import org.as2lib.env.event.distributor.AbstractEventDistributorControl;
    19  import org.as2lib.env.event.distributor.ConsumableEventDistributorControl;
    20  
    21  /**
    22   * {@code SimpleConsumableEventDistributorControl} acts as a listener source and
    23   * event distributor. It enables you to distribute and handle events in the safest
    24   * way possible.
    25   * 
    26   * <p>Note that unlike the {@link SimpleEventDistributorControl} class, this class
    27   * supports the consumption of events. An event is consumed if an event method on a
    28   * listener returns {@code true}. This means that the distribution of the event will
    29   * be stopped immediately. Otherwise the event will further be distributed.
    30   * 
    31   * <p>Example:
    32   * <code>
    33   *   // creates a distributor control with the expected listener type
    34   *   var distributorControl:SimpleConsumableEventDistributorControl = new SimpleConsumableEventDistributorControl(ErrorListener);
    35   *   // adds new listeners that must be of the expected type
    36   *   distributorControl.addListener(new MyErrorListener());
    37   *   distributorControl.addListener(new SimpleErrorListener());
    38   *   // gets a distributor to distribute the event to all listeners
    39   *   var distributor:ErrorListener = ErrorListener(distributorControl.getDistributor());
    40   *   // distributes the event with custom arguments
    41   *   distributor.onError(myErrorCode, myException);
    42   * </code>
    43   *
    44   * <p>If in the above example, the {@code MyErrorListener.onError} method returns
    45   * {@code true}, the {@code SimpleErrorListener.onError} method will not be invoked
    46   * because the event is consumed.
    47   * 
    48   * @author Simon Wacker
    49   * @authro Martin Heidegger
    50   */
    51  class org.as2lib.env.event.distributor.SimpleConsumableEventDistributorControl extends AbstractEventDistributorControl implements ConsumableEventDistributorControl {
    52  	
    53  	/**
    54  	 * Constructs a new {@code SimpleConsumableEventDistributorControl} instance.
    55  	 *
    56  	 * <p>{@code checkListenerType} is by default set to {@code true}.
    57  	 * 
    58  	 * @param listenerType the expected type of listeners
    59  	 * @param checkListenerType determines whether to check that passed-in listeners
    60  	 * are of the expected type
    61  	 * @param listeners (optional) the listeners to add
    62  	 * @throws IllegalArgumentException if the passed-in {@code listenerType} is
    63  	 * {@code null} or {@code undefined}
    64  	 */
    65  	public function SimpleConsumableEventDistributorControl(listenerType:Function, checkListenerType:Boolean, listeners:Array) {
    66  		super (listenerType, checkListenerType);
    67  		if (listeners) {
    68  			addAllListeners(listeners);
    69  		}
    70  	}
    71  	
    72  	/**
    73  	 * Executes the event with the given {@code eventName} on all added listeners, using
    74  	 * the arguments after {@code eventName} as parameters.
    75  	 *
    76  	 * <p>If {@code eventName} is {@code null} or {@code undefined} the distribution
    77  	 * will be omited.
    78  	 *
    79  	 * <p>The distribution will be stopped immediately if an event method of a listener
    80  	 * returns {@code true} and thus consumes the event.
    81  	 *
    82  	 * <p>If {@code args} is {@code null} or {@code undefined} nor parameters will be
    83  	 * passed to the listeners' event methods.
    84  	 * 
    85  	 * @param eventName the name of the event method to execute on the added listeners
    86  	 * @param args any number of arguments that are used as parameters on execution of
    87  	 * the event on the listeners
    88  	 * @throws EventExecutionException if an event method on a listener threw an
    89  	 * exception
    90  	 */
    91  	private function distribute(eventName:String, args:Array):Void {
    92  		if (eventName != null) {
    93  			if (this.l.length > 0) {
    94  				var h:Number = this.l.length;
    95  				var i:Number;
    96  				try {
    97  					for (i = 0; i < h; i++) {
    98  						// check "true" explicitely because only an object or something similar
    99  						// does not suffice, but would also result in "true" for the if-statement
   100  						if (this.l[i][eventName].apply(this.l[i], args) == true) {
   101  							return;
   102  						}
   103  					}
   104  				} catch (e) {
   105  					// "new EventExecutionException" without braces is not MTASC compatible because of the following method call to "initCause"
   106  					throw (new EventExecutionException("Unexpected exception was thrown during distribution of event [" + eventName + "] on listener [" + this.l[i] + "] with arguments [" + args + "].", this, arguments)).initCause(e);
   107  				}
   108  			}
   109  		}
   110  	}
   111  	
   112  }