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

SchemaReaderLoadAbstraction::addGroupAsElement()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

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