Passed
Pull Request — master (#1108)
by Tim
06:37
created

ServletManager::getDirectories()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 1
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * \AppserverIo\Appserver\ServletEngine\ServletManager
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 2015 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/appserver
18
 * @link      http://www.appserver.io
19
 */
20
21
namespace AppserverIo\Appserver\ServletEngine;
22
23
use AppserverIo\Storage\GenericStackable;
24
use AppserverIo\Storage\StorageInterface;
25
use AppserverIo\Appserver\Core\AbstractEpbManager;
26
use AppserverIo\Psr\Di\ObjectManagerInterface;
27
use AppserverIo\Psr\Application\ApplicationInterface;
28
use AppserverIo\Psr\Servlet\ServletInterface;
29
use AppserverIo\Psr\Servlet\ServletContextInterface;
30
use AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface;
31
use AppserverIo\Psr\Servlet\Description\ServletDescriptorInterface;
32
use AppserverIo\Appserver\Application\Interfaces\ManagerSettingsInterface;
33
use AppserverIo\Appserver\Application\Interfaces\ManagerSettingsAwareInterface;
34
35
/**
36
 * The servlet manager handles the servlets registered for the application.
37
 *
38
 * @author    Tim Wagner <[email protected]>
39
 * @copyright 2015 TechDivision GmbH <[email protected]>
40
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
41
 * @link      https://github.com/appserver-io/appserver
42
 * @link      http://www.appserver.io
43
 *
44
 * @property \AppserverIo\Storage\StorageInterface                                  $initParameters    The container for the init parameters
45
 * @property \AppserverIo\Appserver\ServletEngine\ResourceLocatorInterface          $resourceLocator   The resource locator for requested servlets
46
 * @property \AppserverIo\Appserver\ServletEngine\ResourceLocatorInterface          $servletLocator    The resource locator for the servlets
47
 * @property \AppserverIo\Storage\GenericStackable                                  $servletMappings   The container for the servlet mappings
48
 * @property \AppserverIo\Storage\StorageInterface                                  $servlets          The container for the servlets
49
 * @property \AppserverIo\Storage\StorageInterface                                  $sessionParameters The container for the session parameters
50
 * @property \AppserverIo\Appserver\Application\Interfaces\ManagerSettingsInterface $managerSettings   Settings for the servlet manager
51
 */
52
class ServletManager extends AbstractEpbManager implements ServletContextInterface, ManagerSettingsAwareInterface
53
{
54
55
    /**
56
     * Injects the resource locator that locates the requested servlet.
57
     *
58
     * @param \AppserverIo\Appserver\ServletEngine\ResourceLocatorInterface $resourceLocator The resource locator
59
     *
60
     * @return void
61
     */
62
    public function injectResourceLocator(ResourceLocatorInterface $resourceLocator)
63
    {
64
        $this->resourceLocator = $resourceLocator;
65
    }
66
67
    /**
68
     * Injects the container for the servlets.
69
     *
70
     * @param \AppserverIo\Storage\StorageInterface $servlets The container for the servlets
71
     *
72
     * @return void
73
     */
74
    public function injectServlets(StorageInterface $servlets)
75
    {
76
        $this->servlets = $servlets;
77
    }
78
79
    /**
80
     * Injects the container for the servlet mappings.
81
     *
82
     * @param \AppserverIo\Storage\GenericStackable $servletMappings The container for the servlet mappings
83
     *
84
     * @return void
85
     */
86
    public function injectServletMappings(GenericStackable $servletMappings)
87
    {
88
        $this->servletMappings = $servletMappings;
89
    }
90
91
    /**
92
     * Injects the container for the init parameters.
93
     *
94
     * @param \AppserverIo\Storage\StorageInterface $initParameters The container for the init parameters
95
     *
96
     * @return void
97
     */
98
    public function injectInitParameters(StorageInterface $initParameters)
99
    {
100
        $this->initParameters = $initParameters;
101
    }
102
103
    /**
104
     * Injects the container for the secured URL configurations.
105
     *
106
     * @param \AppserverIo\Storage\StorageInterface $securedUrlConfigs The container for the secured URL configurations
107
     *
108
     * @return void
109
     */
110
    public function injectSecuredUrlConfigs(StorageInterface $securedUrlConfigs)
111
    {
112
        $this->securedUrlConfigs = $securedUrlConfigs;
0 ignored issues
show
Bug Best Practice introduced by
The property securedUrlConfigs does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
113
    }
114
115
    /**
116
     * Injects the container for the session parameters.
117
     *
118
     * @param \AppserverIo\Storage\StorageInterface $sessionParameters The container for the session parameters
119
     *
120
     * @return void
121
     */
122
    public function injectSessionParameters(StorageInterface $sessionParameters)
123
    {
124
        $this->sessionParameters = $sessionParameters;
125
    }
126
127
    /**
128
     * Injects the container for the error page configuration.
129
     *
130
     * @param \AppserverIo\Storage\StorageInterface $errorPages The container for the error page configuration
131
     *
132
     * @return void
133
     */
134
    public function injectErrorPages(StorageInterface $errorPages)
135
    {
136
        $this->errorPages = $errorPages;
0 ignored issues
show
Bug Best Practice introduced by
The property errorPages does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
137
    }
138
139
    /**
140
     * Injects the servlet manager settings.
141
     *
142
     * @param \AppserverIo\Appserver\Application\Interfaces\ManagerSettingsInterface $managerSettings The servlet manager settings
143
     *
144
     * @return void
145
     */
146
    public function injectManagerSettings(ManagerSettingsInterface $managerSettings)
147
    {
148
        $this->managerSettings = $managerSettings;
149
    }
150
151
    /**
152
     * Has been automatically invoked by the container after the application
153
     * instance has been created.
154
     *
155
     * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance
156
     *
157
     * @return void
158
     * @see \AppserverIo\Psr\Application\ManagerInterface::initialize()
159
     */
160
    public function initialize(ApplicationInterface $application)
161
    {
162
163
        // register the annotation registries
164
        $application->registerAnnotationRegistries();
0 ignored issues
show
Bug introduced by
The method registerAnnotationRegistries() does not exist on AppserverIo\Psr\Application\ApplicationInterface. It seems like you code against a sub-type of AppserverIo\Psr\Application\ApplicationInterface such as AppserverIo\Appserver\Application\Application. ( Ignorable by Annotation )

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

164
        $application->/** @scrutinizer ignore-call */ 
165
                      registerAnnotationRegistries();
Loading history...
165
166
        // parse the object descriptors
167
        $this->parseObjectDescriptors();
168
169
        // register the servlets
170
        $this->registerServlets($application);
171
    }
172
173
    /**
174
     * Finds all servlets which are provided by the webapps and initializes them.
175
     *
176
     * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance
177
     *
178
     * @return void
179
     *
180
     * @throws \AppserverIo\Appserver\ServletEngine\InvalidServletMappingException
181
     */
182
    public function registerServlets(ApplicationInterface $application)
0 ignored issues
show
Unused Code introduced by
The parameter $application is not used and could be removed. ( Ignorable by Annotation )

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

182
    public function registerServlets(/** @scrutinizer ignore-unused */ ApplicationInterface $application)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
183
    {
184
185
        // load the object manager instance
186
        /** @var \AppserverIo\Psr\Di\ObjectManagerInterface $objectManager */
187
        $objectManager = $this->getApplication()->search(ObjectManagerInterface::IDENTIFIER);
188
189
        // register the beans located by annotations and the XML configuration
190
        /** \AppserverIo\Psr\Deployment\DescriptorInterface $objectDescriptor */
191
        foreach ($objectManager->getObjectDescriptors() as $descriptor) {
192
            // check if we've found a servlet descriptor and register the servlet
193
            if ($descriptor instanceof ServletDescriptorInterface) {
194
                $this->registerServlet($descriptor);
195
            }
196
        }
197
    }
198
199
    /**
200
     * Register the servlet described by the passed descriptor.
201
     *
202
     * @param \AppserverIo\Psr\Servlet\Description\ServletDescriptorInterface $descriptor The servlet descriptor
203
     *
204
     * @return void
205
     */
206
    public function registerServlet(ServletDescriptorInterface $descriptor)
207
    {
208
209
        try {
210
            // prepend the url-pattern - servlet mapping to the servlet mappings
211
            foreach ($descriptor->getUrlPatterns() as $pattern) {
212
                $this->addServletMapping($pattern, $descriptor->getName());
213
            }
214
215
            // register's the servlet's references
216
            $this->registerReferences($descriptor);
217
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
218
        } catch (\Exception $e) {
219
            // log the exception
220
            $this->getApplication()->getInitialContext()->getSystemLogger()->critical($e->__toString());
0 ignored issues
show
Bug introduced by
The method getInitialContext() does not exist on AppserverIo\Psr\Application\ApplicationInterface. It seems like you code against a sub-type of AppserverIo\Psr\Application\ApplicationInterface such as AppserverIo\Appserver\Application\Application. ( Ignorable by Annotation )

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

220
            $this->getApplication()->/** @scrutinizer ignore-call */ getInitialContext()->getSystemLogger()->critical($e->__toString());
Loading history...
221
        }
222
    }
223
224
    /**
225
     * Lifecycle callback that'll be invoked after the application has been started.
226
     *
227
     * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance
228
     *
229
     * @return void
230
     * @see \AppserverIo\Psr\Application\ManagerInterface::postStartup()
231
     */
232
    public function postStartup(ApplicationInterface $application)
233
    {
234
235
        // load the object manager
236
        /** @var \AppserverIo\Psr\Di\ObjectManagerInterface $objectManager */
237
        $objectManager = $application->search(ObjectManagerInterface::IDENTIFIER);
238
239
        // register the beans found by annotations and the XML configuration
240
        /** \AppserverIo\Psr\Deployment\DescriptorInterface $objectDescriptor */
241
        foreach ($objectManager->getObjectDescriptors() as $descriptor) {
242
            // if we found a singleton session bean with a startup callback instanciate it
243
            if ($descriptor instanceof ServletDescriptorInterface) {
244
                // instantiate the servlet
245
                $instance = $this->get($servletName = $descriptor->getName());
246
247
                // initialize the servlet configuration
248
                $servletConfig = new ServletConfiguration();
249
                $servletConfig->injectServletContext($this);
250
                $servletConfig->injectServletName($servletName);
251
252
                // append the init params to the servlet configuration
253
                foreach ($descriptor->getInitParams() as $paramName => $paramValue) {
254
                    $servletConfig->addInitParameter($paramName, $paramValue);
255
                }
256
257
                // initialize the servlet
258
                $instance->init($servletConfig);
259
260
                // the servlet is added to the dictionary using the complete request path as the key
261
                $this->addServlet($servletName, $instance);
262
            }
263
        }
264
    }
265
266
    /**
267
     * Returns all servlets
268
     *
269
     * @return array The servlets collection
270
     */
271
    public function getServlets()
272
    {
273
        return $this->servlets;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->servlets returns the type AppserverIo\Storage\StorageInterface which is incompatible with the documented return type array.
Loading history...
274
    }
275
276
    /**
277
     * Returns the servlet mappings found in the
278
     * configuration file.
279
     *
280
     * @return \AppserverIo\Storage\GenericStackable The servlet mappings
281
     */
282
    public function getServletMappings()
283
    {
284
        return $this->servletMappings;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->servletMappings returns the type AppserverIo\Storage\GenericStackable which is incompatible with the return type mandated by AppserverIo\Psr\Servlet\...e::getServletMappings() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
285
    }
286
287
    /**
288
     * Returns the resource locator for the servlets.
289
     *
290
     * @return \AppserverIo\Appserver\ServletEngine\ResourceLocatorInterface The resource locator for the servlets
291
     */
292
    public function getServletLocator()
293
    {
294
        return $this->servletLocator;
295
    }
296
297
    /**
298
     * Returns the servlet with the passed name.
299
     *
300
     * @param string $key The name of the servlet to return
301
     *
302
     * @return \AppserverIo\Psr\Servlet\ServletInterface The servlet instance
303
     */
304
    public function getServlet($key)
305
    {
306
        if ($this->servlets->has($key)) {
307
            return $this->servlets->get($key);
308
        }
309
    }
310
311
    /**
312
     * Returns the servlet for the passed URL mapping.
313
     *
314
     * @param string $urlMapping The URL mapping to return the servlet for
315
     *
316
     * @return \AppserverIo\Psr\Servlet\ServletInterface The servlet instance
317
     */
318
    public function getServletByMapping($urlMapping)
319
    {
320
        if (isset($this->servletMappings[$urlMapping])) {
321
            return $this->getServlet($this->servletMappings[$urlMapping]);
322
        }
323
    }
324
325
    /**
326
     * Registers a servlet under the passed key.
327
     *
328
     * @param string                                    $key     The servlet to key to register with
329
     * @param \AppserverIo\Psr\Servlet\ServletInterface $servlet The servlet to be registered
330
     *
331
     * @return void
332
     */
333
    public function addServlet($key, ServletInterface $servlet)
334
    {
335
        $this->servlets->set($key, $servlet);
336
    }
337
338
    /**
339
     * Adds an URL mapping for a servlet.
340
     *
341
     * @param string $pattern     The URL pattern we want the servlet to map to
342
     * @param string $servletName The servlet name to map
343
     *
344
     * @return void
345
     */
346
    public function addServletMapping($pattern, $servletName)
347
    {
348
        $this->servletMappings[$pattern] = $servletName;
349
    }
350
351
    /**
352
     * Return the resource locator instance.
353
     *
354
     * @return \AppserverIo\Appserver\ServletEngine\ResourceLocatorInterface The resource locator instance
355
     */
356
    public function getResourceLocator()
357
    {
358
        return $this->resourceLocator;
359
    }
360
361
    /**
362
     * Registers the init parameter under the passed name.
363
     *
364
     * @param string $name  Name to register the init parameter with
365
     * @param string $value The value of the init parameter
366
     *
367
     * @return void
368
     */
369
    public function addInitParameter($name, $value)
370
    {
371
        $this->initParameters->set($name, $value);
372
    }
373
374
    /**
375
     * Returns the init parameter with the passed name.
376
     *
377
     * @param string $name Name of the init parameter to return
378
     *
379
     * @return null|string
380
     */
381
    public function getInitParameter($name)
382
    {
383
        if ($this->initParameters->has($name)) {
384
            return $this->initParameters->get($name);
385
        }
386
    }
387
388
    /**
389
     * Registers the error page under the passed error code.
390
     *
391
     * @param string $errorCodePattern The error code for the page
392
     * @param string $errorLocation    The error page location
393
     *
394
     * @return void
395
     */
396
    public function addErrorPage($errorCodePattern, $errorLocation)
397
    {
398
        $this->errorPages->set($errorCodePattern, $errorLocation);
399
    }
400
401
    /**
402
     * Returns the container with the error page configuration.
403
     *
404
     * @return \AppserverIo\Storage\StorageInterface The container with the error page configuration
405
     */
406
    public function getErrorPages()
407
    {
408
        return $this->errorPages;
409
    }
410
411
    /**
412
     * Returns the webapps security context configurations.
413
     *
414
     * @return array The security context configurations
415
     * @throws \AppserverIo\Appserver\ServletEngine\OperationNotSupportedException Is thrown if this method has been invoked
416
     */
417
    public function getSecuredUrlConfigs()
418
    {
419
        throw new OperationNotSupportedException(sprintf('%s not yet implemented', __METHOD__));
420
    }
421
422
    /**
423
     * Registers the session parameter under the passed name.
424
     *
425
     * @param string $name  Name to register the session parameter with
426
     * @param string $value The value of the session parameter
427
     *
428
     * @return void
429
     */
430
    public function addSessionParameter($name, $value)
431
    {
432
        $this->sessionParameters->set($name, $value);
433
    }
434
435
    /**
436
     * Returns the session parameter with the passed name.
437
     *
438
     * @param string $name Name of the session parameter to return
439
     *
440
     * @return null|string
441
     */
442
    public function getSessionParameter($name)
443
    {
444
        if ($this->sessionParameters->has($name)) {
445
            return $this->sessionParameters->get($name);
446
        }
447
    }
448
449
    /**
450
     * Returns TRUE if we've at least one session parameter configured, else FALSE.
451
     *
452
     * @return boolean TRUE if we've at least one session parameter configured, else FALSE
453
     */
454
    public function hasSessionParameters()
455
    {
456
        return sizeof($this->sessionParameters) > 0;
457
    }
458
459
    /**
460
     * Return's the servlet manager settings.
461
     *
462
     * @return \AppserverIo\Appserver\Application\Interfaces\ManagerSettingsInterface The servlet manager settings
463
     */
464
    public function getManagerSettings()
465
    {
466
        return $this->managerSettings;
467
    }
468
469
    /**
470
     * Tries to locate the resource related with the request.
471
     *
472
     * @param \AppserverIo\Psr\Servlet\Http\HttpServletRequestInterface $servletRequest The request instance to return the servlet for
473
     * @param array                                                     $args           The arguments passed to the servlet constructor
474
     *
475
     * @return \AppserverIo\Psr\Servlet\ServletInterface The requested servlet
476
     * @see \AppserverIo\Appserver\ServletEngine\ServletLocator::locate()
477
     */
478
    public function locate(HttpServletRequestInterface $servletRequest, array $args = array())
479
    {
480
481
        // load the servlet path => to locate the servlet
482
        $servletPath = $servletRequest->getServletPath();
483
484
        // if a session cookie has been sent, initialize the session manager and the session
485
        if ($manager = $this->getApplication()->search(SessionManagerInterface::IDENTIFIER)) {
486
            $requestedSessionName = $manager->getSessionSettings()->getSessionName();
487
            if ($servletRequest->hasCookie($requestedSessionName)) {
488
                $servletRequest->getCookie($requestedSessionName)->getValue();
489
            }
490
        }
491
492
        // return the instance
493
        return $this->lookup($servletPath, $args);
494
    }
495
496
    /**
497
     * Runs a lookup for the servlet with the passed class name and
498
     * session ID.
499
     *
500
     * @param string $servletPath The servlet path
501
     * @param array  $args        The arguments passed to the servlet constructor
502
     *
503
     * @return \AppserverIo\Psr\Servlet\ServletInterface The requested servlet
504
     */
505
    public function lookup($servletPath, array $args = array())
506
    {
507
        return $this->getResourceLocator()->locate($this, $servletPath, $args);
0 ignored issues
show
Unused Code introduced by
The call to AppserverIo\Appserver\Se...atorInterface::locate() has too many arguments starting with $args. ( Ignorable by Annotation )

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

507
        return $this->getResourceLocator()->/** @scrutinizer ignore-call */ locate($this, $servletPath, $args);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
508
    }
509
510
    /**
511
     * Returns the identifier for the servlet manager instance.
512
     *
513
     * @return string
514
     * @see \AppserverIo\Psr\Application\ManagerInterface::getIdentifier()
515
     */
516
    public function getIdentifier()
517
    {
518
        return ServletContextInterface::IDENTIFIER;
519
    }
520
}
521