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.aop.pointcut.CompositePointcut;
    18  import org.as2lib.aop.pointcut.AbstractCompositePointcut;
    19  import org.as2lib.aop.AopConfig;
    20  import org.as2lib.aop.Pointcut;
    21  import org.as2lib.aop.JoinPoint;
    22  
    23  /**
    24   * {@code AndPointcut} combines multiple pointcuts with a logical AND. This means that
    25   * this pointcut captures a given join point if all its contained pointcuts capture the
    26   * given join point.
    27   * 
    28   * <p>This pointcut expects a string representation as parameter on construction. Such
    29   * a string representation may look something like this:
    30   * <code>execution(org.as2lib.env.Logger.*) && execution(org.as2lib.reflect.*.*)</code>
    31   * 
    32   * @author Simon Wacker
    33   * @see <a href="http://www.simonwacker.com/blog/archives/000053.php">Wildcards</a>
    34   */
    35  class org.as2lib.aop.pointcut.AndPointcut extends AbstractCompositePointcut implements CompositePointcut {
    36  	
    37  	/**
    38  	 * Constructs a new {@code AndPointcut} instance.
    39  	 * 
    40  	 * <p>The string representation is supposed to be a combination of multiple
    41  	 * pointcuts where some of them are combined with the {@code &&} operator.
    42  	 * 
    43  	 * @param pointcut (optional) the string representation of this and pointcut
    44  	 */
    45  	public function AndPointcut(pointcut:String) {
    46  		if (pointcut != null && pointcut != "") {
    47  			// source this out
    48  			var pointcuts:Array = pointcut.split("&&");
    49  			for (var i:Number = 0; i < pointcuts.length; i++) {
    50  				addPointcut(AopConfig.getPointcutFactory().getPointcut(pointcuts[i]));
    51  			}
    52  		}
    53  	}
    54  	
    55  	/**
    56  	 * Checks whether this pointcut captures the given {@code joinPoint}. The
    57  	 * {@code joinPoint} is only captured if all sub-pointcuts of this pointcut capture
    58  	 * it.
    59  	 * 
    60  	 * {@code false} will be returned if:
    61  	 * <ul>
    62  	 *   <li>The passed-in {@code joinPoint} is {@code null} or {@code undefined}.</li>
    63  	 *   <li>Any of the sub-pointcuts' {@code captures} method returns {@code false}.</li>
    64  	 *   <li>There are no pointcuts added.</li>
    65  	 * </ul>
    66  	 *
    67  	 * @param joinPoint the join point to check whether it is captured by this pointcut
    68  	 * @return {@code true} if this pointcut captures the given {@code joinPoint} else
    69  	 * {@code false}
    70  	 */
    71  	public function captures(joinPoint:JoinPoint):Boolean {
    72  		if (!joinPoint) return false;
    73  		var i:Number = this.pointcuts.length;
    74  		if (i < 1) return false;
    75  		while (--i-(-1)) {
    76  			var pointcut:Pointcut = this.pointcuts[i];
    77  			if (!pointcut.captures(joinPoint)) {
    78  				return false;
    79  			}
    80  		}
    81  		return true;
    82  	}
    83  	
    84  }