RequestHandler   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 14
eloc 37
dl 0
loc 184
ccs 0
cts 59
cp 0
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A produces() 0 3 2
A getConfigurationParser() 0 3 1
A getApplication() 0 3 1
A init() 0 3 1
A __construct() 0 8 1
A encode() 0 6 1
A addOperation() 0 13 2
A handle() 0 28 4
A getRequestParser() 0 3 1
1
<?php
2
3
/**
4
 * AppserverIo\RestApi\Handlers\OA2\RequestHandler
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    Tim Wagner <[email protected]>
15
 * @copyright 2018 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/appserver-io/restapi
18
 * @link      http://www.appserver.io
19
 */
20
21
namespace AppserverIo\RestApi\Handlers\OA2;
22
23
use JMS\Serializer\SerializerBuilder;
24
use AppserverIo\Psr\HttpMessage\Protocol;
25
use AppserverIo\Psr\Application\ApplicationInterface;
26
use AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface;
27
use AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface;
28
use AppserverIo\RestApi\Utils\FormatKeys;
29
use AppserverIo\RestApi\Parsers\RequestParserInterface;
30
use AppserverIo\RestApi\Parsers\ConfigurationParserInterface;
31
use AppserverIo\RestApi\Handlers\RequestHandlerInterface;
32
use AppserverIo\RestApi\Wrappers\OperationWrapperInterface;
33
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
34
use JMS\Serializer\Naming\IdenticalPropertyNamingStrategy;
35
36
/**
37
 * OpenApi 2.0 compatible request handler.
38
 *
39
 * @author    Tim Wagner <[email protected]>
40
 * @copyright 2018 TechDivision GmbH <[email protected]>
41
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
42
 * @link      https://github.com/appserver-io/restapi
43
 * @link      http://www.appserver.io
44
 */
45
class RequestHandler implements RequestHandlerInterface
46
{
47
48
    /**
49
     * The encoding to mime type mapping.
50
     *
51
     * @var array
52
     */
53
    protected $formatToMimeType = array(
54
        FormatKeys::FORMAT_XML  => 'application/xml',
55
        FormatKeys::FORMAT_JSON => 'application/json'
56
    );
57
58
    /**
59
     * The array with the available operations.
60
     *
61
     * @var array
62
     */
63
    protected $operationWrappers = array();
64
65
    /**
66
     * The application instance.
67
     *
68
     * @var \AppserverIo\Psr\Application\ApplicationInterface
69
     */
70
    protected $application;
71
72
    /**
73
     * The request parser instance to use.
74
     *
75
     * @var \AppserverIo\RestApi\Parsers\RequestParserInterface
76
     */
77
    protected $requestParser;
78
79
    /**
80
     * The configuration parser instance to use.
81
     *
82
     * @var \AppserverIo\RestApi\Parsers\ConfigurationParserInterface
83
     */
84
    protected $configurationParser;
85
86
    /**
87
     * Initializes the request handler with the passed instances.
88
     *
89
     * @param \AppserverIo\Psr\Application\ApplicationInterface         $application         The application instance
90
     * @param \AppserverIo\RestApi\Parsers\RequestParserInterface       $requestParser       The request parser instance
91
     * @param \AppserverIo\RestApi\Parsers\ConfigurationParserInterface $configurationParser The configuration parser instanc
92
     */
93
    public function __construct(
94
        ApplicationInterface $application,
95
        RequestParserInterface $requestParser,
96
        ConfigurationParserInterface $configurationParser
97
    ) {
98
        $this->application = $application;
99
        $this->requestParser = $requestParser;
100
        $this->configurationParser = $configurationParser;
101
    }
102
103
    /**
104
     * Returns the application instance.
105
     *
106
     * @return \AppserverIo\Psr\Application\ApplicationInterface The application instance
107
     */
108
    protected function getApplication()
109
    {
110
        return $this->application;
111
    }
112
113
    /**
114
     * Returns the request parser instance.
115
     *
116
     * @return \AppserverIo\RestApi\Parsers\RequestParserInterface The parser instance
117
     */
118
    protected function getRequestParser()
119
    {
120
        return $this->requestParser;
121
    }
122
123
    /**
124
     * Returns the configuration parser instance.
125
     *
126
     * @return \AppserverIo\RestApi\Parsers\ConfigurationParserInterface The parser instance
127
     */
128
    protected function getConfigurationParser()
129
    {
130
        return $this->configurationParser;
131
    }
132
133
    /**
134
     * Encodes the passed data, to JSON format for example, and returns it.
135
     *
136
     * @param object|array $data   The data to be encoded
137
     * @param string       $format The encoding format (JSON by default)
138
     *
139
     * @return string The encoded data
140
     */
141
    protected function encode($data, $format = FormatKeys::FORMAT_JSON)
142
    {
143
        return SerializerBuilder::create()
144
            ->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy()))
