Completed
Push — php-7.1 ( 280017...51ebd7 )
by SignpostMarv
13:26 queued 03:36
created

SchemaReaderLoadAbstraction::loadAttributeGroup()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 5
ccs 2
cts 2
cp 1
crap 1
rs 9.4285
c 1
b 0
f 0
1
<?php
2
3
namespace GoetasWebservices\XML\XSDReader;
4
5
use Closure;
6
use DOMElement;
7
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Attribute;
8
use GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeDef;
9
use GoetasWebservices\XML\XSDReader\Schema\Attribute\Group as AttributeGroup;
10
use GoetasWebservices\XML\XSDReader\Schema\Element\Element;
11
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementContainer;
12
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementDef;
13
use GoetasWebservices\XML\XSDReader\Schema\Element\ElementRef;
14
use GoetasWebservices\XML\XSDReader\Schema\Element\Group;
15
use GoetasWebservices\XML\XSDReader\Schema\Element\GroupRef;
16
use GoetasWebservices\XML\XSDReader\Schema\Inheritance\Base;
17
use GoetasWebservices\XML\XSDReader\Schema\Inheritance\Extension;
18
use GoetasWebservices\XML\XSDReader\Schema\Inheritance\Restriction;
19
use GoetasWebservices\XML\XSDReader\Schema\Schema;
20
use GoetasWebservices\XML\XSDReader\Schema\Type\BaseComplexType;
21
use GoetasWebservices\XML\XSDReader\Schema\Type\ComplexType;
22
use GoetasWebservices\XML\XSDReader\Schema\Type\ComplexTypeSimpleContent;
23
use GoetasWebservices\XML\XSDReader\Schema\Type\SimpleType;
24
use GoetasWebservices\XML\XSDReader\Schema\Type\Type;
25
26
abstract class SchemaReaderLoadAbstraction extends SchemaReaderFillAbstraction
27
{
28 45
29
    protected function loadAttributeOrElementDef(
30
        Schema $schema,
31
        DOMElement $node,
32 45
        bool $attributeDef
33
    ): Closure {
34
        $name = $node->getAttribute('name');
35 45
        if ($attributeDef) {
36
            $attribute = new AttributeDef($schema, $name);
37
            $schema->addAttribute($attribute);
38
        } else {
39
            $attribute = new ElementDef($schema, $name);
40 45
            $schema->addElement($attribute);
41 45
        }
42 45
43 45
        return function () use ($attribute, $node): void {
44
            $this->fillItem($attribute, $node);
45 45
        };
46 45
    }
47
48
    protected function loadAttributeDef(
49 45
        Schema $schema,
50 45
        DOMElement $node
51 45
    ): Closure {
52
        return $this->loadAttributeOrElementDef($schema, $node, true);
53
    }
54 45
55
    protected static function loadSequenceNormaliseMax(
56
        DOMElement $node,
57
        ? int $max
58 45
    ): ? int {
59
        return
60
        (
61 45
            (is_int($max) && (bool) $max) ||
62
            $node->getAttribute('maxOccurs') == 'unbounded' ||
63
            $node->getAttribute('maxOccurs') > 1
64
        )
65
            ? 2
66
            : null;
67 45
    }
68 45
69 45
    protected function loadSequence(
70
        ElementContainer $elementContainer,
71 45
        DOMElement $node,
72 45
        int $max = null
73
    ): void {
74
        $max = static::loadSequenceNormaliseMax($node, $max);
75 45
76
        static::againstDOMNodeList(
77
            $node,
78
            function (
79
                DOMElement $node,
80 45
                DOMElement $childNode
81
            ) use (
82 45
                $elementContainer,
83 45
                $max
84 45
            ): void {
85
                $this->loadSequenceChildNode(
86
                    $elementContainer,
87
                    $node,
88 45
                    $childNode,
89 45
                    $max
90
                );
91 45
            }
92 45
        );
93 45
    }
94 45
95 45
    protected function loadSequenceChildNode(
96
        ElementContainer $elementContainer,
97 45
        DOMElement $node,
98
        DOMElement $childNode,
99 45
        ? int $max
100
    ): void {
101 45
        $commonMethods = [
102
            [
103
                ['sequence', 'choice', 'all'],
104
                [$this, 'loadSequenceChildNodeLoadSequence'],
105
                [
106
                    $elementContainer,
107
                    $childNode,
108
                    $max,
109 45
                ],
110 45
            ],
111
        ];
112 45
        $methods = [
113 45
            'element' => [
114 45
                [$this, 'loadSequenceChildNodeLoadElement'],
115
                [
116
                    $elementContainer,
117
                    $node,
118
                    $childNode,
119
                    $max,
120 45
                ],
121
            ],
122 45
            'group' => [
123 45
                [$this, 'loadSequenceChildNodeLoadGroup'],
124 45
                [
125 45
                    $elementContainer,
126
                    $node,
127
                    $childNode,
128
                ],
129 45
            ],
130
        ];
131 45
132 45
        $this->maybeCallCallableWithArgs($childNode, $commonMethods, $methods);
133 45
    }
134
135
    protected function loadSequenceChildNodeLoadSequence(
136
        ElementContainer $elementContainer,
137
        DOMElement $childNode,
138 45
        ? int $max
139 45
    ): void {
140
        $this->loadSequence($elementContainer, $childNode, $max);
141 45
    }
142
143
    protected function loadSequenceChildNodeLoadElement(
144
        ElementContainer $elementContainer,
145
        DOMElement $node,
146 45
        DOMElement $childNode,
147 45
        ? int $max
148
    ): void {
149 45
        if ($childNode->hasAttribute('ref')) {
150
            /**
151
             * @var ElementDef $referencedElement
152
             */
153
            $referencedElement = $this->findSomething('findElement', $elementContainer->getSchema(), $node, $childNode->getAttribute('ref'));
154
            $element = ElementRef::loadElementRef(
155 45
                $referencedElement,
156
                $childNode
157
            );
158
        } else {
159 45
            $element = Element::loadElement(
160 45
                $this,
161 45
                $elementContainer->getSchema(),
162 45
                $childNode
163
            );
164
        }
165 45
        if (is_int($max) && (bool) $max) {
166 45
            $element->setMax($max);
167 45
        }
168 45
        $elementContainer->addElement($element);
169
    }
170
171 45
    protected function loadSequenceChildNodeLoadGroup(
172 45
        ElementContainer $elementContainer,
173
        DOMElement $node,
174 45
        DOMElement $childNode
175 45
    ): void {
176
        $this->addGroupAsElement(
177 45
            $elementContainer->getSchema(),
178
            $node,
179
            $childNode,
180
            $elementContainer
181
        );
182 45
    }
183 45
184 45
    protected function addGroupAsElement(
185 45
        Schema $schema,
186 45
        DOMElement $node,
187
        DOMElement $childNode,
188 45
        ElementContainer $elementContainer
189
    ): void {
190 45
        /**
191
         * @var Group
192
         */
193
        $referencedGroup = $this->findSomething(
194
            'findGroup',
195
            $schema,
196
            $node,
197
            $childNode->getAttribute('ref')
198
        );
199 45
200 45
        $group = GroupRef::loadGroupRef($referencedGroup, $childNode);
201 45
        $elementContainer->addElement($group);
202 45
    }
203 45
204
    protected function loadGroup(Schema $schema, DOMElement $node): Closure
205
    {
206 45
        return Group::loadGroup($this, $schema, $node);
207 45
    }
208 45
209
    protected function loadComplexTypeBeforeCallbackCallback(
210 45
        Schema $schema,
211
        DOMElement $node
212 45
    ): BaseComplexType {
213
        /**
214
         * @var bool
215 45
         */
216
        $isSimple = false;
217
218
        static::againstDOMNodeList(
219
            $node,
220
            function (
221
                DOMElement $node,
222 45
                DOMElement $childNode
223
            ) use (
224 45
                &$isSimple
225 45
            ): void {
226 45
                if ($isSimple) {
227
                    return;
228
                }
229
                if ($childNode->localName === 'simpleContent') {
230 45
                    $isSimple = true;
231
                }
232 45
            }
233 1
        );
234
235 45
        $type = $isSimple ? new ComplexTypeSimpleContent($schema, $node->getAttribute('name')) : new ComplexType($schema, $node->getAttribute('name'));
236 2
237
        $type->setDoc(static::getDocumentation($node));
238 45
        if ($node->getAttribute('name')) {
239
            $schema->addType($type);
240
        }
241 45
242
        return $type;
243 45
    }
244 45
245 45
    protected function loadComplexType(
246
        Schema $schema,
247
        DOMElement $node,
248 45
        Closure $callback = null
249
    ): Closure {
250
        $type = $this->loadComplexTypeBeforeCallbackCallback($schema, $node);
251 45
252
        return $this->makeCallbackCallback(
253
            $type,
254
            $node,
255
            function (
256 45
                DOMElement $node,
257
                DOMElement $childNode
258 45
            ) use (
259 45
                $schema,
260 45
                $type
261 45
            ): void {
262
                $this->loadComplexTypeFromChildNode(
263
                    $type,
264
                    $node,
265 45
                    $childNode,
266 45
                    $schema
267
                );
268 45
            },
269 45
            $callback
270 45
        );
271 45
    }
272 45
273
    protected function loadComplexTypeFromChildNode(
274 45
        BaseComplexType $type,
275 45
        DOMElement $node,
276
        DOMElement $childNode,
277
        Schema $schema
278
    ): void {
279 45
        $commonMethods = [
280
            [
281
                ['sequence', 'choice', 'all'],
282
                [$this, 'maybeLoadSequenceFromElementContainer'],
283
                [
284
                    $type,
285
                    $childNode,
286
                ],
287 45
            ],
288 45
        ];
289
        $methods = [
290 45
            'attribute' => [
291 45
                [$type, 'addAttributeFromAttributeOrRef'],
292
                [
293
                    $this,
294
                    $childNode,
295
                    $schema,
296 45
                    $node,
297 45
                ],
298
            ],
299 45
            'attributeGroup' => [
300 45
                (AttributeGroup::class.'::findSomethingLikeThis'),
301 45
                [
302 45
                    $this,
303
                    $schema,
304
                    $node,
305
                    $childNode,
306
                    $type,
307
                ],
308 45
            ],
309 45
        ];
310 45
        if (
311 45
            $type instanceof ComplexType
312 45
        ) {
313
            $methods['group'] = [
314
                [$this, 'addGroupAsElement'],
315
                [
316
                    $schema,
317 45
                    $node,
318
                    $childNode,
319 45
                    $type,
320 45
                ],
321
            ];
322 45
        }
323 45
324 45
        $this->maybeCallCallableWithArgs($childNode, $commonMethods, $methods);
325 45
    }
326
327
    protected function loadSimpleType(
328
        Schema $schema,
329
        DOMElement $node,
330 45
        Closure $callback = null
331 45
    ): Closure {
332
        $type = new SimpleType($schema, $node->getAttribute('name'));
333 45
        $type->setDoc(static::getDocumentation($node));
334
        if ($node->getAttribute('name')) {
335
            $schema->addType($type);
336
        }
337
338 45
        return $this->makeCallbackCallback(
339 45
            $type,
340 45
            $node,
341 45
            $this->CallbackGeneratorMaybeCallMethodAgainstDOMNodeList(
342
                $type,
343
                [
344 45
                    'union' => 'loadUnion',
345 45
                    'list' => 'loadList',
346 45
                ]
347 45
            ),
348 45
            $callback
349
        );
350 45
    }
351
352
    protected function loadList(SimpleType $type, DOMElement $node): void
353
    {
354 45
        if ($node->hasAttribute('itemType')) {
355
            /**
356
             * @var SimpleType
357
             */
358 45
            $listType = $this->findSomeType($type, $node, 'itemType');
359
            $type->setList($listType);
360 45
        } else {
361
            $addCallback = function (SimpleType $list) use ($type): void {
362
                $type->setList($list);
363
            };
364 45
365 45
            Type::loadTypeWithCallbackOnChildNodes(
366
                $this,
367 45
                $type->getSchema(),
368 45
                $node,
369 45
                $addCallback
370
            );
371 45
        }
372 45
    }
373 45
374 45
    protected function loadUnion(SimpleType $type, DOMElement $node): void
375 45
    {
376
        if ($node->hasAttribute('memberTypes')) {
377
            $types = preg_split('/\s+/', $node->getAttribute('memberTypes'));
378 45
            foreach ($types as $typeName) {
379
                /**
380 45
                 * @var SimpleType
381
                 */
382 45
                $unionType = $this->findSomeTypeFromAttribute(
383 45
                    $type,
384 45
                    $node,
385
                    $typeName
386
                );
387
                $type->addUnion($unionType);
388 45
            }
389 45
        }
390 45
        $addCallback = function (SimpleType $unType) use ($type): void {
391 45
            $type->addUnion($unType);
392
        };
393 45
394
        Type::loadTypeWithCallbackOnChildNodes(
395
            $this,
396 45
            $type->getSchema(),
397 45
            $node,
398 45
            $addCallback
399
        );
400 45
    }
401 45
402 45
    protected function loadExtensionChildNodes(
403 45
        BaseComplexType $type,
404 45
        DOMElement $node
405
    ): void {
406 45
        static::againstDOMNodeList(
407
            $node,
408 45
            function (
409
                DOMElement $node,
410
                DOMElement $childNode
411
            ) use (
412 45
                $type
413 45
            ): void {
414 45
                $commonMethods = [
415
                    [
416
                        ['sequence', 'choice', 'all'],
417
                        [$this, 'maybeLoadSequenceFromElementContainer'],
418 45
                        [
419
                            $type,
420
                            $childNode,
421
                        ],
422 45
                    ],
423 45
                ];
424
                $methods = [
425 45
                    'attribute' => [
426 45
                        [$type, 'addAttributeFromAttributeOrRef'],
427
                        [
428
                            $this,
429
                            $childNode,
430
                            $type->getSchema(),
431 45
                            $node,
432 45
                        ],
433
                    ],
434 45
                    'attributeGroup' => [
435 45
                        (AttributeGroup::class.'::findSomethingLikeThis'),
436 45
                        [
437 45
                            $this,
438
                            $type->getSchema(),
439
                            $node,
440
                            $childNode,
441
                            $type,
442
                        ],
443 45
                    ],
444 45
                ];
445 45
446 45
                $this->maybeCallCallableWithArgs(
447 45
                    $childNode,
448
                    $commonMethods,
449
                    $methods
450
                );
451
            }
452 45
        );
453 45
    }
454 45
455 45
    protected function loadExtension(
456
        BaseComplexType $type,
457 45
        DOMElement $node
458
    ): void {
459 45
        $extension = new Extension();
460
        $type->setExtension($extension);
461 45
462
        if ($node->hasAttribute('base')) {
463
            $this->findAndSetSomeBase(
464
                $type,
465 45
                $extension,
466 45
                $node
467
            );
468 45
        }
469 45
        $this->loadExtensionChildNodes($type, $node);
470 45
    }
471 45
472 45
    protected function loadRestriction(Type $type, DOMElement $node): void
473
    {
474
        Restriction::loadRestriction($this, $type, $node);
475 45
    }
476 45
477
    protected function loadElementDef(
478 45
        Schema $schema,
479
        DOMElement $node
480 45
    ): Closure {
481 45
        return $this->loadAttributeOrElementDef($schema, $node, false);
482
    }
483
}
484