Issues (677)

AppserverIo/Appserver/Core/AbstractEpbManager.php (11 issues)

1
<?php
2
3
/**
4
 * \AppserverIo\Appserver\Core\AbstractEpbManager
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
 * @author     Bernhard Wick <[email protected]>
16
 * @copyright  2016 TechDivision GmbH - <[email protected]>
17
 * @license    http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
18
 * @link       http://www.appserver.io/
19
 */
20
21
namespace AppserverIo\Appserver\Core;
22
23
use AppserverIo\Psr\Naming\NamingException;
24
use AppserverIo\Psr\Di\ObjectManagerInterface;
25
use AppserverIo\RemoteMethodInvocation\LocalProxy;
26
use AppserverIo\Appserver\ServletEngine\RequestHandler;
27
use AppserverIo\Psr\Deployment\DescriptorInterface;
28
use AppserverIo\Psr\EnterpriseBeans\BeanContextInterface;
29
use AppserverIo\Psr\EnterpriseBeans\PersistenceContextInterface;
30
use AppserverIo\Psr\EnterpriseBeans\Description\EpbReferenceDescriptorInterface;
31
use AppserverIo\Psr\EnterpriseBeans\Description\ResReferenceDescriptorInterface;
32
use AppserverIo\Psr\EnterpriseBeans\Description\BeanReferenceDescriptorInterface;
33
use AppserverIo\Psr\EnterpriseBeans\Description\PersistenceUnitReferenceDescriptorInterface;
34
35
/**
36
 * Abstract manager which is able to handle EPB, resource and persistence unit registrations.
37
 *
38
 * @author     Tim Wagner <[email protected]>
39
 * @author     Bernhard Wick <[email protected]>
40
 * @copyright  2016 TechDivision GmbH - <[email protected]>
41
 * @license    http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
42
 * @link       http://www.appserver.io/
43
 */
