Parser   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 195
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 4
Bugs 1 Features 2
Metric Value
wmc 19
c 4
b 1
f 2
lcom 1
cbo 1
dl 0
loc 195
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A clearHeaders() 0 4 1
A getHeaderSize() 0 8 2
A getParsedHeaders() 0 10 2
A parseHeaders() 0 10 2
B parseHeaderLine() 0 33 5
A decodeHeaderString() 0 8 1
A validateHeaderValue() 0 20 3
A getKeyValidationList() 0 4 1
A setKeyValidationList() 0 4 1
1
<?php
2
3
/**
4
 * \AppserverIo\Stomp\Parser
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Lars Roettig <[email protected]>
15
 * @copyright 2016 TechDivision GmbH - <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      http://www.appserver.io/
18
 */
19
20
namespace AppserverIo\Stomp;
21
22
use AppserverIo\Stomp\Exception\ProtocolException;
23
use AppserverIo\Stomp\Interfaces\RequestParserInterface;
24
use AppserverIo\Stomp\Protocol\CommonValues;
25
use AppserverIo\Stomp\Protocol\Headers;
26
use AppserverIo\Stomp\Utils\ErrorMessages;
27
28
/**
29
 * Implementation for a StompParser.
30
 *
31
 * @author    Lars Roettig <[email protected]>
32
 * @copyright 2016 TechDivision GmbH - <[email protected]>
33
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
 * @link      http://www.appserver.io/
35
 * @link      https://github.com/stomp/stomp-spec/blob/master/src/stomp-specification-1.1.md
36
 */
37
class Parser implements RequestParserInterface
38
{
39
40
    /**
41
     * List with keys to validate the values
42
     *
43
     * @var array
44
     */
45
    protected $keyValidationList;
46
47
    /**
48
     * Holds the parsed headers as key => value array.
49
     *
50
     * @var array
51
     */
52
    protected $headers;
53
54
    /**
55
     * Init the stomp parser class.
56
     */
57
    public function __construct()
58
    {
59
        $this->setKeyValidationList(array(Headers::CONTENT_LENGTH => "int"));
60
        $this->clearHeaders();
61
    }
62
63
    /**
64
     * Clear the headers to parse new stomp request.
65
     *
66
     * @return void
67
     */
68
    public function clearHeaders()
69
    {
70
        $this->headers = array();
71
    }
72
73
    /**
74
     * Return the headers count.
75
     *
76
     * @return int
77
     */
78
    public function getHeaderSize()
79
    {
80
        if (!isset($this->headers)) {
81
            return 0;
82
        } else {
83
            return count($this->headers);
84
        }
85
    }
86
87
    /**
88
     * Returns the parsed headers.
89
     *
90
     * @return array
91
     */
92
    public function getParsedHeaders()
93
    {
94
        // is accept-version not set than set to stomp version 1.0
95
        if (!array_key_exists(Headers::ACCEPT_VERSION, $this->headers)) {
96
            $this->headers[Headers::ACCEPT_VERSION] = CommonValues::V1_0;
97
        }
98
99
        // returns the parsed stomp headers
100
        return $this->headers;
101
    }
102
103
    /**
104
     * Parse the stomp frame headers.
105
     *
106
     * @param string $frameHeaders The frame headers.
107
     *
108
     * @return void
109
     * @throws \AppserverIo\Stomp\Exception\ProtocolException
110
     */
111
    public function parseHeaders($frameHeaders)
112
    {
113
        // get lines by explode header stomp newline
114
        $lines = explode(Frame::NEWLINE, $frameHeaders);
115
116
        // iterate over all header lines
117
        foreach ($lines as $line) {
118
            $this->parseHeaderLine($line);
119
        }
120
    }
121
122
    /**
123
     * Parse's the given header line.
124
     *
125
     * @param string $line The line defining a stomp request header
126
     *
127
     * @return void
128
     *
129
     * @throws \AppserverIo\Stomp\Exception\ProtocolException
130
     */
131
    public function parseHeaderLine($line)
132
    {
133
        // checks contains the line a separator
134
        if (strpos($line, Frame::COLON) === false) {
135
            throw new ProtocolException(ErrorMessages::UNABLE_PARSE_HEADER_LINE);
136
        }
137
138
        // explode the line by frame colon
139
        list($key, $value) = explode(Frame::COLON, $line, 2);
140
141
        // checks is the header key set
142
        if (strlen($key) === 0) {
143
            throw new ProtocolException(ErrorMessages::UNABLE_PARSE_HEADER_LINE);
144
        }
145
146
        // decode the key value pair
147
        $key = $this->decodeHeaderString($key);
148
        $value = $this->decodeHeaderString($value);
149
150
        // ignore existing keys
151
        if (array_key_exists($key, $this->headers) === true) {
152
            return;
153
        }
154
155
        // validate the value by given key
156
        if ($this->validateHeaderValue($key, $value) === false) {
157
            $type = $this->keyValidationList[$key];
158
            throw new ProtocolException(sprintf(ErrorMessages::HEADER_VALIDATION_ERROR, $key, $type));
159
        }
160
161
        // set the key value pair
162
        $this->headers[$key] = $value;
163
    }
164
165
    /**
166
     * Decode the header string.
167
     *
168
     * @param string $string The string to stomp decode.
169
     *
170
     * @return string
171
     */
172
    protected function decodeHeaderString($string)
173
    {
174
        return strtr($string, array(
175
            '\\n' => Frame::NEWLINE,
176
            '\\c' => Frame::COLON,
177
            '\\\\' => Frame::ESCAPE,
178
        ));
179
    }
180
181
    /**
182
     * Validates the given header value by given key.
183
     *
184
     * @param string $key   The key to find the validation type.
185
     * @param string $value The value to validated by type.
186
     *
187
     * @return bool
188
     */
189
    protected function validateHeaderValue($key, $value)
190
    {
191
        // loads the validation list
192
        $keyValidationList = $this->getKeyValidationList();
193
194
        // checks exist validation for the given key
195
        if (!array_key_exists($key, $keyValidationList)) {
196
            return true;
197
        }
198
199
        // validate the value by key type and returns the result
200
        $type = $keyValidationList[$key];
201
        switch ($type) {
202
            case "int":
203
                return ctype_digit($value);
204
        }
205
206
        // no validation available for the type.
207
        return false;
208
    }
209
210
    /**
211
     * Get the validation list.
212
     *
213
     * @return array
214
     */
215
    public function getKeyValidationList()
216
    {
217
        return $this->keyValidationList;
218
    }
219
220
    /**
221
     * Set the validation list.
222
     *
223
     * @param array $keyValidationList The list to set for validation
224
     *
225
     * @return void
226
     */
227
    public function setKeyValidationList($keyValidationList)
228
    {
229
        $this->keyValidationList = $keyValidationList;
230
    }
231
}
232