Passed
Pull Request — master (#18)
by SignpostMarv
03:22
created

loadSequenceNormaliseMax()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 5
nc 8
nop 2
dl 0
loc 10
ccs 7
cts 7
cp 1
crap 5
rs 8.8571
c 0
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
    /**
29
     * @return Closure
30
     */
31 135
    protected function loadAttributeGroup(Schema $schema, DOMElement $node)
32
    {
33 135
        return AttributeGroup::loadAttributeGroup($this, $schema, $node);
34
    }
35
36
    /**
37
     * @param bool $attributeDef
38
     *
39
     * @return Closure
40
     */
41 135
    protected function loadAttributeOrElementDef(
42
        Schema $schema,
43
        DOMElement $node,
44
        $attributeDef
45
    ) {
46 135
        $name = $node->getAttribute('name');
47 135
        if ($attributeDef) {
48 135
            $attribute = new AttributeDef($schema, $name);
49 135
            $schema->addAttribute($attribute);
50 45
        } else {
51 135
            $attribute = new ElementDef($schema, $name);
52 135
            $schema->addElement($attribute);
53
        }
54
55
        return function () use ($attribute, $node) {
56 135
            $this->fillItem($attribute, $node);
57 135
        };
58
    }
59
60
    /**
61
     * @return Closure
62
     */
63 135
    protected function loadAttributeDef(Schema $schema, DOMElement $node)
64
    {
65 135
        return $this->loadAttributeOrElementDef($schema, $node, true);
66
    }
67
68
    /**
69
     * @param int|null $max
70
     *
71
     * @return int|null
72
     */
73 135
    protected static function loadSequenceNormaliseMax(DOMElement $node, $max)
74
    {
75
        return
76
        (
77 135
            (is_int($max) && (bool) $max) ||
78 135
            $node->getAttribute('maxOccurs') == 'unbounded' ||
79 135
            $node->getAttribute('maxOccurs') > 1
80 45
        )
81 90
            ? 2
82 135
            : null;
83
    }
84
85
    /**
86
     * @param int|null $max
87
     */
88 135
    protected function loadSequence(ElementContainer $elementContainer, DOMElement $node, $max = null)
89
    {
90 135
        $max = static::loadSequenceNormaliseMax($node, $max);
91
92 135
        static::againstDOMNodeList(
93 135
            $node,
94
            function (
95
                DOMElement $node,
96
                DOMElement $childNode
97
            ) use (
98 135
                $elementContainer,
99 135
                $max
100
            ) {
101 135
                $this->loadSequenceChildNode(
102 135
                    $elementContainer,
103 135
                    $node,
104 135
                    $childNode,
105 90
                    $max
106 45
                );
107 135
            }
108 45
        );
109 135
    }
110
111
    /**
112
     * @param int|null $max
113
     */
114 135
    protected function loadSequenceChildNode(
115
        ElementContainer $elementContainer,
116
        DOMElement $node,
117
        DOMElement $childNode,
118
        $max
119
    ) {
120
        $commonMethods = [
121
            [
122 135
                ['sequence', 'choice', 'all'],
123 135
                [$this, 'loadSequenceChildNodeLoadSequence'],
124
                [
125 135
                    $elementContainer,
126 135
                    $childNode,
127 135
                    $max,
128 45
                ],
129 45
            ],
130 45
        ];
131
        $methods = [
132
            'element' => [
133 135
                [$this, 'loadSequenceChildNodeLoadElement'],
134
                [
135 135
                    $elementContainer,
136 135
                    $node,
137 135
                    $childNode,
138 135
                    $max,
139 45
                ],
140 45
            ],
141
            'group' => [
142 135
                [$this, 'loadSequenceChildNodeLoadGroup'],
143
                [
144 135
                    $elementContainer,
145 135
                    $node,
146 135
                    $childNode,
147 45
                ],
148 45
            ],
149 45
        ];
150
151 135
        $this->maybeCallCallableWithArgs($childNode, $commonMethods, $methods);
152 135
    }
153
154
    /**
155
     * @param int|null $max
156
     */
157 135
    protected function loadSequenceChildNodeLoadSequence(
158
        ElementContainer $elementContainer,
159
        DOMElement $childNode,
160
        $max
161
    ) {
162 135
        $this->loadSequence($elementContainer, $childNode, $max);
163 135
    }
164
165
    /**
166
     * @param int|null $max
167
     */
168 135
    protected function loadSequenceChildNodeLoadElement(
169
        ElementContainer $elementContainer,
170
        DOMElement $node,
171
        DOMElement $childNode,
172
        $max
173
    ) {
174 135
        if ($childNode->hasAttribute('ref')) {
175
            /**
176
             * @var ElementDef
177
             */
178 135
            $referencedElement = $this->findSomething('findElement', $elementContainer->getSchema(), $node, $childNode->getAttribute('ref'));
179 135
            $element = ElementRef::loadElementRef(
180 135
                $referencedElement,
0 ignored issues
show
Bug introduced by
It seems like $referencedElement can also be of type GoetasWebservices\XML\XS...\Schema\Attribute\Group and GoetasWebservices\XML\XS...Attribute\AttributeItem and GoetasWebservices\XML\XSDReader\Schema\Type\Type and GoetasWebservices\XML\XS...er\Schema\Element\Group; however, parameter $referenced of GoetasWebservices\XML\XS...ntRef::loadElementRef() does only seem to accept GoetasWebservices\XML\XS...hema\Element\ElementDef, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

180
                /** @scrutinizer ignore-type */ $referencedElement,
Loading history...
181 90
                $childNode
182 45
            );
183 45
        } else {
184 135
            $element = Element::loadElement(
185 135
                $this,
186 135
                $elementContainer->getSchema(),
187 90
                $childNode
188 45
            );
189
        }
190 135
        if (is_int($max) && (bool) $max) {
191 135
            $element->setMax($max);
192 45
        }
193 135
        $elementContainer->addElement($element);
194 135
    }
195
196 135
    protected function loadSequenceChildNodeLoadGroup(
197
        ElementContainer $elementContainer,
198
        DOMElement $node,
199
        DOMElement $childNode
200
    ) {
201 135
        $this->addGroupAsElement(
202 135
            $elementContainer->getSchema(),
203 135
            $node,
204 135
            $childNode,
205 90
            $elementContainer
206 45
        );
207 135
    }
208
209 135
    protected function addGroupAsElement(
210
        Schema $schema,
211
        DOMElement $node,
212
        DOMElement $childNode,
213
        ElementContainer $elementContainer
214
    ) {
215
        /**
216
         * @var Group
217
         */
218 135
        $referencedGroup = $this->findSomething(
219 135
            'findGroup',
220 135
            $schema,
221 135
            $node,
222 135
            $childNode->getAttribute('ref')
223 45
        );
224
225 135
        $group = GroupRef::loadGroupRef($referencedGroup, $childNode);
226 135
        $elementContainer->addElement($group);
227 135
    }
228
229
    /**
230
     * @return Closure
231
     */
232 135
    protected function loadGroup(Schema $schema, DOMElement $node)
233
    {
234 135
        return Group::loadGroup($this, $schema, $node);
235
    }
236
237
    /**
238
     * @return BaseComplexType
239
     */
240 135
    protected function loadComplexTypeBeforeCallbackCallback(
241
        Schema $schema,
242
        DOMElement $node
243
    ) {
244
        /**
245
         * @var bool
246
         */
247 135
        $isSimple = false;
248
249 135
        static::againstDOMNodeList(
250 135
            $node,
251
            function (
252
                DOMElement $node,
253
                DOMElement $childNode
254
            ) use (
255 45
                &$isSimple
256
            ) {
257 135
                if ($isSimple) {
258 3
                    return;
259
                }
260 135
                if ($childNode->localName === 'simpleContent') {
261 6
                    $isSimple = true;
262 2
                }
263 135
            }
264 45
        );
265
266 135
        $type = $isSimple ? new ComplexTypeSimpleContent($schema, $node->getAttribute('name')) : new ComplexType($schema, $node->getAttribute('name'));
267
268 135
        $type->setDoc(static::getDocumentation($node));
269 135
        if ($node->getAttribute('name')) {
270 135
            $schema->addType($type);
271 45
        }
272
273 135
        return $type;
274
    }
275
276
    /**
277
     * @param Closure|null $callback
278
     *
279
     * @return Closure
280
     */
281 135
    protected function loadComplexType(Schema $schema, DOMElement $node, $callback = null)
282
    {
283 135
        $type = $this->loadComplexTypeBeforeCallbackCallback($schema, $node);
284
285 135
        return $this->makeCallbackCallback(
286 135
            $type,
287 135
            $node,
288
            function (
289
                DOMElement $node,
290
                DOMElement $childNode
291
            ) use (
292 135
                $schema,
293 135
                $type
294
            ) {
295 135
                $this->loadComplexTypeFromChildNode(
296 135
                    $type,
297 135
                    $node,
298 135
                    $childNode,
299 90
                    $schema
300 45
                );
301 135
            },
302 90
            $callback
303 45
        );
304
    }
305
306 135
    protected function loadComplexTypeFromChildNode(
307
        BaseComplexType $type,
308
        DOMElement $node,
309
        DOMElement $childNode,
310
        Schema $schema
311
    ) {
312
        $commonMethods = [
313
            [
314 135
                ['sequence', 'choice', 'all'],
315 135
                [$this, 'maybeLoadSequenceFromElementContainer'],
316
                [
317 135
                    $type,
318 135
                    $childNode,
319 45
                ],
320 45
            ],
321 45
        ];
322
        $methods = [
323 90
            'attribute' => [
324 135
                [$type, 'addAttributeFromAttributeOrRef'],
325
                [
326 135
                    $this,
327 135
                    $childNode,
328 135
                    $schema,
329 135
                    $node,
330 45
                ],
331 45
            ],
332
            'attributeGroup' => [
333 45
                (AttributeGroup::class.'::findSomethingLikeThis'),
334
                [
335 135
                    $this,
336 135
                    $schema,
337 135
                    $node,
338 135
                    $childNode,
339 135
                    $type,
340 45
                ],
341 45
            ],
342 45
        ];
343
        if (
344 90
            $type instanceof ComplexType
345 45
        ) {
346 135
            $methods['group'] = [
347 135
                [$this, 'addGroupAsElement'],
348
                [
349 135
                    $schema,
350 135
                    $node,
351 135
                    $childNode,
352 135
                    $type,
353 45
                ],
354
            ];
355 45
        }
356
357 135
        $this->maybeCallCallableWithArgs($childNode, $commonMethods, $methods);
358 135
    }
359
360
    /**
361
     * @param Closure|null $callback
362
     *
363
     * @return Closure
364
     */
365 135
    protected function loadSimpleType(Schema $schema, DOMElement $node, $callback = null)
366
    {
367 135
        $type = new SimpleType($schema, $node->getAttribute('name'));
368 135
        $type->setDoc(static::getDocumentation($node));
369 135
        if ($node->getAttribute('name')) {
370 135
            $schema->addType($type);
371 45
        }
372
373 135
        return $this->makeCallbackCallback(
374 135
            $type,
375 135
            $node,
376 135
            $this->CallbackGeneratorMaybeCallMethodAgainstDOMNodeList(
377 135
                $type,
378
                [
379 135
                    'union' => 'loadUnion',
380 45
                    'list' => 'loadList',
381
                ]
382 45
            ),
383 90
            $callback
384 45
        );
385
    }
386
387 135
    protected function loadList(SimpleType $type, DOMElement $node)
388
    {
389 135
        if ($node->hasAttribute('itemType')) {
390
            /**
391
             * @var SimpleType
392
             */
393 135
            $listType = $this->findSomeType($type, $node, 'itemType');
394 135
            $type->setList($listType);
395 45
        } else {
396
            $addCallback = function (SimpleType $list) use ($type) {
397 135
                $type->setList($list);
398 135
            };
399
400 135
            Type::loadTypeWithCallbackOnChildNodes(
401 135
                $this,
402 135
                $type->getSchema(),
403 135
                $node,
404 90
                $addCallback
405 45
            );
406
        }
407 135
    }
408
409 135
    protected function loadUnion(SimpleType $type, DOMElement $node)
410
    {
411 135
        if ($node->hasAttribute('memberTypes')) {
412 135
            $types = preg_split('/\s+/', $node->getAttribute('memberTypes'));
413 135
            foreach ($types as $typeName) {
414
                /**
415
                 * @var SimpleType
416
                 */
417 135
                $unionType = $this->findSomeTypeFromAttribute(
418 135
                    $type,
419 135
                    $node,
420 90
                    $typeName
421 45
                );
422 135
                $type->addUnion($unionType);
423 45
            }
424 45
        }
425
        $addCallback = function (SimpleType $unType) use ($type) {
426 135
            $type->addUnion($unType);
427 135
        };
428
429 135
        Type::loadTypeWithCallbackOnChildNodes(
430 135
            $this,
431 135
            $type->getSchema(),
432 135
            $node,
433 90
            $addCallback
434 45
        );
435 135
    }
436
437 135
    protected function loadExtensionChildNodes(
438
        BaseComplexType $type,
439
        DOMElement $node
440
    ) {
441 135
        static::againstDOMNodeList(
442 135
            $node,
443 135
            function (
444
                DOMElement $node,
445
                DOMElement $childNode
446
            ) use (
447 135
                $type
448
            ) {
449
                $commonMethods = [
450
                    [
451 135
                        ['sequence', 'choice', 'all'],
452 135
                        [$this, 'maybeLoadSequenceFromElementContainer'],
453
                        [
454 135
                            $type,
455 135
                            $childNode,
456 45
                        ],
457 45
                    ],
458 45
                ];
459
                $methods = [
460 90
                    'attribute' => [
461 135
                        [$type, 'addAttributeFromAttributeOrRef'],
462
                        [
463 135
                            $this,
464 135
                            $childNode,
465 135
                            $type->getSchema(),
466 135
                            $node,
467 45
                        ],
468 45
                    ],
469
                    'attributeGroup' => [
470 45
                        (AttributeGroup::class.'::findSomethingLikeThis'),
471
                        [
472 135
                            $this,
473 135
                            $type->getSchema(),
474 135
                            $node,
475 135
                            $childNode,
476 135
                            $type,
477 45
                        ],
478 45
                    ],
479 45
                ];
480
481 135
                $this->maybeCallCallableWithArgs(
482 135
                    $childNode,
483 135
                    $commonMethods,
484 90
                    $methods
485 45
                );
486 135
            }
487 45
        );
488 135
    }
489
490 135
    protected function loadExtension(BaseComplexType $type, DOMElement $node)
491
    {
492 135
        $extension = new Extension();
493 135
        $type->setExtension($extension);
494
495 135
        if ($node->hasAttribute('base')) {
496 135
            $this->findAndSetSomeBase(
497 135
                $type,
498 135
                $extension,
499 90
                $node
500 45
            );
501 45
        }
502 135
        $this->loadExtensionChildNodes($type, $node);
503 135
    }
504
505 135
    protected function loadRestriction(Type $type, DOMElement $node)
506
    {
507 135
        Restriction::loadRestriction($this, $type, $node);
508 135
    }
509
510
    /**
511
     * @return Closure
512
     */
513 135
    protected function loadElementDef(Schema $schema, DOMElement $node)
514
    {
515 135
        return $this->loadAttributeOrElementDef($schema, $node, false);
516
    }
517
}
518