<?php
/**
 * 短い説明文
 * 
 * 長い説明文
 * 
 * @package aowp.aspect.pointcut
 */
/**
 * Pointcut.class
 * 
 * @package aowp.aspect.pointcut
 */
abstract class AOWP_Pointcut {

	protected $_advice;
	private $_notFlag = false;
	
	public function __clone(){
        foreach ($this as $name => $value){ 
            if (gettype($value) == 'object'){ 
            	$this->$name = clone ($this->$name); 
            } 
        } 
	}
	
	public function setAdvice(AOWP_Advice $advice) {
		$this->_advice = $advice;
	}
	protected function _getAspectInstance() {
		return $this->_advice->getAspect();
	}
	
	/**
	 * ポイントカットが元々選択していたジョインポイントの集合の、補集合を選択するように定義します。
	 * このメソッドは、2回呼び出すと、元の状態に戻ります。
	 * Op*は、新たにオブジェクトを生成して返します。
	 * したがって、自身、引数、返り値はすべて違うオブジェクトになります。
	 * 
	 * @return mixed {@link AOWP_Pointcut}
	 */
	public function opNot() {
		$newPC = clone $this;
		$newPC->_notFlag = !$newPC->_notFlag;
		return $newPC;
	}
	public function isNot() {
		return $this->_notFlag;
	}
	
	public function opAnd(AOWP_Pointcut $pointcut) {
		$leftPC = clone $this;
		$rightPC = clone $pointcut;
		return new AOWP_PointcutComposition($leftPC, $rightPC, AOWP_PointcutComposition::AND_SIGN);
	}
	
	public function opOr(AOWP_Pointcut $pointcut) {
		$leftPC = clone $this;
		$rightPC = clone $pointcut;
		return new AOWP_PointcutComposition($leftPC, $rightPC, AOWP_PointcutComposition::OR_SIGN);
	}
	
	public function isJoinPointShadow(AOWP_JoinPoint $joinPoint) {
		if ($this->isNot() && !($this instanceof AOWP_StaticPointcut)) {
			return true;
		}
		else {
			return $this->_isJoinPointShadow($joinPoint) === !$this->isNot();
		}
	}
	abstract protected function _isJoinPointShadow(AOWP_JoinPoint $joinPoint);

	public function runtimeMatch(AOWP_JoinPoint $joinPoint) {
		return $this->_runtimeMatch($joinPoint) === !$this->isNot();
	}	
	abstract protected function _runtimeMatch(AOWP_JoinPoint $joinPoint);

	public function isHavePointcut(AOWP_Pointcut $pointcut) {
		return get_class($this) == get_class($pointcut);
	}
	
	/**
	 * ポイントカットのテキストパターンを表す引き数の評価に利用します。
	 * 現在は、{@link mb_ereg_match}を利用しています。
	 * 
	 * @param $pattern
	 * @param $targetText
	 * @return bool
	 */
	public static function patternMatch($pattern, $targetText) {
		return mb_ereg_match($pattern, $targetText);
	}
	
}
?>
