Completed
Push — master ( 0fb0f7...99f125 )
by Nikola
04:10
created

SaxParser::getDocumentStream()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4.0741

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 14
ccs 5
cts 6
cp 0.8333
rs 9.2
cc 4
eloc 5
nc 3
nop 1
crap 4.0741
1
<?php
2
/*
3
 * This file is part of the runopencode/sax, an RunOpenCode project.
4
 *
5
 * (c) 2016 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\Sax;
11
12
use Psr\Http\Message\StreamInterface;
13
use RunOpenCode\Sax\Contract\SaxHandlerInterface;
14
use RunOpenCode\Sax\Contract\StreamAdapterInterface;
15
use RunOpenCode\Sax\StreamAdapter\DomDocumentAdapter;
16
use RunOpenCode\Sax\StreamAdapter\ResourceAdapter;
17
use RunOpenCode\Sax\StreamAdapter\SimpleXmlAdapter;
18
19
/**
20
 * Class SaxParser
21
 *
22
 * Utility class for working with SAX handler and XML document.
23
 *
24
 * @package RunOpenCode\Sax
25
 */
26
final class SaxParser
27
{
28
    /**
29
     * @var StreamAdapterInterface[]
30
     */
31
    private $streamAdapters;
32
33
    /**
34
     * SaxParser constructor.
35
     *
36
     * @param StreamAdapterInterface[] $streamAdapters Stream adapters to register to parser.
37
     */
38 4
    public function __construct(array $streamAdapters = array())
39
    {
40 4
        $this->streamAdapters = array();
41
42 4
        foreach ($streamAdapters as $streamAdapter) {
43 2
            $this->addStreamAdapter($streamAdapter);
44 4
        }
45 4
    }
46
47
    /**
48
     * Register stream adapter to parser.
49
     *
50
     * @param StreamAdapterInterface $streamAdapter Stream adapter to register.
51
     * @return SaxParser $this Fluent interface.
52
     */
53 4
    public function addStreamAdapter(StreamAdapterInterface $streamAdapter)
54
    {
55 4
        $this->streamAdapters[] = $streamAdapter;
56 4
        return $this;
57
    }
58
59
    /**
60
     * Parse XML document using provided SAX handler.
61
     *
62
     * @param SaxHandlerInterface $saxHandler Handler to user for parsing document.
63
     * @param mixed $xmlDocument XML document source.
64
     * @param callable|null $onResult Callable to execute when parsing is done.
65
     */
66 4
    public function parse(SaxHandlerInterface $saxHandler, $xmlDocument, callable $onResult = null)
67
    {
68 4
        $xmlDocument = ($xmlDocument instanceof StreamInterface) ? $xmlDocument : $this->getDocumentStream($xmlDocument);
69 4
        $saxHandler->parse($xmlDocument, $onResult);
70 4
    }
71
72
    /**
73
     * Convert XML document to stream source.
74
     *
75
     * @param mixed $xmlDocument XML document source.
76
     * @return StreamInterface Converted XML document to stream.
77
     *
78
     * @throws \RuntimeException
79
     */
80 4
    private function getDocumentStream($xmlDocument)
81
    {
82
        /**
83
         * @var StreamAdapterInterface $streamAdapter
84
         */
85 4
        foreach ($this->streamAdapters as $streamAdapter) {
86
87 4
            if ($streamAdapter->supports($xmlDocument)) {
88 4
                return $streamAdapter->convert($xmlDocument);
89
            }
90 4
        }
91
92
        throw new \RuntimeException(sprintf('Suitable XML document stream adapter is not registered for XML document of type "%s".', is_object($xmlDocument) ? get_class($xmlDocument) : gettype($xmlDocument)));
93
    }
94
95
    /**
96
     * Default SAX parser factory.
97
     *
98
     * @param string $streamClass FQCN to use when converting to XML document source to stream.
99
     * @return SaxParser New SAX parser instance.
100
     */
101 2
    public static function factory($streamClass = 'GuzzleHttp\\Psr7\\Stream')
102
    {
103 2
        return new SaxParser(array(
104 2
            new ResourceAdapter($streamClass),
105 2
            new DomDocumentAdapter($streamClass),
106 2
            new SimpleXmlAdapter($streamClass)
107 2
        ));
108
    }
109
}
110