145
            ->build()
146
            ->serialize($data, $format);
147
    }
148
149
    /**
150
     * Returns the mime type for the given format, which can either be `xml` or `json`.
151
     *
152
     * @param string $format The format to return the mime type for
153
     *
154
     * @return string The mime type
155
     */
156
    protected function produces($format = FormatKeys::FORMAT_JSON)
157
    {
158
        return isset($this->formatToMimeType[$format]) ? $this->formatToMimeType[$format] : FormatKeys::FORMAT_JSON;
159
    }
160
161
    /**
162
     * Initializes the request handler.
163
     *
164
     * @return void
165
     */
166
    public function init()
167
    {
168
        $this->getConfigurationParser()->parse($this);
169
    }
170
171
    /**
172
     * Adds the passed operation wrapper to the servlet.
173
     *
174
     * @param \AppserverIo\RestApi\Wrappers\OperationWrapperInterface $operationWrapper The operation wrapper to add
175
     *
176
     * @return void
177
     */
178
    public function addOperation(OperationWrapperInterface $operationWrapper)
179
    {
180
181
        // load the operations request method
182
        $method = strtolower($operationWrapper->getMethod());
183
184
        // initialize the array with the operations for that request method, if necessary
185
        if (!isset($this->operationWrappers[$method])) {
186
            $this->operationWrappers[$method] = array();
187
        }
188
189
        // append the operation to the array
190
        array_push($this->operationWrappers[$method], $operationWrapper);
191
    }
192
193
    /**
194
     * Process the passed request instance.
195
     *
196
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface  $servletRequest  The HTTP servlet request instance
197
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletResponseInterface $servletResponse The HTTP servlet response instance
198
     *
199
     * @return void
200
     */
201
    public function handle(HttpServletRequestInterface $servletRequest, HttpServletResponseInterface $servletResponse)
202
    {
203
204
        // iterate over the operations for the actual request method
205
        foreach ($this->operationWrappers[strtolower($servletRequest->getMethod())] as $oprationWrapper) {
206
            // query whether or not, the operation's path matches the request path info
207
            if ($oprationWrapper->match($servletRequest)) {
208
                try {
209
                    // load the operations parameters
210
                    $parameters = $this->getRequestParser()->parse($servletRequest, $oprationWrapper);
211
212
                    // lookup the bean instance from the application
213
                    $instance = $this->getApplication()->search($oprationWrapper->getLookupName());
214
215
                    // inovoke the method
216
                    $result = call_user_func_array(array($instance, $oprationWrapper->getMethodName()), $parameters);
217
218
                    // append the result and the headers to the response
219
                    $servletResponse->addHeader(Protocol::HEADER_CONTENT_TYPE, $this->produces());
220
                    $servletResponse->appendBodyStream($this->encode($result));
221
                } catch (\Exception $e) {
222
                    // log the error
223
                    \error($e);
0 ignored issues
show
Bug introduced by
The function error was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

223
                    /** @scrutinizer ignore-call */ 
224
                    \error($e);
Loading history...
224
225
                    // send a 500 status code and append the error message to the response
226
                    $servletResponse->setStatusCode(500);
227
                    $servletResponse->addHeader(Protocol::HEADER_CONTENT_TYPE, $this->produces());
228
                    $servletResponse->appendBodyStream($this->encode(array('error' => $e->getMessage())));
229
                }
230
            }
231
        }
232
    }
233
}
234