1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Soluble Japha / PhpJavaBridge. |
7
|
|
|
* |
8
|
|
|
* @author Vanvelthem Sébastien |
9
|
|
|
* @license MIT |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Soluble\Japha\Bridge\Driver\Pjb62; |
13
|
|
|
|
14
|
|
|
use Monolog\Logger; |
15
|
|
|
use Soluble\Japha\Bridge\Exception; |
16
|
|
|
use Soluble\Japha\Interfaces; |
17
|
|
|
use Soluble\Japha\Bridge\Driver\ClientInterface; |
18
|
|
|
use ArrayObject; |
19
|
|
|
use Soluble\Japha\Bridge\Driver\Pjb62\Exception\IllegalArgumentException; |
20
|
|
|
use Psr\Log\LoggerInterface; |
21
|
|
|
use Psr\Log\NullLogger; |
22
|
|
|
|
23
|
|
|
class PjbProxyClient implements ClientInterface |
24
|
|
|
{ |
25
|
|
|
/** |
26
|
|
|
* @var PjbProxyClient|null |
27
|
|
|
*/ |
28
|
|
|
protected static $instance; |
29
|
|
|
|
30
|
|
|
protected static $unregistering = false; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var array |
34
|
|
|
*/ |
35
|
|
|
protected $defaultOptions = [ |
36
|
|
|
'java_disable_autoload' => true, |
37
|
|
|
'java_log_level' => null, |
38
|
|
|
'java_send_size' => 8192, |
39
|
|
|
'java_recv_size' => 8192, |
40
|
|
|
// java_prefer_values=true is the default working mode |
41
|
|
|
// of the soluble-japha client... It may be less efficient, |
42
|
|
|
// because it casts java String, Boolean, Integer... objects |
43
|
|
|
// automatically into (string, bool, integer...), and thus |
44
|
|
|
// not require additional writing like ($ba->values($myInt)) in |
|
|
|
|
45
|
|
|
// order to use a remote object. But prevent to work on the proxy instead, |
46
|
|
|
// so the value is always transferred for those types. If you put |
47
|
|
|
// at false you'll have to rework on the code. |
48
|
|
|
'java_prefer_values' => true, |
49
|
|
|
// use SimpleParser (pure PHP code) even if NativeParser (based on xml_* php functions) may be used |
50
|
|
|
// should only be used to workaround bugs or limitations regarding the xml extension |
51
|
|
|
'force_simple_xml_parser' => false |
52
|
|
|
]; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @var Client|null |
56
|
|
|
*/ |
57
|
|
|
protected static $client; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* Internal cache for already loaded Java classes. |
61
|
|
|
* |
62
|
|
|
* @var array |
63
|
|
|
*/ |
64
|
|
|
protected $classMapCache = []; |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* @var string |
68
|
|
|
*/ |
69
|
|
|
protected $compatibilityOption; |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* @var ArrayObject |
73
|
|
|
*/ |
74
|
|
|
protected $options; |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* @var LoggerInterface |
78
|
|
|
*/ |
79
|
|
|
protected $logger; |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* @var string|null |
83
|
|
|
*/ |
84
|
|
|
protected static $instanceOptionsKey; |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Private contructor. |
88
|
|
|
* |
89
|
|
|
* $options requires : |
90
|
|
|
* 'servlet_address' => 'http://127.0.0.1:8080/javabridge-bundle/java/servlet.phpjavabridge' |
91
|
|
|
* |
92
|
|
|
* Optionally : |
93
|
|
|
* 'java_log_level' => null |
94
|
|
|
* 'java_send_size' => 8192, |
95
|
|
|
* 'java_recv_size' => 8192 |
96
|
|
|
* |
97
|
|
|
* |
98
|
|
|
* @throws Exception\InvalidArgumentException |
99
|
|
|
* @throws Exception\ConnectionException |
100
|
|
|
* |
101
|
|
|
* @see PjbProxyClient::getInstance() |
102
|
|
|
* |
103
|
25 |
|
* @param array $options |
104
|
|
|
* @param LoggerInterface $logger |
105
|
25 |
|
*/ |
106
|
25 |
|
protected function __construct(array $options, LoggerInterface $logger) |
107
|
|
|
{ |
108
|
25 |
|
$this->options = new ArrayObject(array_merge($this->defaultOptions, $options)); |
109
|
25 |
|
self::$instanceOptionsKey = serialize((array) $this->options); |
110
|
21 |
|
|
111
|
|
|
$this->logger = $logger; |
112
|
|
|
$this->loadClient(); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Return a unique instance of the phpjavabridge client |
117
|
|
|
* $options is an associative array and requires :. |
118
|
|
|
* |
119
|
|
|
* 'servlet_address' => 'http://127.0.0.1:8080/javabridge-bundle/java/servlet.phpjavabridge' |
120
|
|
|
* |
121
|
|
|
* $options can be : |
122
|
|
|
* "java_send_size" => 8192, |
123
|
|
|
* "java_recv_size" => 8192, |
124
|
|
|
* "java_log_level' => null, |
125
|
|
|
* "java_prefer_values" => true (see note) |
126
|
|
|
* |
127
|
|
|
* <code> |
128
|
|
|
* $options = [ |
129
|
|
|
* 'servlet_address' => 'http://127.0.0.1:8080/javabridge-bundle/servlet.phpjavabridge' |
130
|
|
|
* "java_send_size" => 8192, |
131
|
|
|
* "java_recv_size" => 8192, |
132
|
|
|
* "internal_encoding" => 'UTF-8' |
133
|
|
|
* ]; |
134
|
|
|
* $pjb = PjbProxyClient::getInstance($options, $logger); |
135
|
|
|
* </code> |
136
|
|
|
* |
137
|
|
|
* Note: java_prefer_values=true is the default working mode |
138
|
|
|
* of the soluble-japha client... |
139
|
|
|
* |
140
|
|
|
* Disadvantage: Not good for performance !!! |
141
|
|
|
* > From mailinglist: Please note that the option JAVA_PREFER_VALUES kills performance as it |
142
|
|
|
* > checks for an exception after each call (I.e. each java call generates a full network round-trip). |
143
|
|
|
* Note that in simple_benchmarks.php no difference have been measured (localhost), need more |
144
|
|
|
* taylor made tests to see. |
145
|
|
|
* |
146
|
|
|
* Advantage: More readable / writable |
147
|
|
|
* > it casts java String, Boolean, Integer... objects |
148
|
|
|
* > automatically into (string, bool, integer...), and thus |
149
|
|
|
* > not require additional writing like ($ba->values($myInt)) in |
150
|
|
|
* > order to get the value. (proxy) |
151
|
|
|
* |
152
|
|
|
* If you put at false you'll have to rework on the code. |
153
|
|
|
* Check what's best for yourself |
154
|
|
|
* |
155
|
|
|
* @throws Exception\InvalidArgumentException |
156
|
|
|
* @throws Exception\ConnectionException |
157
|
|
|
* @throws \Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException |
158
|
|
|
* |
159
|
|
|
* @param array|null $options |
160
|
|
|
* @param LoggerInterface|null $logger any psr3 logger |
161
|
150 |
|
* |
162
|
|
|
* @return PjbProxyClient |
163
|
150 |
|
*/ |
164
|
26 |
|
public static function getInstance(?array $options = null, ?LoggerInterface $logger = null): PjbProxyClient |
165
|
3 |
|
{ |
166
|
|
|
if (self::$instance === null) { |
167
|
3 |
|
if ($options === null) { |
168
|
|
|
throw new Exception\InvalidUsageException( |
169
|
|
|
'Cannot instanciate PjbProxyClient without "$options" the first time, '. |
170
|
25 |
|
'or the instance have been unregistered since' |
171
|
11 |
|
); |
172
|
|
|
} |
173
|
25 |
|
if ($logger === null) { |
174
|
|
|
$logger = new NullLogger(); |
175
|
|
|
} |
176
|
147 |
|
self::$instance = new self($options, $logger); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
return self::$instance; |
180
|
|
|
} |
181
|
|
|
|
182
|
3 |
|
/** |
183
|
|
|
* @return bool |
184
|
3 |
|
*/ |
185
|
|
|
public static function isInitialized(): bool |
186
|
|
|
{ |
187
|
|
|
return self::$instance !== null; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Load pjb client with options. |
192
|
|
|
* |
193
|
25 |
|
* @throws Exception\InvalidArgumentException |
194
|
|
|
* @throws Exception\ConnectionException |
195
|
25 |
|
*/ |
196
|
25 |
|
protected function loadClient(): void |
197
|
|
|
{ |
198
|
25 |
|
if (self::$client === null) { |
199
|
1 |
|
$options = $this->options; |
200
|
|
|
|
201
|
|
|
if (!isset($options['servlet_address'])) { |
202
|
24 |
|
throw new Exception\InvalidArgumentException(__METHOD__.' Missing required parameter servlet_address'); |
203
|
|
|
} |
204
|
23 |
|
|
205
|
23 |
|
$connection = static::parseServletUrl($options['servlet_address']); |
206
|
23 |
|
|
207
|
23 |
|
$params = new ArrayObject([ |
208
|
23 |
|
Client::PARAM_JAVA_HOSTS => $connection['servlet_host'], |
209
|
23 |
|
Client::PARAM_JAVA_SERVLET => $connection['servlet_uri'], |
210
|
23 |
|
Client::PARAM_JAVA_AUTH_USER => $connection['auth_user'], |
211
|
23 |
|
Client::PARAM_JAVA_AUTH_PASSWORD => $connection['auth_password'], |
212
|
23 |
|
Client::PARAM_JAVA_DISABLE_AUTOLOAD => $options['java_disable_autoload'], |
213
|
23 |
|
Client::PARAM_JAVA_PREFER_VALUES => $options['java_prefer_values'], |
214
|
23 |
|
Client::PARAM_JAVA_SEND_SIZE => $options['java_send_size'], |
215
|
|
|
Client::PARAM_JAVA_RECV_SIZE => $options['java_recv_size'], |
216
|
|
|
Client::PARAM_JAVA_LOG_LEVEL => $options['java_log_level'], |
217
|
23 |
|
Client::PARAM_XML_PARSER_FORCE_SIMPLE_PARSER => $options['force_simple_xml_parser'], |
218
|
|
|
]); |
219
|
|
|
|
220
|
21 |
|
self::$client = new Client($params, $this->logger); |
221
|
|
|
|
222
|
21 |
|
// Added in order to work with custom exceptions |
223
|
|
|
self::getClient()->throwExceptionProxyFactory = new Proxy\DefaultThrowExceptionProxyFactory(self::$client, $this->logger); |
224
|
21 |
|
|
225
|
|
|
$this->bootstrap(); |
226
|
|
|
} |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* Return Pjb62 internal client. |
231
|
135 |
|
* |
232
|
|
|
* @return Client |
233
|
135 |
|
* |
234
|
5 |
|
* @throws Exception\BrokenConnectionException |
235
|
|
|
*/ |
236
|
|
|
public static function getClient(): Client |
237
|
135 |
|
{ |
238
|
|
|
if (self::$client === null) { |
239
|
|
|
throw new Exception\BrokenConnectionException('Client is not registered'); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
return self::$client; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
/** |
246
|
|
|
* Return a Java class. |
247
|
|
|
* |
248
|
|
|
* @throws \Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException |
249
|
56 |
|
* |
250
|
|
|
* @param string $name Name of the java class |
251
|
56 |
|
* |
252
|
25 |
|
* @return JavaClass |
253
|
|
|
*/ |
254
|
|
|
public function getJavaClass($name): Interfaces\JavaClass |
255
|
50 |
|
{ |
256
|
|
|
if (!array_key_exists($name, $this->classMapCache)) { |
257
|
|
|
$this->classMapCache[$name] = new JavaClass($name); |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
return $this->classMapCache[$name]; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* Invoke a method dynamically. |
265
|
|
|
* |
266
|
|
|
* Example: |
267
|
|
|
* <code> |
268
|
|
|
* $bigint1 = new Java('java.math.BigInteger', 10); |
269
|
|
|
* $bigint2 = new Java('java.math.BigInteger', 20); |
270
|
|
|
* $bigint3 = PjbProxyClient::invokeMethod($bigint, "add", [$bigint2]) |
271
|
|
|
* </code> |
272
|
|
|
* |
273
|
|
|
* <br> Any declared exception can be caught by PHP code. <br> |
274
|
|
|
* Exceptions derived from java.lang.RuntimeException or Error should |
275
|
|
|
* not be caught unless declared in the methods throws clause -- OutOfMemoryErrors cannot be caught at all, |
276
|
|
|
* even if declared. |
277
|
|
|
* |
278
|
|
|
* @throws \Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException |
279
|
|
|
* |
280
|
|
|
* @param Interfaces\JavaType|null $object a java object or type |
281
|
5 |
|
* @param string $method A method string |
282
|
|
|
* @param mixed $args Arguments to send to method |
283
|
5 |
|
* |
284
|
|
|
* @return mixed |
285
|
5 |
|
*/ |
286
|
|
|
public function invokeMethod(?Interfaces\JavaType $object = null, string $method, array $args = []) |
287
|
|
|
{ |
288
|
|
|
$id = ($object === null) ? 0 : $object->__getJavaInternalObjectId(); |
289
|
|
|
|
290
|
|
|
return self::getClient()->invokeMethod($id, $method, $args); |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
/** |
294
|
|
|
* Inspect the java object | type. |
295
|
|
|
* |
296
|
|
|
* @throws \Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException |
297
|
|
|
* |
298
|
|
|
* @param Interfaces\JavaType $object |
299
|
12 |
|
* |
300
|
|
|
* @return string |
301
|
|
|
* |
302
|
|
|
* @throws IllegalArgumentException |
303
|
12 |
|
*/ |
304
|
|
|
public function inspect(Interfaces\JavaType $object): string |
305
|
|
|
{ |
306
|
|
|
return self::getClient()->invokeMethod(0, 'inspect', [$object]); |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
/** |
310
|
|
|
* Test whether an object is an instance of java class or interface. |
311
|
|
|
* |
312
|
|
|
* @throws Exception\InvalidArgumentException |
313
|
|
|
* @throws \Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException |
314
|
|
|
* |
315
|
|
|
* @param Interfaces\JavaObject $object |
316
|
|
|
* @param JavaType|string|Interfaces\JavaClass|Interfaces\JavaObject|string $class |
317
|
8 |
|
* |
318
|
|
|
* @return bool |
319
|
8 |
|
*/ |
320
|
|
|
public function isInstanceOf(Interfaces\JavaObject $object, $class): bool |
321
|
6 |
|
{ |
322
|
|
|
if (is_string($class)) { |
323
|
6 |
|
// Attempt to initiate a class |
324
|
3 |
|
$name = $class; |
325
|
2 |
|
// Will eventually throws ClassNotFoundException |
326
|
|
|
$class = $this->getJavaClass($name); |
327
|
|
|
} elseif (!$class instanceof Interfaces\JavaObject) { |
328
|
4 |
|
throw new Exception\InvalidArgumentException(__METHOD__.'Class $class parameter must be of Interfaces\JavaClass, Interfaces\JavaObject or string'); |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
return self::getClient()->invokeMethod(0, 'instanceOf', [$object, $class]); |
|
|
|
|
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* Evaluate a Java object. |
336
|
|
|
* |
337
|
|
|
* Evaluate a object and fetch its content, if possible. Use java_values() to convert a Java object into an equivalent PHP value. |
338
|
|
|
* |
339
|
|
|
* A java array, Map or Collection object is returned |
340
|
|
|
* as a php array. |
341
|
|
|
* An array, Map or Collection proxy is returned as a java array, Map or |
342
|
|
|
* Collection object, and a null proxy is returned as null. |
343
|
|
|
* All values of java types for which a primitive php type exists are |
344
|
|
|
* returned as php values. |
345
|
|
|
* Everything else is returned unevaluated. |
346
|
|
|
* Please make sure that the values do not not exceed |
347
|
|
|
* php's memory limit. Example: |
348
|
|
|
* |
349
|
|
|
* |
350
|
|
|
* <code> |
351
|
|
|
* $str = new java("java.lang.String", "hello"); |
352
|
|
|
* echo java_values($str); |
353
|
|
|
* => hello |
354
|
|
|
* $chr = $str->toCharArray(); |
355
|
|
|
* echo $chr; |
356
|
|
|
* => [o(array_of-C):"[C@1b10d42"] |
357
|
|
|
* $ar = java_values($chr); |
358
|
|
|
* print $ar; |
359
|
|
|
* => Array |
360
|
|
|
* print $ar[0]; |
361
|
|
|
* => [o(Character):"h"] |
362
|
|
|
* print java_values($ar[0]); |
363
|
|
|
* => h |
364
|
|
|
* </code> |
365
|
|
|
* |
366
|
|
|
* @throws \Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException |
367
|
|
|
* |
368
|
|
|
* @param Interfaces\JavaObject $object |
369
|
12 |
|
* |
370
|
|
|
* @return mixed |
371
|
12 |
|
*/ |
372
|
|
|
public function getValues(Interfaces\JavaObject $object) |
373
|
|
|
{ |
374
|
|
|
return self::getClient()->invokeMethod(0, 'getValues', [$object]); |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
/** |
378
|
|
|
* Return latest exception. |
379
|
|
|
* |
380
|
|
|
* @deprecated |
381
|
|
|
* |
382
|
|
|
* @throws \Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException |
383
|
1 |
|
* |
384
|
|
|
* @return \Soluble\Japha\Bridge\Driver\Pjb62\Exception\JavaException |
385
|
1 |
|
*/ |
386
|
|
|
public function getLastException() |
387
|
|
|
{ |
388
|
|
|
return self::getClient()->invokeMethod(0, 'getLastException', []); |
|
|
|
|
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
/** |
392
|
|
|
* Clear last exception. |
393
|
|
|
* |
394
|
|
|
* @deprecated |
395
|
1 |
|
* |
396
|
|
|
* @throws \Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException |
397
|
1 |
|
*/ |
398
|
1 |
|
public function clearLastException(): void |
399
|
|
|
{ |
400
|
|
|
self::getClient()->invokeMethod(0, 'clearLastException', []); |
401
|
|
|
} |
402
|
|
|
|
403
|
|
|
/** |
404
|
|
|
* @param Client $client |
405
|
21 |
|
* |
406
|
|
|
* @return string |
407
|
21 |
|
*/ |
408
|
21 |
|
public function getCompatibilityOption(Client $client = null): string |
409
|
1 |
|
{ |
410
|
|
|
if ($this->compatibilityOption === null) { |
411
|
|
|
if ($client === null) { |
412
|
21 |
|
$client = $client = self::getClient(); |
|
|
|
|
413
|
21 |
|
} |
414
|
21 |
|
|
415
|
21 |
|
$java_prefer_values = $this->getOption('java_prefer_values'); |
416
|
|
|
$java_log_level = $this->getOption('java_log_level'); |
417
|
|
|
$compatibility = ($client->RUNTIME['PARSER'] === 'NATIVE') ? (0103 - $java_prefer_values) : (0100 + $java_prefer_values); |
418
|
21 |
|
if (is_int($java_log_level)) { |
419
|
|
|
$compatibility |= 128 | (7 & $java_log_level) << 2; |
420
|
|
|
} |
421
|
21 |
|
$this->compatibilityOption = chr($compatibility); |
422
|
|
|
} |
423
|
|
|
|
424
|
|
|
return $this->compatibilityOption; |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
/** |
428
|
|
|
* Utility class to parse servlet_address, |
429
|
|
|
* i.e 'http://localhost:8080/javabridge-bundle/java/servlet.phpjavabridge'. |
430
|
|
|
* |
431
|
|
|
* @throws Exception\InvalidArgumentException |
432
|
|
|
* |
433
|
|
|
* @param string $servlet_address |
434
|
27 |
|
* |
435
|
|
|
* @return array associative array with 'servlet_host' and 'servlet_uri' |
436
|
27 |
|
*/ |
437
|
|
|
public static function parseServletUrl(string $servlet_address): array |
438
|
27 |
|
{ |
439
|
1 |
|
$url = parse_url($servlet_address); |
440
|
|
|
|
441
|
|
|
if ($url === false || !isset($url['host'])) { |
442
|
26 |
|
throw new Exception\InvalidArgumentException(__METHOD__." Cannot parse url '$servlet_address'"); |
443
|
26 |
|
} |
444
|
26 |
|
|
445
|
|
|
$scheme = ''; |
446
|
26 |
|
if (isset($url['scheme'])) { |
447
|
26 |
|
$scheme = $url['scheme'] === 'https' ? 'ssl://' : $scheme; |
448
|
26 |
|
} |
449
|
|
|
$host = $url['host']; |
450
|
|
|
$port = $url['port']; |
451
|
26 |
|
$path = $url['path'] ?? ''; |
452
|
26 |
|
|
453
|
26 |
|
$infos = [ |
454
|
26 |
|
'servlet_host' => "{$scheme}{$host}:{$port}", |
455
|
|
|
'servlet_uri' => $path, |
456
|
|
|
'auth_user' => $url['user'] ?? null, |
457
|
26 |
|
'auth_password' => $url['pass'] ?? null, |
458
|
|
|
]; |
459
|
|
|
|
460
|
|
|
return $infos; |
461
|
|
|
} |
462
|
|
|
|
463
|
21 |
|
/** |
464
|
|
|
* For compatibility usage all constants have been kept. |
465
|
21 |
|
*/ |
466
|
21 |
|
protected function bootstrap($options = []): void |
|
|
|
|
467
|
|
|
{ |
468
|
|
|
register_shutdown_function(['Soluble\Japha\Bridge\Driver\Pjb62\PjbProxyClient', 'unregisterInstance']); |
469
|
|
|
} |
470
|
|
|
|
471
|
|
|
/** |
472
|
|
|
* Return options. |
473
|
2 |
|
* |
474
|
|
|
* @return ArrayObject |
475
|
2 |
|
*/ |
476
|
|
|
public function getOptions(): ArrayObject |
477
|
|
|
{ |
478
|
|
|
return $this->options; |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
/** |
482
|
|
|
* Return specific option. |
483
|
|
|
* |
484
|
|
|
* @return mixed |
485
|
21 |
|
*/ |
486
|
|
|
public function getOption(string $name) |
487
|
21 |
|
{ |
488
|
1 |
|
if (!array_key_exists($name, $this->options)) { |
|
|
|
|
489
|
|
|
throw new Exception\InvalidArgumentException("Option '$name' does not exists'"); |
490
|
|
|
} |
491
|
21 |
|
|
492
|
|
|
return $this->options[$name]; |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
public function getLogger(): LoggerInterface |
496
|
|
|
{ |
497
|
20 |
|
return $this->logger; |
498
|
|
|
} |
499
|
20 |
|
|
500
|
|
|
/** |
501
|
|
|
* @throws Exception\BrokenConnectionException|Exception\AuthenticationException |
502
|
|
|
*/ |
503
|
|
|
public static function unregisterAndThrowBrokenConnectionException(string $message = null, int $code = null): void |
504
|
|
|
{ |
505
|
20 |
|
if (self::$instance !== null) { |
506
|
|
|
$message = $message ?? 'undefined messsage'; |
507
|
|
|
|
508
|
|
|
switch ($code) { |
509
|
|
|
case 401: |
|
|
|
|
510
|
20 |
|
$exception = new Exception\AuthenticationException(sprintf( |
511
|
20 |
|
'Java bridge authentication failure: code: %s', |
512
|
14 |
|
$code |
513
|
|
|
)); |
514
|
|
|
break; |
515
|
|
|
default: |
|
|
|
|
516
|
|
|
$exception = new Exception\BrokenConnectionException(sprintf( |
517
|
|
|
'Java bridge broken connection: "%s" (code: %s)', |
518
|
|
|
$message, |
519
|
20 |
|
$code |
520
|
20 |
|
)); |
521
|
|
|
} |
522
|
20 |
|
try { |
523
|
14 |
|
self::$instance->getLogger()->critical(sprintf( |
524
|
|
|
'[soluble-japha] BrokenConnectionException to "%s": "%s" (code: "%s")', |
525
|
|
|
self::$instance->getOption('servlet_address'), |
526
|
|
|
$message, |
527
|
|
|
$code ?? '?' |
528
|
20 |
|
)); |
529
|
20 |
|
} catch (\Throwable $e) { |
530
|
20 |
|
// discard logger errors |
531
|
|
|
} |
532
|
20 |
|
|
533
|
|
|
self::unregisterInstance(); |
534
|
|
|
throw $exception; |
535
|
|
|
} |
536
|
|
|
} |
537
|
|
|
|
538
|
|
|
/** |
539
|
|
|
* Clean up PjbProxyClient instance. |
540
|
|
|
*/ |
541
|
|
|
public static function unregisterInstance(): void |
542
|
|
|
{ |
543
|
|
|
if (!self::$unregistering && self::$client !== null) { |
544
|
|
|
self::$unregistering = true; |
545
|
|
|
|
546
|
|
|
if (self::$client->preparedToSendBuffer) { |
|
|
|
|
547
|
|
|
self::$client->sendBuffer .= self::$client->preparedToSendBuffer; |
548
|
|
|
} |
549
|
|
|
|
550
|
|
|
try { |
551
|
|
|
self::$client->sendBuffer .= self::$client->protocol->getKeepAlive(); |
552
|
|
|
self::$client->protocol->flush(); |
553
|
|
|
} catch (\Throwable $e) { |
|
|
|
|
554
|
|
|
} |
555
|
|
|
|
556
|
|
|
// TODO MUST TEST, IT WAS REMOVED FROM FUNCTION |
557
|
|
|
// BECAUSE IT SIMPLY LOOKS LIKE THE LINES BEFORE |
558
|
|
|
// ADDED AN IF TO CHECK THE CHANNEL In CASE OF |
559
|
|
|
// |
560
|
|
|
if (isset(self::$client->protocol->handler->channel) && |
561
|
|
|
false === strpos(get_class(self::getClient()->protocol->handler->channel), '/EmptyChannel/')) { |
562
|
|
|
try { |
563
|
|
|
self::$client->protocol->keepAlive(); |
564
|
|
|
} catch (\Throwable $e) { |
565
|
|
|
// silently discard exceptions when unregistering |
566
|
|
|
} |
567
|
|
|
} |
568
|
|
|
|
569
|
|
|
self::$client = null; |
570
|
|
|
self::$instance = null; |
571
|
|
|
self::$instanceOptionsKey = null; |
572
|
|
|
self::$unregistering = false; |
573
|
|
|
} |
574
|
|
|
} |
575
|
|
|
} |
576
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.