Exemplo n.º 1
0
 /**
  * Will create a PointcutPointcut instance referencing all concrete pointcuts configured for a certain advice.
  * Needs a list of these pointcuts
  *
  * @param array                                                  $pointcutNames List of names of referenced pointcuts
  * @param \AppserverIo\Doppelgaenger\Entities\Definitions\Aspect $aspect        The aspect to which the advice belongs
  *
  * @return \AppserverIo\Doppelgaenger\Entities\Pointcuts\PointcutPointcut
  */
 protected function generatePointcutPointcut(array $pointcutNames, Aspect $aspect)
 {
     // there might be several pointcuts
     // we have to look them up within the pointcuts we got here and the ones we already have in our register
     $pointcutFactory = new PointcutFactory();
     $referencedPointcuts = array();
     $pointcutExpression = array();
     foreach ($pointcutNames as $pointcutName) {
         $pointcutName = (string) $pointcutName;
         $referenceCount = count($referencedPointcuts);
         // check if we recently parsed the referenced pointcut
         if ($pointcut = $aspect->getPointcuts()->get($pointcutName)) {
             $referencedPointcuts[] = $pointcut;
         } else {
             // or did we already know of it?
             $referencedPointcuts = array_merge($referencedPointcuts, $this->getAspectRegister()->lookupPointcuts($pointcutName));
         }
         // build up the expression string for the PointcutPointcut instance
         if ($referenceCount < count($referencedPointcuts)) {
             $pointcutExpression[] = $pointcutName;
         }
     }
     /** @var \AppserverIo\Doppelgaenger\Entities\Pointcuts\PointcutPointcut $pointcutPointcut */
     $pointcutPointcut = $pointcutFactory->getInstance(PointcutPointcut::TYPE . '(' . implode(PointcutPointcut::EXPRESSION_CONNECTOR, $pointcutExpression) . ')');
     $pointcutPointcut->setReferencedPointcuts($referencedPointcuts);
     return $pointcutPointcut;
 }
Exemplo n.º 2
0
 /**
  * Will register a complete aspect to the AspectRegister.
  * This include its advices and pointcuts which can be looked up from this point on
  *
  * @param \AppserverIo\Doppelgaenger\Entities\Definitions\AspectDefinition $aspectDefinition Structure to register as an aspect
  *
  * @return null
  */
 public function register(AspectDefinition $aspectDefinition)
 {
     // create the new aspect and fill it with things we already know
     $aspect = new Aspect();
     $aspect->setName($aspectDefinition->getName());
     $aspect->setNamespace($aspectDefinition->getNamespace());
     // prepare the tokenizer we will need for further processing
     $needles = array(AfterReturning::ANNOTATION, AfterThrowing::ANNOTATION, After::ANNOTATION, Around::ANNOTATION, Before::ANNOTATION);
     $tokenizer = new Tokenizer();
     $tokenizer->ignore(array('param', 'return', 'throws'));
     // iterate the functions and filter out the ones used as advices
     $scheduledAdviceDefinitions = array();
     foreach ($aspectDefinition->getFunctionDefinitions() as $functionDefinition) {
         $foundNeedle = false;
         foreach ($needles as $needle) {
             // create the advice
             if (strpos($functionDefinition->getDocBlock(), '@' . $needle) !== false) {
                 $foundNeedle = true;
                 $scheduledAdviceDefinitions[$needle][] = $functionDefinition;
                 break;
             }
         }
         // create the pointcut
         if (!$foundNeedle && strpos($functionDefinition->getDocBlock(), '@' . Pointcut::ANNOTATION) !== false) {
             $pointcut = new PointcutDefinition();
             $pointcut->setName($functionDefinition->getName());
             $tokens = new Tokens($tokenizer->parse($functionDefinition->getDocBlock()));
             // convert to array and run it through our advice factory
             $toArray = new ToArray();
             $annotations = $toArray->convert($tokens);
             // create the entities for the join-points and advices the pointcut describes
             $pointcut->setPointcutExpression(new PointcutExpression(array_pop(array_pop($annotations)->values)));
             $aspect->getPointcuts()->add($pointcut);
         }
     }
     $this->add($aspect);
     // do the pointcut lookups where we will need the pointcut factory for later use
     $pointcutFactory = new PointcutFactory();
     foreach ($scheduledAdviceDefinitions as $codeHook => $hookedAdviceDefinitions) {
         foreach ($hookedAdviceDefinitions as $scheduledAdviceDefinition) {
             // create our advice
             $advice = new Advice();
             $advice->setAspectName($aspectDefinition->getQualifiedName());
             $advice->setName($scheduledAdviceDefinition->getName());
             $advice->setCodeHook((string) $codeHook);
             $tokens = new Tokens($tokenizer->parse($scheduledAdviceDefinition->getDocBlock()));
             // convert to array and run it through our advice factory
             $toArray = new ToArray();
             $annotations = $toArray->convert($tokens);
             // create the entities for the join-points and advices the pointcut describes
             foreach ($annotations as $annotation) {
                 $pointcut = $pointcutFactory->getInstance(array_pop($annotation->values));
                 if ($pointcut instanceof PointcutPointcut) {
                     // get the referenced pointcuts for the split parts of the expression
                     $expressionParts = explode(PointcutPointcut::EXPRESSION_CONNECTOR, $pointcut->getExpression());
                     // lookup all the referenced pointcuts
                     $referencedPointcuts = array();
                     foreach ($expressionParts as $expressionPart) {
                         $referencedPointcuts = array_merge($referencedPointcuts, $this->lookupPointcuts($expressionPart));
                     }
                     $pointcut->setReferencedPointcuts($referencedPointcuts);
                 }
                 $advice->getPointcuts()->add($pointcut);
             }
             $aspect->getAdvices()->add($advice);
         }
     }
     $this->set($aspectDefinition->getQualifiedName(), $aspect);
 }