imported UnsupportedOperationException;
[core.git] / framework / main / classes / class_BaseFrameworkSystem.php
1 <?php
2 // Own namespace
3 namespace CoreFramework\Object;
4
5 // Import framework stuff
6 use CoreFramework\Bootstrap\FrameworkBootstrap;
7 use CoreFramework\Compressor\Compressor;
8 use CoreFramework\Configuration\FrameworkConfiguration;
9 use CoreFramework\Connection\Database\DatabaseConnection;
10 use CoreFramework\Controller\Controller;
11 use CoreFramework\Criteria\Criteria;
12 use CoreFramework\Criteria\Local\LocalSearchCriteria;
13 use CoreFramework\Criteria\Local\LocalUpdateCriteria;
14 use CoreFramework\Crypto\Cryptable;
15 use CoreFramework\Crypto\RandomNumber\RandomNumberGenerator;
16 use CoreFramework\Database\Frontend\DatabaseWrapper;
17 use CoreFramework\Factory\Database\Wrapper\DatabaseWrapperFactory;
18 use CoreFramework\Factory\ObjectFactory;
19 use CoreFramework\Filesystem\Block;
20 use CoreFramework\Filesystem\FilePointer;
21 use CoreFramework\Filesystem\FrameworkDirectory;
22 use CoreFramework\Filesystem\PathWriteProtectedException;
23 use CoreFramework\Generic\FrameworkInterface;
24 use CoreFramework\Generic\NullPointerException;
25 use CoreFramework\Generic\UnsupportedOperationException;
26 use CoreFramework\Handler\Stream\IoHandler;
27 use CoreFramework\Index\Indexable;
28 use CoreFramework\Listener\Listenable;
29 use CoreFramework\Lists\Listable;
30 use CoreFramework\Loader\ClassLoader;
31 use CoreFramework\Manager\ManageableApplication;
32 use CoreFramework\Middleware\Compressor\CompressorChannel;
33 use CoreFramework\Middleware\Debug\DebugMiddleware;
34 use CoreFramework\Parser\Parseable;
35 use CoreFramework\Registry\Register;
36 use CoreFramework\Registry\Registry;
37 use CoreFramework\Resolver\Resolver;
38 use CoreFramework\Result\Database\CachedDatabaseResult;
39 use CoreFramework\Result\Search\SearchableResult;
40 use CoreFramework\Stacker\Stackable;
41 use CoreFramework\State\Stateable;
42 use CoreFramework\Stream\Output\OutputStreamer;
43 use CoreFramework\Template\CompileableTemplate;
44 use CoreFramework\User\ManageableAccount;
45 use CoreFramework\Visitor\Visitor;
46
47 // Import SPL stuff
48 use \stdClass;
49 use \Iterator;
50 use \ReflectionClass;
51
52 /**
53  * The simulator system class is the super class of all other classes. This
54  * class handles saving of games etc.
55  *
56  * @author              Roland Haeder <webmaster@shipsimu.org>
57  * @version             0.0.0
58  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
59  * @license             GNU GPL 3.0 or any newer version
60  * @link                http://www.shipsimu.org
61  *
62  * This program is free software: you can redistribute it and/or modify
63  * it under the terms of the GNU General Public License as published by
64  * the Free Software Foundation, either version 3 of the License, or
65  * (at your option) any later version.
66  *
67  * This program is distributed in the hope that it will be useful,
68  * but WITHOUT ANY WARRANTY; without even the implied warranty of
69  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
70  * GNU General Public License for more details.
71  *
72  * You should have received a copy of the GNU General Public License
73  * along with this program. If not, see <http://www.gnu.org/licenses/>.
74  */
75 class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
76         /**
77          * Length of output from hash()
78          */
79         private static $hashLength = NULL;
80
81         /**
82          * The real class name
83          */
84         private $realClass = 'BaseFrameworkSystem';
85
86         /**
87          * Search criteria instance
88          */
89         private $searchInstance = NULL;
90
91         /**
92          * Update criteria instance
93          */
94         private $updateInstance = NULL;
95
96         /**
97          * The file I/O instance for the template loader
98          */
99         private $fileIoInstance = NULL;
100
101         /**
102          * Resolver instance
103          */
104         private $resolverInstance = NULL;
105
106         /**
107          * Template engine instance
108          */
109         private $templateInstance = NULL;
110
111         /**
112          * Database result instance
113          */
114         private $resultInstance = NULL;
115
116         /**
117          * Instance for user class
118          */
119         private $userInstance = NULL;
120
121         /**
122          * A controller instance
123          */
124         private $controllerInstance = NULL;
125
126         /**
127          * Instance of a RNG
128          */
129         private $rngInstance = NULL;
130
131         /**
132          * Instance of a crypto helper
133          */
134         private $cryptoInstance = NULL;
135
136         /**
137          * Instance of an Iterator class
138          */
139         private $iteratorInstance = NULL;
140
141         /**
142          * Instance of the list
143          */
144         private $listInstance = NULL;
145
146         /**
147          * Instance of a menu
148          */
149         private $menuInstance = NULL;
150
151         /**
152          * Instance of the image
153          */
154         private $imageInstance = NULL;
155
156         /**
157          * Instance of the stacker
158          */
159         private $stackInstance = NULL;
160
161         /**
162          * A Compressor instance
163          */
164         private $compressorInstance = NULL;
165
166         /**
167          * A Parseable instance
168          */
169         private $parserInstance = NULL;
170
171         /**
172          * A HandleableProtocol instance
173          */
174         private $protocolInstance = NULL;
175
176         /**
177          * A database wrapper instance
178          */
179         private $databaseInstance = NULL;
180
181         /**
182          * A helper instance for the form
183          */
184         private $helperInstance = NULL;
185
186         /**
187          * An instance of a Source class
188          */
189         private $sourceInstance = NULL;
190
191         /**
192          * An instance of a UrlSource class
193          */
194         private $urlSourceInstance = NULL;
195
196         /**
197          * An instance of a InputStream class
198          */
199         private $inputStreamInstance = NULL;
200
201         /**
202          * An instance of a OutputStream class
203          */
204         private $outputStreamInstance = NULL;
205
206         /**
207          * Networkable handler instance
208          */
209         private $handlerInstance = NULL;
210
211         /**
212          * Visitor handler instance
213          */
214         private $visitorInstance = NULL;
215
216         /**
217          * DHT instance
218          */
219         private $dhtInstance = NULL;
220
221         /**
222          * An instance of a database wrapper class
223          */
224         private $wrapperInstance = NULL;
225
226         /**
227          * An instance of a file I/O pointer class (not handler)
228          */
229         private $pointerInstance = NULL;
230
231         /**
232          * An instance of an Indexable class
233          */
234         private $indexInstance = NULL;
235
236         /**
237          * An instance of a Block class
238          */
239         private $blockInstance = NULL;
240
241         /**
242          * A Minable instance
243          */
244         private $minableInstance = NULL;
245
246         /**
247          * A FrameworkDirectory instance
248          */
249         private $directoryInstance = NULL;
250
251         /**
252          * Listener instance
253          */
254         private $listenerInstance = NULL;
255
256         /**
257          * An instance of a communicator
258          */
259         private $communicatorInstance = NULL;
260
261         /**
262          * The concrete output instance
263          */
264         private $outputInstance = NULL;
265
266         /**
267          * State instance
268          */
269         private $stateInstance = NULL;
270
271         /**
272          * Thousands separator
273          */
274         private $thousands = '.'; // German
275
276         /**
277          * Decimal separator
278          */
279         private $decimals  = ','; // German
280
281         /**
282          * Socket resource
283          */
284         private $socketResource = false;
285
286         /**
287          * Regular expression to use for validation
288          */
289         private $regularExpression = '';
290
291         /**
292          * Package data
293          */
294         private $packageData = array();
295
296         /**
297          * Generic array
298          */
299         private $genericArray = array();
300
301         /**
302          * Command name
303          */
304         private $commandName = '';
305
306         /**
307          * Controller name
308          */
309         private $controllerName = '';
310
311         /**
312          * Name of used protocol
313          */
314         private $protocolName = 'invalid';
315
316         /**
317          * Array with bitmasks and such for pack/unpack methods to support both
318          * 32-bit and 64-bit systems
319          */
320         private $packingData = array(
321                 32 => array(
322                         'step'   => 3,
323                         'left'   => 0xffff0000,
324                         'right'  => 0x0000ffff,
325                         'factor' => 16,
326                         'format' => 'II',
327                 ),
328                 64 => array(
329                         'step'   => 7,
330                         'left'   => 0xffffffff00000000,
331                         'right'  => 0x00000000ffffffff,
332                         'factor' => 32,
333                         'format' => 'NN'
334                 )
335         );
336
337         /**
338          * Simple 64-bit check, thanks to "Salman A" from stackoverflow.com:
339          *
340          * The integer size is 4 bytes on 32-bit and 8 bytes on a 64-bit system.
341          */
342         private $archArrayElement = false;
343
344         /***********************
345          * Exception codes.... *
346          ***********************/
347
348         // @todo Try to clean these constants up
349         const EXCEPTION_IS_NULL_POINTER              = 0x001;
350         const EXCEPTION_IS_NO_OBJECT                 = 0x002;
351         const EXCEPTION_IS_NO_ARRAY                  = 0x003;
352         const EXCEPTION_MISSING_METHOD               = 0x004;
353         const EXCEPTION_CLASSES_NOT_MATCHING         = 0x005;
354         const EXCEPTION_INDEX_OUT_OF_BOUNDS          = 0x006;
355         const EXCEPTION_DIMENSION_ARRAY_INVALID      = 0x007;
356         const EXCEPTION_ITEM_NOT_TRADEABLE           = 0x008;
357         const EXCEPTION_ITEM_NOT_IN_PRICE_LIST       = 0x009;
358         const EXCEPTION_GENDER_IS_WRONG              = 0x00a;
359         const EXCEPTION_BIRTH_DATE_IS_INVALID        = 0x00b;
360         const EXCEPTION_EMPTY_STRUCTURES_ARRAY       = 0x00c;
361         const EXCEPTION_HAS_ALREADY_PERSONELL_LIST   = 0x00d;
362         const EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES      = 0x00e;
363         const EXCEPTION_TOTAL_PRICE_NOT_CALCULATED   = 0x00f;
364         const EXCEPTION_HARBOR_HAS_NO_SHIPYARDS      = 0x010;
365         const EXCEPTION_CONTRACT_PARTNER_INVALID     = 0x011;
366         const EXCEPTION_CONTRACT_PARTNER_MISMATCH    = 0x012;
367         const EXCEPTION_CONTRACT_ALREADY_SIGNED      = 0x013;
368         const EXCEPTION_UNEXPECTED_EMPTY_STRING      = 0x014;
369         const EXCEPTION_PATH_NOT_FOUND               = 0x015;
370         const EXCEPTION_INVALID_PATH_NAME            = 0x016;
371         const EXCEPTION_READ_PROTECED_PATH           = 0x017;
372         const EXCEPTION_WRITE_PROTECED_PATH          = 0x018;
373         const EXCEPTION_DIR_POINTER_INVALID          = 0x019;
374         const EXCEPTION_FILE_POINTER_INVALID         = 0x01a;
375         const EXCEPTION_INVALID_RESOURCE             = 0x01b;
376         const EXCEPTION_UNEXPECTED_OBJECT            = 0x01c;
377         const EXCEPTION_LIMIT_ELEMENT_IS_UNSUPPORTED = 0x01d;
378         const EXCEPTION_GETTER_IS_MISSING            = 0x01e;
379         const EXCEPTION_ARRAY_EXPECTED               = 0x01f;
380         const EXCEPTION_ARRAY_HAS_INVALID_COUNT      = 0x020;
381         const EXCEPTION_ID_IS_INVALID_FORMAT         = 0x021;
382         const EXCEPTION_MD5_CHECKSUMS_MISMATCH       = 0x022;
383         const EXCEPTION_UNEXPECTED_STRING_SIZE       = 0x023;
384         const EXCEPTION_SIMULATOR_ID_INVALID         = 0x024;
385         const EXCEPTION_MISMATCHING_COMPRESSORS      = 0x025;
386         const EXCEPTION_CONTAINER_ITEM_IS_NULL       = 0x026;
387         const EXCEPTION_ITEM_IS_NO_ARRAY             = 0x027;
388         const EXCEPTION_CONTAINER_MAYBE_DAMAGED      = 0x028;
389         const EXCEPTION_INVALID_STRING               = 0x029;
390         const EXCEPTION_VARIABLE_NOT_SET             = 0x02a;
391         const EXCEPTION_ATTRIBUTES_ARE_MISSING       = 0x02b;
392         const EXCEPTION_ARRAY_ELEMENTS_MISSING       = 0x02c;
393         const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED  = 0x02d;
394         const EXCEPTION_UNSPPORTED_OPERATION         = 0x02e;
395         const EXCEPTION_FACTORY_REQUIRE_PARAMETER    = 0x02f;
396         const EXCEPTION_MISSING_ELEMENT              = 0x030;
397         const EXCEPTION_HEADERS_ALREADY_SENT         = 0x031;
398         const EXCEPTION_DEFAULT_CONTROLLER_GONE      = 0x032;
399         const EXCEPTION_CLASS_NOT_FOUND              = 0x033;
400         const EXCEPTION_REQUIRED_INTERFACE_MISSING   = 0x034;
401         const EXCEPTION_FATAL_ERROR                  = 0x035;
402         const EXCEPTION_FILE_NOT_FOUND               = 0x036;
403         const EXCEPTION_ASSERTION_FAILED             = 0x037;
404         const EXCEPTION_FILE_NOT_REACHABLE           = 0x038;
405         const EXCEPTION_FILE_CANNOT_BE_READ          = 0x039;
406         const EXCEPTION_FILE_CANNOT_BE_WRITTEN       = 0x03a;
407         const EXCEPTION_PATH_CANNOT_BE_WRITTEN       = 0x03b;
408         const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x03c;
409         const EXCEPTION_FILTER_CHAIN_INTERCEPTED     = 0x03d;
410
411         /**
412          * Hexadecimal->Decimal translation array
413          */
414         private static $hexdec = array(
415                 '0' => 0,
416                 '1' => 1,
417                 '2' => 2,
418                 '3' => 3,
419                 '4' => 4,
420                 '5' => 5,
421                 '6' => 6,
422                 '7' => 7,
423                 '8' => 8,
424                 '9' => 9,
425                 'a' => 10,
426                 'b' => 11,
427                 'c' => 12,
428                 'd' => 13,
429                 'e' => 14,
430                 'f' => 15
431         );
432
433         /**
434          * Decimal->hexadecimal translation array
435          */
436         private static $dechex = array(
437                  0 => '0',
438                  1 => '1',
439                  2 => '2',
440                  3 => '3',
441                  4 => '4',
442                  5 => '5',
443                  6 => '6',
444                  7 => '7',
445                  8 => '8',
446                  9 => '9',
447                 10 => 'a',
448                 11 => 'b',
449                 12 => 'c',
450                 13 => 'd',
451                 14 => 'e',
452                 15 => 'f'
453         );
454
455         /**
456          * Startup time in miliseconds
457          */
458         private static $startupTime = 0;
459
460         /**
461          * Protected super constructor
462          *
463          * @param       $className      Name of the class
464          * @return      void
465          */
466         protected function __construct ($className) {
467                 // Set real class
468                 $this->setRealClass($className);
469
470                 // Set configuration instance if no registry ...
471                 if (!$this instanceof Register) {
472                         // ... because registries doesn't need to be configured
473                         $this->setConfigInstance(FrameworkConfiguration::getSelfInstance());
474                 } // END - if
475
476                 // Is the startup time set? (0 cannot be true anymore)
477                 if (self::$startupTime == 0) {
478                         // Then set it
479                         self::$startupTime = microtime(true);
480                 } // END - if
481
482                 // Set array element
483                 $this->archArrayElement = (PHP_INT_SIZE === 8 ? 64 : 32);
484         }
485
486         /**
487          * Destructor for all classes. You should not call this method on your own.
488          *
489          * @return      void
490          */
491         public function __destruct () {
492                 // Flush any updated entries to the database
493                 $this->flushPendingUpdates();
494
495                 // Is this object already destroyed?
496                 if ($this->__toString() != 'DestructedObject') {
497                         // Destroy all informations about this class but keep some text about it alive
498                         $this->setRealClass('DestructedObject');
499                 } elseif ((defined('DEBUG_DESTRUCTOR')) && (is_object($this->getDebugInstance()))) {
500                         // Already destructed object
501                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('[%s:] The object <span class="object_name">%s</span> is already destroyed.',
502                                 __CLASS__,
503                                 $this->__toString()
504                         ));
505                 } else {
506                         // Do not call this twice
507                         trigger_error(__METHOD__ . ': Called twice.');
508                         exit;
509                 }
510         }
511
512         /**
513          * The __call() method where all non-implemented methods end up
514          *
515          * @param       $methodName             Name of the missing method
516          * @args        $args                   Arguments passed to the method
517          * @return      void
518          */
519         public final function __call ($methodName, $args) {
520                 return self::__callStatic($methodName, $args);
521         }
522
523         /**
524          * The __callStatic() method where all non-implemented static methods end up
525          *
526          * @param       $methodName             Name of the missing method
527          * @args        $args                   Arguments passed to the method
528          * @return      void
529          */
530         public static final function __callStatic ($methodName, $args) {
531                 // Trace message
532                 //* PRINT-DEBUG: */ printf('[%s:%d]: methodName=%s,args[]=%s - CALLED!' . PHP_EOL, __METHOD__, __LINE__, $methodName, gettype($args));
533
534                 // Init argument string
535                 $argsString = '';
536
537                 // Is it NULL, empty or an array?
538                 if (is_null($args)) {
539                         // No arguments
540                         $argsString = 'NULL';
541                 } elseif (is_array($args)) {
542                         // Start braces
543                         $argsString = '(';
544
545                         // Some arguments are there
546                         foreach ($args as $arg) {
547                                 // Add data about the argument
548                                 $argsString .= gettype($arg) . ':';
549
550                                 if (is_null($arg)) {
551                                         // Found a NULL argument
552                                         $argsString .= 'NULL';
553                                 } elseif (is_string($arg)) {
554                                         // Add length for strings
555                                         $argsString .= strlen($arg);
556                                 } elseif ((is_int($arg)) || (is_float($arg))) {
557                                         // ... integer/float
558                                         $argsString .= $arg;
559                                 } elseif (is_array($arg)) {
560                                         // .. or size if array
561                                         $argsString .= count($arg);
562                                 } elseif (is_object($arg)) {
563                                         // Get reflection
564                                         $reflection = new ReflectionClass($arg);
565
566                                         // Is an other object, maybe no __toString() available
567                                         $argsString .= $reflection->getName();
568                                 } elseif ($arg === true) {
569                                         // ... is boolean 'true'
570                                         $argsString .= 'true';
571                                 } elseif ($arg === false) {
572                                         // ... is boolean 'false'
573                                         $argsString .= 'false';
574                                 }
575
576                                 // Comma for next one
577                                 $argsString .= ', ';
578                         } // END - foreach
579
580                         // Remove last comma
581                         if (substr($argsString, -2, 1) == ',') {
582                                 $argsString = substr($argsString, 0, -2);
583                         } // END - if
584
585                         // Close braces
586                         $argsString .= ')';
587                 } else {
588                         // Invalid arguments!
589                         $argsString = '!INVALID:' . gettype($args) . '!';
590                 }
591
592                 // Output stub message
593                 // @TODO __CLASS__ does always return BaseFrameworkSystem but not the extending (=child) class
594                 self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('[unknown::%s:] Stub! Args: %s',
595                         $methodName,
596                         $argsString
597                 ));
598
599                 // Return nothing
600                 return NULL;
601         }
602
603         /**
604          * Getter for $realClass
605          *
606          * @return      $realClass The name of the real class (not BaseFrameworkSystem)
607          */
608         public function __toString () {
609                 return $this->realClass;
610         }
611
612         /**
613          * Magic method to catch setting of missing but set class fields/attributes
614          *
615          * @param       $name   Name of the field/attribute
616          * @param       $value  Value to store
617          * @return      void
618          */
619         public final function __set ($name, $value) {
620                 $this->debugBackTrace(sprintf('Tried to set a missing field. name=%s, value[%s]=%s',
621                         $name,
622                         gettype($value),
623                         print_r($value, true)
624                 ));
625         }
626
627         /**
628          * Magic method to catch getting of missing fields/attributes
629          *
630          * @param       $name   Name of the field/attribute
631          * @return      void
632          */
633         public final function __get ($name) {
634                 $this->debugBackTrace(sprintf('Tried to get a missing field. name=%s',
635                         $name
636                 ));
637         }
638
639         /**
640          * Magic method to catch unsetting of missing fields/attributes
641          *
642          * @param       $name   Name of the field/attribute
643          * @return      void
644          */
645         public final function __unset ($name) {
646                 $this->debugBackTrace(sprintf('Tried to unset a missing field. name=%s',
647                         $name
648                 ));
649         }
650
651         /**
652          * Magic method to catch object serialization
653          *
654          * @return      $unsupported    Unsupported method
655          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
656          */
657         public final function __sleep () {
658                 throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
659         }
660
661         /**
662          * Magic method to catch object deserialization
663          *
664          * @return      $unsupported    Unsupported method
665          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
666          */
667         public final function __wakeup () {
668                 throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
669         }
670
671         /**
672          * Magic method to catch calls when an object instance is called
673          *
674          * @return      $unsupported    Unsupported method
675          * @throws      UnsupportedOperationException   Objects of this framework cannot be serialized
676          */
677         public final function __invoke () {
678                 throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
679         }
680
681         /**
682          * Setter for the real class name
683          *
684          * @param       $realClass      Class name (string)
685          * @return      void
686          */
687         public final function setRealClass ($realClass) {
688                 // Set real class
689                 $this->realClass = (string) $realClass;
690         }
691
692         /**
693          * Setter for database result instance
694          *
695          * @param       $resultInstance         An instance of a database result class
696          * @return      void
697          * @todo        SearchableResult and UpdateableResult shall have a super interface to use here
698          */
699         protected final function setResultInstance (SearchableResult $resultInstance) {
700                 $this->resultInstance =  $resultInstance;
701         }
702
703         /**
704          * Getter for database result instance
705          *
706          * @return      $resultInstance         An instance of a database result class
707          */
708         public final function getResultInstance () {
709                 return $this->resultInstance;
710         }
711
712         /**
713          * Setter for template engine instances
714          *
715          * @param       $templateInstance       An instance of a template engine class
716          * @return      void
717          */
718         protected final function setTemplateInstance (CompileableTemplate $templateInstance) {
719                 $this->templateInstance = $templateInstance;
720         }
721
722         /**
723          * Getter for template engine instances
724          *
725          * @return      $templateInstance       An instance of a template engine class
726          */
727         protected final function getTemplateInstance () {
728                 return $this->templateInstance;
729         }
730
731         /**
732          * Setter for search instance
733          *
734          * @param       $searchInstance         Searchable criteria instance
735          * @return      void
736          */
737         public final function setSearchInstance (LocalSearchCriteria $searchInstance) {
738                 $this->searchInstance = $searchInstance;
739         }
740
741         /**
742          * Getter for search instance
743          *
744          * @return      $searchInstance         Searchable criteria instance
745          */
746         public final function getSearchInstance () {
747                 return $this->searchInstance;
748         }
749
750         /**
751          * Setter for update instance
752          *
753          * @param       $updateInstance         An instance of a LocalUpdateCriteria clase
754          * @return      void
755          */
756         public final function setUpdateInstance (LocalUpdateCriteria $updateInstance) {
757                 $this->updateInstance = $updateInstance;
758         }
759
760         /**
761          * Getter for update instance
762          *
763          * @return      $updateInstance         Updateable criteria instance
764          */
765         public final function getUpdateInstance () {
766                 return $this->updateInstance;
767         }
768
769         /**
770          * Setter for resolver instance
771          *
772          * @param       $resolverInstance       Instance of a command resolver class
773          * @return      void
774          */
775         public final function setResolverInstance (Resolver $resolverInstance) {
776                 $this->resolverInstance = $resolverInstance;
777         }
778
779         /**
780          * Getter for resolver instance
781          *
782          * @return      $resolverInstance       Instance of a command resolver class
783          */
784         public final function getResolverInstance () {
785                 return $this->resolverInstance;
786         }
787
788         /**
789          * Setter for language instance
790          *
791          * @param       $configInstance         The configuration instance which shall
792          *                                                              be FrameworkConfiguration
793          * @return      void
794          */
795         public final function setConfigInstance (FrameworkConfiguration $configInstance) {
796                 Registry::getRegistry()->addInstance('config', $configInstance);
797         }
798
799         /**
800          * Getter for configuration instance
801          *
802          * @return      $configInstance         Configuration instance
803          */
804         public final function getConfigInstance () {
805                 $configInstance = Registry::getRegistry()->getInstance('config');
806                 return $configInstance;
807         }
808
809         /**
810          * Setter for debug instance
811          *
812          * @param       $debugInstance  The instance for debug output class
813          * @return      void
814          */
815         public final function setDebugInstance (DebugMiddleware $debugInstance) {
816                 Registry::getRegistry()->addInstance('debug', $debugInstance);
817         }
818
819         /**
820          * Getter for debug instance
821          *
822          * @return      $debugInstance  Instance to class DebugConsoleOutput or DebugWebOutput
823          */
824         public final function getDebugInstance () {
825                 // Get debug instance
826                 $debugInstance = Registry::getRegistry()->getInstance('debug');
827
828                 // Return it
829                 return $debugInstance;
830         }
831
832         /**
833          * Setter for web output instance
834          *
835          * @param       $webInstance    The instance for web output class
836          * @return      void
837          */
838         public final function setWebOutputInstance (OutputStreamer $webInstance) {
839                 Registry::getRegistry()->addInstance('web_output', $webInstance);
840         }
841
842         /**
843          * Getter for web output instance
844          *
845          * @return      $webOutputInstance - Instance to class WebOutput
846          */
847         public final function getWebOutputInstance () {
848                 $webOutputInstance = Registry::getRegistry()->getInstance('web_output');
849                 return $webOutputInstance;
850         }
851
852         /**
853          * Setter for database instance
854          *
855          * @param       $databaseInstance       The instance for the database connection (forced DatabaseConnection)
856          * @return      void
857          */
858         public final function setDatabaseInstance (DatabaseConnection $databaseInstance) {
859                 Registry::getRegistry()->addInstance('db_instance', $databaseInstance);
860         }
861
862         /**
863          * Getter for database layer
864          *
865          * @return      $databaseInstance       The database layer instance
866          */
867         public final function getDatabaseInstance () {
868                 // Get instance
869                 $databaseInstance = Registry::getRegistry()->getInstance('db_instance');
870
871                 // Return instance
872                 return $databaseInstance;
873         }
874
875         /**
876          * Setter for compressor channel
877          *
878          * @param       $compressorInstance             An instance of CompressorChannel
879          * @return      void
880          */
881         public final function setCompressorChannel (CompressorChannel $compressorInstance) {
882                 Registry::getRegistry()->addInstance('compressor', $compressorInstance);
883         }
884
885         /**
886          * Getter for compressor channel
887          *
888          * @return      $compressorInstance             The compressor channel
889          */
890         public final function getCompressorChannel () {
891                 $compressorInstance = Registry::getRegistry()->getInstance('compressor');
892                 return $compressorInstance;
893         }
894
895         /**
896          * Protected getter for a manageable application helper class
897          *
898          * @return      $applicationInstance    An instance of a manageable application helper class
899          */
900         protected final function getApplicationInstance () {
901                 $applicationInstance = Registry::getRegistry()->getInstance('app');
902                 return $applicationInstance;
903         }
904
905         /**
906          * Setter for a manageable application helper class
907          *
908          * @param       $applicationInstance    An instance of a manageable application helper class
909          * @return      void
910          */
911         public final function setApplicationInstance (ManageableApplication $applicationInstance) {
912                 Registry::getRegistry()->addInstance('application', $applicationInstance);
913         }
914
915         /**
916          * Private getter for language instance
917          *
918          * @return      $langInstance   An instance to the language sub-system
919          */
920         protected final function getLanguageInstance () {
921                 $langInstance = Registry::getRegistry()->getInstance('language');
922                 return $langInstance;
923         }
924
925         /**
926          * Setter for language instance
927          *
928          * @param       $langInstance   An instance to the language sub-system
929          * @return      void
930          * @see         LanguageSystem
931          */
932         public final function setLanguageInstance (ManageableLanguage $langInstance) {
933                 Registry::getRegistry()->addInstance('language', $langInstance);
934         }
935
936         /**
937          * Private getter for file IO instance
938          *
939          * @return      $fileIoInstance         An instance to the file I/O sub-system
940          */
941         protected final function getFileIoInstance () {
942                 return $this->fileIoInstance;
943         }
944
945         /**
946          * Setter for file I/O instance
947          *
948          * @param       $fileIoInstance         An instance to the file I/O sub-system
949          * @return      void
950          */
951         public final function setFileIoInstance (IoHandler $fileIoInstance) {
952                 $this->fileIoInstance = $fileIoInstance;
953         }
954
955         /**
956          * Protected setter for user instance
957          *
958          * @param       $userInstance   An instance of a user class
959          * @return      void
960          */
961         protected final function setUserInstance (ManageableAccount $userInstance) {
962                 $this->userInstance = $userInstance;
963         }
964
965         /**
966          * Getter for user instance
967          *
968          * @return      $userInstance   An instance of a user class
969          */
970         public final function getUserInstance () {
971                 return $this->userInstance;
972         }
973
974         /**
975          * Setter for controller instance (this surely breaks a bit the MVC patterm)
976          *
977          * @param       $controllerInstance             An instance of the controller
978          * @return      void
979          */
980         public final function setControllerInstance (Controller $controllerInstance) {
981                 $this->controllerInstance = $controllerInstance;
982         }
983
984         /**
985          * Getter for controller instance (this surely breaks a bit the MVC patterm)
986          *
987          * @return      $controllerInstance             An instance of the controller
988          */
989         public final function getControllerInstance () {
990                 return $this->controllerInstance;
991         }
992
993         /**
994          * Setter for RNG instance
995          *
996          * @param       $rngInstance    An instance of a random number generator (RNG)
997          * @return      void
998          */
999         protected final function setRngInstance (RandomNumberGenerator $rngInstance) {
1000                 $this->rngInstance = $rngInstance;
1001         }
1002
1003         /**
1004          * Getter for RNG instance
1005          *
1006          * @return      $rngInstance    An instance of a random number generator (RNG)
1007          */
1008         public final function getRngInstance () {
1009                 return $this->rngInstance;
1010         }
1011
1012         /**
1013          * Setter for Cryptable instance
1014          *
1015          * @param       $cryptoInstance An instance of a Cryptable class
1016          * @return      void
1017          */
1018         protected final function setCryptoInstance (Cryptable $cryptoInstance) {
1019                 $this->cryptoInstance = $cryptoInstance;
1020         }
1021
1022         /**
1023          * Getter for Cryptable instance
1024          *
1025          * @return      $cryptoInstance An instance of a Cryptable class
1026          */
1027         public final function getCryptoInstance () {
1028                 return $this->cryptoInstance;
1029         }
1030
1031         /**
1032          * Setter for the list instance
1033          *
1034          * @param       $listInstance   A list of Listable
1035          * @return      void
1036          */
1037         protected final function setListInstance (Listable $listInstance) {
1038                 $this->listInstance = $listInstance;
1039         }
1040
1041         /**
1042          * Getter for the list instance
1043          *
1044          * @return      $listInstance   A list of Listable
1045          */
1046         protected final function getListInstance () {
1047                 return $this->listInstance;
1048         }
1049
1050         /**
1051          * Setter for the menu instance
1052          *
1053          * @param       $menuInstance   A RenderableMenu instance
1054          * @return      void
1055          */
1056         protected final function setMenuInstance (RenderableMenu $menuInstance) {
1057                 $this->menuInstance = $menuInstance;
1058         }
1059
1060         /**
1061          * Getter for the menu instance
1062          *
1063          * @return      $menuInstance   A RenderableMenu instance
1064          */
1065         protected final function getMenuInstance () {
1066                 return $this->menuInstance;
1067         }
1068
1069         /**
1070          * Setter for image instance
1071          *
1072          * @param       $imageInstance  An instance of an image
1073          * @return      void
1074          */
1075         public final function setImageInstance (BaseImage $imageInstance) {
1076                 $this->imageInstance = $imageInstance;
1077         }
1078
1079         /**
1080          * Getter for image instance
1081          *
1082          * @return      $imageInstance  An instance of an image
1083          */
1084         public final function getImageInstance () {
1085                 return $this->imageInstance;
1086         }
1087
1088         /**
1089          * Setter for stacker instance
1090          *
1091          * @param       $stackInstance  An instance of an stacker
1092          * @return      void
1093          */
1094         public final function setStackInstance (Stackable $stackInstance) {
1095                 $this->stackInstance = $stackInstance;
1096         }
1097
1098         /**
1099          * Getter for stacker instance
1100          *
1101          * @return      $stackInstance  An instance of an stacker
1102          */
1103         public final function getStackInstance () {
1104                 return $this->stackInstance;
1105         }
1106
1107         /**
1108          * Setter for compressor instance
1109          *
1110          * @param       $compressorInstance     An instance of an compressor
1111          * @return      void
1112          */
1113         public final function setCompressorInstance (Compressor $compressorInstance) {
1114                 $this->compressorInstance = $compressorInstance;
1115         }
1116
1117         /**
1118          * Getter for compressor instance
1119          *
1120          * @return      $compressorInstance     An instance of an compressor
1121          */
1122         public final function getCompressorInstance () {
1123                 return $this->compressorInstance;
1124         }
1125
1126         /**
1127          * Setter for Parseable instance
1128          *
1129          * @param       $parserInstance An instance of an Parseable
1130          * @return      void
1131          */
1132         public final function setParserInstance (Parseable $parserInstance) {
1133                 $this->parserInstance = $parserInstance;
1134         }
1135
1136         /**
1137          * Getter for Parseable instance
1138          *
1139          * @return      $parserInstance An instance of an Parseable
1140          */
1141         public final function getParserInstance () {
1142                 return $this->parserInstance;
1143         }
1144
1145         /**
1146          * Setter for HandleableProtocol instance
1147          *
1148          * @param       $protocolInstance       An instance of an HandleableProtocol
1149          * @return      void
1150          */
1151         public final function setProtocolInstance (HandleableProtocol $protocolInstance) {
1152                 $this->protocolInstance = $protocolInstance;
1153         }
1154
1155         /**
1156          * Getter for HandleableProtocol instance
1157          *
1158          * @return      $protocolInstance       An instance of an HandleableProtocol
1159          */
1160         public final function getProtocolInstance () {
1161                 return $this->protocolInstance;
1162         }
1163
1164         /**
1165          * Setter for DatabaseWrapper instance
1166          *
1167          * @param       $wrapperInstance        An instance of an DatabaseWrapper
1168          * @return      void
1169          */
1170         public final function setWrapperInstance (DatabaseWrapper $wrapperInstance) {
1171                 $this->wrapperInstance = $wrapperInstance;
1172         }
1173
1174         /**
1175          * Getter for DatabaseWrapper instance
1176          *
1177          * @return      $wrapperInstance        An instance of an DatabaseWrapper
1178          */
1179         public final function getWrapperInstance () {
1180                 return $this->wrapperInstance;
1181         }
1182
1183         /**
1184          * Setter for socket resource
1185          *
1186          * @param       $socketResource         A valid socket resource
1187          * @return      void
1188          */
1189         public final function setSocketResource ($socketResource) {
1190                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource=' . $socketResource . ',previous[' . gettype($this->socketResource) . ']=' . $this->socketResource);
1191                 $this->socketResource = $socketResource;
1192         }
1193
1194         /**
1195          * Getter for socket resource
1196          *
1197          * @return      $socketResource         A valid socket resource
1198          */
1199         public final function getSocketResource () {
1200                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': socketResource[' . gettype($this->socketResource) . ']=' . $this->socketResource);
1201                 return $this->socketResource;
1202         }
1203
1204         /**
1205          * Setter for regular expression
1206          *
1207          * @param       $regularExpression      A valid regular expression
1208          * @return      void
1209          */
1210         public final function setRegularExpression ($regularExpression) {
1211                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression=' . $regularExpression . ',previous[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
1212                 $this->regularExpression = $regularExpression;
1213         }
1214
1215         /**
1216          * Getter for regular expression
1217          *
1218          * @return      $regularExpression      A valid regular expression
1219          */
1220         public final function getRegularExpression () {
1221                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
1222                 return $this->regularExpression;
1223         }
1224
1225         /**
1226          * Setter for helper instance
1227          *
1228          * @param       $helperInstance         An instance of a helper class
1229          * @return      void
1230          */
1231         protected final function setHelperInstance (Helper $helperInstance) {
1232                 $this->helperInstance = $helperInstance;
1233         }
1234
1235         /**
1236          * Getter for helper instance
1237          *
1238          * @return      $helperInstance         An instance of a helper class
1239          */
1240         public final function getHelperInstance () {
1241                 return $this->helperInstance;
1242         }
1243
1244         /**
1245          * Setter for a Source instance
1246          *
1247          * @param       $sourceInstance         An instance of a Source class
1248          * @return      void
1249          */
1250         protected final function setSourceInstance (Source $sourceInstance) {
1251                 $this->sourceInstance = $sourceInstance;
1252         }
1253
1254         /**
1255          * Getter for a Source instance
1256          *
1257          * @return      $sourceInstance         An instance of a Source class
1258          */
1259         protected final function getSourceInstance () {
1260                 return $this->sourceInstance;
1261         }
1262
1263         /**
1264          * Setter for a UrlSource instance
1265          *
1266          * @param       $sourceInstance         An instance of a UrlSource class
1267          * @return      void
1268          */
1269         protected final function setUrlSourceInstance (UrlSource $urlSourceInstance) {
1270                 $this->urlSourceInstance = $urlSourceInstance;
1271         }
1272
1273         /**
1274          * Getter for a UrlSource instance
1275          *
1276          * @return      $urlSourceInstance              An instance of a UrlSource class
1277          */
1278         protected final function getUrlSourceInstance () {
1279                 return $this->urlSourceInstance;
1280         }
1281
1282         /**
1283          * Getter for a InputStream instance
1284          *
1285          * @param       $inputStreamInstance    The InputStream instance
1286          */
1287         protected final function getInputStreamInstance () {
1288                 return $this->inputStreamInstance;
1289         }
1290
1291         /**
1292          * Setter for a InputStream instance
1293          *
1294          * @param       $inputStreamInstance    The InputStream instance
1295          * @return      void
1296          */
1297         protected final function setInputStreamInstance (InputStream $inputStreamInstance) {
1298                 $this->inputStreamInstance = $inputStreamInstance;
1299         }
1300
1301         /**
1302          * Getter for a OutputStream instance
1303          *
1304          * @param       $outputStreamInstance   The OutputStream instance
1305          */
1306         protected final function getOutputStreamInstance () {
1307                 return $this->outputStreamInstance;
1308         }
1309
1310         /**
1311          * Setter for a OutputStream instance
1312          *
1313          * @param       $outputStreamInstance   The OutputStream instance
1314          * @return      void
1315          */
1316         protected final function setOutputStreamInstance (OutputStream $outputStreamInstance) {
1317                 $this->outputStreamInstance = $outputStreamInstance;
1318         }
1319
1320         /**
1321          * Setter for handler instance
1322          *
1323          * @param       $handlerInstance        An instance of a Handleable class
1324          * @return      void
1325          */
1326         protected final function setHandlerInstance (Handleable $handlerInstance) {
1327                 $this->handlerInstance = $handlerInstance;
1328         }
1329
1330         /**
1331          * Getter for handler instance
1332          *
1333          * @return      $handlerInstance        A Networkable instance
1334          */
1335         protected final function getHandlerInstance () {
1336                 return $this->handlerInstance;
1337         }
1338
1339         /**
1340          * Setter for visitor instance
1341          *
1342          * @param       $visitorInstance        A Visitor instance
1343          * @return      void
1344          */
1345         protected final function setVisitorInstance (Visitor $visitorInstance) {
1346                 $this->visitorInstance = $visitorInstance;
1347         }
1348
1349         /**
1350          * Getter for visitor instance
1351          *
1352          * @return      $visitorInstance        A Visitor instance
1353          */
1354         protected final function getVisitorInstance () {
1355                 return $this->visitorInstance;
1356         }
1357
1358         /**
1359          * Setter for DHT instance
1360          *
1361          * @param       $dhtInstance    A Distributable instance
1362          * @return      void
1363          */
1364         protected final function setDhtInstance (Distributable $dhtInstance) {
1365                 $this->dhtInstance = $dhtInstance;
1366         }
1367
1368         /**
1369          * Getter for DHT instance
1370          *
1371          * @return      $dhtInstance    A Distributable instance
1372          */
1373         protected final function getDhtInstance () {
1374                 return $this->dhtInstance;
1375         }
1376
1377         /**
1378          * Setter for raw package Data
1379          *
1380          * @param       $packageData    Raw package Data
1381          * @return      void
1382          */
1383         public final function setPackageData (array $packageData) {
1384                 $this->packageData = $packageData;
1385         }
1386
1387         /**
1388          * Getter for raw package Data
1389          *
1390          * @return      $packageData    Raw package Data
1391          */
1392         public function getPackageData () {
1393                 return $this->packageData;
1394         }
1395
1396
1397         /**
1398          * Setter for Iterator instance
1399          *
1400          * @param       $iteratorInstance       An instance of an Iterator
1401          * @return      void
1402          */
1403         protected final function setIteratorInstance (Iterator $iteratorInstance) {
1404                 $this->iteratorInstance = $iteratorInstance;
1405         }
1406
1407         /**
1408          * Getter for Iterator instance
1409          *
1410          * @return      $iteratorInstance       An instance of an Iterator
1411          */
1412         public final function getIteratorInstance () {
1413                 return $this->iteratorInstance;
1414         }
1415
1416         /**
1417          * Setter for FilePointer instance
1418          *
1419          * @param       $pointerInstance        An instance of an FilePointer class
1420          * @return      void
1421          */
1422         protected final function setPointerInstance (FilePointer $pointerInstance) {
1423                 $this->pointerInstance = $pointerInstance;
1424         }
1425
1426         /**
1427          * Getter for FilePointer instance
1428          *
1429          * @return      $pointerInstance        An instance of an FilePointer class
1430          */
1431         public final function getPointerInstance () {
1432                 return $this->pointerInstance;
1433         }
1434
1435         /**
1436          * Unsets pointer instance which triggers a call of __destruct() if the
1437          * instance is still there. This is surely not fatal on already "closed"
1438          * file pointer instances.
1439          *
1440          * I don't want to mess around with above setter by giving it a default
1441          * value NULL as setter should always explicitly only set (existing) object
1442          * instances and NULL is NULL.
1443          *
1444          * @return      void
1445          */
1446         protected final function unsetPointerInstance () {
1447                 // Simply it to NULL
1448                 $this->pointerInstance = NULL;
1449         }
1450
1451         /**
1452          * Setter for Indexable instance
1453          *
1454          * @param       $indexInstance  An instance of an Indexable class
1455          * @return      void
1456          */
1457         protected final function setIndexInstance (Indexable $indexInstance) {
1458                 $this->indexInstance = $indexInstance;
1459         }
1460
1461         /**
1462          * Getter for Indexable instance
1463          *
1464          * @return      $indexInstance  An instance of an Indexable class
1465          */
1466         public final function getIndexInstance () {
1467                 return $this->indexInstance;
1468         }
1469
1470         /**
1471          * Setter for Block instance
1472          *
1473          * @param       $blockInstance  An instance of an Block class
1474          * @return      void
1475          */
1476         protected final function setBlockInstance (Block $blockInstance) {
1477                 $this->blockInstance = $blockInstance;
1478         }
1479
1480         /**
1481          * Getter for Block instance
1482          *
1483          * @return      $blockInstance  An instance of an Block class
1484          */
1485         public final function getBlockInstance () {
1486                 return $this->blockInstance;
1487         }
1488
1489         /**
1490          * Setter for Minable instance
1491          *
1492          * @param       $minableInstance        A Minable instance
1493          * @return      void
1494          */
1495         protected final function setMinableInstance (Minable $minableInstance) {
1496                 $this->minableInstance = $minableInstance;
1497         }
1498
1499         /**
1500          * Getter for minable instance
1501          *
1502          * @return      $minableInstance        A Minable instance
1503          */
1504         protected final function getMinableInstance () {
1505                 return $this->minableInstance;
1506         }
1507
1508         /**
1509          * Setter for FrameworkDirectory instance
1510          *
1511          * @param       $directoryInstance      A FrameworkDirectory instance
1512          * @return      void
1513          */
1514         protected final function setDirectoryInstance (FrameworkDirectory $directoryInstance) {
1515                 $this->directoryInstance = $directoryInstance;
1516         }
1517
1518         /**
1519          * Getter for FrameworkDirectory instance
1520          *
1521          * @return      $directoryInstance      A FrameworkDirectory instance
1522          */
1523         protected final function getDirectoryInstance () {
1524                 return $this->directoryInstance;
1525         }
1526
1527         /**
1528          * Setter for listener instance
1529          *
1530          * @param       $listenerInstance       A Listenable instance
1531          * @return      void
1532          */
1533         protected final function setListenerInstance (Listenable $listenerInstance) {
1534                 $this->listenerInstance = $listenerInstance;
1535         }
1536
1537         /**
1538          * Getter for listener instance
1539          *
1540          * @return      $listenerInstance       A Listenable instance
1541          */
1542         protected final function getListenerInstance () {
1543                 return $this->listenerInstance;
1544         }
1545
1546         /**
1547          * Getter for communicator instance
1548          *
1549          * @return      $communicatorInstance   An instance of a Communicator class
1550          */
1551         public final function getCommunicatorInstance () {
1552                 return $this->communicatorInstance;
1553         }
1554
1555         /**
1556          * Setter for communicator instance
1557          *
1558          * @param       $communicatorInstance   An instance of a Communicator class
1559          * @return      void
1560          */
1561         protected final function setCommunicatorInstance (Communicator $communicatorInstance) {
1562                 $this->communicatorInstance = $communicatorInstance;
1563         }
1564
1565         /**
1566          * Setter for state instance
1567          *
1568          * @param       $stateInstance  A Stateable instance
1569          * @return      void
1570          */
1571         public final function setStateInstance (Stateable $stateInstance) {
1572                 $this->stateInstance = $stateInstance;
1573         }
1574
1575         /**
1576          * Getter for state instance
1577          *
1578          * @return      $stateInstance  A Stateable instance
1579          */
1580         public final function getStateInstance () {
1581                 return $this->stateInstance;
1582         }
1583
1584         /**
1585          * Setter for output instance
1586          *
1587          * @param       $outputInstance The debug output instance
1588          * @return      void
1589          */
1590         public final function setOutputInstance (OutputStreamer $outputInstance) {
1591                 $this->outputInstance = $outputInstance;
1592         }
1593
1594         /**
1595          * Getter for output instance
1596          *
1597          * @return      $outputInstance The debug output instance
1598          */
1599         public final function getOutputInstance () {
1600                 return $this->outputInstance;
1601         }
1602
1603         /**
1604          * Setter for command name
1605          *
1606          * @param       $commandName    Last validated command name
1607          * @return      void
1608          */
1609         protected final function setCommandName ($commandName) {
1610                 $this->commandName = $commandName;
1611         }
1612
1613         /**
1614          * Getter for command name
1615          *
1616          * @return      $commandName    Last validated command name
1617          */
1618         protected final function getCommandName () {
1619                 return $this->commandName;
1620         }
1621
1622         /**
1623          * Setter for controller name
1624          *
1625          * @param       $controllerName Last validated controller name
1626          * @return      void
1627          */
1628         protected final function setControllerName ($controllerName) {
1629                 $this->controllerName = $controllerName;
1630         }
1631
1632         /**
1633          * Getter for controller name
1634          *
1635          * @return      $controllerName Last validated controller name
1636          */
1637         protected final function getControllerName () {
1638                 return $this->controllerName;
1639         }
1640
1641         /**
1642          * Getter for protocol name
1643          *
1644          * @return      $protocolName   Name of used protocol
1645          */
1646         public final function getProtocolName () {
1647                 return $this->protocolName;
1648         }
1649
1650         /**
1651          * Setter for protocol name
1652          *
1653          * @param       $protocolName   Name of used protocol
1654          * @return      void
1655          */
1656         protected final function setProtocolName ($protocolName) {
1657                 $this->protocolName = $protocolName;
1658         }
1659
1660         /**
1661          * Checks whether an object equals this object. You should overwrite this
1662          * method to implement own equality checks
1663          *
1664          * @param       $objectInstance         An instance of a FrameworkInterface object
1665          * @return      $equals                         Whether both objects equals
1666          */
1667         public function equals (FrameworkInterface $objectInstance) {
1668                 // Now test it
1669                 $equals = ((
1670                         $this->__toString() == $objectInstance->__toString()
1671                 ) && (
1672                         $this->hashCode() == $objectInstance->hashCode()
1673                 ));
1674
1675                 // Return the result
1676                 return $equals;
1677         }
1678
1679         /**
1680          * Generates a generic hash code of this class. You should really overwrite
1681          * this method with your own hash code generator code. But keep KISS in mind.
1682          *
1683          * @return      $hashCode       A generic hash code respresenting this whole class
1684          */
1685         public function hashCode () {
1686                 // Simple hash code
1687                 return crc32($this->__toString());
1688         }
1689
1690         /**
1691          * Formats computer generated price values into human-understandable formats
1692          * with thousand and decimal separators.
1693          *
1694          * @param       $value          The in computer format value for a price
1695          * @param       $currency       The currency symbol (use HTML-valid characters!)
1696          * @param       $decNum         Number of decimals after commata
1697          * @return      $price          The for the current language formated price string
1698          * @throws      MissingDecimalsThousandsSeparatorException      If decimals or
1699          *                                                                                              thousands separator
1700          *                                                                                              is missing
1701          */
1702         public function formatCurrency ($value, $currency = '&euro;', $decNum = 2) {
1703                 // Are all required attriutes set?
1704                 if ((!isset($this->decimals)) || (!isset($this->thousands))) {
1705                         // Throw an exception
1706                         throw new MissingDecimalsThousandsSeparatorException($this, self::EXCEPTION_ATTRIBUTES_ARE_MISSING);
1707                 } // END - if
1708
1709                 // Cast the number
1710                 $value = (float) $value;
1711
1712                 // Reformat the US number
1713                 $price = number_format($value, $decNum, $this->decimals, $this->thousands) . $currency;
1714
1715                 // Return as string...
1716                 return $price;
1717         }
1718
1719         /**
1720          * Appends a trailing slash to a string
1721          *
1722          * @param       $str    A string (maybe) without trailing slash
1723          * @return      $str    A string with an auto-appended trailing slash
1724          */
1725         public final function addMissingTrailingSlash ($str) {
1726                 // Is there a trailing slash?
1727                 if (substr($str, -1, 1) != '/') {
1728                         $str .= '/';
1729                 } // END - if
1730
1731                 // Return string with trailing slash
1732                 return $str;
1733         }
1734
1735         /**
1736          * Prepare the template engine (HtmlTemplateEngine by default) for a given
1737          * application helper instance (ApplicationHelper by default).
1738          *
1739          * @param               $applicationInstance    An application helper instance or
1740          *                                                                              null if we shall use the default
1741          * @return              $templateInstance               The template engine instance
1742          * @throws              NullPointerException    If the discovered application
1743          *                                                                              instance is still null
1744          */
1745         protected function prepareTemplateInstance (ManageableApplication $applicationInstance = NULL) {
1746                 // Is the application instance set?
1747                 if (is_null($applicationInstance)) {
1748                         // Get the current instance
1749                         $applicationInstance = Registry::getRegistry()->getInstance('app');
1750
1751                         // Still null?
1752                         if (is_null($applicationInstance)) {
1753                                 // Thrown an exception
1754                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
1755                         } // END - if
1756                 } // END - if
1757
1758                 // Initialize the template engine
1759                 $templateInstance = ObjectFactory::createObjectByConfiguredName('html_template_class');
1760
1761                 // Return the prepared instance
1762                 return $templateInstance;
1763         }
1764
1765         /**
1766          * Debugs this instance by putting out it's full content
1767          *
1768          * @param       $message        Optional message to show in debug output
1769          * @return      void
1770          */
1771         public final function debugInstance ($message = '') {
1772                 // Restore the error handler to avoid trouble with missing array elements or undeclared variables
1773                 restore_error_handler();
1774
1775                 // Init content
1776                 $content = '';
1777
1778                 // Is a message set?
1779                 if (!empty($message)) {
1780                         // Construct message
1781                         $content = sprintf('<div class="debug_message">Message: %s</div>' . PHP_EOL, $message);
1782                 } // END - if
1783
1784                 // Generate the output
1785                 $content .= sprintf('<pre>%s</pre>',
1786                         trim(
1787                                 htmlentities(
1788                                         print_r($this, true)
1789                                 )
1790                         )
1791                 );
1792
1793                 // Output it
1794                 ApplicationEntryPoint::app_exit(sprintf('<div class="debug_header">%s debug output:</div><div class="debug_content">%s</div>Loaded includes: <div class="debug_include_list">%s</div>',
1795                         $this->__toString(),
1796                         $content,
1797                         ClassLoader::getSelfInstance()->getPrintableIncludeList()
1798                 ));
1799         }
1800
1801         /**
1802          * Replaces control characters with printable output
1803          *
1804          * @param       $str    String with control characters
1805          * @return      $str    Replaced string
1806          */
1807         protected function replaceControlCharacters ($str) {
1808                 // Replace them
1809                 $str = str_replace(
1810                         chr(13), '[r]', str_replace(
1811                         chr(10), '[n]', str_replace(
1812                         chr(9) , '[t]',
1813                         $str
1814                 )));
1815
1816                 // Return it
1817                 return $str;
1818         }
1819
1820         /**
1821          * Output a partial stub message for the caller method
1822          *
1823          * @param       $message        An optional message to display
1824          * @return      void
1825          */
1826         protected function partialStub ($message = '') {
1827                 // Get the backtrace
1828                 $backtrace = debug_backtrace();
1829
1830                 // Generate the class::method string
1831                 $methodName = 'UnknownClass-&gt;unknownMethod';
1832                 if ((isset($backtrace[1]['class'])) && (isset($backtrace[1]['function']))) {
1833                         $methodName = $backtrace[1]['class'] . '-&gt;' . $backtrace[1]['function'];
1834                 } // END - if
1835
1836                 // Construct the full message
1837                 $stubMessage = sprintf('[%s:] Partial stub!',
1838                         $methodName
1839                 );
1840
1841                 // Is the extra message given?
1842                 if (!empty($message)) {
1843                         // Then add it as well
1844                         $stubMessage .= ' Message: ' . $message;
1845                 } // END - if
1846
1847                 // Debug instance is there?
1848                 if (!is_null($this->getDebugInstance())) {
1849                         // Output stub message
1850                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($stubMessage);
1851                 } else {
1852                         // Trigger an error
1853                         trigger_error($stubMessage);
1854                         exit;
1855                 }
1856         }
1857
1858         /**
1859          * Outputs a debug backtrace and stops further script execution
1860          *
1861          * @param       $message        An optional message to output
1862          * @param       $doExit         Whether exit the program (true is default)
1863          * @return      void
1864          */
1865         public function debugBackTrace ($message = '', $doExit = true) {
1866                 // Sorry, there is no other way getting this nice backtrace
1867                 if (!empty($message)) {
1868                         // Output message
1869                         printf('Message: %s<br />' . PHP_EOL, $message);
1870                 } // END - if
1871
1872                 print('<pre>');
1873                 debug_print_backtrace();
1874                 print('</pre>');
1875
1876                 // Exit program?
1877                 if ($doExit === true) {
1878                         exit();
1879                 } // END - if
1880         }
1881
1882         /**
1883          * Creates an instance of a debugger instance
1884          *
1885          * @param       $className              Name of the class (currently unsupported)
1886          * @param       $lineNumber             Line number where the call was made
1887          * @return      $debugInstance  An instance of a debugger class
1888          * @deprecated  Not fully, as the new Logger facilities are not finished yet.
1889          */
1890         public final static function createDebugInstance ($className, $lineNumber = NULL) {
1891                 // Is the instance set?
1892                 if (!Registry::getRegistry()->instanceExists('debug')) {
1893                         // Init debug instance
1894                         $debugInstance = NULL;
1895
1896                         // Try it
1897                         try {
1898                                 // Get a debugger instance
1899                                 $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_class'), $className);
1900                         } catch (NullPointerException $e) {
1901                                 // Didn't work, no instance there
1902                                 exit(sprintf('Cannot create debugInstance! Exception=%s,message=%s,className=%s,lineNumber=%d' . PHP_EOL, $e->__toString(), $e->getMessage(), $className, $lineNumber));
1903                         }
1904
1905                         // Empty string should be ignored and used for testing the middleware
1906                         DebugMiddleware::getSelfInstance()->output('');
1907
1908                         // Set it in its own class. This will set it in the registry
1909                         $debugInstance->setDebugInstance($debugInstance);
1910                 } else {
1911                         // Get instance from registry
1912                         $debugInstance = Registry::getRegistry()->getDebugInstance();
1913                 }
1914
1915                 // Return it
1916                 return $debugInstance;
1917         }
1918
1919         /**
1920          * Simple output of a message with line-break
1921          *
1922          * @param       $message        Message to output
1923          * @return      void
1924          */
1925         public function outputLine ($message) {
1926                 // Simply output it
1927                 print($message . PHP_EOL);
1928         }
1929
1930         /**
1931          * Outputs a debug message whether to debug instance (should be set!) or
1932          * dies with or ptints the message. Do NEVER EVER rewrite the exit() call to
1933          * ApplicationEntryPoint::app_exit(), this would cause an endless loop.
1934          *
1935          * @param       $message        Message we shall send out...
1936          * @param       $doPrint        Whether print or die here (default: print)
1937          * @paran       $stripTags      Whether to strip tags (default: false)
1938          * @return      void
1939          */
1940         public function debugOutput ($message, $doPrint = true, $stripTags = false) {
1941                 // Set debug instance to NULL
1942                 $debugInstance = NULL;
1943
1944                 // Try it:
1945                 try {
1946                         // Get debug instance
1947                         $debugInstance = $this->getDebugInstance();
1948                 } catch (NullPointerException $e) {
1949                         // The debug instance is not set (yet)
1950                 }
1951
1952                 // Is the debug instance there?
1953                 if (is_object($debugInstance)) {
1954                         // Use debug output handler
1955                         $debugInstance->output($message, $stripTags);
1956
1957                         if ($doPrint === false) {
1958                                 // Die here if not printed
1959                                 exit();
1960                         } // END - if
1961                 } else {
1962                         // Are debug times enabled?
1963                         if ($this->getConfigInstance()->getConfigEntry('debug_' . FrameworkBootstrap::getRequestTypeFromSystem() . '_output_timings') == 'Y') {
1964                                 // Prepent it
1965                                 $message = $this->getPrintableExecutionTime() . $message;
1966                         } // END - if
1967
1968                         // Put directly out
1969                         if ($doPrint === true) {
1970                                 // Print message
1971                                 $this->outputLine($message);
1972                         } else {
1973                                 // Die here
1974                                 exit($message);
1975                         }
1976                 }
1977         }
1978
1979         /**
1980          * Converts e.g. a command from URL to a valid class by keeping out bad characters
1981          *
1982          * @param       $str            The string, what ever it is needs to be converted
1983          * @return      $className      Generated class name
1984          */
1985         public static final function convertToClassName ($str) {
1986                 // Init class name
1987                 $className = '';
1988
1989                 // Convert all dashes in underscores
1990                 $str = self::convertDashesToUnderscores($str);
1991
1992                 // Now use that underscores to get classname parts for hungarian style
1993                 foreach (explode('_', $str) as $strPart) {
1994                         // Make the class name part lower case and first upper case
1995                         $className .= ucfirst(strtolower($strPart));
1996                 } // END - foreach
1997
1998                 // Return class name
1999                 return $className;
2000         }
2001
2002         /**
2003          * Converts dashes to underscores, e.g. useable for configuration entries
2004          *
2005          * @param       $str    The string with maybe dashes inside
2006          * @return      $str    The converted string with no dashed, but underscores
2007          */
2008         public static final function convertDashesToUnderscores ($str) {
2009                 // Convert them all
2010                 $str = str_replace('-', '_', $str);
2011
2012                 // Return converted string
2013                 return $str;
2014         }
2015
2016         /**
2017          * Marks up the code by adding e.g. line numbers
2018          *
2019          * @param       $phpCode                Unmarked PHP code
2020          * @return      $markedCode             Marked PHP code
2021          */
2022         public function markupCode ($phpCode) {
2023                 // Init marked code
2024                 $markedCode = '';
2025
2026                 // Get last error
2027                 $errorArray = error_get_last();
2028
2029                 // Init the code with error message
2030                 if (is_array($errorArray)) {
2031                         // Get error infos
2032                         $markedCode = sprintf('<div id="error_header">File: <span id="error_data">%s</span>, Line: <span id="error_data">%s</span>, Message: <span id="error_data">%s</span>, Type: <span id="error_data">%s</span></div>',
2033                                 basename($errorArray['file']),
2034                                 $errorArray['line'],
2035                                 $errorArray['message'],
2036                                 $errorArray['type']
2037                         );
2038                 } // END - if
2039
2040                 // Add line number to the code
2041                 foreach (explode(chr(10), $phpCode) as $lineNo => $code) {
2042                         // Add line numbers
2043                         $markedCode .= sprintf('<span id="code_line">%s</span>: %s' . PHP_EOL,
2044                                 ($lineNo + 1),
2045                                 htmlentities($code, ENT_QUOTES)
2046                         );
2047                 } // END - foreach
2048
2049                 // Return the code
2050                 return $markedCode;
2051         }
2052
2053         /**
2054          * Filter a given GMT timestamp (non Uni* stamp!) to make it look more
2055          * beatiful for web-based front-ends. If null is given a message id
2056          * null_timestamp will be resolved and returned.
2057          *
2058          * @param       $timestamp      Timestamp to prepare (filter) for display
2059          * @return      $readable       A readable timestamp
2060          */
2061         public function doFilterFormatTimestamp ($timestamp) {
2062                 // Default value to return
2063                 $readable = '???';
2064
2065                 // Is the timestamp null?
2066                 if (is_null($timestamp)) {
2067                         // Get a message string
2068                         $readable = $this->getLanguageInstance()->getMessage('null_timestamp');
2069                 } else {
2070                         switch ($this->getLanguageInstance()->getLanguageCode()) {
2071                                 case 'de': // German format is a bit different to default
2072                                         // Split the GMT stamp up
2073                                         $dateTime  = explode(' ', $timestamp  );
2074                                         $dateArray = explode('-', $dateTime[0]);
2075                                         $timeArray = explode(':', $dateTime[1]);
2076
2077                                         // Construct the timestamp
2078                                         $readable = sprintf($this->getConfigInstance()->getConfigEntry('german_date_time'),
2079                                                 $dateArray[0],
2080                                                 $dateArray[1],
2081                                                 $dateArray[2],
2082                                                 $timeArray[0],
2083                                                 $timeArray[1],
2084                                                 $timeArray[2]
2085                                         );
2086                                         break;
2087
2088                                 default: // Default is pass-through
2089                                         $readable = $timestamp;
2090                                         break;
2091                         } // END - switch
2092                 }
2093
2094                 // Return the stamp
2095                 return $readable;
2096         }
2097
2098         /**
2099          * Filter a given number into a localized number
2100          *
2101          * @param       $value          The raw value from e.g. database
2102          * @return      $localized      Localized value
2103          */
2104         public function doFilterFormatNumber ($value) {
2105                 // Generate it from config and localize dependencies
2106                 switch ($this->getLanguageInstance()->getLanguageCode()) {
2107                         case 'de': // German format is a bit different to default
2108                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), ',', '.');
2109                                 break;
2110
2111                         default: // US, etc.
2112                                 $localized = number_format($value, $this->getConfigInstance()->getConfigEntry('decimals'), '.', ',');
2113                                 break;
2114                 } // END - switch
2115
2116                 // Return it
2117                 return $localized;
2118         }
2119
2120         /**
2121          * "Getter" for databse entry
2122          *
2123          * @return      $entry  An array with database entries
2124          * @throws      NullPointerException    If the database result is not found
2125          * @throws      InvalidDatabaseResultException  If the database result is invalid
2126          */
2127         protected final function getDatabaseEntry () {
2128                 // Is there an instance?
2129                 if (!$this->getResultInstance() instanceof SearchableResult) {
2130                         // Throw an exception here
2131                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
2132                 } // END - if
2133
2134                 // Rewind it
2135                 $this->getResultInstance()->rewind();
2136
2137                 // Do we have an entry?
2138                 if ($this->getResultInstance()->valid() === false) {
2139                         // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available
2140                         throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
2141                 } // END - if
2142
2143                 // Get next entry
2144                 $this->getResultInstance()->next();
2145
2146                 // Fetch it
2147                 $entry = $this->getResultInstance()->current();
2148
2149                 // And return it
2150                 return $entry;
2151         }
2152
2153         /**
2154          * Getter for field name
2155          *
2156          * @param       $fieldName              Field name which we shall get
2157          * @return      $fieldValue             Field value from the user
2158          * @throws      NullPointerException    If the result instance is null
2159          */
2160         public final function getField ($fieldName) {
2161                 // Default field value
2162                 $fieldValue = NULL;
2163
2164                 // Get result instance
2165                 $resultInstance = $this->getResultInstance();
2166
2167                 // Is this instance null?
2168                 if (is_null($resultInstance)) {
2169                         // Then the user instance is no longer valid (expired cookies?)
2170                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
2171                 } // END - if
2172
2173                 // Get current array
2174                 $fieldArray = $resultInstance->current();
2175                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, true).'</pre>');
2176
2177                 // Convert dashes to underscore
2178                 $fieldName2 = self::convertDashesToUnderscores($fieldName);
2179
2180                 // Does the field exist?
2181                 if ($this->isFieldSet($fieldName)) {
2182                         // Get it
2183                         $fieldValue = $fieldArray[$fieldName2];
2184                 } elseif (defined('DEVELOPER')) {
2185                         // Missing field entry, may require debugging
2186                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldArray<pre>=' . print_r($fieldArray, true) . '</pre>,fieldName=' . $fieldName . ' not found!');
2187                 } else {
2188                         // Missing field entry, may require debugging
2189                         self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldName=' . $fieldName . ' not found!');
2190                 }
2191
2192                 // Return it
2193                 return $fieldValue;
2194         }
2195
2196         /**
2197          * Checks if given field is set
2198          *
2199          * @param       $fieldName      Field name to check
2200          * @return      $isSet          Whether the given field name is set
2201          * @throws      NullPointerException    If the result instance is null
2202          */
2203         public function isFieldSet ($fieldName) {
2204                 // Get result instance
2205                 $resultInstance = $this->getResultInstance();
2206
2207                 // Is this instance null?
2208                 if (is_null($resultInstance)) {
2209                         // Then the user instance is no longer valid (expired cookies?)
2210                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
2211                 } // END - if
2212
2213                 // Get current array
2214                 $fieldArray = $resultInstance->current();
2215                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('[' . $this->__toString() . ':' . __LINE__ . '] fieldName=' . $fieldName . ',fieldArray=<pre>'.print_r($fieldArray, true).'</pre>');
2216
2217                 // Convert dashes to underscore
2218                 $fieldName = self::convertDashesToUnderscores($fieldName);
2219
2220                 // Determine it
2221                 $isSet = isset($fieldArray[$fieldName]);
2222
2223                 // Return result
2224                 return $isSet;
2225         }
2226
2227         /**
2228          * Flushs all pending updates to the database layer
2229          *
2230          * @return      void
2231          */
2232         public function flushPendingUpdates () {
2233                 // Get result instance
2234                 $resultInstance = $this->getResultInstance();
2235
2236                 // Do we have data to update?
2237                 if ((is_object($resultInstance)) && ($resultInstance->ifDataNeedsFlush())) {
2238                         // Get wrapper class name config entry
2239                         $configEntry = $resultInstance->getUpdateInstance()->getWrapperConfigEntry();
2240
2241                         // Create object instance
2242                         $wrapperInstance = DatabaseWrapperFactory::createWrapperByConfiguredName($configEntry);
2243
2244                         // Yes, then send the whole result to the database layer
2245                         $wrapperInstance->doUpdateByResult($this->getResultInstance());
2246                 } // END - if
2247         }
2248
2249         /**
2250          * Outputs a deprecation warning to the developer.
2251          *
2252          * @param       $message        The message we shall output to the developer
2253          * @return      void
2254          * @todo        Write a logging mechanism for productive mode
2255          */
2256         public function deprecationWarning ($message) {
2257                 // Is developer mode active?
2258                 if (defined('DEVELOPER')) {
2259                         // Debug instance is there?
2260                         if (!is_null($this->getDebugInstance())) {
2261                                 // Output stub message
2262                                 self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($message);
2263                         } else {
2264                                 // Trigger an error
2265                                 trigger_error($message . "<br />\n");
2266                                 exit;
2267                         }
2268                 } else {
2269                         // @TODO Finish this part!
2270                         $this->partialStub('Developer mode inactive. Message:' . $message);
2271                 }
2272         }
2273
2274         /**
2275          * Checks whether the given PHP extension is loaded
2276          *
2277          * @param       $phpExtension   The PHP extension we shall check
2278          * @return      $isLoaded       Whether the PHP extension is loaded
2279          */
2280         public final function isPhpExtensionLoaded ($phpExtension) {
2281                 // Is it loaded?
2282                 $isLoaded = in_array($phpExtension, get_loaded_extensions());
2283
2284                 // Return result
2285                 return $isLoaded;
2286         }
2287
2288         /**
2289          * "Getter" as a time() replacement but with milliseconds. You should use this
2290          * method instead of the encapsulated getimeofday() function.
2291          *
2292          * @return      $milliTime      Timestamp with milliseconds
2293          */
2294         public function getMilliTime () {
2295                 // Get the time of day as float
2296                 $milliTime = gettimeofday(true);
2297
2298                 // Return it
2299                 return $milliTime;
2300         }
2301
2302         /**
2303          * Idles (sleeps) for given milliseconds
2304          *
2305          * @return      $hasSlept       Whether it goes fine
2306          */
2307         public function idle ($milliSeconds) {
2308                 // Sleep is fine by default
2309                 $hasSlept = true;
2310
2311                 // Idle so long with found function
2312                 if (function_exists('time_sleep_until')) {
2313                         // Get current time and add idle time
2314                         $sleepUntil = $this->getMilliTime() + abs($milliSeconds) / 1000;
2315
2316                         // New PHP 5.1.0 function found, ignore errors
2317                         $hasSlept = @time_sleep_until($sleepUntil);
2318                 } else {
2319                         /*
2320                          * My Sun station doesn't have that function even with latest PHP
2321                          * package. :(
2322                          */
2323                         usleep($milliSeconds * 1000);
2324                 }
2325
2326                 // Return result
2327                 return $hasSlept;
2328         }
2329         /**
2330          * Converts a hexadecimal string, even with negative sign as first string to
2331          * a decimal number using BC functions.
2332          *
2333          * This work is based on comment #86673 on php.net documentation page at:
2334          * <http://de.php.net/manual/en/function.dechex.php#86673>
2335          *
2336          * @param       $hex    Hexadecimal string
2337          * @return      $dec    Decimal number
2338          */
2339         protected function hex2dec ($hex) {
2340                 // Convert to all lower-case
2341                 $hex = strtolower($hex);
2342
2343                 // Detect sign (negative/positive numbers)
2344                 $sign = '';
2345                 if (substr($hex, 0, 1) == '-') {
2346                         $sign = '-';
2347                         $hex = substr($hex, 1);
2348                 } // END - if
2349
2350                 // Decode the hexadecimal string into a decimal number
2351                 $dec = 0;
2352                 for ($i = strlen($hex) - 1, $e = 1; $i >= 0; $i--, $e = bcmul($e, 16)) {
2353                         $factor = self::$hexdec[substr($hex, $i, 1)];
2354                         $dec = bcadd($dec, bcmul($factor, $e));
2355                 } // END - for
2356
2357                 // Return the decimal number
2358                 return $sign . $dec;
2359         }
2360
2361         /**
2362          * Converts even very large decimal numbers, also signed, to a hexadecimal
2363          * string.
2364          *
2365          * This work is based on comment #97756 on php.net documentation page at:
2366          * <http://de.php.net/manual/en/function.hexdec.php#97756>
2367          *
2368          * @param       $dec            Decimal number, even with negative sign
2369          * @param       $maxLength      Optional maximum length of the string
2370          * @return      $hex    Hexadecimal string
2371          */
2372         protected function dec2hex ($dec, $maxLength = 0) {
2373                 // maxLength can be zero or devideable by 2
2374                 assert(($maxLength == 0) || (($maxLength % 2) == 0));
2375
2376                 // Detect sign (negative/positive numbers)
2377                 $sign = '';
2378                 if ($dec < 0) {
2379                         $sign = '-';
2380                         $dec = abs($dec);
2381                 } // END - if
2382
2383                 // Encode the decimal number into a hexadecimal string
2384                 $hex = '';
2385                 do {
2386                         $hex = self::$dechex[($dec % (2 ^ 4))] . $hex;
2387                         $dec /= (2 ^ 4);
2388                 } while ($dec >= 1);
2389
2390                 /*
2391                  * Leading zeros are required for hex-decimal "numbers". In some
2392                  * situations more leading zeros are wanted, so check for both
2393                  * conditions.
2394                  */
2395                 if ($maxLength > 0) {
2396                         // Prepend more zeros
2397                         $hex = str_pad($hex, $maxLength, '0', STR_PAD_LEFT);
2398                 } elseif ((strlen($hex) % 2) != 0) {
2399                         // Only make string's length dividable by 2
2400                         $hex = '0' . $hex;
2401                 }
2402
2403                 // Return the hexadecimal string
2404                 return $sign . $hex;
2405         }
2406
2407         /**
2408          * Converts a ASCII string (0 to 255) into a decimal number.
2409          *
2410          * @param       $asc    The ASCII string to be converted
2411          * @return      $dec    Decimal number
2412          */
2413         protected function asc2dec ($asc) {
2414                 // Convert it into a hexadecimal number
2415                 $hex = bin2hex($asc);
2416
2417                 // And back into a decimal number
2418                 $dec = $this->hex2dec($hex);
2419
2420                 // Return it
2421                 return $dec;
2422         }
2423
2424         /**
2425          * Converts a decimal number into an ASCII string.
2426          *
2427          * @param       $dec            Decimal number
2428          * @return      $asc    An ASCII string
2429          */
2430         protected function dec2asc ($dec) {
2431                 // First convert the number into a hexadecimal string
2432                 $hex = $this->dec2hex($dec);
2433
2434                 // Then convert it into the ASCII string
2435                 $asc = $this->hex2asc($hex);
2436
2437                 // Return it
2438                 return $asc;
2439         }
2440
2441         /**
2442          * Converts a hexadecimal number into an ASCII string. Negative numbers
2443          * are not allowed.
2444          *
2445          * @param       $hex    Hexadecimal string
2446          * @return      $asc    An ASCII string
2447          */
2448         protected function hex2asc ($hex) {
2449                 // Check for length, it must be devideable by 2
2450                 //* DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('hex='.$hex);
2451                 assert((strlen($hex) % 2) == 0);
2452
2453                 // Walk the string
2454                 $asc = '';
2455                 for ($idx = 0; $idx < strlen($hex); $idx+=2) {
2456                         // Get the decimal number of the chunk
2457                         $part = hexdec(substr($hex, $idx, 2));
2458
2459                         // Add it to the final string
2460                         $asc .= chr($part);
2461                 } // END - for
2462
2463                 // Return the final string
2464                 return $asc;
2465         }
2466
2467         /**
2468          * Checks whether the given encoded data was encoded with Base64
2469          *
2470          * @param       $encodedData    Encoded data we shall check
2471          * @return      $isBase64               Whether the encoded data is Base64
2472          */
2473         protected function isBase64Encoded ($encodedData) {
2474                 // Determine it
2475                 $isBase64 = (@base64_decode($encodedData, true) !== false);
2476
2477                 // Return it
2478                 return $isBase64;
2479         }
2480
2481         /**
2482          * Gets a cache key from Criteria instance
2483          *
2484          * @param       $criteriaInstance       An instance of a Criteria class
2485          * @param       $onlyKeys                       Only use these keys for a cache key
2486          * @return      $cacheKey                       A cache key suitable for lookup/storage purposes
2487          */
2488         protected function getCacheKeyByCriteria (Criteria $criteriaInstance, array $onlyKeys = array()) {
2489                 // Generate it
2490                 $cacheKey = sprintf('%s@%s',
2491                         $this->__toString(),
2492                         $criteriaInstance->getCacheKey($onlyKeys)
2493                 );
2494
2495                 // And return it
2496                 //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput($this->__toString() . ': cacheKey=' . $cacheKey);
2497                 return $cacheKey;
2498         }
2499
2500         /**
2501          * Getter for startup time in miliseconds
2502          *
2503          * @return      $startupTime    Startup time in miliseconds
2504          */
2505         protected function getStartupTime () {
2506                 return self::$startupTime;
2507         }
2508
2509         /**
2510          * "Getter" for a printable currently execution time in nice braces
2511          *
2512          * @return      $executionTime  Current execution time in nice braces
2513          */
2514         protected function getPrintableExecutionTime () {
2515                 // Caculate the execution time
2516                 $executionTime = microtime(true) - $this->getStartupTime();
2517
2518                 // Pack it in nice braces
2519                 $executionTime = sprintf('[ %01.5f ] ', $executionTime);
2520
2521                 // And return it
2522                 return $executionTime;
2523         }
2524
2525         /**
2526          * Hashes a given string with a simple but stronger hash function (no salt)
2527          * and hex-encode it.
2528          *
2529          * @param       $str    The string to be hashed
2530          * @return      $hash   The hash from string $str
2531          */
2532         public static final function hash ($str) {
2533                 // Hash given string with (better secure) hasher
2534                 $hash = bin2hex(mhash(MHASH_SHA256, $str));
2535
2536                 // Return it
2537                 return $hash;
2538         }
2539
2540         /**
2541          * "Getter" for length of hash() output. This will be "cached" to speed up
2542          * things.
2543          *
2544          * @return      $length         Length of hash() output
2545          */
2546         public static final function getHashLength () {
2547                 // Is it cashed?
2548                 if (is_null(self::$hashLength)) {
2549                         // No, then hash a string and save its length.
2550                         self::$hashLength = strlen(self::hash('abc123'));
2551                 } // END - if
2552
2553                 // Return it
2554                 return self::$hashLength;
2555         }
2556
2557         /**
2558          * Checks whether the given number is really a number (only chars 0-9).
2559          *
2560          * @param       $num            A string consisting only chars between 0 and 9
2561          * @param       $castValue      Whether to cast the value to double. Do only use this to secure numbers from Requestable classes.
2562          * @param       $assertMismatch         Whether to assert mismatches
2563          * @return      $ret            The (hopefully) secured numbered value
2564          */
2565         public function bigintval ($num, $castValue = true, $assertMismatch = false) {
2566                 // Filter all numbers out
2567                 $ret = preg_replace('/[^0123456789]/', '', $num);
2568
2569                 // Shall we cast?
2570                 if ($castValue === true) {
2571                         // Cast to biggest numeric type
2572                         $ret = (double) $ret;
2573                 } // END - if
2574
2575                 // Assert only if requested
2576                 if ($assertMismatch === true) {
2577                         // Has the whole value changed?
2578                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2579                 } // END - if
2580
2581                 // Return result
2582                 return $ret;
2583         }
2584
2585         /**
2586          * Checks whether the given hexadecimal number is really a hex-number (only chars 0-9,a-f).
2587          *
2588          * @param       $num    A string consisting only chars between 0 and 9
2589          * @param       $assertMismatch         Whether to assert mismatches
2590          * @return      $ret    The (hopefully) secured hext-numbered value
2591          */
2592         public function hexval ($num, $assertMismatch = false) {
2593                 // Filter all numbers out
2594                 $ret = preg_replace('/[^0123456789abcdefABCDEF]/', '', $num);
2595
2596                 // Assert only if requested
2597                 if ($assertMismatch === true) {
2598                         // Has the whole value changed?
2599                         assert(('' . $ret . '' != '' . $num . '') && (!is_null($num)));
2600                 } // END - if
2601
2602                 // Return result
2603                 return $ret;
2604         }
2605
2606         /**
2607          * Checks whether start/end marker are set
2608          *
2609          * @param       $data   Data to be checked
2610          * @return      $isset  Whether start/end marker are set
2611          */
2612         public final function ifStartEndMarkersSet ($data) {
2613                 // Determine it
2614                 $isset = ((substr($data, 0, strlen(BaseRawDataHandler::STREAM_START_MARKER)) == BaseRawDataHandler::STREAM_START_MARKER) && (substr($data, -1 * strlen(BaseRawDataHandler::STREAM_END_MARKER), strlen(BaseRawDataHandler::STREAM_END_MARKER)) == BaseRawDataHandler::STREAM_END_MARKER));
2615
2616                 // ... and return it
2617                 return $isset;
2618         }
2619
2620         /**
2621          * Determines if an element is set in the generic array
2622          *
2623          * @param       $keyGroup       Main group for the key
2624          * @param       $subGroup       Sub group for the key
2625          * @param       $key            Key to check
2626          * @param       $element        Element to check
2627          * @return      $isset          Whether the given key is set
2628          */
2629         protected final function isGenericArrayElementSet ($keyGroup, $subGroup, $key, $element) {
2630                 // Debug message
2631                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2632
2633                 // Is it there?
2634                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
2635
2636                 // Return it
2637                 return $isset;
2638         }
2639         /**
2640          * Determines if a key is set in the generic array
2641          *
2642          * @param       $keyGroup       Main group for the key
2643          * @param       $subGroup       Sub group for the key
2644          * @param       $key            Key to check
2645          * @return      $isset          Whether the given key is set
2646          */
2647         protected final function isGenericArrayKeySet ($keyGroup, $subGroup, $key) {
2648                 // Debug message
2649                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2650
2651                 // Is it there?
2652                 $isset = isset($this->genericArray[$keyGroup][$subGroup][$key]);
2653
2654                 // Return it
2655                 return $isset;
2656         }
2657
2658
2659         /**
2660          * Determines if a group is set in the generic array
2661          *
2662          * @param       $keyGroup       Main group
2663          * @param       $subGroup       Sub group
2664          * @return      $isset          Whether the given group is set
2665          */
2666         protected final function isGenericArrayGroupSet ($keyGroup, $subGroup) {
2667                 // Debug message
2668                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
2669
2670                 // Is it there?
2671                 $isset = isset($this->genericArray[$keyGroup][$subGroup]);
2672
2673                 // Return it
2674                 return $isset;
2675         }
2676
2677         /**
2678          * Getter for sub key group
2679          *
2680          * @param       $keyGroup       Main key group
2681          * @param       $subGroup       Sub key group
2682          * @return      $array          An array with all array elements
2683          */
2684         protected final function getGenericSubArray ($keyGroup, $subGroup) {
2685                 // Is it there?
2686                 if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
2687                         // No, then abort here
2688                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
2689                         exit;
2690                 } // END - if
2691
2692                 // Debug message
2693                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',value=' . print_r($this->genericArray[$keyGroup][$subGroup], true));
2694
2695                 // Return it
2696                 return $this->genericArray[$keyGroup][$subGroup];
2697         }
2698
2699         /**
2700          * Unsets a given key in generic array
2701          *
2702          * @param       $keyGroup       Main group for the key
2703          * @param       $subGroup       Sub group for the key
2704          * @param       $key            Key to unset
2705          * @return      void
2706          */
2707         protected final function unsetGenericArrayKey ($keyGroup, $subGroup, $key) {
2708                 // Debug message
2709                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2710
2711                 // Remove it
2712                 unset($this->genericArray[$keyGroup][$subGroup][$key]);
2713         }
2714
2715         /**
2716          * Unsets a given element in generic array
2717          *
2718          * @param       $keyGroup       Main group for the key
2719          * @param       $subGroup       Sub group for the key
2720          * @param       $key            Key to unset
2721          * @param       $element        Element to unset
2722          * @return      void
2723          */
2724         protected final function unsetGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
2725                 // Debug message
2726                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
2727
2728                 // Remove it
2729                 unset($this->genericArray[$keyGroup][$subGroup][$key][$element]);
2730         }
2731
2732         /**
2733          * Append a string to a given generic array key
2734          *
2735          * @param       $keyGroup       Main group for the key
2736          * @param       $subGroup       Sub group for the key
2737          * @param       $key            Key to unset
2738          * @param       $value          Value to add/append
2739          * @return      void
2740          */
2741         protected final function appendStringToGenericArrayKey ($keyGroup, $subGroup, $key, $value, $appendGlue = '') {
2742                 // Debug message
2743                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, true) . ',appendGlue=' . $appendGlue);
2744
2745                 // Is it already there?
2746                 if ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2747                         // Append it
2748                         $this->genericArray[$keyGroup][$subGroup][$key] .= $appendGlue . (string) $value;
2749                 } else {
2750                         // Add it
2751                         $this->genericArray[$keyGroup][$subGroup][$key] = (string) $value;
2752                 }
2753         }
2754
2755         /**
2756          * Append a string to a given generic array element
2757          *
2758          * @param       $keyGroup       Main group for the key
2759          * @param       $subGroup       Sub group for the key
2760          * @param       $key            Key to unset
2761          * @param       $element        Element to check
2762          * @param       $value          Value to add/append
2763          * @return      void
2764          */
2765         protected final function appendStringToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value, $appendGlue = '') {
2766                 // Debug message
2767                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, true) . ',appendGlue=' . $appendGlue);
2768
2769                 // Is it already there?
2770                 if ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2771                         // Append it
2772                         $this->genericArray[$keyGroup][$subGroup][$key][$element] .= $appendGlue . (string) $value;
2773                 } else {
2774                         // Add it
2775                         $this->setStringGenericArrayElement($keyGroup, $subGroup, $key, $element, $value);
2776                 }
2777         }
2778
2779         /**
2780          * Sets a string in a given generic array element
2781          *
2782          * @param       $keyGroup       Main group for the key
2783          * @param       $subGroup       Sub group for the key
2784          * @param       $key            Key to unset
2785          * @param       $element        Element to check
2786          * @param       $value          Value to add/append
2787          * @return      void
2788          */
2789         protected final function setStringGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value, $appendGlue = '') {
2790                 // Debug message
2791                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, true) . ',appendGlue=' . $appendGlue);
2792
2793                 // Set it
2794                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = (string) $value;
2795         }
2796
2797         /**
2798          * Initializes given generic array group
2799          *
2800          * @param       $keyGroup       Main group for the key
2801          * @param       $subGroup       Sub group for the key
2802          * @param       $key            Key to use
2803          * @param       $forceInit      Optionally force initialization
2804          * @return      void
2805          */
2806         protected final function initGenericArrayGroup ($keyGroup, $subGroup, $forceInit = false) {
2807                 // Debug message
2808                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',forceInit=' . intval($forceInit));
2809
2810                 // Is it already set?
2811                 if (($forceInit === false) && ($this->isGenericArrayGroupSet($keyGroup, $subGroup))) {
2812                         // Already initialized
2813                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' already initialized.');
2814                         exit;
2815                 } // END - if
2816
2817                 // Initialize it
2818                 $this->genericArray[$keyGroup][$subGroup] = array();
2819         }
2820
2821         /**
2822          * Initializes given generic array key
2823          *
2824          * @param       $keyGroup       Main group for the key
2825          * @param       $subGroup       Sub group for the key
2826          * @param       $key            Key to use
2827          * @param       $forceInit      Optionally force initialization
2828          * @return      void
2829          */
2830         protected final function initGenericArrayKey ($keyGroup, $subGroup, $key, $forceInit = false) {
2831                 // Debug message
2832                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',forceInit=' . intval($forceInit));
2833
2834                 // Is it already set?
2835                 if (($forceInit === false) && ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key))) {
2836                         // Already initialized
2837                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' already initialized.');
2838                         exit;
2839                 } // END - if
2840
2841                 // Initialize it
2842                 $this->genericArray[$keyGroup][$subGroup][$key] = array();
2843         }
2844
2845         /**
2846          * Initializes given generic array element
2847          *
2848          * @param       $keyGroup       Main group for the key
2849          * @param       $subGroup       Sub group for the key
2850          * @param       $key            Key to use
2851          * @param       $element        Element to use
2852          * @param       $forceInit      Optionally force initialization
2853          * @return      void
2854          */
2855         protected final function initGenericArrayElement ($keyGroup, $subGroup, $key, $element, $forceInit = false) {
2856                 // Debug message
2857                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',forceInit=' . intval($forceInit));
2858
2859                 // Is it already set?
2860                 if (($forceInit === false) && ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element))) {
2861                         // Already initialized
2862                         trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' already initialized.');
2863                         exit;
2864                 } // END - if
2865
2866                 // Initialize it
2867                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = array();
2868         }
2869
2870         /**
2871          * Pushes an element to a generic key
2872          *
2873          * @param       $keyGroup       Main group for the key
2874          * @param       $subGroup       Sub group for the key
2875          * @param       $key            Key to use
2876          * @param       $value          Value to add/append
2877          * @return      $count          Number of array elements
2878          */
2879         protected final function pushValueToGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
2880                 // Debug message
2881                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, true));
2882
2883                 // Is it set?
2884                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2885                         // Initialize array
2886                         $this->initGenericArrayKey($keyGroup, $subGroup, $key);
2887                 } // END - if
2888
2889                 // Then push it
2890                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key], $value);
2891
2892                 // Return count
2893                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
2894                 //* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
2895                 return $count;
2896         }
2897
2898         /**
2899          * Pushes an element to a generic array element
2900          *
2901          * @param       $keyGroup       Main group for the key
2902          * @param       $subGroup       Sub group for the key
2903          * @param       $key            Key to use
2904          * @param       $element        Element to check
2905          * @param       $value          Value to add/append
2906          * @return      $count          Number of array elements
2907          */
2908         protected final function pushValueToGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
2909                 // Debug message
2910                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, true));
2911
2912                 // Is it set?
2913                 if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
2914                         // Initialize array
2915                         $this->initGenericArrayElement($keyGroup, $subGroup, $key, $element);
2916                 } // END - if
2917
2918                 // Then push it
2919                 $count = array_push($this->genericArray[$keyGroup][$subGroup][$key][$element], $value);
2920
2921                 // Return count
2922                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
2923                 //* DEBUG: */ print(__METHOD__ . ': count=' . $count . PHP_EOL);
2924                 return $count;
2925         }
2926
2927         /**
2928          * Pops an element from  a generic group
2929          *
2930          * @param       $keyGroup       Main group for the key
2931          * @param       $subGroup       Sub group for the key
2932          * @param       $key            Key to unset
2933          * @return      $value          Last "popped" value
2934          */
2935         protected final function popGenericArrayElement ($keyGroup, $subGroup, $key) {
2936                 // Debug message
2937                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2938
2939                 // Is it set?
2940                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2941                         // Not found
2942                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
2943                         exit;
2944                 } // END - if
2945
2946                 // Then "pop" it
2947                 $value = array_pop($this->genericArray[$keyGroup][$subGroup][$key]);
2948
2949                 // Return value
2950                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
2951                 //* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, true) . PHP_EOL);
2952                 return $value;
2953         }
2954
2955         /**
2956          * Shifts an element from  a generic group
2957          *
2958          * @param       $keyGroup       Main group for the key
2959          * @param       $subGroup       Sub group for the key
2960          * @param       $key            Key to unset
2961          * @return      $value          Last "popped" value
2962          */
2963         protected final function shiftGenericArrayElement ($keyGroup, $subGroup, $key) {
2964                 // Debug message
2965                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
2966
2967                 // Is it set?
2968                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
2969                         // Not found
2970                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
2971                         exit;
2972                 } // END - if
2973
2974                 // Then "shift" it
2975                 $value = array_shift($this->genericArray[$keyGroup][$subGroup][$key]);
2976
2977                 // Return value
2978                 //* DEBUG: */ print(__METHOD__ . ': genericArray=' . print_r($this->genericArray[$keyGroup][$subGroup][$key], true));
2979                 //* DEBUG: */ print(__METHOD__ . ': value[' . gettype($value) . ']=' . print_r($value, true) . PHP_EOL);
2980                 return $value;
2981         }
2982
2983         /**
2984          * Count generic array group
2985          *
2986          * @param       $keyGroup       Main group for the key
2987          * @return      $count          Count of given group
2988          */
2989         protected final function countGenericArray ($keyGroup) {
2990                 // Debug message
2991                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
2992
2993                 // Is it there?
2994                 if (!isset($this->genericArray[$keyGroup])) {
2995                         // Abort here
2996                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' not found.');
2997                         exit;
2998                 } // END - if
2999
3000                 // Then count it
3001                 $count = count($this->genericArray[$keyGroup]);
3002
3003                 // Debug message
3004                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',count=' . $count);
3005
3006                 // Return it
3007                 return $count;
3008         }
3009
3010         /**
3011          * Count generic array sub group
3012          *
3013          * @param       $keyGroup       Main group for the key
3014          * @param       $subGroup       Sub group for the key
3015          * @return      $count          Count of given group
3016          */
3017         protected final function countGenericArrayGroup ($keyGroup, $subGroup) {
3018                 // Debug message
3019                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
3020
3021                 // Is it there?
3022                 if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
3023                         // Abort here
3024                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
3025                         exit;
3026                 } // END - if
3027
3028                 // Then count it
3029                 $count = count($this->genericArray[$keyGroup][$subGroup]);
3030
3031                 // Debug message
3032                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',count=' . $count);
3033
3034                 // Return it
3035                 return $count;
3036         }
3037
3038         /**
3039          * Count generic array elements
3040          *
3041          * @param       $keyGroup       Main group for the key
3042          * @param       $subGroup       Sub group for the key
3043          * @para        $key            Key to count
3044          * @return      $count          Count of given key
3045          */
3046         protected final function countGenericArrayElements ($keyGroup, $subGroup, $key) {
3047                 // Debug message
3048                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
3049
3050                 // Is it there?
3051                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
3052                         // Abort here
3053                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
3054                         exit;
3055                 } elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
3056                         // Not valid
3057                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' is not an array.');
3058                         exit;
3059                 }
3060
3061                 // Then count it
3062                 $count = count($this->genericArray[$keyGroup][$subGroup][$key]);
3063
3064                 // Debug message
3065                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',count=' . $count);
3066
3067                 // Return it
3068                 return $count;
3069         }
3070
3071         /**
3072          * Getter for whole generic group array
3073          *
3074          * @param       $keyGroup       Key group to get
3075          * @return      $array          Whole generic array group
3076          */
3077         protected final function getGenericArray ($keyGroup) {
3078                 // Debug message
3079                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup);
3080
3081                 // Is it there?
3082                 if (!isset($this->genericArray[$keyGroup])) {
3083                         // Then abort here
3084                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' does not exist.');
3085                         exit;
3086                 } // END - if
3087
3088                 // Return it
3089                 return $this->genericArray[$keyGroup];
3090         }
3091
3092         /**
3093          * Setter for generic array key
3094          *
3095          * @param       $keyGroup       Key group to get
3096          * @param       $subGroup       Sub group for the key
3097          * @param       $key            Key to unset
3098          * @param       $value          Mixed value from generic array element
3099          * @return      void
3100          */
3101         protected final function setGenericArrayKey ($keyGroup, $subGroup, $key, $value) {
3102                 // Debug message
3103                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',value[' . gettype($value) . ']=' . print_r($value, true));
3104
3105                 // Set value here
3106                 $this->genericArray[$keyGroup][$subGroup][$key] = $value;
3107         }
3108
3109         /**
3110          * Getter for generic array key
3111          *
3112          * @param       $keyGroup       Key group to get
3113          * @param       $subGroup       Sub group for the key
3114          * @param       $key            Key to unset
3115          * @return      $value          Mixed value from generic array element
3116          */
3117         protected final function getGenericArrayKey ($keyGroup, $subGroup, $key) {
3118                 // Debug message
3119                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
3120
3121                 // Is it there?
3122                 if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
3123                         // Then abort here
3124                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' does not exist.');
3125                         exit;
3126                 } // END - if
3127
3128                 // Return it
3129                 return $this->genericArray[$keyGroup][$subGroup][$key];
3130         }
3131
3132         /**
3133          * Sets a value in given generic array key/element
3134          *
3135          * @param       $keyGroup       Main group for the key
3136          * @param       $subGroup       Sub group for the key
3137          * @param       $key            Key to set
3138          * @param       $element        Element to set
3139          * @param       $value          Value to set
3140          * @return      void
3141          */
3142         protected final function setGenericArrayElement ($keyGroup, $subGroup, $key, $element, $value) {
3143                 // Debug message
3144                 //* NOISY-DEBUG: */ if (!is_object($value)) $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ',value[' . gettype($value) . ']=' . print_r($value, true));
3145
3146                 // Then set it
3147                 $this->genericArray[$keyGroup][$subGroup][$key][$element] = $value;
3148         }
3149
3150         /**
3151          * Getter for generic array element
3152          *
3153          * @param       $keyGroup       Key group to get
3154          * @param       $subGroup       Sub group for the key
3155          * @param       $key            Key to look for
3156          * @param       $element        Element to look for
3157          * @return      $value          Mixed value from generic array element
3158          */
3159         protected final function getGenericArrayElement ($keyGroup, $subGroup, $key, $element) {
3160                 // Debug message
3161                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element);
3162
3163                 // Is it there?
3164                 if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
3165                         // Then abort here
3166                         trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' does not exist.');
3167                         exit;
3168                 } // END - if
3169
3170                 // Return it
3171                 return $this->genericArray[$keyGroup][$subGroup][$key][$element];
3172         }
3173
3174         /**
3175          * Checks if a given sub group is valid (array)
3176          *
3177          * @param       $keyGroup       Key group to get
3178          * @param       $subGroup       Sub group for the key
3179          * @return      $isValid        Whether given sub group is valid
3180          */
3181         protected final function isValidGenericArrayGroup ($keyGroup, $subGroup) {
3182                 // Debug message
3183                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup);
3184
3185                 // Determine it
3186                 $isValid = (($this->isGenericArrayGroupSet($keyGroup, $subGroup)) && (is_array($this->getGenericSubArray($keyGroup, $subGroup))));
3187
3188                 // Return it
3189                 return $isValid;
3190         }
3191
3192         /**
3193          * Checks if a given key is valid (array)
3194          *
3195          * @param       $keyGroup       Key group to get
3196          * @param       $subGroup       Sub group for the key
3197          * @param       $key            Key to check
3198          * @return      $isValid        Whether given sub group is valid
3199          */
3200         protected final function isValidGenericArrayKey ($keyGroup, $subGroup, $key) {
3201                 // Debug message
3202                 //* NOISY-DEBUG: */ $this->outputLine('[' . __METHOD__ . ':' . __LINE__ . '] keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key);
3203
3204                 // Determine it
3205                 $isValid = (($this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) && (is_array($this->getGenericArrayKey($keyGroup, $subGroup, $key))));
3206
3207                 // Return it
3208                 return $isValid;
3209         }
3210
3211         /**
3212          * Initializes the web output instance
3213          *
3214          * @return      void
3215          */
3216         protected function initWebOutputInstance () {
3217                 // Get application instance
3218                 $applicationInstance = Registry::getRegistry()->getInstance('app');
3219
3220                 // Init web output instance
3221                 $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class', array($applicationInstance));
3222
3223                 // Set it locally
3224                 $this->setWebOutputInstance($outputInstance);
3225         }
3226
3227         /**
3228          * Translates boolean true to 'Y' and false to 'N'
3229          *
3230          * @param       $boolean                Boolean value
3231          * @return      $translated             Translated boolean value
3232          */
3233         public static final function translateBooleanToYesNo ($boolean) {
3234                 // Make sure it is really boolean
3235                 assert(is_bool($boolean));
3236
3237                 // "Translate" it
3238                 $translated = ($boolean === true) ? 'Y' : 'N';
3239
3240                 // ... and return it
3241                 return $translated;
3242         }
3243
3244         /**
3245          * Encodes raw data (almost any type) by "serializing" it and then pack it
3246          * into a "binary format".
3247          *
3248          * @param       $rawData        Raw data (almost any type)
3249          * @return      $encoded        Encoded data
3250          */
3251         protected function encodeData ($rawData) {
3252                 // Make sure no objects or resources pass through
3253                 assert(!is_object($rawData));
3254                 assert(!is_resource($rawData));
3255
3256                 // First "serialize" it (json_encode() is faster than serialize())
3257                 $encoded = $this->packString(json_encode($rawData));
3258
3259                 // And return it
3260                 return $encoded;
3261         }
3262
3263         /**
3264          * Pack a string into a "binary format". Please execuse me that this is
3265          * widely undocumented. :-(
3266          *
3267          * @param       $str            Unpacked string
3268          * @return      $packed         Packed string
3269          * @todo        Improve documentation
3270          */
3271         protected function packString ($str) {
3272                 // Debug message
3273                 //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('str=' . $str . ' - CALLED!');
3274
3275                 // First compress the string (gzcompress is okay)
3276                 $str = gzcompress($str);
3277
3278                 // Init variable
3279                 $packed = '';
3280
3281                 // And start the "encoding" loop
3282                 for ($idx = 0; $idx < strlen($str); $idx += $this->packingData[$this->archArrayElement]['step']) {
3283                         $big = 0;
3284                         for ($i = 0; $i < $this->packingData[$this->archArrayElement]['step']; $i++) {
3285                                 $factor = ($this->packingData[$this->archArrayElement]['step'] - 1 - $i);
3286
3287                                 if (($idx + $i) <= strlen($str)) {
3288                                         $ord = ord(substr($str, ($idx + $i), 1));
3289
3290                                         $add = $ord * pow(256, $factor);
3291
3292                                         $big += $add;
3293
3294                                         //print 'idx=' . $idx . ',i=' . $i . ',ord=' . $ord . ',factor=' . $factor . ',add=' . $add . ',big=' . $big . PHP_EOL;
3295                                 } // END - if
3296                         } // END - for
3297
3298                         $l = ($big & $this->packingData[$this->archArrayElement]['left']) >>$this->packingData[$this->archArrayElement]['factor'];
3299                         $r = $big & $this->packingData[$this->archArrayElement]['right'];
3300
3301                         $chunk = str_pad(pack($this->packingData[$this->archArrayElement]['format'], $l, $r), 8, '0', STR_PAD_LEFT);
3302                         //* NOISY-DEBUG */ print 'big=' . $big . ',chunk('.strlen($chunk) . ')='.md5($chunk).PHP_EOL;
3303
3304                         $packed .= $chunk;
3305                 } // END - for
3306
3307                 // Return it
3308                 //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('packed=' . $packed . ' - EXIT!');
3309                 return $packed;
3310         }
3311
3312         /**
3313          * Creates a full-qualified file name (FQFN) for given file name by adding
3314          * a configured temporary file path to it.
3315          *
3316          * @param       $fileName       Name for temporary file
3317          * @return      $fqfn   Full-qualified file name
3318          * @throw       PathWriteProtectedException If the path in 'temp_file_path' is write-protected
3319          * @throws      FileIoException If the file cannot be written
3320          */
3321          protected static function createTempPathForFile ($fileName) {
3322                 // Get config entry
3323                 $basePath = FrameworkConfiguration::getSelfInstance()->getConfigEntry('temp_file_path');
3324
3325                 // Is the path writeable?
3326                 if (!is_writable($basePath)) {
3327                         // Path is write-protected
3328                         throw new PathWriteProtectedException($fileName, self::EXCEPTION_PATH_CANNOT_BE_WRITTEN);
3329                 } // END - if
3330
3331                 // Add it
3332                 $fqfn = $basePath . '/' . $fileName;
3333
3334                 // Is it reachable?
3335                 if (!FrameworkBootstrap::isReachableFilePath($fqfn)) {
3336                         // Not reachable
3337                         throw new FileIoException($fqfn, self::EXCEPTION_FILE_NOT_REACHABLE);
3338                 } // END - if
3339
3340                 // Return it
3341                 return $fqfn;
3342          }
3343
3344         /**
3345          * "Getter" for a printable state name
3346          *
3347          * @return      $stateName      Name of the node's state in a printable format
3348          */
3349         public final function getPrintableState () {
3350                 // Default is 'null'
3351                 $stateName = 'null';
3352
3353                 // Get the state instance
3354                 $stateInstance = $this->getStateInstance();
3355
3356                 // Is it an instance of Stateable?
3357                 if ($stateInstance instanceof Stateable) {
3358                         // Then use that state name
3359                         $stateName = $stateInstance->getStateName();
3360                 } // END - if
3361
3362                 // Return result
3363                 return $stateName;
3364         }
3365
3366         /**
3367          * Handles socket error for given socket resource and peer data. This method
3368          * validates $socketResource if it is a valid resource (see is_resource())
3369          * but assumes valid data in array $recipientData, except that
3370          * count($recipientData) is always 2.
3371          *
3372          * @param       $method                         Value of __METHOD__ from calling method
3373          * @param       $line                           Value of __LINE__ from calling method
3374          * @param       $socketResource         A valid socket resource
3375          * @param       $socketData                     A valid socket data array (0 = IP/file name, 1 = port)
3376          * @return      void
3377          * @throws      InvalidSocketException  If $socketResource is no socket resource
3378          * @throws      NoSocketErrorDetectedException  If socket_last_error() gives zero back
3379          * @todo        Move all this socket-related stuff into own class, most of it resides in BaseListener
3380          */
3381         protected final function handleSocketError ($method, $line, $socketResource, array $socketData) {
3382                 // This method handles only socket resources
3383                 if (!is_resource($socketResource)) {
3384                         // No resource, abort here
3385                         throw new InvalidSocketException(array($this, $socketResource), BaseListener::EXCEPTION_INVALID_SOCKET);
3386                 } // END - if
3387
3388                 // Check socket array, 1st element is mostly IP address (or file name), 2nd is port number
3389                 //* DEBUG-DIE: */ die(__METHOD__ . ':socketData=' . print_r($socketData, true));
3390                 assert(isset($socketData[0]));
3391                 assert(isset($socketData[1]));
3392
3393                 // Get error code for first validation (0 is not an error)
3394                 $errorCode = socket_last_error($socketResource);
3395
3396                 // If the error code is zero, someone called this method without an error
3397                 if ($errorCode == 0) {
3398                         // No error detected (or previously cleared outside this method)
3399                         throw new NoSocketErrorDetectedException(array($this, $socketResource), BaseListener::EXCEPTION_NO_SOCKET_ERROR);
3400                 } // END - if
3401
3402                 // Get handler (method) name
3403                 $handlerName = $this->getSocketErrorHandlerFromCode($errorCode);
3404
3405                 // Call-back the error handler method
3406                 call_user_func_array(array($this, $handlerName), array($socketResource, $socketData));
3407
3408                 // Finally clear the error because it has been handled
3409                 socket_clear_error($socketResource);
3410         }
3411
3412 }