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

BeanManager::getResourceLocator()   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 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * \AppserverIo\Appserver\PersistenceContainer\BeanManager
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    Bernhard Wick <[email protected]>
15
 * @author    Tim Wagner <[email protected]>
16
 * @copyright 2015 TechDivision GmbH <[email protected]>
17
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
18
 * @link      https://github.com/appserver-io/appserver
19
 * @link      http://www.appserver.io
20
 */
21
22
namespace AppserverIo\Appserver\PersistenceContainer;
23
24
use AppserverIo\Storage\GenericStackable;
25
use AppserverIo\Storage\StorageInterface;
26
use AppserverIo\Collections\CollectionInterface;
27
use AppserverIo\Lang\Reflection\AnnotationInterface;
28
use AppserverIo\RemoteMethodInvocation\RemoteMethodInterface;
29
use AppserverIo\Appserver\Core\Environment;
30
use AppserverIo\Appserver\Core\AbstractEpbManager;
31
use AppserverIo\Appserver\Core\Utilities\EnvironmentKeys;
32
use AppserverIo\Psr\Servlet\SessionUtils;
33
use AppserverIo\Psr\Di\ObjectManagerInterface;
34
use AppserverIo\Psr\Deployment\DescriptorInterface;
35
use AppserverIo\Psr\Application\ApplicationInterface;
36
use AppserverIo\Psr\EnterpriseBeans\BeanContextInterface;
37
use AppserverIo\Psr\EnterpriseBeans\ResourceLocatorInterface;
38
use AppserverIo\Psr\EnterpriseBeans\InvalidBeanTypeException;
39
use AppserverIo\Psr\EnterpriseBeans\Description\BeanDescriptorInterface;
40
use AppserverIo\Psr\EnterpriseBeans\Description\SessionBeanDescriptorInterface;
41
use AppserverIo\Psr\EnterpriseBeans\Description\SingletonSessionBeanDescriptorInterface;
42
use AppserverIo\Psr\EnterpriseBeans\Description\StatefulSessionBeanDescriptorInterface;
43
use AppserverIo\Psr\EnterpriseBeans\Description\StatelessSessionBeanDescriptorInterface;
44
use AppserverIo\Psr\EnterpriseBeans\Description\MessageDrivenBeanDescriptorInterface;
45
use AppserverIo\Appserver\Application\Interfaces\ManagerSettingsInterface;
46
use AppserverIo\Appserver\Application\Interfaces\ManagerSettingsAwareInterface;
47
use AppserverIo\Appserver\PersistenceContainer\Utils\SessionBeanUtil;
48
use AppserverIo\Appserver\PersistenceContainer\Tasks\StartupBeanTask;
49
use AppserverIo\Appserver\PersistenceContainer\DependencyInjection\DirectoryParser;
0 ignored issues
show
Bug introduced by
The type AppserverIo\Appserver\Pe...jection\DirectoryParser was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
50
use AppserverIo\Appserver\PersistenceContainer\DependencyInjection\DeploymentDescriptorParser;
51
use AppserverIo\Appserver\PersistenceContainer\GarbageCollectors\StandardGarbageCollector;
52
use AppserverIo\Appserver\PersistenceContainer\RemoteMethodInvocation\ProxyGeneratorInterface;
53
use AppserverIo\Appserver\PersistenceContainer\GarbageCollectors\StartupBeanTaskGarbageCollector;
54
55
/**
56
 * The bean manager handles the message and session beans registered for the application.
57
 *
58
 * @author    Bernhard Wick <[email protected]>
59
 * @author    Tim Wagner <[email protected]>
60
 * @copyright 2015 TechDivision GmbH <[email protected]>
61
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
62
 * @link      https://github.com/appserver-io/appserver
63
 * @link      http://www.appserver.io
64
 *
65
 * @property array                                                                                         $requestContext                  The request context to cache the beans
66
 * @property \AppserverIo\Psr\EnterpriseBeans\ResourceLocatorInterface                                     $resourceLocator                 The resource locator
67
 * @property \AppserverIo\Storage\StorageInterface                                                         $statefulSessionBeans            The storage for the stateful session beans
68
 * @property \AppserverIo\Storage\StorageInterface                                                         $singletonSessionBeans           The storage for the singleton session beans
69
 * @property \AppserverIo\Appserver\PersistenceContainer\BeanManagerSettingsInterface                      $managerSettings                 Settings for the bean manager
70
 * @property \AppserverIo\Appserver\PersistenceContainer\StatefulSessionBeanMapFactory                     $statefulSessionBeanMapFactory   The factory instance
71
 * @property \AppserverIo\Appserver\PersistenceContainer\ObjectFactoryInterface                            $objectFactory                   The object factory instance
72
 * @property \AppserverIo\Appserver\PersistenceContainer\RemoteMethodInvocation\ProxyGeneratorInterface    $remoteProxyGenerator            The remote proxy generator
73
 * @property \AppserverIo\Storage\GenericStackable                                                         $startupBeanTasks                The storage with manager's startup bean tasks
74
 * @property \AppserverIo\Appserver\PersistenceContainer\GarbageCollectors\StandardGarbageCollector        $garbageCollector                The standard garbage collection for the SFSBs
75
 * @property \AppserverIo\Appserver\PersistenceContainer\GarbageCollectors\StartupBeanTaskGarbageCollector $startupBeanTaskGarbageCollector The garbage collector for the startup bean tasks
76
 */
