validateAnnotations()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 8
cts 8
cp 1
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 2
crap 3
1
<?php
2
3
/*
4
 * Copyright (c) 2011-2015, Celestino Diaz <[email protected]>
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
25
namespace Brickoo\Component\Annotation;
26
27
use ArrayIterator;
28
use Brickoo\Component\Annotation\Definition\AnnotationDefinitionTargetFilter;
29
use Brickoo\Component\Annotation\Exception\MissingRequiredAnnotationException;
30
use Brickoo\Component\Annotation\Exception\MissingRequiredAnnotationParametersException;
31
use Brickoo\Component\Common\Collection;
32
use Traversable;
33
34
/**
35
 * AnnotationReaderResultValidator
36
 *
37
 * Implements a reader result validator.
38
 * @author Celestino Diaz <[email protected]>
39
 */
40
class AnnotationReaderResultValidator {
41
42
    /**
43
     * Validates a reader result against the provided definition.
44
     * @param \Brickoo\Component\Common\Collection $collection
45
     * @param \Brickoo\Component\Annotation\AnnotationReaderResult $readerResult
46
     * @throws \Brickoo\Component\Annotation\Exception\MissingRequiredAnnotationException
47
     * @throws \Brickoo\Component\Annotation\Exception\MissingRequiredAnnotationParametersException
48
     * @return void
49
     */
50 3
    public function validate(Collection $collection, AnnotationReaderResult $readerResult) {
51 3
        $targets = [Annotation::TARGET_CLASS, Annotation::TARGET_METHOD, Annotation::TARGET_PROPERTY];
52
53 3
        $annotationFilter = new AnnotationDefinitionTargetFilter($collection);
54 3
        foreach ($targets as $annotationTarget) {
55 3
            $this->validateAnnotations(
56 3
                $annotationFilter->filter($annotationTarget),
57 3
                $readerResult->getAnnotationsByTarget($annotationTarget)
58 3
            );
59 3
        }
60 1
    }
61
62
    /**
63
     * Validates the annotations definitions against the result.
64
     * @param Traversable $definitions
65
     * @param Traversable $results
66
     * @return void
67
     */
68 3
    private function validateAnnotations(Traversable $definitions, Traversable $results) {
69 3
        if (($requiredAnnotationsParameters = $this->getRequiredAnnotationsParameters($definitions))) {
70 3
            $annotationsValues = $this->getAnnotationsValues($results);
71
72 3
            foreach ($requiredAnnotationsParameters as $requiredAnnotation => $requiredParameters) {
73 3
                $this->checkAnnotationRequirements($requiredAnnotation, $requiredParameters, $annotationsValues);
74 3
            }
75 3
        }
76 3
    }
77
78
    /**
79
     * Returns the required annotations and their parameters.
80
     * @param Traversable $definitions
81
     * @return array required annotations definitions
82
     */
83 3
    private function getRequiredAnnotationsParameters(Traversable $definitions) {
84 3
        $requiredAnnotations = [];
85 3
        foreach ($definitions as $annotationDefinition) {
86 3
            if ($annotationDefinition->isRequired() || $annotationDefinition->hasRequiredParameters()) {
87 3
                $requiredAnnotations[$annotationDefinition->getName()] = $annotationDefinition->getRequiredParameters();
88 3
            }
89 3
        }
90 3
        return $requiredAnnotations;
91
    }
92
93
    /**
94
     * Returns the available result annotations and their values.
95
     * @param Traversable $annotationsIterator
96
     * @return array annotation values
97
     */
98 3
    private function getAnnotationsValues(Traversable $annotationsIterator) {
99 3
        $annotations = [];
100 3
        foreach ($annotationsIterator as $annotation) {
101 3
            $annotations[$annotation->getName()] = $annotation->getValues();
102 3
        }
103 3
        return $annotations;
104
    }
105
106
    /**
107
     * Checks if the read annotations matches the definition requirements.
108
     * @param string $requiredAnnotation
109
     * @param array $requiredParameters
110
     * @param array $annotationsRead
111
     * @throws \Brickoo\Component\Annotation\Exception\MissingRequiredAnnotationException
112
     * @throws \Brickoo\Component\Annotation\Exception\MissingRequiredAnnotationParametersException
113
     * @return void
114
     */
115 3
    private function checkAnnotationRequirements($requiredAnnotation, array $requiredParameters, array $annotationsRead) {
116 3
        if (!$this->hasRequiredAnnotation($requiredAnnotation, $annotationsRead)) {
117 1
            throw new MissingRequiredAnnotationException($requiredAnnotation);
118
        }
119 3
        if (($missingParameters = $this->getMissingParameters($requiredParameters, $annotationsRead[$requiredAnnotation]))) {
120 1
            throw new MissingRequiredAnnotationParametersException($requiredAnnotation, $missingParameters);
121
        }
122 3
    }
123
124
    /**
125
     * Checks if the required annotation is available in the result.
126
     * @param string $annotationName
127
     * @param array $readAnnotations
128
     * @return boolean check result
129
     */
130 3
    private function hasRequiredAnnotation($annotationName, array $readAnnotations) {
131 3
        return isset($readAnnotations[$annotationName]);
132
    }
133
134
    /**
135
     * Returns the missing required parameters if any.
136
     * @param array $requiredParameters
137
     * @param array $readParameters
138
     * @return array the missing parameters
139
     */
140 2
    private function getMissingParameters(array $requiredParameters, array $readParameters) {
141 2
        $missingParameters = [];
142 2
        foreach ($requiredParameters as $parameter) {
143 2
            if (!isset($readParameters[$parameter->getName()])) {
144 1
                $missingParameters[] = $parameter->getName();
145 1
            }
146 2
        }
147 2
        return $missingParameters;
148
    }
149
150
}
151