Passed
Push — static-analysis ( 935891...314368 )
by SignpostMarv
02:22
created

AbstractSchema::addAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace GoetasWebservices\XML\XSDReader\Schema;
4
5
use Closure;
6
use DOMElement;
7
use RuntimeException;
8
use GoetasWebservices\XML\XSDReader\AbstractSchemaReader;
9
use GoetasWebservices\XML\XSDReader\SchemaReaderLoadAbstraction;
10
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
11
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Group as AttributeGroup;
12
use GoetasWebservices\XML\XSDReader\Schema\Element\Group;
13
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementDef;
14
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementItem;
15
use GoetasWebservices\XML\XSDReader\Schema\Exception\TypeNotFoundException;
16
use GoetasWebservices\XML\XSDReader\Schema\Exception\SchemaException;
17
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeItem;
18
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeDef;
19
use GoetasWebservices\XML\XSDReader\Utils\UrlUtils;
20
21
abstract class AbstractSchema
22
{
23
    /**
24
     * @var bool
25
     */
26
    protected $elementsQualification = false;
27
28
    /**
29
     * @var bool
30
     */
31
    protected $attributesQualification = false;
32
33
    /**
34
     * @var string|null
35
     */
36
    protected $targetNamespace;
37
38
    /**
39
     * @var Schema[]
40
     */
41
    protected $schemas = array();
42
43
    /**
44
     * @var Type[]
45
     */
46
    protected $types = array();
47
48
    /**
49
     * @var ElementDef[]
50
     */
51
    protected $elements = array();
52
53
    /**
54
     * @var Group[]
55
     */
56
    protected $groups = array();
57
58
    /**
59
     * @var AttributeGroup[]
60
     */
61
    protected $attributeGroups = array();
62
63
    /**
64
     * @var AttributeDef[]
65
     */
66
    protected $attributes = array();
67
68
    /**
69
     * @var string|null
70
     */
71
    protected $doc;
72
73
    /**
74
     * @var \GoetasWebservices\XML\XSDReader\Schema\SchemaItem[]
75
     */
76
    protected $typeCache = array();
77
78
    /**
79
     * @return bool
80
     */
81
    public function getElementsQualification()
82
    {
83
        return $this->elementsQualification;
84
    }
85
86
    /**
87
     * @param bool $elementsQualification
88
     */
89 45
    public function setElementsQualification($elementsQualification)
90 1
    {
91 45
        $this->elementsQualification = $elementsQualification;
92 45
    }
93
94
    /**
95
     * @return bool
96
     */
97
    public function getAttributesQualification()
98
    {
99
        return $this->attributesQualification;
100
    }
101
102
    /**
103
     * @param bool $attributesQualification
104
     */
105 45
    public function setAttributesQualification($attributesQualification)
106
    {
107 45
        $this->attributesQualification = $attributesQualification;
108 45
    }
109
110
    /**
111
     * @return string|null
112
     */
113 45
    public function getTargetNamespace()
114
    {
115 45
        return $this->targetNamespace;
116
    }
117
118
    /**
119
     * @param string|null $targetNamespace
120
     */
121 45
    public function setTargetNamespace($targetNamespace)
122
    {
123 45
        $this->targetNamespace = $targetNamespace;
124 45
    }
125
126
    /**
127
     * @return Type[]
128
     */
129 5
    public function getTypes()
130
    {
131 5
        return $this->types;
132
    }
133
134
    /**
135
     * @return ElementDef[]
136
     */
137 3
    public function getElements()
138
    {
139 3
        return $this->elements;
140
    }
141
142
    /**
143
     * @return Schema[]
144
     */
145 45
    public function getSchemas()
146
    {
147 45
        return $this->schemas;
148
    }
149
150
    /**
151
     * @return AttributeDef[]
152
     */
153 1
    public function getAttributes()
154
    {
155 1
        return $this->attributes;
156
    }
157
158
    /**
159
     * @return Group[]
160
     */
161 2
    public function getGroups()
162
    {
163 2
        return $this->groups;
164
    }
165
166
    /**
167
     * @return string|null
168
     */
169
    public function getDoc()
170
    {
171
        return $this->doc;
172
    }
173
174
    /**
175
     * @param string $doc
176
     */
177 45
    public function setDoc($doc)
178
    {
179 45
        $this->doc = $doc;
180 45
    }
181
182 45
    public function addType(Type $type)
183
    {
184 45
        $this->types[$type->getName()] = $type;
185 45
    }
186
187 45
    public function addElement(ElementDef $element)
188
    {
189 45
        $this->elements[$element->getName()] = $element;
190 45
    }
191
192
    /**
193
     * @param string|null $namespace
194
     */
195 45
    public function addSchema(Schema $schema, $namespace = null)
196
    {
197 45
        if ($namespace !== null) {
198 45
            if ($schema->getTargetNamespace() !== $namespace) {
199
                throw new SchemaException(
200
                    sprintf(
201
                        "The target namespace ('%s') for schema, does not match the declared namespace '%s'",
202
                        $schema->getTargetNamespace(),
203
                        $namespace
204
                    )
205
                );
206
            }
207 45
            $this->schemas[$namespace] = $schema;
208 45
        } else {
209 45
            $this->schemas[] = $schema;
210
        }
211 45
    }
212
213 45
    public function addAttribute(AttributeDef $attribute)
214
    {
215 45
        $this->attributes[$attribute->getName()] = $attribute;
216 45
    }
217
218 45
    public function addGroup(Group $group)
219
    {
220 45
        $this->groups[$group->getName()] = $group;
221 45
    }
222
223 45
    public function addAttributeGroup(AttributeGroup $group)
224
    {
225 45
        $this->attributeGroups[$group->getName()] = $group;
226 45
    }
227
228
    /**
229
     * @return AttributeGroup[]
230
     */
231 1
    public function getAttributeGroups()
232
    {
233 1
        return $this->attributeGroups;
234
    }
235
236
    /**
237
     * @param string $name
238
     *
239
     * @return Group|false
240
     */
241 45
    public function getGroup($name)
242
    {
243 45
        if (isset($this->groups[$name])) {
244 45
            return $this->groups[$name];
245
        }
246
247
        return false;
248
    }
249
250
    /**
251
     * @param string $name
252
     *
253
     * @return ElementItem|false
254
     */
255 45
    public function getElement($name)
256
    {
257 45
        if (isset($this->elements[$name])) {
258 45
            return $this->elements[$name];
259
        }
260
261
        return false;
262
    }
263
264
    /**
265
     * @param string $name
266
     *
267
     * @return Type|false
268
     */
269 45
    public function getType($name)
270
    {
271 45
        if (isset($this->types[$name])) {
272 45
            return $this->types[$name];
273
        }
274
275
        return false;
276
    }
277
278
    /**
279
     * @param string $name
280
     *
281
     * @return AttributeItem|false
282
     */
283 45
    public function getAttribute($name)
284
    {
285 45
        if (isset($this->attributes[$name])) {
286 45
            return $this->attributes[$name];
287
        }
288
289
        return false;
290
    }
291
292
    /**
293
     * @param string $name
294
     *
295
     * @return AttributeGroup|false
296
     */
297 45
    public function getAttributeGroup($name)
298
    {
299 45
        if (isset($this->attributeGroups[$name])) {
300 45
            return $this->attributeGroups[$name];
301
        }
302
303
        return false;
304
    }
305
306
    public function __toString()
307
    {
308
        return sprintf('Target namespace %s', $this->getTargetNamespace());
309
    }
310
311
    /**
312
     * @param string $getter
313
     * @param string $name
314
     * @param string $namespace
315
     * @param bool[] $calling
316
     * @param bool   $throw
317
     *
318
     * @return SchemaItem|null
319
     */
320
    abstract protected function findSomethingNoThrow(
321
        $getter,
322
        $name,
323
        $namespace = null,
324
        array &$calling = array()
325
    );
326
327
    /**
328
     * @param Schema[] $schemas
329
     * @param string   $cid
330
     * @param string   $getter
331
     * @param string   $name
332
     * @param string   $namespace
333
     * @param bool[]   $calling
334
     * @param bool     $throw
335
     *
336
     * @return SchemaItem|null
337
     */
338
    abstract protected function findSomethingNoThrowSchemas(
339
        array $schemas,
340
        $cid,
341
        $getter,
342
        $name,
343
        $namespace = null,
344
        array &$calling = array()
345
    );
346
347
    /**
348
     * @param string $getter
349
     * @param string $name
350
     * @param string $namespace
351
     * @param bool[] $calling
352
     * @param bool   $throw
353
     *
354
     * @throws TypeNotFoundException
355
     *
356
     * @return SchemaItem
357
     */
358
    abstract protected function findSomething(
359
        $getter,
360
        $name,
361
        $namespace = null,
362
        &$calling = array()
363
    );
364
365
    /**
366
     * @param string $name
367
     * @param string $namespace
368
     *
369
     * @return Type
370
     */
371 45
    public function findType($name, $namespace = null)
372
    {
373
        /**
374
         * @var Type
375
         */
376 45
        $out = $this->findSomething('getType', $name, $namespace);
377
378 45
        return $out;
379
    }
380
381
    /**
382
     * @param string $name
383
     * @param string $namespace
384
     *
385
     * @return Group
386
     */
387 45
    public function findGroup($name, $namespace = null)
388
    {
389
        /**
390
         * @var Group
391
         */
392 45
        $out = $this->findSomething('getGroup', $name, $namespace);
393
394 45
        return $out;
395
    }
396
397
    /**
398
     * @param string $name
399
     * @param string $namespace
400
     *
401
     * @return ElementDef
402
     */
403 45
    public function findElement($name, $namespace = null)
404
    {
405
        /**
406
         * @var ElementDef
407
         */
408 45
        $out = $this->findSomething('getElement', $name, $namespace);
409
410 45
        return $out;
411
    }
412
413
    /**
414
     * @param string $name
415
     * @param string $namespace
416
     *
417
     * @return AttributeItem
418
     */
419 45
    public function findAttribute($name, $namespace = null)
420
    {
421
        /**
422
         * @var AttributeItem
423
         */
424 45
        $out = $this->findSomething('getAttribute', $name, $namespace);
425
426 45
        return $out;
427
    }
428
429
    /**
430
     * @param string $name
431
     * @param string $namespace
432
     *
433
     * @return AttributeGroup
434
     */
435 45
    public function findAttributeGroup($name, $namespace = null)
436
    {
437
        /**
438
         * @var AttributeGroup
439
         */
440 45
        $out = $this->findSomething('getAttributeGroup', $name, $namespace);
441
442 45
        return $out;
443
    }
444
445
    /**
446
     * @var Schema[]
447
     */
448
    protected static $loadedFiles = array();
449
450
    /**
451
     * @param string ...$keys
452
     *
453
     * @return bool
454
     */
455 45
    public static function hasLoadedFile(...$keys)
456
    {
457 45
        foreach ($keys as $key) {
458 45
            if (isset(self::$loadedFiles[$key])) {
459 45
                return true;
460
            }
461 1
        }
462
463 1
        return false;
464
    }
465
466
    /**
467
     * @param string ...$keys
468
     *
469
     * @return Schema
470
     *
471
     * @throws RuntimeException if loaded file not found
472
     */
473 45
    public static function getLoadedFile(...$keys)
474
    {
475 45
        foreach ($keys as $key) {
476 45
            if (isset(self::$loadedFiles[$key])) {
477 45
                return self::$loadedFiles[$key];
478
            }
479
        }
480
481
        throw new RuntimeException('Loaded file was not found!');
482
    }
483
484
    /**
485
     * @param string $key
486
     *
487
     * @return Schema
488
     */
489 45
    public static function setLoadedFile($key, Schema $schema)
490
    {
491 45
        self::$loadedFiles[$key] = $schema;
492
493 45
        return $schema;
494
    }
495
496 45
    public function setSchemaThingsFromNode(
497
        DOMElement $node,
498
        Schema $parent = null
499
    ) {
500 45
        $this->setDoc(AbstractSchemaReader::getDocumentation($node));
501
502 45
        if ($node->hasAttribute('targetNamespace')) {
503 45
            $this->setTargetNamespace($node->getAttribute('targetNamespace'));
504 45
        } elseif ($parent) {
505
            $this->setTargetNamespace($parent->getTargetNamespace());
506
        }
507 45
        $this->setElementsQualification($node->getAttribute('elementFormDefault') == 'qualified');
508 45
        $this->setAttributesQualification($node->getAttribute('attributeFormDefault') == 'qualified');
509 45
        $this->setDoc(AbstractSchemaReader::getDocumentation($node));
510 45
    }
511
512
    /**
513
     * @param string $file
514
     * @param string $namespace
515
     *
516
     * @return Closure
517
     */
518 45
    public static function loadImport(
519
        SchemaReaderLoadAbstraction $reader,
520
        Schema $schema,
521
        DOMElement $node
522
    ) {
523 45
        $base = urldecode($node->ownerDocument->documentURI);
524 45
        $file = UrlUtils::resolveRelativeUrl($base, $node->getAttribute('schemaLocation'));
525
526 45
        $namespace = $node->getAttribute('namespace');
527
528 45
        $keys = static::loadImportFreshKeys($reader, $namespace, $file);
529
530
        if (
531 45
            static::hasLoadedFile(...$keys)
532 45
        ) {
533 45
            $schema->addSchema(static::getLoadedFile(...$keys));
534
535 45
            return function () {
536 45
            };
537
        }
538
539 1
        return static::loadImportFresh($namespace, $reader, $schema, $file);
540
    }
541
542
    /**
543
     * @param string $namespace
544
     * @param string $file
545
     *
546
     * @return mixed[]
547
     */
548
    abstract protected static function loadImportFreshKeys(
549
        SchemaReaderLoadAbstraction $reader,
550
        $namespace,
551
        $file
552
    );
553
554
    /**
555
     * @param string $namespace
556
     * @param string $file
557
     *
558
     * @return Schema
559
     */
560
    abstract protected static function loadImportFreshCallbacksNewSchema(
561
        $namespace,
562
        SchemaReaderLoadAbstraction $reader,
563
        Schema $schema,
564
        $file
565
    );
566
567
    /**
568
     * @param string $namespace
569
     * @param string $file
570
     *
571
     * @return Closure[]
572
     */
573
    abstract protected static function loadImportFreshCallbacks(
574
        $namespace,
575
        SchemaReaderLoadAbstraction $reader,
576
        Schema $schema,
577
        $file
578
    );
579
580
    /**
581
     * @param string $namespace
582
     * @param string $file
583
     *
584
     * @return Closure
585
     */
586
    abstract protected static function loadImportFresh(
587
        $namespace,
588
        SchemaReaderLoadAbstraction $reader,
589
        Schema $schema,
590
        $file
591
    );
592
}
593