1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* \AppserverIo\Configuration\Configuration |
5
|
|
|
* |
6
|
|
|
* NOTICE OF LICENSE |
7
|
|
|
* |
8
|
|
|
* This source file is subject to the Open Software License (OSL 3.0) |
9
|
|
|
* that is available through the world-wide-web at this URL: |
10
|
|
|
* http://opensource.org/licenses/osl-3.0.php |
11
|
|
|
* |
12
|
|
|
* PHP version 5 |
13
|
|
|
* |
14
|
|
|
* @author Tim Wagner <[email protected]> |
15
|
|
|
* @copyright 2015 TechDivision GmbH <[email protected]> |
16
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
17
|
|
|
* @link http://github.com/appserver-io/configuration |
18
|
|
|
* @link http://www.appserver.io |
19
|
|
|
*/ |
20
|
|
|
|
21
|
|
|
namespace AppserverIo\Configuration; |
22
|
|
|
|
23
|
|
|
use AppserverIo\Configuration\Interfaces\ConfigurationInterface; |
24
|
|
|
use AppserverIo\Configuration\Interfaces\PersistableConfigurationInterface; |
25
|
|
|
use AppserverIo\Configuration\Interfaces\ValidityAwareConfigurationInterface; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* A simple XML based configuration implementation. |
29
|
|
|
* |
30
|
|
|
* @author Tim Wagner <[email protected]> |
31
|
|
|
* @copyright 2015 TechDivision GmbH <[email protected]> |
32
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
33
|
|
|
* @link http://github.com/appserver-io/configuration |
34
|
|
|
* @link http://www.appserver.io |
35
|
|
|
*/ |
36
|
|
|
class Configuration implements ConfigurationInterface, ValidityAwareConfigurationInterface, PersistableConfigurationInterface |
37
|
|
|
{ |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* XSD schema filename used for validation. |
41
|
|
|
* |
42
|
|
|
* @var string |
43
|
|
|
*/ |
44
|
|
|
protected $schemaFile; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* the node name to use. |
48
|
|
|
* |
49
|
|
|
* @var string |
50
|
|
|
*/ |
51
|
|
|
protected $nodeName; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* The node's position in the tree. |
55
|
|
|
* |
56
|
|
|
* @var integer |
57
|
|
|
*/ |
58
|
|
|
protected $position = 0; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* The node value. |
62
|
|
|
* |
63
|
|
|
* @var string |
64
|
|
|
*/ |
65
|
|
|
protected $value; |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* The array with configuration parameters. |
69
|
|
|
* |
70
|
|
|
* @var array |
71
|
|
|
*/ |
72
|
|
|
protected $data = array(); |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* The array with the child configurations. |
76
|
|
|
* |
77
|
|
|
* @var array |
78
|
|
|
*/ |
79
|
|
|
protected $children = array(); |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Initializes the configuration with the node name of the |
83
|
|
|
* node in the XML structure. |
84
|
|
|
* |
85
|
|
|
* @param string|null $nodeName The configuration element's node name |
86
|
|
|
* @param integer $position The node's position in the tree |
87
|
|
|
*/ |
88
|
23 |
|
public function __construct($nodeName = null, $position = 0) |
89
|
|
|
{ |
90
|
23 |
|
$this->setNodeName($nodeName); |
91
|
23 |
|
$this->setPosition($position); |
92
|
23 |
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Sets the configuration element's node name. |
96
|
|
|
* |
97
|
|
|
* @param string $nodeName The node name |
98
|
|
|
* |
99
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The instance itself |
100
|
|
|
*/ |
101
|
23 |
|
public function setNodeName($nodeName) |
102
|
|
|
{ |
103
|
23 |
|
$this->nodeName = $nodeName; |
104
|
23 |
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Returns the configuration element's node name. |
108
|
|
|
* |
109
|
|
|
* @return string The node name |
110
|
|
|
*/ |
111
|
12 |
|
public function getNodeName() |
112
|
|
|
{ |
113
|
12 |
|
return $this->nodeName; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Sets the position of the node in the tree. |
118
|
|
|
* |
119
|
|
|
* @param integer $position The node's position |
120
|
|
|
* |
121
|
|
|
* @return void |
122
|
|
|
*/ |
123
|
23 |
|
public function setPosition($position) |
124
|
|
|
{ |
125
|
23 |
|
$this->position = $position; |
126
|
23 |
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Returns the position of the node in the tree. |
130
|
|
|
* |
131
|
|
|
* @return integer The node's position |
132
|
|
|
*/ |
133
|
1 |
|
public function getPosition() |
134
|
|
|
{ |
135
|
1 |
|
return $this->position; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* Checks if the passed configuration is equal. If yes, the method |
140
|
|
|
* returns TRUE, if not FALSE. |
141
|
|
|
* |
142
|
|
|
* @param \AppserverIo\Configuration\Interfaces\ConfigurationInterface $configuration The configuration to compare to |
143
|
|
|
* |
144
|
|
|
* @return boolean TRUE if the configurations are equal, else FALSE |
145
|
|
|
*/ |
146
|
2 |
|
public function equals(ConfigurationInterface $configuration) |
147
|
|
|
{ |
148
|
2 |
|
return $this === $configuration; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Adds a new child configuration. |
153
|
|
|
* |
154
|
|
|
* @param \AppserverIo\Configuration\Interfaces\ConfigurationInterface $configuration The child configuration itself |
155
|
|
|
* |
156
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The configuration instance |
157
|
|
|
*/ |
158
|
17 |
|
public function addChild(ConfigurationInterface $configuration) |
159
|
|
|
{ |
160
|
17 |
|
$this->children[] = $configuration; |
161
|
17 |
|
return $this; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* Creates a new child configuration node with the passed name and value |
166
|
|
|
* and adds it as child to this node. |
167
|
|
|
* |
168
|
|
|
* @param string $nodeName The child's node name |
169
|
|
|
* @param string $value The child's node value |
170
|
|
|
* |
171
|
|
|
* @return void |
172
|
|
|
*/ |
173
|
|
|
public function addChildWithNameAndValue($nodeName, $value) |
174
|
|
|
{ |
175
|
|
|
$node = new Configuration(); |
176
|
|
|
$node->setNodeName($nodeName); |
177
|
|
|
$node->setValue($value); |
178
|
|
|
$this->addChild($node); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Initializes the configuration with the XML information found |
183
|
|
|
* in the file with the passed relative or absolute path. |
184
|
|
|
* |
185
|
|
|
* @param string $file The path to the file |
186
|
|
|
* |
187
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The initialized configuration |
188
|
|
|
* @throws \Exception Is thrown if the file with the passed name is not a valid XML file |
189
|
|
|
*/ |
190
|
4 |
View Code Duplication |
public function initFromFile($file) |
|
|
|
|
191
|
|
|
{ |
192
|
4 |
|
if (($root = simplexml_load_file($file)) === false) { |
193
|
|
|
$errors = array(); |
194
|
|
|
foreach (libxml_get_errors() as $error) { |
195
|
|
|
$errors[] = sprintf( |
196
|
|
|
'Found a schema validation error on line %s with code %s and message %s when validating configuration file %s', |
197
|
|
|
$error->line, |
198
|
|
|
$error->code, |
199
|
|
|
$error->message, |
200
|
|
|
$error->file |
201
|
|
|
); |
202
|
|
|
} |
203
|
|
|
throw new \Exception(implode(PHP_EOL, $errors)); |
204
|
|
|
} |
205
|
4 |
|
return $this->init($root); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Initializes the configuration with the XML information passed as string. |
210
|
|
|
* |
211
|
|
|
* @param string $string The string with the XML content to initialize from |
212
|
|
|
* |
213
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The initialized configuration |
214
|
|
|
* @throws \Exception Is thrown if the passed XML string is not valid |
215
|
|
|
*/ |
216
|
|
View Code Duplication |
public function initFromString($string) |
|
|
|
|
217
|
|
|
{ |
218
|
|
|
if (($root = simplexml_load_string($string)) === false) { |
219
|
|
|
$errors = array(); |
220
|
|
|
foreach (libxml_get_errors() as $error) { |
221
|
|
|
$errors[] = sprintf( |
222
|
|
|
'Found a schema validation error on line %s with code %s and message %s when validating configuration file %s', |
223
|
|
|
$error->line, |
224
|
|
|
$error->code, |
225
|
|
|
$error->message, |
226
|
|
|
$error->file |
227
|
|
|
); |
228
|
|
|
} |
229
|
|
|
throw new \Exception(implode(PHP_EOL, $errors)); |
230
|
|
|
} |
231
|
|
|
return $this->init($root); |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
/** |
235
|
|
|
* Initializes the configuration with the XML information found |
236
|
|
|
* in the passed DOMDocument. |
237
|
|
|
* |
238
|
|
|
* @param \DOMDocument $domDocument The DOMDocument with XML information |
239
|
|
|
* |
240
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The initialized configuration |
241
|
|
|
*/ |
242
|
1 |
|
public function initFromDomDocument(\DOMDocument $domDocument) |
243
|
|
|
{ |
244
|
1 |
|
$root = simplexml_import_dom($domDocument); |
245
|
1 |
|
return $this->init($root); |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Recursively initializes the configuration instance with the data from the |
250
|
|
|
* passed SimpleXMLElement. |
251
|
|
|
* |
252
|
|
|
* @param \SimpleXMLElement $node The node to load the data from |
253
|
|
|
* |
254
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The node instance itself |
255
|
|
|
*/ |
256
|
15 |
|
public function init(\SimpleXMLElement $node) |
257
|
|
|
{ |
258
|
|
|
|
259
|
|
|
// set the node name + value |
260
|
15 |
|
$this->setNodeName($node->getName()); |
261
|
|
|
|
262
|
|
|
// check if we found a node value |
263
|
15 |
|
$nodeValue = (string) $node; |
264
|
15 |
|
if (empty($nodeValue) === false) { |
265
|
15 |
|
$this->setValue(trim($nodeValue)); |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
// load the attributes |
269
|
15 |
|
foreach ($node->attributes() as $key => $value) { |
270
|
14 |
|
$this->setData($key, (string) $value); |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
// initialize the position counter |
274
|
15 |
|
$position = 0; |
275
|
|
|
|
276
|
|
|
// append children |
277
|
15 |
|
foreach ($node->children() as $child) { |
278
|
|
|
// create a new configuration node |
279
|
15 |
|
$cnt = new Configuration(null, $position++); |
280
|
|
|
|
281
|
|
|
// parse the configuration recursive |
282
|
15 |
|
$cnt->init($child); |
283
|
|
|
|
284
|
|
|
// append the configuration node to the parent |
285
|
15 |
|
$this->addChild($cnt); |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
// return the instance node itself |
289
|
15 |
|
return $this; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
/** |
293
|
|
|
* Returns the child configuration nodes with the passed type. |
294
|
|
|
* |
295
|
|
|
* @param string $path The path of the configuration to return |
296
|
|
|
* |
297
|
|
|
* @return array The requested child configuration nodes |
298
|
|
|
*/ |
299
|
9 |
|
public function getChilds($path) |
300
|
|
|
{ |
301
|
9 |
|
$token = strtok($path, '/'); |
302
|
9 |
|
$next = substr($path, strlen('/' . $token)); |
303
|
9 |
|
if ($this->getNodeName() == $token && empty($next)) { |
304
|
7 |
|
return $this; |
|
|
|
|
305
|
9 |
|
} elseif ($this->getNodeName() == $token && empty($next) === false) { |
306
|
7 |
|
$matches = array(); |
307
|
7 |
|
foreach ($this->getChildren() as $child) { |
308
|
7 |
|
$result = $child->getChilds($next); |
309
|
7 |
|
if (is_array($result)) { |
310
|
4 |
|
$matches = $result; |
311
|
7 |
|
} elseif ($result instanceof Configuration) { |
312
|
7 |
|
$matches[] = $result; |
313
|
|
|
} |
314
|
|
|
} |
315
|
7 |
|
return $matches; |
316
|
|
|
} else { |
317
|
6 |
|
return null; |
318
|
|
|
} |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
/** |
322
|
|
|
* Returns the child configuration with the passed type. |
323
|
|
|
* |
324
|
|
|
* @param string $path The path of the configuration to return |
325
|
|
|
* |
326
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The requested configuration |
327
|
|
|
*/ |
328
|
9 |
|
public function getChild($path) |
329
|
|
|
{ |
330
|
9 |
|
if (is_array($childs = $this->getChilds($path))) { |
331
|
7 |
|
return current($childs); |
332
|
|
|
} |
333
|
2 |
|
} |
334
|
|
|
|
335
|
|
|
/** |
336
|
|
|
* Removes the children of the configuration with passed path and |
337
|
|
|
* returns the parent configuration. |
338
|
|
|
* |
339
|
|
|
* @param string $path The path of the configuration to remove the children for |
340
|
|
|
* |
341
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The instance the children has been removed |
342
|
|
|
* @see \AppserverIo\Configuration\Interfaces\ConfigurationInterface::getChild($path) |
343
|
|
|
* @see \AppserverIo\Configuration\Interfaces\ConfigurationInterface::getChilds($path) |
344
|
|
|
*/ |
345
|
3 |
|
public function removeChilds($path) |
346
|
|
|
{ |
347
|
3 |
|
$token = strtok($path, '/'); |
348
|
3 |
|
$next = substr($path, strlen('/' . $token)); |
349
|
3 |
|
if ($this->getNodeName() == $token && empty($next) === false) { |
350
|
2 |
|
$this->setChildren(array()); |
351
|
2 |
|
return $this; |
352
|
|
|
} else { |
353
|
1 |
|
return $this; |
354
|
|
|
} |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
/** |
358
|
|
|
* Returns all child configurations. |
359
|
|
|
* |
360
|
|
|
* @return array The child configurations |
361
|
|
|
*/ |
362
|
16 |
|
public function getChildren() |
363
|
|
|
{ |
364
|
16 |
|
return $this->children; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* Replaces actual children with the passed array. If children |
369
|
|
|
* already exists they will be lost. |
370
|
|
|
* |
371
|
|
|
* @param array $children The array with the children to set |
372
|
|
|
* |
373
|
|
|
* @return void |
374
|
|
|
*/ |
375
|
2 |
|
public function setChildren(array $children) |
376
|
|
|
{ |
377
|
2 |
|
$this->children = $children; |
378
|
2 |
|
} |
379
|
|
|
|
380
|
|
|
/** |
381
|
|
|
* Check's if the node has children, if yes the method |
382
|
|
|
* returns TRUE, else the method returns FALSE. |
383
|
|
|
* |
384
|
|
|
* @return boolean TRUE if the node has children, else FALSE |
385
|
|
|
*/ |
386
|
9 |
|
public function hasChildren() |
387
|
|
|
{ |
388
|
|
|
// check the children size |
389
|
9 |
|
if (sizeof($this->getChildren()) == 0) { |
390
|
3 |
|
return false; |
391
|
|
|
} |
392
|
8 |
|
return true; |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
/** |
396
|
|
|
* Adds the passed configuration value. |
397
|
|
|
* |
398
|
|
|
* @param string $key Name of the configuration value |
399
|
|
|
* @param mixed $value The configuration value |
400
|
|
|
* |
401
|
|
|
* @return void |
402
|
|
|
*/ |
403
|
15 |
|
public function setData($key, $value) |
404
|
|
|
{ |
405
|
15 |
|
$this->data[$key] = $value; |
406
|
15 |
|
} |
407
|
|
|
|
408
|
|
|
/** |
409
|
|
|
* Returns the configuration value with the passed name. |
410
|
|
|
* |
411
|
|
|
* @param string $key The name of the requested configuration value. |
412
|
|
|
* |
413
|
|
|
* @return mixed The configuration value itself |
414
|
|
|
*/ |
415
|
4 |
|
public function getData($key) |
416
|
|
|
{ |
417
|
4 |
|
if (array_key_exists($key, $this->data)) { |
418
|
2 |
|
return $this->data[$key]; |
419
|
|
|
} |
420
|
2 |
|
} |
421
|
|
|
|
422
|
|
|
/** |
423
|
|
|
* Appends the passed attributes to the configuration node. If the |
424
|
|
|
* attribute already exists it will be overwritten by default. |
425
|
|
|
* |
426
|
|
|
* @param array $data The data with the attributes to append |
427
|
|
|
* |
428
|
|
|
* @return void |
429
|
|
|
*/ |
430
|
|
|
public function appendData(array $data) |
431
|
|
|
{ |
432
|
|
|
foreach ($data as $key => $value) { |
433
|
|
|
$this->data[$key] = $value; |
434
|
|
|
} |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* Replaces actual attributes with the passed array. If attributes |
439
|
|
|
* already exists they will be lost. |
440
|
|
|
* |
441
|
|
|
* @param array $data The array with the key value attribute pairs |
442
|
|
|
* |
443
|
|
|
* @return void |
444
|
|
|
*/ |
445
|
2 |
|
public function setAllData($data) |
446
|
|
|
{ |
447
|
2 |
|
$this->data = $data; |
448
|
2 |
|
} |
449
|
|
|
|
450
|
|
|
/** |
451
|
|
|
* Returns all attributes. |
452
|
|
|
* |
453
|
|
|
* @return array The array with all attributes |
454
|
|
|
*/ |
455
|
2 |
|
public function getAllData() |
456
|
|
|
{ |
457
|
2 |
|
return $this->data; |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
/** |
461
|
|
|
* Wrapper method for getter/setter methods. |
462
|
|
|
* |
463
|
|
|
* @param string $method The called method name |
464
|
|
|
* @param array $args The methods arguments |
465
|
|
|
* |
466
|
|
|
* @return mixed The value if a getter has been invoked |
467
|
|
|
* @throws \Exception Is thrown if nor a getter/setter has been invoked |
468
|
|
|
*/ |
469
|
5 |
|
public function __call($method, $args) |
470
|
|
|
{ |
471
|
|
|
// lowercase the first character of the member |
472
|
5 |
|
$key = lcfirst(substr($method, 3)); |
473
|
|
|
// check if a getter/setter has been called |
474
|
5 |
|
switch (substr($method, 0, 3)) { |
475
|
5 |
|
case 'get': |
476
|
3 |
|
$child = $this->getChild("/{$this->getNodeName()}/$key"); |
477
|
3 |
|
if ($child instanceof Configuration) { |
478
|
2 |
|
return $child; |
479
|
|
|
} |
480
|
2 |
|
return $this->getData($key); |
481
|
2 |
|
case 'set': |
482
|
1 |
|
$this->setData($key, isset($args[0]) ? $args[0] : null); |
483
|
1 |
|
break; |
484
|
|
|
default: |
485
|
1 |
|
throw new \Exception("Invalid method " . get_class($this) . "::" . $method . "(" . print_r($args, true) . ")"); |
486
|
|
|
} |
487
|
1 |
|
} |
488
|
|
|
|
489
|
|
|
/** |
490
|
|
|
* Sets the configuration node's value e.g. <node>VALUE</node>. |
491
|
|
|
* |
492
|
|
|
* @param string $value The node's value |
493
|
|
|
* |
494
|
|
|
* @return void |
495
|
|
|
*/ |
496
|
15 |
|
public function setValue($value) |
497
|
|
|
{ |
498
|
15 |
|
$this->value = $value; |
499
|
15 |
|
} |
500
|
|
|
|
501
|
|
|
/** |
502
|
|
|
* Returns the configuration node's value. |
503
|
|
|
* |
504
|
|
|
* @return string The node's value |
505
|
|
|
*/ |
506
|
4 |
|
public function getValue() |
507
|
|
|
{ |
508
|
4 |
|
return $this->value; |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
/** |
512
|
|
|
* Returns the configuration node's value. |
513
|
|
|
* |
514
|
|
|
* @return string The configuration node's value |
515
|
|
|
*/ |
516
|
2 |
|
public function __toString() |
517
|
|
|
{ |
518
|
2 |
|
return $this->getValue(); |
519
|
|
|
} |
520
|
|
|
|
521
|
|
|
/** |
522
|
|
|
* Merge the configuration |
523
|
|
|
* |
524
|
|
|
* @param \AppserverIo\Configuration\Interfaces\ConfigurationInterface $configuration A configuration to merge |
525
|
|
|
* |
526
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The instance |
527
|
|
|
*/ |
528
|
2 |
|
public function merge(ConfigurationInterface $configuration) |
529
|
|
|
{ |
530
|
2 |
|
if ($this->hasSameSignature($configuration)) { |
531
|
2 |
|
$this->setValue($configuration->getValue()); |
532
|
2 |
|
$this->setAllData($configuration->getAllData()); |
533
|
2 |
|
if ($configuration->hasChildren()) { |
534
|
2 |
|
foreach ($configuration->getChildren() as $child) { |
535
|
2 |
|
$path = $this->getNodeName() . "/" . $child->getNodeName(); |
536
|
2 |
|
if ($this->getChild($path)) { |
537
|
2 |
|
if ($newChild = $this->getChild($path)->merge($child)) { |
538
|
2 |
|
$this->addChild($newChild); |
539
|
|
|
} |
540
|
|
|
} else { |
541
|
2 |
|
$this->addChild($child); |
542
|
|
|
} |
543
|
|
|
} |
544
|
|
|
} |
545
|
|
|
} else { |
546
|
2 |
|
return $configuration; |
547
|
|
|
} |
548
|
2 |
|
} |
549
|
|
|
|
550
|
|
|
/** |
551
|
|
|
* Merges this configuration element with the data found in the passed configuration file. |
552
|
|
|
* |
553
|
|
|
* @param string $file The path to the file we want to merge |
554
|
|
|
* |
555
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The configuration created from the passed file |
556
|
|
|
*/ |
557
|
|
|
public function mergeFromFile($file) |
558
|
|
|
{ |
559
|
|
|
|
560
|
|
|
// initialize a new configuration instance |
561
|
|
|
$configuration = new Configuration(); |
562
|
|
|
$configuration->initFromFile($file); |
563
|
|
|
|
564
|
|
|
// merge the instance with this one |
565
|
|
|
$this->merge($configuration); |
566
|
|
|
|
567
|
|
|
// return this instance |
568
|
|
|
return $configuration; |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
/** |
572
|
|
|
* Merges this configuration element with the passed configuration data. |
573
|
|
|
* |
574
|
|
|
* @param string $string The string with the XML content to initialize from |
575
|
|
|
* |
576
|
|
|
* @return \AppserverIo\Configuration\Interfaces\ConfigurationInterface The configuration created from the passed string |
577
|
|
|
*/ |
578
|
|
|
public function mergeFromString($string) |
579
|
|
|
{ |
580
|
|
|
|
581
|
|
|
// initialize a new configuration instance |
582
|
|
|
$configuration = new Configuration(); |
583
|
|
|
$configuration->initFromString($string); |
584
|
|
|
|
585
|
|
|
// merge the instance with this one |
586
|
|
|
$this->merge($configuration); |
587
|
|
|
|
588
|
|
|
// return this instance |
589
|
|
|
return $configuration; |
590
|
|
|
} |
591
|
|
|
|
592
|
|
|
/** |
593
|
|
|
* Returns the node signature using a md5 hash based on |
594
|
|
|
* the node name and the param data. |
595
|
|
|
* |
596
|
|
|
* @return string The node signature as md5 hash |
597
|
|
|
*/ |
598
|
2 |
|
public function getSignature() |
599
|
|
|
{ |
600
|
2 |
|
return md5($this->getNodeName() . implode('', $this->getAllData())); |
601
|
|
|
} |
602
|
|
|
|
603
|
|
|
/** |
604
|
|
|
* Returns TRUE if the node signatures are equals, else FALSE |
605
|
|
|
* |
606
|
|
|
* @param \AppserverIo\Configuration\Interfaces\ConfigurationInterface $configuration The configuration node to check the signature |
607
|
|
|
* |
608
|
|
|
* @return boolean TRUE if the signature of the passed node equals the signature of this instance, else FALSE |
609
|
|
|
*/ |
610
|
2 |
|
public function hasSameSignature(ConfigurationInterface $configuration) |
611
|
|
|
{ |
612
|
2 |
|
return $this->getSignature() === $configuration->getSignature(); |
613
|
|
|
} |
614
|
|
|
|
615
|
|
|
/** |
616
|
|
|
* Saves the configuration node recursively to the |
617
|
|
|
* file with the passed name. |
618
|
|
|
* |
619
|
|
|
* @param string $filename The filename to save the configuration node to |
620
|
|
|
* |
621
|
|
|
* @return void |
622
|
|
|
*/ |
623
|
|
|
public function save($filename) |
624
|
|
|
{ |
625
|
|
|
$this->toDomDocument()->save($filename); |
626
|
|
|
} |
627
|
|
|
|
628
|
|
|
/** |
629
|
|
|
* Creates and returns a DOM document by recursively parsing |
630
|
|
|
* the configuration node and it's childs. |
631
|
|
|
* |
632
|
|
|
* @param string $namespaceURI The dom document namespace |
633
|
|
|
* |
634
|
|
|
* @return \DOMDocument The configuration node as DOM document |
635
|
|
|
*/ |
636
|
|
|
public function toDomDocument($namespaceURI = 'http://www.appserver.io/appserver') |
637
|
|
|
{ |
638
|
|
|
$domDocument = new \DOMDocument('1.0', 'UTF-8'); |
639
|
|
|
$domDocument->appendChild($this->toDomElement($domDocument, $namespaceURI)); |
640
|
|
|
return $domDocument; |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
/** |
644
|
|
|
* Sets the filename of the schema file used for validation. |
645
|
|
|
* |
646
|
|
|
* @param string $schemaFile Filename of the schema for validation of the configuration node |
647
|
|
|
* |
648
|
|
|
* @return void |
649
|
|
|
*/ |
650
|
|
|
public function setSchemaFile($schemaFile) |
651
|
|
|
{ |
652
|
|
|
$this->schemaFile = $schemaFile; |
653
|
|
|
} |
654
|
|
|
|
655
|
|
|
/** |
656
|
|
|
* Returns the filename of the schema file used for validation. |
657
|
|
|
* |
658
|
|
|
* @return string The filename of the schema file used for validation |
659
|
|
|
*/ |
660
|
|
|
public function getSchemaFile() |
661
|
|
|
{ |
662
|
|
|
return $this->schemaFile; |
663
|
|
|
} |
664
|
|
|
|
665
|
|
|
/** |
666
|
|
|
* Recursively creates and returns a DOM element of this configuration node. |
667
|
|
|
* |
668
|
|
|
* @param \DOMDocument $domDocument The DOM document necessary to create a \DOMElement instance |
669
|
|
|
* @param string $namespaceURI The namespace URI to use |
670
|
|
|
* |
671
|
|
|
* @return \DOMElement The initialized DOM element |
672
|
|
|
*/ |
673
|
|
|
public function toDomElement(\DOMDocument $domDocument, $namespaceURI = null) |
674
|
|
|
{ |
675
|
|
|
// if a namespace URI was given, create namespaced DOM element |
676
|
|
|
if ($namespaceURI) { |
|
|
|
|
677
|
|
|
$domElement = $domDocument->createElementNS($namespaceURI, $this->getNodeName(), $this->getValue()); |
678
|
|
|
} else { |
679
|
|
|
$domElement = $domDocument->createElement($this->getNodeName(), $this->getValue()); |
680
|
|
|
} |
681
|
|
|
|
682
|
|
|
// append the element's attributes |
683
|
|
|
foreach ($this->getAllData() as $key => $value) { |
684
|
|
|
$domElement->setAttribute($key, $value); |
685
|
|
|
} |
686
|
|
|
|
687
|
|
|
// append the element's child nodes |
688
|
|
|
foreach ($this->getChildren() as $child) { |
689
|
|
|
$domElement->appendChild($child->toDomElement($domDocument)); |
690
|
|
|
} |
691
|
|
|
|
692
|
|
|
// return the |
693
|
|
|
return $domElement; |
694
|
|
|
} |
695
|
|
|
|
696
|
|
|
/** |
697
|
|
|
* Validates the configuration node against the schema file. |
698
|
|
|
* |
699
|
|
|
* @throws \Exception Is thrown if the validation was not successful |
700
|
|
|
* @return \DOMDocument The validated DOM document |
701
|
|
|
* @see \AppserverIo\Configuration\Configuration::setSchemaFile() |
702
|
|
|
*/ |
703
|
|
|
public function validate() |
704
|
|
|
{ |
705
|
|
|
|
706
|
|
|
// check if a schema file was specified and exists |
707
|
|
|
if ($this->getSchemaFile() == null) { |
708
|
|
|
throw new \Exception("Missing XSD schema file for validation"); |
709
|
|
|
} |
710
|
|
|
if (file_exists($this->getSchemaFile()) === false) { |
711
|
|
|
throw new \Exception(sprintf("XSD schema file %s for validation not available", $this->getSchemaFile())); |
712
|
|
|
} |
713
|
|
|
|
714
|
|
|
// activate internal error handling, necessary to catch errors with libxml_get_errors() |
715
|
|
|
libxml_use_internal_errors(true); |
716
|
|
|
|
717
|
|
|
// recursively create a DOM document from the configuration node and validate it |
718
|
|
|
$domDocument = $this->toDomDocument(); |
719
|
|
|
if ($domDocument->schemaValidate($this->getSchemaFile()) === false) { |
720
|
|
|
foreach (libxml_get_errors() as $error) { |
721
|
|
|
$message = "Found a schema validation error on line %s with code %s and message %s when validating configuration file %s"; |
722
|
|
|
|
723
|
|
|
throw new \Exception(sprintf($message, $error->line, $error->code, $error->message, $error->file)); |
724
|
|
|
} |
725
|
|
|
} |
726
|
|
|
return $domDocument; |
727
|
|
|
} |
728
|
|
|
} |
729
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.