/** * 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 necessary). * * @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 * @throws \TYPO3\FLOW3\Aop\Exception */ protected function buildAspectContainer($aspectClassName) { $aspectContainer = new \TYPO3\FLOW3\Aop\AspectContainer($aspectClassName); $methodNames = get_class_methods($aspectClassName); foreach ($methodNames as $methodName) { foreach ($this->reflectionService->getMethodAnnotations($aspectClassName, $methodName) as $annotation) { $annotationClass = get_class($annotation); switch ($annotationClass) { case 'TYPO3\\FLOW3\\Annotations\\Around': $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass)); $advice = new \TYPO3\FLOW3\Aop\Advice\AroundAdvice($aspectClassName, $methodName); $pointcut = new \TYPO3\FLOW3\Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName); $advisor = new \TYPO3\FLOW3\Aop\Advisor($advice, $pointcut); $aspectContainer->addAdvisor($advisor); break; case 'TYPO3\\FLOW3\\Annotations\\Before': $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass)); $advice = new \TYPO3\FLOW3\Aop\Advice\BeforeAdvice($aspectClassName, $methodName); $pointcut = new \TYPO3\FLOW3\Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName); $advisor = new \TYPO3\FLOW3\Aop\Advisor($advice, $pointcut); $aspectContainer->addAdvisor($advisor); break; case 'TYPO3\\FLOW3\\Annotations\\AfterReturning': $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass)); $advice = new \TYPO3\FLOW3\Aop\Advice\AfterReturningAdvice($aspectClassName, $methodName); $pointcut = new \TYPO3\FLOW3\Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName); $advisor = new \TYPO3\FLOW3\Aop\Advisor($advice, $pointcut); $aspectContainer->addAdvisor($advisor); break; case 'TYPO3\\FLOW3\\Annotations\\AfterThrowing': $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass)); $advice = new \TYPO3\FLOW3\Aop\Advice\AfterThrowingAdvice($aspectClassName, $methodName); $pointcut = new \TYPO3\FLOW3\Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName); $advisor = new \TYPO3\FLOW3\Aop\Advisor($advice, $pointcut); $aspectContainer->addAdvisor($advisor); break; case 'TYPO3\\FLOW3\\Annotations\\After': $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass)); $advice = new \TYPO3\FLOW3\Aop\Advice\AfterAdvice($aspectClassName, $methodName); $pointcut = new \TYPO3\FLOW3\Aop\Pointcut\Pointcut($annotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName); $advisor = new \TYPO3\FLOW3\Aop\Advisor($advice, $pointcut); $aspectContainer->addAdvisor($advisor); break; case 'TYPO3\\FLOW3\\Annotations\\Pointcut': $pointcutFilterComposite = $this->pointcutExpressionParser->parse($annotation->expression, $this->renderSourceHint($aspectClassName, $methodName, $annotationClass)); $pointcut = new \TYPO3\FLOW3\Aop\Pointcut\Pointcut($annotation->expression, $pointcutFilterComposite, $aspectClassName, $methodName); $aspectContainer->addPointcut($pointcut); break; } } } $introduceAnnotation = $this->reflectionService->getClassAnnotation($aspectClassName, 'TYPO3\\FLOW3\\Annotations\\Introduce'); if ($introduceAnnotation !== NULL) { if ($introduceAnnotation->interfaceName === NULL) { throw new \TYPO3\FLOW3\Aop\Exception('The interface introduction in class "' . $aspectClassName . '" does not contain the required interface name).', 1172694761); } $pointcutFilterComposite = $this->pointcutExpressionParser->parse($introduceAnnotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $methodName, 'TYPO3\\FLOW3\\Annotations\\Introduce')); $pointcut = new \TYPO3\FLOW3\Aop\Pointcut\Pointcut($introduceAnnotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName); $introduction = new \TYPO3\FLOW3\Aop\InterfaceIntroduction($aspectClassName, $introduceAnnotation->interfaceName, $pointcut); $aspectContainer->addInterfaceIntroduction($introduction); } foreach ($this->reflectionService->getClassPropertyNames($aspectClassName) as $propertyName) { $introduceAnnotation = $this->reflectionService->getPropertyAnnotation($aspectClassName, $propertyName, 'TYPO3\\FLOW3\\Annotations\\Introduce'); if ($introduceAnnotation !== NULL) { $pointcutFilterComposite = $this->pointcutExpressionParser->parse($introduceAnnotation->pointcutExpression, $this->renderSourceHint($aspectClassName, $propertyName, 'TYPO3\\FLOW3\\Annotations\\Introduce')); $pointcut = new \TYPO3\FLOW3\Aop\Pointcut\Pointcut($introduceAnnotation->pointcutExpression, $pointcutFilterComposite, $aspectClassName); $introduction = new \TYPO3\FLOW3\Aop\PropertyIntroduction($aspectClassName, $propertyName, $pointcut); $aspectContainer->addPropertyIntroduction($introduction); } } if (count($aspectContainer->getAdvisors()) < 1 && count($aspectContainer->getPointcuts()) < 1 && count($aspectContainer->getInterfaceIntroductions()) < 1) { throw new \TYPO3\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; }