Schema::findElement()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 4
cts 5
cp 0.8
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 2
crap 2.032
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GoetasWebservices\XML\XSDReader\Schema;
6
7
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeDef;
8
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeItem;
9
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Group as AttributeGroup;
10
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementDef;
11
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementItem;
12
use GoetasWebservices\XML\XSDReader\Schema\Element\Group;
13
use GoetasWebservices\XML\XSDReader\Schema\Exception\SchemaException;
14
use GoetasWebservices\XML\XSDReader\Schema\Exception\TypeNotFoundException;
15
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
16
17
class Schema
18
{
19
    /**
20
     * @param bool[] $calling
21
     */
22 58
    protected function findSomethingNoThrow(
23
        string $getter,
24
        string $name,
25
        string $namespace = null,
26
        array &$calling = array()
27
    ): ? SchemaItem {
28 58
        $calling[spl_object_hash($this)] = true;
29 58
        $cid = "$getter, $name, $namespace";
30
31 58
        if (isset($this->typeCache[$cid])) {
32 58
            return $this->typeCache[$cid];
33
        } elseif (
34 58
            $this->getTargetNamespace() === $namespace
35
        ) {
36
            /**
37
             * @var SchemaItem|null
38
             */
39 58
            $item = $this->$getter($name);
40
41 58
            if ($item instanceof SchemaItem) {
42 58
                return $this->typeCache[$cid] = $item;
43
            }
44
        }
45
46 58
        return $this->findSomethingNoThrowSchemas(
47 58
            $this->getSchemas(),
48 58
            $cid,
49 58
            $getter,
50 58
            $name,
51 58
            $namespace,
52 58
            $calling
53
        );
54
    }
55
56
    /**
57
     * @param Schema[] $schemas
58
     * @param bool[]   $calling
59
     */
60 58
    protected function findSomethingNoThrowSchemas(
61
        array $schemas,
62
        string $cid,
63
        string $getter,
64
        string $name,
65
        string $namespace = null,
66
        array &$calling = array()
67
    ): ? SchemaItem {
68 58
        foreach ($schemas as $childSchema) {
69 58
            if (!isset($calling[spl_object_hash($childSchema)])) {
70
                /**
71
                 * @var SchemaItem|null
72
                 */
73 58
                $in = $childSchema->findSomethingNoThrow($getter, $name, $namespace, $calling);
74
75 58
                if ($in instanceof SchemaItem) {
76 58
                    return $this->typeCache[$cid] = $in;
77
                }
78
            }
79
        }
80
81 9
        return null;
82
    }
83
84
    /**
85
     * @throws TypeNotFoundException
86
     */
87 58
    protected function findSomething(string $getter, string $name, string $namespace = null, array &$calling = array()): SchemaItem
88
    {
89 58
        $in = $this->findSomethingNoThrow(
90 58
            $getter,
91 58
            $name,
92 58
            $namespace,
93 58
            $calling
94
        );
95
96 58
        if ($in instanceof SchemaItem) {
97 58
            return $in;
98
        }
99
100 5
        throw new TypeNotFoundException(
101 5
            sprintf(
102 5
                "Can't find the %s named {%s}#%s.",
103 5
                (string) substr($getter, 3),
104 5
                $namespace,
105 5
                $name
106
            )
107
        );
108
    }
109
110
    /**
111
     * @var bool
112
     */
113
    protected $elementsQualification = false;
114
115
    /**
116
     * @var bool
117
     */
118
    protected $attributesQualification = false;
119
120
    /**
121
     * @var string|null
122
     */
123
    protected $targetNamespace;
124
125
    /**
126
     * @var Schema[]
127
     */
128
    protected $schemas = array();
129
130
    /**
131
     * @var Type[]
132
     */
133
    protected $types = array();
134
135
    /**
136
     * @var ElementDef[]
137
     */
138
    protected $elements = array();
139
140
    /**
141
     * @var Group[]
142
     */
143
    protected $groups = array();
144
145
    /**
146
     * @var AttributeGroup[]
147
     */
148
    protected $attributeGroups = array();
149
150
    /**
151
     * @var AttributeDef[]
152
     */
153
    protected $attributes = array();
154
155
    /**
156
     * @var string|null
157
     */
158
    protected $doc;
159
160
    /**
161
     * @var \GoetasWebservices\XML\XSDReader\Schema\SchemaItem[]
162
     */
163
    protected $typeCache = array();
164
165
    public function getElementsQualification(): bool
166
    {
167
        return $this->elementsQualification;
168
    }
169
170 58
    public function setElementsQualification(bool $elementsQualification): void
171
    {
172 58
        $this->elementsQualification = $elementsQualification;
173 58
    }
174
175
    public function getAttributesQualification(): bool
176
    {
177
        return $this->attributesQualification;
178
    }
179
180 58
    public function setAttributesQualification(bool $attributesQualification): void
181
    {
182 58
        $this->attributesQualification = $attributesQualification;
183 58
    }
184
185 58
    public function getTargetNamespace(): ?string
186
    {
187 58
        return $this->targetNamespace;
188
    }
189
190 58
    public function setTargetNamespace(? string $targetNamespace): void
191
    {
192 58
        $this->targetNamespace = $targetNamespace;
193 58
    }
194
195
    /**
196
     * @return Type[]
197
     */
198 5
    public function getTypes(): array
199
    {
200 5
        return $this->types;
201
    }
202
203
    /**
204
     * @return ElementDef[]
205
     */
206 3
    public function getElements(): array
207
    {
208 3
        return $this->elements;
209
    }
210
211
    /**
212
     * @return Schema[]
213
     */
214 58
    public function getSchemas(): array
215
    {
216 58
        return $this->schemas;
217
    }
218
219
    /**
220
     * @return AttributeDef[]
221
     */
222 1
    public function getAttributes(): array
223
    {
224 1
        return $this->attributes;
225
    }
226
227
    /**
228
     * @return Group[]
229
     */
230 2
    public function getGroups(): array
231
    {
232 2
        return $this->groups;
233
    }
234
235
    public function getDoc(): ?string
236
    {
237
        return $this->doc;
238
    }
239
240 58
    public function setDoc(string $doc): void
241
    {
242 58
        $this->doc = $doc;
243 58
    }
244
245 58
    public function addType(Type $type): void
246
    {
247 58
        $this->types[(string) $type->getName()] = $type;
248 58
    }
249
250 58
    public function addElement(ElementDef $element): void
251
    {
252 58
        $this->elements[$element->getName()] = $element;
253 58
    }
254
255 58
    public function addSchema(self $schema, string $namespace = null): void
256
    {
257 58
        if ($namespace !== null) {
258 58
            if ($schema->getTargetNamespace() !== $namespace) {
259
                throw new SchemaException(
260
                    sprintf(
261
                        "The target namespace ('%s') for schema, does not match the declared namespace '%s'",
262
                        $schema->getTargetNamespace(),
263
                        $namespace
264
                    )
265
                );
266
            }
267 58
            $this->schemas[$namespace] = $schema;
268
        } else {
269 58
            $this->schemas[] = $schema;
270
        }
271 58
    }
272
273 58
    public function addAttribute(AttributeDef $attribute): void
274
    {
275 58
        $this->attributes[$attribute->getName()] = $attribute;
276 58
    }
277
278 58
    public function addGroup(Group $group): void
279
    {
280 58
        $this->groups[$group->getName()] = $group;
281 58
    }
282
283 58
    public function addAttributeGroup(AttributeGroup $group): void
284
    {
285 58
        $this->attributeGroups[$group->getName()] = $group;
286 58
    }
287
288
    /**
289
     * @return AttributeGroup[]
290
     */
291 1
    public function getAttributeGroups(): array
292
    {
293 1
        return $this->attributeGroups;
294
    }
295
296 58
    public function getGroup(string $name): ?Group
297
    {
298 58
        if (isset($this->groups[$name])) {
299 58
            return $this->groups[$name];
300
        }
301
302
        return null;
303
    }
304
305 58
    public function getElement(string $name): ?ElementItem
306
    {
307 58
        if (isset($this->elements[$name])) {
308 58
            return $this->elements[$name];
309
        }
310
311
        return null;
312
    }
313
314 58
    public function getType(string $name): ?Type
315
    {
316 58
        if (isset($this->types[$name])) {
317 58
            return $this->types[$name];
318
        }
319
320
        return null;
321
    }
322
323 58
    public function getAttribute(string $name): ? AttributeItem
324
    {
325 58
        if (isset($this->attributes[$name])) {
326 58
            return $this->attributes[$name];
327
        }
328
329
        return null;
330
    }
331
332 58
    public function getAttributeGroup(string $name): ?AttributeGroup
333
    {
334 58
        if (isset($this->attributeGroups[$name])) {
335 58
            return $this->attributeGroups[$name];
336
        }
337
338
        return null;
339
    }
340
341
    public function __toString(): string
342
    {
343
        return sprintf('Target namespace %s', $this->getTargetNamespace());
344
    }
345
346 58
    public function findType(string $name, string $namespace = null): Type
347
    {
348 58
        $out = $this->findSomething('getType', $name, $namespace);
349
350 58
        if (!($out instanceof Type)) {
351
            throw new TypeNotFoundException(sprintf("Can't find the %s named {%s}#%s.", 'Type', $namespace, $name));
352
        }
353
354 58
        return $out;
355
    }
356
357 58
    public function findGroup(string $name, string $namespace = null): Group
358
    {
359 58
        $out = $this->findSomething('getGroup', $name, $namespace);
360
361 58
        if (!($out instanceof Group)) {
362
            throw new TypeNotFoundException(sprintf("Can't find the %s named {%s}#%s.", 'Group', $namespace, $name));
363
        }
364
365 58
        return $out;
366
    }
367
368 58
    public function findElement(string $name, string $namespace = null): ElementDef
369
    {
370 58
        $out = $this->findSomething('getElement', $name, $namespace);
371
372 58
        if (!($out instanceof ElementDef)) {
373
            throw new TypeNotFoundException(sprintf("Can't find the %s named {%s}#%s.", 'Element', $namespace, $name));
374
        }
375
376 58
        return $out;
377
    }
378
379 58
    public function findAttribute(string $name, string $namespace = null): AttributeItem
380
    {
381 58
        $out = $this->findSomething('getAttribute', $name, $namespace);
382
383 58
        if (!($out instanceof AttributeItem)) {
384
            throw new TypeNotFoundException(sprintf("Can't find the %s named {%s}#%s.", 'Attribute', $namespace, $name));
385
        }
386
387 58
        return $out;
388
    }
389
390 58
    public function findAttributeGroup(string $name, string $namespace = null): AttributeGroup
391
    {
392 58
        $out = $this->findSomething('getAttributeGroup', $name, $namespace);
393
394 58
        if (!($out instanceof AttributeGroup)) {
395
            throw new TypeNotFoundException(sprintf("Can't find the %s named {%s}#%s.", 'AttributeGroup', $namespace, $name));
396
        }
397
398 58
        return $out;
399
    }
400
}
401