Completed
Push — php-7.1 ( 657786...020623 )
by SignpostMarv
11:22 queued 02:43
created

Schema::setSchemaThingsFromNode()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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