77
class BeanManager extends AbstractEpbManager implements BeanContextInterface, ManagerSettingsAwareInterface
78
{
79
80
    /**
81
     * Injects the request context to cache the beans.
82
     *
83
     * @param array $requestContext The request context
84
     *
85
     * @return void
86
     */
87
    public function injectRequestContext(array $requestContext)
88
    {
89
        $this->requestContext = $requestContext;
90
    }
91
92
    /**
93
     * Injects the resource locator to lookup the requested queue.
94
     *
95
     * @param \AppserverIo\Psr\EnterpriseBeans\ResourceLocatorInterface $resourceLocator The resource locator
96
     *
97
     * @return void
98
     */
99
    public function injectResourceLocator(ResourceLocatorInterface $resourceLocator)
100
    {
101
        $this->resourceLocator = $resourceLocator;
102
    }
103
104
    /**
105
     * Injects the storage for the stateful session beans.
106
     *
107
     * @param \AppserverIo\Storage\StorageInterface $statefulSessionBeans The storage for the stateful session beans
108
     *
109
     * @return void
110
     */
111
    public function injectStatefulSessionBeans($statefulSessionBeans)
112
    {
113
        $this->statefulSessionBeans = $statefulSessionBeans;
114
    }
115
116
    /**
117
     * Injects the storage for the singleton session beans.
118
     *
119
     * @param \AppserverIo\Storage\StorageInterface $singletonSessionBeans The storage for the singleton session beans
120
     *
121
     * @return void
122
     */
123
    public function injectSingletonSessionBeans(StorageInterface $singletonSessionBeans)
124
    {
125
        $this->singletonSessionBeans = $singletonSessionBeans;
126
    }
127
128
    /**
129
     * Injects the bean manager settings.
130
     *
131
     * @param \AppserverIo\Appserver\PersistenceContainer\BeanManagerSettingsInterface $managerSettings The bean manager settings
132
     *
133
     * @return void
134
     */
135
    public function injectManagerSettings(ManagerSettingsInterface $managerSettings)
136
    {
137
        $this->managerSettings = $managerSettings;
0 ignored issues
show
Documentation Bug introduced by
$managerSettings is of type AppserverIo\Appserver\Ap...anagerSettingsInterface, but the property $managerSettings was declared to be of type AppserverIo\Appserver\Pe...anagerSettingsInterface. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
138
    }
139
140
    /**
141
     * Injects the object factory instance.
142
     *
143
     * @param \AppserverIo\Appserver\PersistenceContainer\ObjectFactoryInterface $objectFactory The object factory instance
144
     *
145
     * @return void
146
     */
147
    public function injectObjectFactory(ObjectFactoryInterface $objectFactory)
148
    {
149
        $this->objectFactory = $objectFactory;
150
    }
151
152
    /**
153
     * Injects the garbage collector.
154
     *
155
     * @param \AppserverIo\Appserver\PersistenceContainer\GarbageCollectors\StandardGarbageCollector $garbageCollector The garbage collector
156
     *
157
     * @return void
158
     */
159
    public function injectGarbageCollector(StandardGarbageCollector $garbageCollector)
160
    {
161
        $this->garbageCollector = $garbageCollector;
162
    }
163
164
    /**
165
     * Injects the startup bean task garbage collector.
166
     *
167
     * @param \AppserverIo\Appserver\PersistenceContainer\GarbageCollectors\StartupBeanTaskGarbageCollector $startupBeanTaskGarbageCollector The garbage collector
168
     *
169
     * @return void
170
     */
171
    public function injectStartupBeanTaskGarbageCollector(StartupBeanTaskGarbageCollector $startupBeanTaskGarbageCollector)
172
    {
173
        $this->startupBeanTaskGarbageCollector = $startupBeanTaskGarbageCollector;
174
    }
175
176
    /**
177
     * Injects the remote proxy generator.
178
     *
179
     * @param \AppserverIo\Appserver\PersistenceContainer\RemoteMethodInvocation\ProxyGeneratorInterface $remoteProxyGenerator The remote proxy generator
180
     *
181
     * @return void
182
     */
183
    public function injectRemoteProxyGenerator(ProxyGeneratorInterface $remoteProxyGenerator)
184
    {
185
        $this->remoteProxyGenerator = $remoteProxyGenerator;
186
    }
187
188
    /**
189
     * Injects the storage for the startup bean tasks.
190
     *
191
     * @param \AppserverIo\Storage\GenericStackable $startupBeanTasks The storage for the startup bean tasks
192
     *
193
     * @return void
194
     */
195
    public function injectStartupBeanTasks(GenericStackable $startupBeanTasks)
196
    {
197
        $this->startupBeanTasks = $startupBeanTasks;
198
    }
199
200
    /**
201
     * Lifecycle callback that'll be invoked after the application has been started.
202
     *
203
     * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance
204
     *
205
     * @return void
206
     * @see \AppserverIo\Psr\Application\ManagerInterface::postStartup()
207
     */
208
    public function postStartup(ApplicationInterface $application)
209
    {
210
211
        // load the object manager
212
        /** @var \AppserverIo\Psr\Di\ObjectManagerInterface $objectManager */
213
        $objectManager = $application->search(ObjectManagerInterface::IDENTIFIER);
214
215
        // register the beans found by annotations and the XML configuration
216
        /** \AppserverIo\Psr\Deployment\DescriptorInterface $objectDescriptor */
217
        foreach ($objectManager->getObjectDescriptors() as $descriptor) {
218
            // if we found a singleton session bean with a startup callback instanciate it
219
            if ($descriptor instanceof SingletonSessionBeanDescriptorInterface && $descriptor->isInitOnStartup()) {
220
                $this->startupBeanTasks[] = new StartupBeanTask($application, $descriptor);
221
            }
222
        }
223
    }
224
225
    /**
226
     * Has been automatically invoked by the container after the application
227
     * instance has been created.
228
     *
229
     * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance
230
     *
231
     * @return void
232
     * @see \AppserverIo\Psr\Application\ManagerInterface::initialize()
233
     */
234
    public function initialize(ApplicationInterface $application)
235
    {
236
237
        // add the application instance to the environment
238
        Environment::singleton()->setAttribute(EnvironmentKeys::APPLICATION, $application);
239
240
        // create s simulated request/session ID whereas session equals request ID
241
        Environment::singleton()->setAttribute(EnvironmentKeys::SESSION_ID, $sessionId = SessionUtils::generateRandomString());
242
        Environment::singleton()->setAttribute(EnvironmentKeys::REQUEST_ID, $sessionId);
243
244
        // finally register the beans
245
        $this->registerBeans($application);
246
    }
247
248
    /**
249
     * Registers the message beans at startup.
250
     *
251
     * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance
252
     *
253
     * @return void
254
     */
255
    public function registerBeans(ApplicationInterface $application)
256
    {
257
258
        // query whether or not the web application folder exists
259
        if (is_dir($this->getWebappPath()) === false) {
260
            return;
261
        }
262
263
        // parse the object descriptors
264
        $this->parseObjectDescriptors();
265
266
        // load the object manager
267
        /** @var \AppserverIo\Psr\Di\ObjectManagerInterface $objectManager */
268
        $objectManager = $this->getApplication()->search(ObjectManagerInterface::IDENTIFIER);
269
270
        // register the beans found by annotations and the XML configuration
271
        /** \AppserverIo\Psr\Deployment\DescriptorInterface $objectDescriptor */
272
        foreach ($objectManager->getObjectDescriptors() as $descriptor) {
273
            // check if we've found a bean descriptor and register the bean
274
            if ($descriptor instanceof BeanDescriptorInterface) {
275
                $this->registerBean($descriptor);
276
            }
277
        }
278
    }
279
280
    /**
281
     * Register the bean described by the passed descriptor.
282
     *
283
     * @param \AppserverIo\Psr\EnterpriseBeans\Description\BeanDescriptorInterface $descriptor The bean descriptor
284
     *
285
     * @return void
286
     */
287
    public function registerBean(BeanDescriptorInterface $descriptor)
288
    {
289
290
        try {
291
            // load the application instance
292
            $application = $this->getApplication();
293
294
            // register the bean with the default name/short class name
295
            $application->getNamingDirectory()
0 ignored issues
show
Bug introduced by
The method getNamingDirectory() 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

295
            $application->/** @scrutinizer ignore-call */ 
296
                          getNamingDirectory()
Loading history...
296
                        ->bind(
297
                            sprintf('php:global/%s/%s', $application->getUniqueName(), $descriptor->getName()),
0 ignored issues
show
Bug introduced by
The method getUniqueName() 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

297
                            sprintf('php:global/%s/%s', $application->/** @scrutinizer ignore-call */ getUniqueName(), $descriptor->getName()),
Loading history...
298
                            array(&$this, 'lookup'),
299
                            array($descriptor->getName())
300
                        );
301
302
            // register's the bean's references
303
            $this->registerReferences($descriptor);
304
305
            // generate the remote proxy and register it in the naming directory
306
            $this->getRemoteProxyGenerator()->generate($descriptor);
307
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
308
        } catch (\Exception $e) {
309
            // log the exception
310
            $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

310
            $this->getApplication()->/** @scrutinizer ignore-call */ getInitialContext()->getSystemLogger()->critical($e->__toString());
Loading history...
311
        }
312
    }
313
314
    /**
315
     * Creates a new new instance of the annotation type, defined in the passed reflection annotation.
316
     *
317
     * @param \AppserverIo\Lang\Reflection\AnnotationInterface $annotation The reflection annotation we want to create the instance for
318
     *
319
     * @return \AppserverIo\Lang\Reflection\AnnotationInterface The real annotation instance
320
     */
321
    public function newAnnotationInstance(AnnotationInterface $annotation)
322
    {
323
        return $this->getApplication()->search('ProviderInterface')->newAnnotationInstance($annotation);
324
    }
325
326
    /**
327
     * Return the resource locator instance.
328
     *
329
     * @return \AppserverIo\Psr\EnterpriseBeans\ResourceLocatorInterface The resource locator instance
330
     */
331
    public function getResourceLocator()
332
    {
333
        return $this->resourceLocator;
334
    }
335
336
    /**
337
     * Return the storage with the singleton session beans.
338
     *
339
     * @return \AppserverIo\Storage\StorageInterface The storage with the singleton session beans
340
     */
341
    public function getSingletonSessionBeans()
342
    {
343
        return $this->singletonSessionBeans;
344
    }
345
346
    /**
347
     * Return the storage with the stateful session beans.
348
     *
349
     * @return \AppserverIo\Storage\StorageInterface The storage with the stateful session beans
350
     */
351
    public function getStatefulSessionBeans()
352
    {
353
        return $this->statefulSessionBeans;
354
    }
355
356
    /**
357
     * Return's the bean manager settings.
358
     *
359
     * @return \AppserverIo\Appserver\PersistenceContainer\BeanManagerSettingsInterface The bean manager settings
360
     */
361
    public function getManagerSettings()
362
    {
363
        return $this->managerSettings;
364
    }
365
366
    /**
367
     * Returns the object factory instance.
368
     *
369
     * @return \AppserverIo\Appserver\PersistenceContainer\ObjectFactoryInterface The object factory instance
370
     */
371
    public function getObjectFactory()
372
    {
373
        return $this->objectFactory;
374
    }
375
376
    /**
377
     * Returns the garbage collector instance.
378
     *
379
     * @return \AppserverIo\Appserver\PersistenceContainer\GarbageCollectors\StandardGarbageCollector The garbage collector instance
380
     */
381
    public function getGarbageCollector()
382
    {
383
        return $this->garbageCollector;
384
    }
385
386
    /**
387
     * Returns the startup bean task garbage collector instance.
388
     *
389
     * @return \AppserverIo\Appserver\PersistenceContainer\GarbageCollectors\StartupBeanTaskGarbageCollector The garbage collector instance
390
     */
391
    public function getStartupBeanTaskGarbageCollector()
392
    {
393
        return $this->startupBeanTaskGarbageCollector;
394
    }
395
396
    /**
397
     * Return's the remote proxy generator instance.
398
     *
399
     * @return \AppserverIo\Appserver\PersistenceContainer\RemoteMethodInvocation\ProxyGeneratorInterface The remote proxy generator instance
400
     */
401
    public function getRemoteProxyGenerator()
402
    {
403
        return $this->remoteProxyGenerator;
404
    }
405
406
    /**
407
     * Return's the storage of the manager's post startup threads.
408
     *
409
     * @return \AppserverIo\Storage\GenericStackable The storage for the post startup threads
410
     */
411
    public function getStartupBeanTasks()
412
    {
413
        return $this->startupBeanTasks;
414
    }
415
416
    /**
417
     * Runs a lookup for the session bean with the passed class name and
418
     * session ID.
419
     *
420
     * If the passed class name is a session bean an instance
421
     * will be returned.
422
     *
423
     * @param string $className The name of the session bean's class
424
     * @param array  $args      The arguments passed to the session beans constructor
425
     *
426
     * @return object The requested bean instance
427
     */
428
    public function lookup($className, array $args = array())
429
    {
430
        return $this->getResourceLocator()->lookup($this, $className, $args);
431
    }
432
433
    /**
434
     * Retrieves the requested stateful session bean.
435
     *
436
     * @param string $sessionId The session-ID of the stateful session bean to retrieve
437
     * @param string $className The class name of the session bean to retrieve
438
     *
439
     * @return object|null The stateful session bean if available
440
     */
441
    public function lookupStatefulSessionBean($sessionId, $className)
442
    {
443
444
        // create a unique SFSB identifier
445
        $identifier = SessionBeanUtil::createIdentifier($sessionId, $className);
446
447
        // load the map with the SFSBs
448
        $sessionBeans = $this->getStatefulSessionBeans();
449
450
        // if the SFSB exists, return it
451
        if ($sessionBeans->exists($identifier)) {
0 ignored issues
show
Bug introduced by
The method exists() does not exist on AppserverIo\Storage\StorageInterface. ( Ignorable by Annotation )

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

451
        if ($sessionBeans->/** @scrutinizer ignore-call */ exists($identifier)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
452
            return $sessionBeans->get($identifier);
453
        }
454
    }
455
456
    /**
457
     * Removes the stateful session bean with the passed session-ID and class name
458
     * from the bean manager.
459
     *
460
     * @param string $sessionId The session-ID of the stateful session bean to retrieve
461
     * @param string $className The class name of the session bean to retrieve
462
     *
463
     * @return void
464
     */
465
    public function removeStatefulSessionBean($sessionId, $className)
466
    {
467
468
        // create a unique SFSB identifier
469
        $identifier = SessionBeanUtil::createIdentifier($sessionId, $className);
470
471
        // load the map with the SFSBs
472
        $sessionBeans = $this->getStatefulSessionBeans();
473
474
        // query whether the SFSB with the passed identifier exists
475
        if ($sessionBeans->exists($identifier)) {
476
            $sessionBeans->remove($identifier, array($this, 'destroyBeanInstance'));
0 ignored issues
show
Unused Code introduced by
The call to AppserverIo\Storage\StorageInterface::remove() has too many arguments starting with array($this, 'destroyBeanInstance'). ( Ignorable by Annotation )

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

476
            $sessionBeans->/** @scrutinizer ignore-call */ 
477
                           remove($identifier, array($this, 'destroyBeanInstance'));

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...
477
        }
478
    }
479
480
    /**
481
     * Returns a new instance of the SSB with the passed class name.
482
     *
483
     * @param string $className The fully qualified class name to return the instance for
484
     * @param array  $args      Arguments to pass to the constructor of the instance
485
     *
486
     * @return object The instance itself
487
     */
488
    public function newSingletonSessionBeanInstance($className, array $args = array())
489
    {
490
        return $this->getObjectFactory()->newInstance($className, $args);
0 ignored issues
show
Unused Code introduced by
The call to AppserverIo\Appserver\Pe...nterface::newInstance() 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

490
        return $this->getObjectFactory()->/** @scrutinizer ignore-call */ newInstance($className, $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...
491
    }
492
493
    /**
494
     * Retrieves the requested singleton session bean.
495
     *
496
     * @param string $className The class name of the session bean to retrieve
497
     *
498
     * @return object|null The singleton session bean if available
499
     */
500
    public function lookupSingletonSessionBean($className)
501
    {
502
        if ($this->getSingletonSessionBeans()->has($className) === true) {
503
            return $this->getSingletonSessionBeans()->get($className);
504
        }
505
    }
506
507
    /**
508
     * Invokes the bean method with a pre-destroy callback.
509
     *
510
     * @param object $instance The instance to invoke the method
511
     *
512
     * @return void
513
     */
514
    public function destroyBeanInstance($instance)
515
    {
516
517
        // load the object manager
518
        $objectManager = $this->getApplication()->search(ObjectManagerInterface::IDENTIFIER);
519
520
        // load the bean descriptor
521
        $descriptor = $objectManager->getObjectDescriptors()->get(get_class($instance));
522
523
        // invoke the pre-destroy callbacks if we've a session bean
524
        if ($descriptor instanceof SessionBeanDescriptorInterface) {
525
            foreach ($descriptor->getPreDestroyCallbacks() as $preDestroyCallback) {
526
                $instance->$preDestroyCallback();
527
            }
528
        }
529
    }
530
531
    /**
532
     * Invoke the passed remote method on the described session bean and return the result.
533
     *
534
     * @param \AppserverIo\RemoteMethodInvocation\RemoteMethodInterface $remoteMethod The remote method description
535
     * @param \AppserverIo\Collections\CollectionInterface              $sessions     The collection with the sessions
536
     *
537
     * @return mixed The result of the remote method invocation
538
     */
539
    public function invoke(RemoteMethodInterface $remoteMethod, CollectionInterface $sessions)
540
    {
541
542
        // prepare method name and parameters and invoke method
543
        $className  = $remoteMethod->getClassName();
544
        $methodName = $remoteMethod->getMethodName();
545
        $parameters = $remoteMethod->getParameters();
546
547
        // load the session ID from the environment
548
        $sessionId = Environment::singleton()->getAttribute(EnvironmentKeys::SESSION_ID);
549
550
        // load the application instance
551
        $application = $this->getApplication();
552
553
        // load a fresh bean instance and add it to the session container
554
        $instance = $this->lookup($className);
555
556
        // invoke the remote method call on the local instance
557
        $response = call_user_func_array(array($instance, $methodName), $parameters);
558
559
        // load the object manager
560
        $objectManager = $application->search(ObjectManagerInterface::IDENTIFIER);
561
562
        // load the bean descriptor
563
        $objectDescriptor = $objectManager->getObjectDescriptor($className);
564
565
        // initialize the flag to mark the instance to be re-attached
566
        $attach = true;
567
568
        // query if we've SFSB
569
        if ($objectDescriptor instanceof StatefulSessionBeanDescriptorInterface) {
570
            // remove the SFSB instance if a remove method has been called
571
            if ($objectDescriptor->isRemoveMethod($methodName)) {
572
                $this->removeStatefulSessionBean($sessionId, $objectDescriptor->getClassName());
573
                $attach = false;
574
            }
575
        }
576
577
        // re-attach the bean instance if necessary
578
        if ($attach === true) {
579
            $this->attach($objectDescriptor, $instance);
580
        }
581
582
        // return the remote method call result
583
        return $response;
584
    }
585
586
    /**
587
     * Attaches the passed bean, depending on it's type to the container.
588
     *
589
     * @param \AppserverIo\Psr\Deployment\DescriptorInterface $objectDescriptor The object descriptor for the passed instance
590
     * @param object                                          $instance         The bean instance to attach
591
     *
592
     * @return void
593
     * @throws \AppserverIo\Psr\EnterpriseBeans\InvalidBeanTypeException Is thrown if a invalid bean type has been detected
594
     */
595
    public function attach(DescriptorInterface $objectDescriptor, $instance)
596
    {
597
598
        // load the session ID from the environment
599
        $sessionId = Environment::singleton()->getAttribute(EnvironmentKeys::SESSION_ID);
600
601
        // query if we've stateful session bean
602
        if ($objectDescriptor instanceof StatefulSessionBeanDescriptorInterface) {
603
            // check if we've a session-ID available
604
            if ($sessionId == null) {
605
                throw new \Exception('Can\'t find a session-ID to attach stateful session bean');
606
            }
607
608
            // load the lifetime from the session bean settings
609
            $lifetime = $this->getManagerSettings()->getLifetime();
610
611
            // we've to check for pre-attach callbacks
612
            foreach ($objectDescriptor->getPreAttachCallbacks() as $preAttachCallback) {
613
                $instance->$preAttachCallback();
614
            }
615
616
            // create a unique SFSB identifier
617
            $identifier = SessionBeanUtil::createIdentifier($sessionId, $objectDescriptor->getName());
618
619
            // load the map with the SFSBs
620
            $sessionBeans = $this->getStatefulSessionBeans();
621
622
            // add the stateful session bean to the map
623
            $sessionBeans->add($identifier, $instance, $lifetime);
0 ignored issues
show
Bug introduced by
The method add() does not exist on AppserverIo\Storage\StorageInterface. ( Ignorable by Annotation )

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

623
            $sessionBeans->/** @scrutinizer ignore-call */ 
624
                           add($identifier, $instance, $lifetime);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
624
625
            // stop processing here
626
            return;
627
        }
628
629
        // query if we've stateless session or message bean
630
        if ($objectDescriptor instanceof StatelessSessionBeanDescriptorInterface ||
631
            $objectDescriptor instanceof MessageDrivenBeanDescriptorInterface) {
632
            // simply destroy the instance
633
            $this->destroyBeanInstance($instance);
634
635
            // stop processing here
636
            return;
637
        }
638
639
        // query if we've singleton session bean
640
        if ($objectDescriptor instanceof SingletonSessionBeanDescriptorInterface) {
641
            // we've to check for pre-attach callbacks
642
            foreach ($objectDescriptor->getPreAttachCallbacks() as $preAttachCallback) {
643
                $instance->$preAttachCallback();
644
            }
645
646
            // stop processing here
647
            return;
648
        }
649
650
        // we've an unknown bean type => throw an exception
651
        throw new InvalidBeanTypeException('Tried to attach invalid bean type');
652
    }
653
654
    /**
655
     * Returns the identifier for the bean manager instance.
656
     *
657
     * @return string
658
     * @see \AppserverIo\Psr\Application\ManagerInterface::getIdentifier()
659
     */
660
    public function getIdentifier()
661
    {
662
        return BeanContextInterface::IDENTIFIER;
663
    }
664
665
    /**
666
     * Shutdown the session manager instance.
667
     *
668
     * @return void
669
     * \AppserverIo\Psr\Application\ManagerInterface::stop()
670
     */
671
    public function stop()
672
    {
673
        $this->getGarbageCollector()->stop();
674
        $this->getObjectFactory()->stop();
0 ignored issues
show
Bug introduced by
The method stop() does not exist on AppserverIo\Appserver\Pe...\ObjectFactoryInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to AppserverIo\Appserver\Pe...\ObjectFactoryInterface. ( Ignorable by Annotation )

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

674
        $this->getObjectFactory()->/** @scrutinizer ignore-call */ stop();
Loading history...
675
    }
676
}
677