/**
  * Adds the needed valiators to the Arguments:
  * - Validators checking the data type from the @param annotation
  * - Custom validators specified with @validate.
  *
  * In case @dontvalidate is NOT set for an argument, the following two
  * validators are also added:
  * - Model-based validators (@validate annotations in the model)
  * - Custom model validator classes
  *
  * @return void
  * @author Sebastian Kurfürst <*****@*****.**>
  */
 protected function initializeActionMethodValidators()
 {
     $parameterValidators = $this->validatorResolver->buildMethodArgumentsValidatorConjunctions(get_class($this), $this->actionMethodName);
     $dontValidateAnnotations = array();
     $methodTagsValues = $this->reflectionService->getMethodTagsValues(get_class($this), $this->actionMethodName);
     if (isset($methodTagsValues['dontvalidate'])) {
         $dontValidateAnnotations = $methodTagsValues['dontvalidate'];
     }
     foreach ($this->arguments as $argument) {
         $validator = $parameterValidators[$argument->getName()];
         if (array_search('$' . $argument->getName(), $dontValidateAnnotations) === FALSE) {
             $baseValidatorConjunction = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType());
             if ($baseValidatorConjunction !== NULL) {
                 $validator->addValidator($baseValidatorConjunction);
             }
         }
         $argument->setValidator($validator);
     }
 }
 /**
  * Detects and registers any validators for arguments:
  * - by the data type specified in the @param annotations
  * - additional validators specified in the @validate annotations of a method
  *
  * @param string $className
  * @param string $methodName
  * @return array An Array of ValidatorConjunctions for each method parameters.
  * @author Robert Lemke <*****@*****.**>
  * @author Sebastian Kurfürst <*****@*****.**>
  */
 public function buildMethodArgumentsValidatorConjunctions($className, $methodName)
 {
     $validatorConjunctions = array();
     $methodParameters = $this->reflectionService->getMethodParameters($className, $methodName);
     if (!count($methodParameters)) {
         // early return in case no parameters were found.
         return $validatorConjunctions;
     }
     foreach ($methodParameters as $parameterName => $methodParameter) {
         $validatorConjunction = $this->createValidator('F3\\FLOW3\\Validation\\Validator\\ConjunctionValidator');
         if (strpos($methodParameter['type'], '\\') === FALSE) {
             $typeValidator = $this->createValidator($methodParameter['type']);
         } elseif (strpos($methodParameter['type'], '\\Model\\') !== FALSE) {
             $possibleValidatorClassName = str_replace('\\Model\\', '\\Validator\\', $methodParameter['type']) . 'Validator';
             $typeValidator = $this->createValidator($possibleValidatorClassName);
         } else {
             $typeValidator = NULL;
         }
         if ($typeValidator !== NULL) {
             $validatorConjunction->addValidator($typeValidator);
         }
         $validatorConjunctions[$parameterName] = $validatorConjunction;
     }
     $methodTagsValues = $this->reflectionService->getMethodTagsValues($className, $methodName);
     if (isset($methodTagsValues['validate'])) {
         foreach ($methodTagsValues['validate'] as $validateValue) {
             $parsedAnnotation = $this->parseValidatorAnnotation($validateValue);
             foreach ($parsedAnnotation['validators'] as $validatorConfiguration) {
                 $newValidator = $this->createValidator($validatorConfiguration['validatorName'], $validatorConfiguration['validatorOptions']);
                 if ($newValidator === NULL) {
                     throw new \F3\FLOW3\Validation\Exception\NoSuchValidatorException('Invalid validate annotation in ' . $className . '->' . $methodName . '(): Could not resolve class name for  validator "' . $validatorConfiguration['validatorName'] . '".', 1239853109);
                 }
                 if (isset($validatorConjunctions[$parsedAnnotation['argumentName']])) {
                     $validatorConjunctions[$parsedAnnotation['argumentName']]->addValidator($newValidator);
                 } else {
                     throw new \F3\FLOW3\Validation\Exception\InvalidValidationConfigurationException('Invalid validate annotation in ' . $className . '->' . $methodName . '(): Validator specified for argument name "' . $parsedAnnotation['argumentName'] . '", but this argument does not exist.', 1253172726);
                 }
             }
         }
     }
     return $validatorConjunctions;
 }
 /**
  * Creates and returns an aspect from the annotations found in a class which
  * is tagged as an aspect. The object acting as an advice will already be
  * fetched (and therefore instantiated if neccessary).
  *
  * @param  string $aspectClassName Name of the class which forms the aspect, contains advices etc.
  * @return mixed The aspect container containing one or more advisors or FALSE if no container could be built
  * @author Robert Lemke <*****@*****.**>
  */
 protected function buildAspectContainer($aspectClassName)
 {
     if (!$this->reflectionService->isClassReflected($aspectClassName)) {
         return FALSE;
     }
     if (!$this->reflectionService->isClassTaggedWith($aspectClassName, 'aspect')) {
         return FALSE;
     }
     $aspectContainer = new \F3\FLOW3\AOP\AspectContainer($aspectClassName);
     foreach ($this->reflectionService->getClassMethodNames($aspectClassName) as $methodName) {
         foreach ($this->reflectionService->getMethodTagsValues($aspectClassName, $methodName) as $tagName => $tagValues) {
             foreach ($tagValues as $tagValue) {
                 switch ($tagName) {
                     case 'around':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\AroundAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'before':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\BeforeAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'afterreturning':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\AfterReturningAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'afterthrowing':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\AfterThrowingAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'after':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $advice = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advice\\AfterAdvice', $aspectClassName, $methodName);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName);
                         $advisor = $this->objectFactory->create('F3\\FLOW3\\AOP\\Advisor', $advice, $pointcut);
                         $aspectContainer->addAdvisor($advisor);
                         break;
                     case 'pointcut':
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($tagValue);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $tagValue, $pointcutFilterComposite, $aspectClassName, $methodName);
                         $aspectContainer->addPointcut($pointcut);
                         break;
                 }
             }
         }
     }
     foreach ($this->reflectionService->getClassPropertyNames($aspectClassName) as $propertyName) {
         foreach ($this->reflectionService->getPropertyTagsValues($aspectClassName, $propertyName) as $tagName => $tagValues) {
             foreach ($tagValues as $tagValue) {
                 switch ($tagName) {
                     case 'introduce':
                         $splittedTagValue = explode(',', $tagValue);
                         if (!is_array($splittedTagValue) || count($splittedTagValue) != 2) {
                             throw new \F3\FLOW3\AOP\Exception('The introduction in class "' . $aspectClassName . '" does not contain the two required parameters.', 1172694761);
                         }
                         $pointcutExpression = trim($splittedTagValue[1]);
                         $pointcutFilterComposite = $this->pointcutExpressionParser->parse($pointcutExpression);
                         $pointcut = $this->objectFactory->create('F3\\FLOW3\\AOP\\Pointcut\\Pointcut', $pointcutExpression, $pointcutFilterComposite, $aspectClassName);
                         $interfaceName = trim($splittedTagValue[0]);
                         $introduction = $this->objectFactory->create('F3\\FLOW3\\AOP\\Introduction', $aspectClassName, $interfaceName, $pointcut);
                         $aspectContainer->addIntroduction($introduction);
                         break;
                 }
             }
         }
     }
     if (count($aspectContainer->getAdvisors()) < 1 && count($aspectContainer->getPointcuts()) < 1 && count($aspectContainer->getIntroductions()) < 1) {
         throw new \F3\FLOW3\AOP\Exception('The class "' . $aspectClassName . '" is tagged to be an aspect but doesn\'t contain advices nor pointcut or introduction declarations.', 1169124534);
     }
     return $aspectContainer;
 }