1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Flying\Struct\Metadata; |
4
|
|
|
|
5
|
|
|
use Doctrine\Common\Annotations\AnnotationRegistry; |
6
|
|
|
use Doctrine\Common\Annotations\Reader; |
7
|
|
|
use Doctrine\Common\Annotations\SimpleAnnotationReader; |
8
|
|
|
use Flying\Struct\Annotation\Struct\Annotation; |
9
|
|
|
use Flying\Struct\Annotation\Struct\Property; |
10
|
|
|
use Flying\Struct\Annotation\Struct\Struct; |
11
|
|
|
use Flying\Struct\ConfigurationManager; |
12
|
|
|
use Flying\Struct\Exception; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Structures metadata parser implementation for parsing structure annotations |
16
|
|
|
*/ |
17
|
|
|
class AnnotationParser extends AbstractMetadataParser |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* Annotations reader |
21
|
|
|
* |
22
|
|
|
* @var Reader |
23
|
|
|
*/ |
24
|
|
|
private $reader; |
25
|
|
|
/** |
26
|
|
|
* Namespaces for annotations autoloading |
27
|
|
|
* |
28
|
|
|
* @var array |
29
|
|
|
*/ |
30
|
|
|
private $namespaces = []; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Load annotation class |
34
|
|
|
* |
35
|
|
|
* @param string $class |
36
|
|
|
* |
37
|
|
|
* @return boolean |
38
|
|
|
*/ |
39
|
145 |
|
public function loadClass($class) |
40
|
|
|
{ |
41
|
145 |
|
if (class_exists($class)) { |
42
|
1 |
|
return true; |
43
|
|
|
} |
44
|
145 |
|
$class = ucfirst(trim($class, '\\')); |
45
|
145 |
|
foreach ($this->namespaces as $ns) { |
46
|
145 |
|
$fqcn = $ns . '\\' . $class; |
47
|
145 |
|
if (class_exists($fqcn)) { |
48
|
|
|
return true; |
49
|
|
|
} |
50
|
145 |
|
} |
51
|
145 |
|
return false; |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* {@inheritdoc} |
56
|
|
|
* @throws \Flying\Struct\Exception |
57
|
|
|
* @throws \InvalidArgumentException |
58
|
|
|
*/ |
59
|
182 |
|
protected function parseMetadata(\ReflectionClass $reflection, StructMetadata $metadata) |
60
|
|
|
{ |
61
|
182 |
|
$reader = $this->getReader(); |
62
|
182 |
|
$annotations = $reader->getClassAnnotations($reflection); |
63
|
182 |
|
foreach ($annotations as $annotation) { |
64
|
181 |
|
$metadata->addProperty($this->convertToMetadata($annotation)); |
65
|
182 |
|
} |
66
|
181 |
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Get annotations reader |
70
|
|
|
* |
71
|
|
|
* @return Reader |
72
|
|
|
* @throws \InvalidArgumentException |
73
|
|
|
*/ |
74
|
182 |
|
public function getReader() |
75
|
|
|
{ |
76
|
182 |
|
if (!$this->reader) { |
77
|
182 |
|
$this->reader = new SimpleAnnotationReader(); |
78
|
182 |
|
$namespaces = ConfigurationManager::getConfiguration()->getAnnotationNamespacesMap()->getAll(); |
79
|
182 |
|
foreach ($namespaces as $ns) { |
80
|
182 |
|
$this->reader->addNamespace($ns); |
81
|
182 |
|
} |
82
|
182 |
|
$this->namespaces = array_reverse($namespaces, true); |
83
|
182 |
|
AnnotationRegistry::registerLoader([$this, 'loadClass']); |
|
|
|
|
84
|
182 |
|
} |
85
|
182 |
|
return $this->reader; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* Set annotations reader to use for parsing structure annotations |
90
|
|
|
* |
91
|
|
|
* @param Reader $reader |
92
|
|
|
* |
93
|
|
|
* @return $this |
94
|
|
|
*/ |
95
|
1 |
|
public function setReader(Reader $reader) |
96
|
|
|
{ |
97
|
1 |
|
$this->reader = $reader; |
98
|
1 |
|
return $this; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Convert given structure annotation into structure metadata |
103
|
|
|
* |
104
|
|
|
* @param Annotation $annotation Structure annotation to convert |
105
|
|
|
* |
106
|
|
|
* @return PropertyMetadata |
107
|
|
|
* @throws \InvalidArgumentException |
108
|
|
|
* @throws Exception |
109
|
|
|
*/ |
110
|
181 |
|
protected function convertToMetadata(Annotation $annotation) |
111
|
|
|
{ |
112
|
181 |
|
if ($annotation instanceof Property) { |
113
|
179 |
|
$class = $this->resolvePropertyClass($annotation->getType()); |
114
|
179 |
|
if (!$class) { |
|
|
|
|
115
|
1 |
|
throw new Exception('Unable to resolve structure property class for type: ' . $annotation->getType()); |
116
|
|
|
} |
117
|
178 |
|
$property = new PropertyMetadata($annotation->getName(), $class, $annotation->getConfig()); |
118
|
178 |
|
return $property; |
119
|
|
|
} |
120
|
|
|
|
121
|
67 |
|
if (!($annotation instanceof Struct)) { |
122
|
|
|
throw new Exception('Unknown structure annotation type'); |
123
|
|
|
} |
124
|
|
|
|
125
|
67 |
|
if ($annotation->getClass()) { |
126
|
67 |
|
$class = $this->resolveStructClass($annotation->getClass()); |
127
|
67 |
|
if (!$class) { |
|
|
|
|
128
|
2 |
|
throw new Exception('Unable to resolve structure class: ' . $annotation->getClass()); |
129
|
|
|
} |
130
|
65 |
|
$struct = ConfigurationManager::getConfiguration()->getMetadataManager()->getMetadata($class); |
131
|
65 |
|
if (!$struct instanceof StructMetadata) { |
132
|
1 |
|
throw new Exception('Failed to get structure metadata for class: ' . $class); |
133
|
|
|
} |
134
|
64 |
|
$struct->setName($annotation->getName()); |
135
|
64 |
|
$struct->setConfig($annotation->getConfig()); |
136
|
64 |
|
} else { |
137
|
15 |
|
if (!count($annotation->getProperties())) { |
138
|
|
|
throw new Exception('Structure metadata should have either class name or explicitly defined list of structure properties'); |
139
|
|
|
} |
140
|
15 |
|
$struct = new StructMetadata($annotation->getName(), null, $annotation->getConfig()); |
141
|
15 |
|
foreach ($annotation->getProperties() as $p) { |
142
|
15 |
|
$struct->addProperty($this->convertToMetadata($p)); |
143
|
15 |
|
} |
144
|
|
|
} |
145
|
64 |
|
return $struct; |
146
|
|
|
} |
147
|
|
|
} |
148
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.