Pjb62Driver::getContext()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.2559

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 7
ccs 3
cts 5
cp 0.6
crap 2.2559
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Soluble\Japha\Bridge\Driver\Pjb62;
6
7
use Psr\Log\LoggerInterface;
8
use Psr\Log\NullLogger;
9
use Soluble\Japha\Bridge\Driver\AbstractDriver;
10
use Soluble\Japha\Bridge\Driver\ClientInterface;
11
use Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException as Pjb62BrokenConnectionException;
12
use Soluble\Japha\Bridge\Exception\BrokenConnectionException;
13
use Soluble\Japha\Interfaces;
14
use Soluble\Japha\Bridge\Exception;
15
16
class Pjb62Driver extends AbstractDriver
17
{
18
    /**
19
     * @var bool
20
     */
21
    protected $connected = false;
22
23
    /**
24
     * @var PjbProxyClient
25
     */
26
    protected $pjbProxyClient;
27
28
    /**
29
     * @var LoggerInterface
30
     */
31
    protected $logger;
32
33
    /**
34
     * Constructor.
35
     *
36
     * <code>
37
     *
38
     * $ba = new Pjb62Driver([
39
     *     'servlet_address' => 'http://127.0.0.1:8080/javabridge-bundle/servlet.phpjavabridge'
40
     *      //'use_persistent_connection' => false,
41
     *      //'java_default_timezone' => null,
42
     *      //'java_prefer_values' => true,
43
     *      //'java_log_level' => null,
44
     *      //'java_send_size' => 8192,
45
     *      //'java_recv_size' => 8192,
46
     *      //'internal_encoding' => 'UTF-8',
47
     *      //'force_simple_xml_parser' => false
48
     *    ], $logger);
49
     *
50
     * </code>
51
     *
52
     * @param array           $options
53
     * @param LoggerInterface $logger
54
     *
55
     * @throws Exception\InvalidArgumentException
56
     * @throws Exception\ConnectionException
57
     */
58 142
    public function __construct(array $options, LoggerInterface $logger = null)
59
    {
60 142
        if ($logger === null) {
61 1
            $logger = new NullLogger();
62
        }
63
64 142
        $this->logger = $logger;
65
66
        try {
67 142
            $this->pjbProxyClient = PjbProxyClient::getInstance($options, $this->logger);
68 4
        } catch (Exception\ConnectionException $e) {
69 2
            $address = $options['servlet_address'];
70 2
            $msg = "Cannot connect to php-java-bridge server on '$address', server didn't respond.";
71 2
            $this->logger->critical("[soluble-japha] $msg (".$e->getMessage().')');
0 ignored issues
show
Bug introduced by
The method critical() does not exist on null. ( Ignorable by Annotation )

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

71
            $this->logger->/** @scrutinizer ignore-call */ 
72
                           critical("[soluble-japha] $msg (".$e->getMessage().')');

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...
72 2
            throw $e;
73 2
        } catch (Exception\InvalidArgumentException $e) {
74 2
            $msg = 'Invalid arguments, cannot initiate connection to java-bridge.';
75 2
            $this->logger->error("[soluble-japha] $msg (".$e->getMessage().')');
76 2
            throw $e;
77
        }
78 139
    }
79
80 1
    public function getLogger(): LoggerInterface
81
    {
82 1
        return $this->logger;
83
    }
84
85
    /**
86
     * Return underlying bridge client.
87
     *
88
     * @return PjbProxyClient
89
     */
90 11
    public function getClient(): ClientInterface
91
    {
92 11
        return $this->pjbProxyClient;
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     *
98
     * @throws BrokenConnectionException
99
     */
100 50
    public function getJavaClass(string $class_name): Interfaces\JavaClass
101
    {
102
        try {
103 50
            $class = $this->pjbProxyClient->getJavaClass($class_name);
104 3
        } catch (Pjb62BrokenConnectionException | Exception\InvalidUsageException $e) {
105 1
            PjbProxyClient::unregisterInstance();
106 1
            throw new BrokenConnectionException($e->getMessage(), $e->getCode(), $e);
107
        }
108
109 47
        return $class;
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     *
115
     * @throws BrokenConnectionException
116
     */
117 66
    public function instanciate(string $class_name, ...$args): Interfaces\JavaObject
118
    {
119
        try {
120 66
            $java = new Java($class_name, ...$args);
121 4
        } catch (Pjb62BrokenConnectionException | Exception\InvalidUsageException $e) {
122 1
            PjbProxyClient::unregisterInstance();
123 1
            throw new BrokenConnectionException($e->getMessage(), $e->getCode(), $e);
124
        }
125
126 63
        return $java;
127
    }
128
129
    /**
130
     * Set the java file encoding, for example UTF-8, ISO-8859-1 or ASCII.
131
     *
132
     * Needed because php does not support unicode. All string to byte array
133
     * conversions use this encoding. Example:
134
     *
135
     * @param string $encoding Please see Java file.encoding documentation for a list of valid encodings.
136
     *
137
     * @throws BrokenConnectionException
138
     */
139 1
    public function setFileEncoding(string $encoding): void
140
    {
141 1
        $this->invoke(null, 'setFileEncoding', [$encoding]);
142 1
    }
143
144
    /**
145
     * Return bridge connection options.
146
     *
147
     * @throws BrokenConnectionException
148
     *
149
     * @return Interfaces\JavaObject Java("io.soluble.pjb.bridge.Options")
150
     */
151 1
    public function getConnectionOptions(): Interfaces\JavaObject
152
    {
153 1
        return $this->invoke(null, 'getOptions');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->invoke(null, 'getOptions') returns the type Soluble\Japha\Bridge\Driver\Pjb62\JavaType which is incompatible with the type-hinted return Soluble\Japha\Interfaces\JavaObject.
Loading history...
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     *
159
     * @throws BrokenConnectionException
160
     */
161 4
    public function invoke(Interfaces\JavaType $javaObject = null, string $method, array $args = [])
162
    {
163
        try {
164 4
            return $this->pjbProxyClient->invokeMethod($javaObject, $method, $args);
165 1
        } catch (Pjb62BrokenConnectionException | Exception\InvalidUsageException $e) {
166
            PjbProxyClient::unregisterInstance();
167
            throw new BrokenConnectionException($e->getMessage(), $e->getCode(), $e);
168
        }
169
    }
170
171
    /**
172
     * Returns the jsr223 script context handle.
173
     *
174
     * @throws BrokenConnectionException
175
     *
176
     * @return Interfaces\JavaObject
177
     */
178 5
    public function getContext(): Interfaces\JavaObject
179
    {
180
        try {
181 5
            return $this->pjbProxyClient::getClient()->getContext();
182 1
        } catch (Pjb62BrokenConnectionException | Exception\InvalidUsageException $e) {
183
            PjbProxyClient::unregisterInstance();
184
            throw new BrokenConnectionException($e->getMessage(), $e->getCode(), $e);
185
        }
186
    }
187
188
    /**
189
     * Return java servlet session.
190
     *
191
     * <code>
192
     * $session = $adapter->getDriver()->getJavaSession();
193
     * $counter = $session->get('counter');
194
     * if ($adapter->isNull($counter)) {
195
     *    $session->put('counter', 1);
196
     * } else {
197
     *    $session->put('counter', $counter + 1);
198
     * }
199
     * </code>
200
     *
201
     * @param array $args
202
     *
203
     * @throws BrokenConnectionException
204
     *
205
     * @return Interfaces\JavaObject
206
     */
207 2
    public function getJavaSession(array $args = []): Interfaces\JavaObject
208
    {
209
        try {
210 2
            return $this->pjbProxyClient::getClient()->getSession();
211 2
        } catch (Pjb62BrokenConnectionException | Exception\InvalidUsageException $e) {
212
            PjbProxyClient::unregisterInstance();
213
            throw new BrokenConnectionException($e->getMessage(), $e->getCode(), $e);
214
        }
215
    }
216
217
    /**
218
     * Inspect the class internals.
219
     *
220
     * @param Interfaces\JavaObject $javaObject
221
     *
222
     * @throws BrokenConnectionException
223
     *
224
     * @return string
225
     */
226 12
    public function inspect(Interfaces\JavaObject $javaObject): string
227
    {
228
        try {
229 12
            $inspect = $this->pjbProxyClient->inspect($javaObject);
230
        } catch (Pjb62BrokenConnectionException | Exception\InvalidUsageException $e) {
231
            PjbProxyClient::unregisterInstance();
232
            throw new BrokenConnectionException($e->getMessage(), $e->getCode(), $e);
233
        }
234
235 12
        return $inspect;
236
    }
237
238
    /**
239
     * {@inheritdoc}
240
     *
241
     * @throws BrokenConnectionException
242
     */
243 8
    public function isInstanceOf(Interfaces\JavaObject $javaObject, $className): bool
244
    {
245
        try {
246 8
            return $this->pjbProxyClient->isInstanceOf($javaObject, $className);
247 4
        } catch (Pjb62BrokenConnectionException | Exception\InvalidUsageException $e) {
248
            PjbProxyClient::unregisterInstance();
249
            throw new BrokenConnectionException($e->getMessage(), $e->getCode(), $e);
250
        }
251
    }
252
253
    /**
254
     * {@inheritdoc}
255
     *
256
     * @throws BrokenConnectionException
257
     */
258 12
    public function values(Interfaces\JavaObject $javaObject)
259
    {
260
        try {
261 12
            return $this->pjbProxyClient->getValues($javaObject);
262
        } catch (Pjb62BrokenConnectionException | Exception\InvalidUsageException $e) {
263
            PjbProxyClient::unregisterInstance();
264
            throw new BrokenConnectionException($e->getMessage(), $e->getCode(), $e);
265
        }
266
    }
267
268
    /**
269
     * Return java bridge header or empty string if nothing.
270
     *
271
     * @param string $name
272
     * @param array  $array
273
     *
274
     * @return string header value or empty string if not exists
275
     */
276 31
    public static function getJavaBridgeHeader(string $name, array $array): string
277
    {
278 31
        if (array_key_exists($name, $array)) {
279 1
            return $array[$name];
280
        }
281 31
        $name = "HTTP_$name";
282 31
        if (array_key_exists($name, $array)) {
283 1
            return $array[$name];
284
        }
285
286 31
        return '';
287
    }
288
289
    /**
290
     * Cast internal objects to a new type.
291
     *
292
     * @param Interfaces\JavaObject|JavaType|mixed $javaObject
293
     * @param string                               $cast_type
294
     *
295
     * @return mixed
296
     */
297 8
    public static function castPjbInternal($javaObject, string $cast_type)
298
    {
299 8
        if ($javaObject instanceof JavaType) {
300 8
            return $javaObject->__cast($cast_type);
301
        }
302
303
        // mixed (string | int | bool)
304
        $first_char = strtoupper($cast_type[0]);
305
        switch ($first_char) {
306
            case 'S':
307
                return (string) $javaObject;
308
            case 'B':
309
                return (bool) $javaObject;
310
            case 'L':
311
            case 'I':
312
                return (int) $javaObject;
313
            case 'D':
314
            case 'F':
315
                return (float) $javaObject;
316
            case 'N':
317
                return null;
318
            case 'A':
319
                return (array) $javaObject;
320
            case 'O':
321
                return (object) $javaObject;
322
        }
323
    }
324
325
    /**
326
     * {@inheritdoc}
327
     *
328
     * @param Interfaces\JavaObject|int|float $javaObject
329
     */
330
    public function cast($javaObject, string $cast_type)
331
    {
332
        /* @todo see how can it be possible to clean up to new structure
333
            const CAST_TYPE_STRING  = 'string';
334
            const CAST_TYPE_BOOLEAN = 'boolean';
335
            const CAST_TYPE_INTEGER = 'integer';
336
            const CAST_TYPE_FLOAT   = 'float';
337
            const CAST_TYPE_ARRAY   = 'array';
338
            const CAST_TYPE_NULL    = 'null';
339
            const CAST_TYPE_OBJECT  = 'object';
340
            const CAST_TYPE_NULL -> null
341
         */
342
        $first_char = strtoupper(substr($cast_type, 0, 1));
343
        switch ($first_char) {
344
            case 'S':
345
                return (string) $javaObject;
346
            case 'B':
347
                return (bool) $javaObject;
348
            case 'L':
349
            case 'I':
350
                return (int) $javaObject;
351
            case 'D':
352
            case 'F':
353
                return (float) $javaObject;
354
            case 'N':
355
                return null;
356
            case 'A':
357
                return (array) $javaObject;
358
            case 'O':
359
                return (object) $javaObject;
360
            default:
361
                throw new Exception\RuntimeException("Unsupported cast_type parameter: $cast_type");
362
        }
363
    }
364
365
    /**
366
     * Return object java class name.
367
     *
368
     * @throws Exception\UnexpectedException
369
     * @throws BrokenConnectionException
370
     *
371
     * @param Interfaces\JavaObject $javaObject
372
     *
373
     * @return string
374
     */
375 11
    public function getClassName(Interfaces\JavaObject $javaObject): string
376
    {
377 11
        $inspect = $this->inspect($javaObject);
378
379
        // [class java.sql.DriverManager:
380 11
        $matches = [];
381 11
        preg_match('/^\[class (.+)\:/', $inspect, $matches);
382 11
        if (!isset($matches[1]) || $matches[1] == '') {
383
            throw new Exception\UnexpectedException(__METHOD__.' Cannot determine class name');
384
        }
385
386 11
        return $matches[1];
387
    }
388
}
389