44
abstract class AbstractEpbManager extends AbstractManager
45
{
46
47
    /**
48
     * Register's the references of the passed descriptor.
49
     *
50
     * @param \AppserverIo\Psr\Deployment\DescriptorInterface $descriptor The descriptor to register the references for
51
     *
52
     * @return void
53
     */
54
    public function registerReferences(DescriptorInterface $descriptor)
55
    {
56
57
        //  register the EPB references
58
        foreach ($descriptor->getEpbReferences() as $epbReference) {
0 ignored issues
show
The method getEpbReferences() does not exist on AppserverIo\Psr\Deployment\DescriptorInterface. It seems like you code against a sub-type of AppserverIo\Psr\Deployment\DescriptorInterface such as AppserverIo\Ldap\Descrip...toryDescriptorInterface or AppserverIo\Description\BeanDescriptor or AppserverIo\Description\EnterpriseBeanDescriptor or AppserverIo\Description\ServletDescriptor. ( Ignorable by Annotation )

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

58
        foreach ($descriptor->/** @scrutinizer ignore-call */ getEpbReferences() as $epbReference) {
Loading history...
59
            $this->registerEpbReference($epbReference);
60
        }
61
62
        // register the resource references
63
        foreach ($descriptor->getResReferences() as $resReference) {
0 ignored issues
show
The method getResReferences() does not exist on AppserverIo\Psr\Deployment\DescriptorInterface. It seems like you code against a sub-type of AppserverIo\Psr\Deployment\DescriptorInterface such as AppserverIo\Ldap\Descrip...toryDescriptorInterface or AppserverIo\Description\BeanDescriptor or AppserverIo\Description\EnterpriseBeanDescriptor or AppserverIo\Description\ServletDescriptor. ( Ignorable by Annotation )

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

63
        foreach ($descriptor->/** @scrutinizer ignore-call */ getResReferences() as $resReference) {
Loading history...
64
            $this->registerResReference($resReference);
65
        }
66
67
        // register the bean references
68
        foreach ($descriptor->getBeanReferences() as $beanReference) {
0 ignored issues
show
The method getBeanReferences() does not exist on AppserverIo\Psr\Deployment\DescriptorInterface. It seems like you code against a sub-type of AppserverIo\Psr\Deployment\DescriptorInterface such as AppserverIo\Ldap\Descrip...toryDescriptorInterface or AppserverIo\Description\BeanDescriptor or AppserverIo\Description\EnterpriseBeanDescriptor or AppserverIo\Description\ServletDescriptor. ( Ignorable by Annotation )

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

68
        foreach ($descriptor->/** @scrutinizer ignore-call */ getBeanReferences() as $beanReference) {
Loading history...
69
            $this->registerBeanReference($beanReference);
70
        }
71
72
        // register the persistence unit references
73
        foreach ($descriptor->getPersistenceUnitReferences() as $persistenceUnitReference) {
0 ignored issues
show
The method getPersistenceUnitReferences() does not exist on AppserverIo\Psr\Deployment\DescriptorInterface. It seems like you code against a sub-type of AppserverIo\Psr\Deployment\DescriptorInterface such as AppserverIo\Ldap\Descrip...toryDescriptorInterface or AppserverIo\Description\BeanDescriptor or AppserverIo\Description\EnterpriseBeanDescriptor or AppserverIo\Description\ServletDescriptor. ( Ignorable by Annotation )

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

73
        foreach ($descriptor->/** @scrutinizer ignore-call */ getPersistenceUnitReferences() as $persistenceUnitReference) {
Loading history...
74
            $this->registerPersistenceUnitReference($persistenceUnitReference);
75
        }
76
    }
77
78
    /**
79
     * Registers the passed EPB reference in the applications directory.
80
     *
81
     * @param \AppserverIo\Psr\EnterpriseBeans\Description\EpbReferenceDescriptorInterface $epbReference The EPB reference to register
82
     *
83
     * @return void
84
     */
85
    public function registerEpbReference(EpbReferenceDescriptorInterface $epbReference)
86
    {
87
88
        try {
89
            // load the application instance and reference name
90
            $application = $this->getApplication();
91
            $name = $epbReference->getRefName();
92
93
            // initialize the bean's URI
94
            $uri = sprintf('php:global/%s/%s', $application->getUniqueName(), $name);
0 ignored issues
show
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

94
            $uri = sprintf('php:global/%s/%s', $application->/** @scrutinizer ignore-call */ getUniqueName(), $name);
Loading history...
95
96
            // query whether the reference has already been bound to the application
97
            if ($application->getNamingDirectory()->isBound($uri)) {
0 ignored issues
show
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

97
            if ($application->/** @scrutinizer ignore-call */ getNamingDirectory()->isBound($uri)) {
Loading history...
98
                // log a message that the reference has already been bound
99
                $application->getInitialContext()->getSystemLogger()->debug(
0 ignored issues
show
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

99
                $application->/** @scrutinizer ignore-call */ 
100
                              getInitialContext()->getSystemLogger()->debug(
Loading history...
100
                    sprintf('Enterprise bean reference %s has already been bound to naming directory', $uri)
101
                );
102
103
                // return immediately
104
                return;
105
            }
106
107
            // this has to be refactored, because it'll be quite faster to inject either
108
            // the remote/local proxy instance as injection a callback that creates the
109
            // proxy on-the-fly!
110
111
            // query whether or not we've a lookup name specified
112
            if ($lookup = $epbReference->getLookup()) {
113
                // create a reference to a bean in the global directory
114
                $application->getNamingDirectory()->bind($uri, array(&$this, 'lookup'), array($lookup));
115
116
            // try to load the bean name, if no lookup name has been specified
117
            } elseif ($beanName = $epbReference->getBeanName()) {
118
                // query whether we've a local business interface
119
                if ($epbReference->getBeanInterface() === sprintf('%sLocal', $beanName)) {
120
                    // bind the local business interface of the bean to the appliations naming directory
121
                    $application->getNamingDirectory()
122
                                ->bind(
123
                                    $uri,
124
                                    array(&$this, 'lookupProxy'),
125
                                    array(sprintf('%s/local', $beanName))
126
                                );
127
128
                // query whether we've a remote business interface
129
                } elseif ($epbReference->getBeanInterface() === (sprintf('%sRemote', $beanName))) {
130
                    // bind the remote business interface of the bean to the applications naming directory
131
                    $application->getNamingDirectory()
132
                                ->bind(
133
                                    $uri,
134
                                    array(&$this, 'lookupProxy'),
135
                                    array(sprintf('%s/remote', $beanName))
136
                                );
137
138
                // at least, we need a business interface
139
                } else {
140
                    // log a critical message that we can't bind the reference
141
                    $application->getInitialContext()->getSystemLogger()->critical(
142
                        sprintf('Can\'t bind bean reference %s to naming directory', $uri)
143
                    );
144
                }
145
146
            } else {
147
                $application->getInitialContext()->getSystemLogger()->critical(
148
                    sprintf('Can\'t bind enterprise bean reference %s to naming directory, because of missing lookup/bean name', $uri)
149
                );
150
            }
151
152
        // catch all other exceptions
153
        } catch (\Exception $e) {
154
            $application->getInitialContext()->getSystemLogger()->critical($e->__toString());
155
        }
156
    }
157
158
    /**
159
     * Registers the passed resource reference in the applications directory.
160
     *
161
     * @param \AppserverIo\Psr\EnterpriseBeans\Description\ResReferenceDescriptorInterface $resReference The resource reference to register
162
     *
163
     * @return void
164
     */
165
    public function registerResReference(ResReferenceDescriptorInterface $resReference)
166
    {
167
        try {
168
            // load the application instance and reference name
169
            $application = $this->getApplication();
170
171
            // initialize the resource URI
172
            $uri = sprintf('php:global/%s/%s', $application->getUniqueName(), $resReference->getRefName());
173
174
            // query whether the reference has already been bound to the application
175
            if ($application->getNamingDirectory()->isBound($uri)) {
176
                // log a message that the reference has already been bound
177
                $application->getInitialContext()->getSystemLogger()->debug(
178
                    sprintf('Resource reference %s has already been bound to naming directory', $uri)
179
                );
180
181
                // return immediately
182
                return;
183
            }
184
185
        // catch the NamingException if the ref name is not bound yet
186
        } catch (NamingException $e) {
187
            // log a message that we've to register the resource reference now
188
            $application->getInitialContext()->getSystemLogger()->debug(
189
                sprintf('Resource reference %s has not been bound to naming directory', $uri)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $uri does not seem to be defined for all execution paths leading up to this point.
Loading history...
190
            );
191
        }
192
193
        try {
194
            // try to use the lookup to bind the reference to
195
            if ($lookup = $resReference->getLookup()) {
196
                // create a reference to a resource in the global directory
197
                $application->getNamingDirectory()->bindReference($uri, $lookup);
198
199
            // try to bind the reference by the specified type
200
            } elseif ($type = $resReference->getType()) {
201
                // bind a reference to the resource shortname
202
                $application->getNamingDirectory()
203
                            ->bindReference(
204
                                $uri,
205
                                sprintf('php:global/%s/%s', $application->getUniqueName(), $type)
206
                            );
207
208
            // log a critical message that we can't bind the reference
209
            } else {
210
                $application->getInitialContext()->getSystemLogger()->critical(
211
                    sprintf('Can\'t bind resource reference %s to naming directory, because of missing source bean/lookup name', $uri)
212
                );
213
            }
214
215
        // catch all other exceptions
216
        } catch (\Exception $e) {
217
            $application->getInitialContext()->getSystemLogger()->critical($e->__toString());
218
        }
219
    }
220
221
    /**
222
     * Registers the passed bean reference in the applications directory.
223
     *
224
     * @param \AppserverIo\Psr\EnterpriseBeans\Description\BeanReferenceDescriptorInterface $beanReference The bean reference to register
225
     *
226
     * @return void
227
     */
228
    public function registerBeanReference(BeanReferenceDescriptorInterface $beanReference)
229
    {
230
        try {
231
            // load the application instance and reference name
232
            $application = $this->getApplication();
233
234
            // initialize the class URI
235
            $uri = sprintf('php:global/%s/%s', $application->getUniqueName(), $beanReference->getRefName());
236
237
            // query whether the reference has already been bound to the application
238
            if ($application->getNamingDirectory()->isBound($uri)) {
239
                // log a message that the reference has already been bound
240
                $application->getInitialContext()->getSystemLogger()->debug(
241
                    sprintf('Bean reference %s has already been bound to naming directory', $uri)
242
                );
243
244
                // return immediately
245
                return;
246
            }
247
248
        // catch the NamingException if the ref name is not bound yet
249
        } catch (NamingException $e) {
250
            // log a message that we've to register the bean reference now
251
            $application->getInitialContext()->getSystemLogger()->debug(
252
                sprintf('Bean reference %s has not been bound to naming directory', $uri)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $uri does not seem to be defined for all execution paths leading up to this point.
Loading history...
253
            );
254
        }
255
256
        try {
257
            // try to bind the bean by the specified bean name
258
            if ($beanName = $beanReference->getBeanName()) {
259
                // bind a reference to the class type
260
                $application->getNamingDirectory()
261
                            ->bind(
262
                                $uri,
263
                                array(&$this, 'lookupBean'),
264
                                array($beanName)
265
                            );
266
267
            // log a critical message that we can't bind the reference
268
            } else {
269
                $application->getInitialContext()->getSystemLogger()->critical(
270
                    sprintf('Can\'t bind bean reference %s to naming directory, because of missing source bean name', $uri)
271
                );
272
            }
273
274
        // catch all other exceptions
275
        } catch (\Exception $e) {
276
            $application->getInitialContext()->getSystemLogger()->critical($e->__toString());
277
        }
278
    }
279
280
    /**
281
     * Registers the passed persistence unit reference in the applications directory.
282
     *
283
     * @param \AppserverIo\Psr\EnterpriseBeans\Description\PersistenceUnitReferenceDescriptorInterface $persistenceUnitReference The persistence unit reference to register
284
     *
285
     * @return void
286
     */
287
    public function registerPersistenceUnitReference(PersistenceUnitReferenceDescriptorInterface $persistenceUnitReference)
288
    {
289
        try {
290
            // load the application instance and reference name
291
            $application = $this->getApplication();
292
293
            // initialize the persistence unit URI
294
            $uri = sprintf('php:global/%s/%s', $application->getUniqueName(), $persistenceUnitReference->getRefName());
295
296
            // query whether the reference has already been bound to the application
297
            if ($application->getNamingDirectory()->isBound($uri)) {
298
                // log a message that the reference has already been bound
299
                $application->getInitialContext()->getSystemLogger()->debug(
300
                    sprintf('Persistence unit reference %s has already been bound to naming directory', $uri)
301
                );
302
303
                // return immediately
304
                return;
305
            }
306
307
        // catch the NamingException if the ref name is not bound yet
308
        } catch (NamingException $e) {
309
            // log a message that we've to register the resource reference now
310
            $application->getInitialContext()->getSystemLogger()->debug(
311
                sprintf('Persistence unit reference %s has not been bound to naming directory', $uri)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $uri does not seem to be defined for all execution paths leading up to this point.
Loading history...
312
            );
313
        }
314
315
        try {
316
            // try to use the unit name to bind the reference to
317
            if ($unitName = $persistenceUnitReference->getUnitName()) {
318
                // load the persistenc manager to bind the callback to
319
                $persistenceManager = $application->search(PersistenceContextInterface::IDENTIFIER);
320
                // create a reference to a persistence unit in the global directory
321
                $application->getNamingDirectory()
322
                            ->bind(
323
                                $uri,
324
                                array(&$persistenceManager, 'lookupProxy'),
325
                                array($unitName)
326
                            );
327
328
            // log a critical message that we can't bind the reference
329
            } else {
330
                $application->getInitialContext()->getSystemLogger()->critical(
331
                    sprintf('Can\'t bind persistence unit Reference %s to naming directory, because of missing unit name definition', $uri)
332
                );
333
            }
334
335
        // catch all other exceptions
336
        } catch (\Exception $e) {
337
            $application->getInitialContext()->getSystemLogger()->critical($e->__toString());
338
        }
339
    }
340
341
    /**
342
     * This returns an instance of the requested bean.
343
     *
344
     * @param string $lookupName The lookup name for the requested bean
345
     *
346
     * @return object The bean instance
347
     */
348
    public function lookupBean($lookupName)
349
    {
350
        return $this->getApplication()->search($lookupName);
351
    }
352
353
    /**
354
     * This returns a proxy to the requested session bean. If the proxy has already been
355
     * instanciated for the actual request, the existing instance will be returned.
356
     *
357
     * @param string $lookupName The lookup name for the requested session bean
358
     *
359
     * @return \AppserverIo\RemoteMethodInvocation\RemoteObjectInterface The proxy instance
360
     */
361
    public function lookupProxy($lookupName)
362
    {
363
364
        // load the initial context instance
365
        $initialContext = $this->getInitialContext();
366
367
        // query whether a request context is available
368
        if ($servletRequest = RequestHandler::getRequestContext()) {
369
            // inject the servlet request to handle SFSBs correctly
370
            $initialContext->injectServletRequest($servletRequest);
371
        }
372
373
        // return the proxy instance
374
        return $initialContext->lookup($lookupName);
375
    }
376
377
    /**
378
     * This returns a local proxy to the requested session bean.
379
     *
380
     * @param string $lookupName The lookup name for the requested session bean
381
     *
382
     * @return \AppserverIo\RemoteMethodInvocation\RemoteObjectInterface The proxy instance
383
     */
384
    public function lookupLocalProxy($lookupName)
385
    {
386
387
        // extract the session bean name from the lookup name
388
        $beanName = str_replace('/local', '', $lookupName);
389
390
        // load the application
391
        $application = $this->getApplication();
392
393
        // load bean and object manager
394
        $beanManager = $application->search(BeanContextInterface::IDENTIFIER);
395
        $objectManager = $application->search(ObjectManagerInterface::IDENTIFIER);
396
397
        // load the requested session bean
398
        $sessionBean = $application->search($beanName);
399
400
        // load the bean descriptor
401
        $sessionBeanDescriptor = $objectManager->getObjectDescriptors()->get(get_class($sessionBean));
402
403
        // initialize the local proxy instance
404
        return new LocalProxy(
0 ignored issues
show
The call to AppserverIo\RemoteMethod...calProxy::__construct() has too few arguments starting with sessionId. ( Ignorable by Annotation )

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

404
        return /** @scrutinizer ignore-call */ new LocalProxy(

This check compares calls to functions or methods with their respective definitions. If the call has less 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...
405
            $beanManager,
406
            $sessionBeanDescriptor,
407
            $sessionBean
408
        );
409
    }
410
}
411