From 2efc7a1a33e9c7112100e7807c62de448d97e8f1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Tue, 18 May 2010 19:57:58 +0000 Subject: [PATCH] A whole bunch of classes/interfaces/exceptions added, many refacturings: - New classes for "tag support" added. Tags can be the "object types" this hub is going to share. But the purpose is kept somewhere generic so other purposes may come. - A way lot interfaces updated and added (sorry for lame description) - New factories added: (read full description way down) + The SocketDiscoveryFactory creates singleton instances for socket discovery + The PackageDiscoveryFactory does the same for package recipient discovery + The RecipientListFactory creates instances for recipient lists + The PackageTagsFactory creates singleton instances for package tags - New class RecipientList added which can be used for tracking recipients and iterated on. - New discovery classes added: ("Resolver" may also be fine naming these classes) + The PackageSocketDiscovery tries to "discover" the correct socket resource depending on the package's tags. Well, mostly this will be TCP, but UDP should not be forgotten... ;-) + The PackageRecipientDiscovery tries to "discover" the correct recipient based on the 'recipient' entry in the package data. May sound not obvious but there are some recipients which are no session id and/or IP:port combination. A good example is 'upper' which is an alias for all upper nodes like bootstrap, master and list nodes are. - New ObjectTypeRegistry added. This registry does hold a list of all valid and therefore "shareable" object types in an XML. For example 'announcement' should only be shared with the 'upper' nodes, and only spreaded once. - New (required for above registry) ObjectRegistryTemplateEngine added to handle the object_registry.xml file. - Announcement descriptor updated - TODOs.txt/README updated --- .gitattributes | 18 + application/hub/class_ApplicationHelper.php | 6 +- application/hub/config.php | 39 +- application/hub/exceptions.php | 12 +- application/hub/exceptions/tags/.htaccess | 1 + .../tags/class_InvalidTagException.php | 45 ++ .../hub/interfaces/discovery/.htaccess | 1 + .../discovery/class_DiscoverableRecipient.php | 42 ++ .../discovery/class_DiscoverableSocket.php | 36 ++ .../interfaces/package/class_Deliverable.php | 18 +- application/hub/interfaces/tags/.htaccess | 1 + .../hub/interfaces/tags/class_Tagable.php | 28 ++ application/hub/main/class_Base | 2 +- application/hub/main/discovery/.htaccess | 1 + .../hub/main/discovery/package/.htaccess | 1 + .../class_PackageRecipientDiscovery.php | 97 ++++ .../hub/main/discovery/socket/.htaccess | 1 + .../socket/class_PackageSocketDiscovery.php | 77 +++ .../hub/main/factories/discovery/.htaccess | 1 + .../class_PackageDiscoveryFactory.php | 61 +++ .../class_SocketDiscoveryFactory.php | 61 +++ .../hub/main/factories/lists/.htaccess | 1 + .../lists/class_RecipientListFactory.php | 61 +++ .../package/class_NetworkPackageFactory.php | 22 +- .../factories/states/class_StateFactory.php | 22 +- application/hub/main/factories/tags/.htaccess | 1 + .../tags/class_PackageTagsFactory.php | 61 +++ .../class_HubDescriptorHelper.php | 23 +- application/hub/main/helper/hub/class_ | 6 + .../main/listener/tcp/class_TcpListener.php | 2 +- .../main/listener/udp/class_UdpListener.php | 82 +++- .../hub/main/lists/recipient/.htaccess | 1 + .../lists/recipient/class_RecipientList.php | 57 +++ .../hub/main/package/class_NetworkPackage.php | 176 ++++++- application/hub/main/registry/.htaccess | 1 + .../hub/main/registry/objects/.htaccess | 1 + .../objects/class_ObjectTypeRegistry.php | 71 +++ application/hub/main/tags/.htaccess | 1 + application/hub/main/tags/class_ | 50 ++ application/hub/main/tags/class_BaseTags.php | 62 +++ application/hub/main/tags/package/.htaccess | 1 + .../main/tags/package/class_PackageTags.php | 164 +++++++ .../class_NetworkPackageWriterTask.php | 9 +- .../class_AnnouncementTemplateEngine.php | 31 +- .../hub/main/template/objects/.htaccess | 1 + .../class_ObjectRegistryTemplateEngine.php | 456 ++++++++++++++++++ .../xml/announcement/self_announcement.xml | 3 - .../templates/xml/object_registry/.htaccess | 1 + .../xml/object_registry/object_registry.xml | 61 +++ docs/README | 30 +- docs/TODOs.txt | 41 +- 51 files changed, 1927 insertions(+), 121 deletions(-) create mode 100644 application/hub/exceptions/tags/.htaccess create mode 100644 application/hub/exceptions/tags/class_InvalidTagException.php create mode 100644 application/hub/interfaces/discovery/.htaccess create mode 100644 application/hub/interfaces/discovery/class_DiscoverableRecipient.php create mode 100644 application/hub/interfaces/discovery/class_DiscoverableSocket.php create mode 100644 application/hub/interfaces/tags/.htaccess create mode 100644 application/hub/interfaces/tags/class_Tagable.php create mode 100644 application/hub/main/discovery/.htaccess create mode 100644 application/hub/main/discovery/package/.htaccess create mode 100644 application/hub/main/discovery/package/class_PackageRecipientDiscovery.php create mode 100644 application/hub/main/discovery/socket/.htaccess create mode 100644 application/hub/main/discovery/socket/class_PackageSocketDiscovery.php create mode 100644 application/hub/main/factories/discovery/.htaccess create mode 100644 application/hub/main/factories/discovery/class_PackageDiscoveryFactory.php create mode 100644 application/hub/main/factories/discovery/class_SocketDiscoveryFactory.php create mode 100644 application/hub/main/factories/lists/.htaccess create mode 100644 application/hub/main/factories/lists/class_RecipientListFactory.php create mode 100644 application/hub/main/factories/tags/.htaccess create mode 100644 application/hub/main/factories/tags/class_PackageTagsFactory.php create mode 100644 application/hub/main/lists/recipient/.htaccess create mode 100644 application/hub/main/lists/recipient/class_RecipientList.php create mode 100644 application/hub/main/registry/.htaccess create mode 100644 application/hub/main/registry/objects/.htaccess create mode 100644 application/hub/main/registry/objects/class_ObjectTypeRegistry.php create mode 100644 application/hub/main/tags/.htaccess create mode 100644 application/hub/main/tags/class_ create mode 100644 application/hub/main/tags/class_BaseTags.php create mode 100644 application/hub/main/tags/package/.htaccess create mode 100644 application/hub/main/tags/package/class_PackageTags.php create mode 100644 application/hub/main/template/objects/.htaccess create mode 100644 application/hub/main/template/objects/class_ObjectRegistryTemplateEngine.php create mode 100644 application/hub/templates/xml/object_registry/.htaccess create mode 100644 application/hub/templates/xml/object_registry/object_registry.xml diff --git a/.gitattributes b/.gitattributes index 1a0e4f7d4..07b514819 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,12 +16,14 @@ application/hub/exceptions/lists/class_ListGroupAlreadyAddedException.php -text application/hub/exceptions/lists/class_NoListGroupException.php -text application/hub/exceptions/state/.htaccess -text application/hub/exceptions/state/class_InvalidStateException.php -text +application/hub/exceptions/tags/.htaccess -text application/hub/exceptions/tasks/.htaccess -text application/hub/exceptions/tasks/class_InvalidTaskException.php -text application/hub/init.php -text application/hub/interfaces/.htaccess -text application/hub/interfaces/connectors/.htaccess -text application/hub/interfaces/connectors/class_Connectable.php -text +application/hub/interfaces/discovery/.htaccess -text application/hub/interfaces/handler/.htaccess -text application/hub/interfaces/handler/class_Handleable.php -text application/hub/interfaces/handler/network/.htaccess -text @@ -56,6 +58,7 @@ application/hub/interfaces/states/hub/.htaccess -text application/hub/interfaces/states/hub/class_HubStateable.php -text application/hub/interfaces/states/node/.htaccess -text application/hub/interfaces/states/node/class_NodeStateable.php -text +application/hub/interfaces/tags/.htaccess -text application/hub/interfaces/tasks/.htaccess -text application/hub/interfaces/tasks/class_Taskable.php -text application/hub/interfaces/visitor/.htaccess -text @@ -107,10 +110,16 @@ application/hub/main/database/wrapper/class_NodeInformationDatabaseWrapper.php - application/hub/main/database/wrapper/class_NodeListDatabaseWrapper.php -text application/hub/main/decorators/.htaccess -text application/hub/main/decorators/class_BaseDecorator.php -text +application/hub/main/discovery/.htaccess -text +application/hub/main/discovery/package/.htaccess -text +application/hub/main/discovery/socket/.htaccess -text application/hub/main/factories/.htaccess -text +application/hub/main/factories/discovery/.htaccess -text +application/hub/main/factories/lists/.htaccess -text application/hub/main/factories/package/.htaccess -text application/hub/main/factories/states/.htaccess -text application/hub/main/factories/states/class_StateFactory.php -text +application/hub/main/factories/tags/.htaccess -text application/hub/main/filter/.htaccess -text application/hub/main/filter/activation/.htaccess -text application/hub/main/filter/activation/class_HubActivation -text @@ -206,6 +215,7 @@ application/hub/main/lists/pool/class_PoolEntriesList.php -text application/hub/main/lists/query/.htaccess -text application/hub/main/lists/query/local/.htaccess -text application/hub/main/lists/query/local/class_LocalQueryList.php -text +application/hub/main/lists/recipient/.htaccess -text application/hub/main/lists/tasks/.htaccess -text application/hub/main/lists/tasks/class_TaskList.php -text application/hub/main/nodes/.htaccess -text @@ -238,6 +248,8 @@ application/hub/main/queues/class_ -text application/hub/main/queues/class_BaseQueue.php -text application/hub/main/queues/client/.htaccess -text application/hub/main/queues/client/class_LocalClientQueue.php -text +application/hub/main/registry/.htaccess -text +application/hub/main/registry/objects/.htaccess -text application/hub/main/resolver/.htaccess -text application/hub/main/resolver/command/.htaccess -text application/hub/main/resolver/command/console/.htaccess -text @@ -267,6 +279,9 @@ application/hub/main/states/node/init/.htaccess -text application/hub/main/states/node/init/class_NodeInitState.php -text application/hub/main/states/node/virgin/.htaccess -text application/hub/main/states/node/virgin/class_NodeVirginState.php -text +application/hub/main/tags/.htaccess -text +application/hub/main/tags/class_ -text +application/hub/main/tags/package/.htaccess -text application/hub/main/tasks/.htaccess -text application/hub/main/tasks/class_ -text application/hub/main/tasks/class_BaseTask.php -text @@ -284,6 +299,7 @@ application/hub/main/tasks/network/.htaccess -text application/hub/main/template/.htaccess -text application/hub/main/template/announcement/.htaccess -text application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php -text +application/hub/main/template/objects/.htaccess -text application/hub/main/visitor/.htaccess -text application/hub/main/visitor/class_ -text application/hub/main/visitor/class_BaseVisitor.php -text @@ -304,6 +320,8 @@ application/hub/templates/xml/announcement/.htaccess -text application/hub/templates/xml/announcement/self_announcement.xml -text application/hub/templates/xml/node/.htaccess -text application/hub/templates/xml/node/node_status.xml -text +application/hub/templates/xml/object_registry/.htaccess -text +application/hub/templates/xml/object_registry/object_registry.xml -text /clear-cache.sh -text db/.htaccess -text db/news/.htaccess -text diff --git a/application/hub/class_ApplicationHelper.php b/application/hub/class_ApplicationHelper.php index 053a4b111..46343ff37 100644 --- a/application/hub/class_ApplicationHelper.php +++ b/application/hub/class_ApplicationHelper.php @@ -42,17 +42,17 @@ class ApplicationHelper extends BaseFrameworkSystem implements ManageableApplica /** * The version number of this application */ - private $appVersion = ""; + private $appVersion = ''; /** * The human-readable name for this application */ - private $appName = ""; + private $appName = ''; /** * The short uni*-like name for this application */ - private $shortName = ""; + private $shortName = ''; /** * An instance of this class diff --git a/application/hub/config.php b/application/hub/config.php index d7b5a92eb..45a0dd544 100644 --- a/application/hub/config.php +++ b/application/hub/config.php @@ -189,12 +189,27 @@ $cfg->setConfigEntry('announcement_template_extension', '.xml'); // CFG: ANNOUNCEMENT-TEMPLATE-TYPE $cfg->setConfigEntry('announcement_template_type', 'xml/announcement'); -// CFG: CODE-TEMPLATE-TYPE -$cfg->setConfigEntry('code_template_type', 'xml/announcement'); - // CFG: ANNOUNCEMENT-STACKER-CLASS $cfg->setConfigEntry('announcement_stacker_class', 'FiLoStacker'); +// CFG: OBJECT-REGISTRY-TEMPLATE-CLASS +$cfg->setConfigEntry('object_registry_template_class', 'ObjectRegistryTemplateEngine'); + +// CFG: OBJECT-REGISTRY-TEMPLATE-EXTENSION +$cfg->setConfigEntry('object_registry_template_extension', '.xml'); + +// CFG: OBJECT-REGISTRY-TEMPLATE-TYPE +$cfg->setConfigEntry('object_registry_template_type', 'xml/object_registry'); + +// CFG: OBJECT-REGISTRY-STACKER-CLASS +$cfg->setConfigEntry('object_registry_stacker_class', 'FiLoStacker'); + +// CFG: OBJECT-TYPE-REGISTRY-CLASS +$cfg->setConfigEntry('object_type_registry_class', 'ObjectTypeRegistry'); + +// CFG: CODE-TEMPLATE-TYPE +$cfg->setConfigEntry('code_template_type', 'xml/announcement'); + // CFG: PACKAGE-STACKER-CLASS $cfg->setConfigEntry('package_stacker_class', 'FiFoStacker'); @@ -204,6 +219,12 @@ $cfg->setConfigEntry('stacker_announcement_max_size', 20); // CFG: STACKER-UNDECLARED-MAX-SIZE $cfg->setConfigEntry('stacker_undeclared_max_size', 10000); +// CFG: STACKER-DECLARED-MAX-SIZE +$cfg->setConfigEntry('stacker_declared_max_size', 1000); + +// CFG: STACKER-OBJECT-REGISTRY-MAX-SIZE +$cfg->setConfigEntry('stacker_object_registry_max_size', 100); + // CFG: NEWS-MAIN-LIMIT $cfg->setConfigEntry('news_main_limit', 5); @@ -354,5 +375,17 @@ $cfg->setConfigEntry('socket_registry_class', 'SocketRegistry'); // CFG: SOCKET-CONTAINER-CLASS $cfg->setConfigEntry('socket_container_class', 'SocketContainer'); +// CFG: PACKAGE-RECIPIENT-DISCOVERY +$cfg->setConfigEntry('package_recipient_discovery_class', 'PackageRecipientDiscovery'); + +// CFG: SOCKET-DISCOVERY +$cfg->setConfigEntry('socket_discovery_class', 'PackageSocketDiscovery'); + +// CFG: RECIPIENT-LIST-CLASS +$cfg->setConfigEntry('recipient_list_class', 'RecipientList'); + +// CFG: PACKAGE-TAGS-CLASS +$cfg->setConfigEntry('package_tags_class', 'PackageTags'); + // [EOF] ?> diff --git a/application/hub/exceptions.php b/application/hub/exceptions.php index b9daf47d1..3e621fa94 100644 --- a/application/hub/exceptions.php +++ b/application/hub/exceptions.php @@ -30,21 +30,23 @@ function hub_exception_handler ($exceptionInstance) { $trace = $exceptionInstance->getTrace(); // Get 3 call levels - $backTrace = ""; + $backTrace = ''; for ($idx = 0; $idx < 3; $idx++) { // Copy array for argument analysis and init variable $traceArray = $trace[$idx]; - $argsString = ""; + $argsString = ''; // Convert arguments type into human-readable foreach ($traceArray['args'] as $arg) { - $argsString .= ", " . gettype($arg); + $argsString .= ', ' . gettype($arg); } // END - foreach $argsString = substr($argsString, 2); // Set missing file/line - if (!isset($traceArray['file'])) $traceArray['file'] = 'unknown'; - if (!isset($traceArray['line'])) $traceArray['line'] = '0'; + if (!isset($traceArray['file'])) $traceArray['file'] = 'unknown'; + if (!isset($traceArray['line'])) $traceArray['line'] = '0'; + if (!isset($traceArray['class'])) $traceArray['class'] = 'UnknownObject'; + if (!isset($traceArray['type'])) $traceArray['type'] = '->'; $backTrace .= sprintf("---------- Pos %d: ---------- Method : %s%s%s(%s) diff --git a/application/hub/exceptions/tags/.htaccess b/application/hub/exceptions/tags/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/exceptions/tags/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/exceptions/tags/class_InvalidTagException.php b/application/hub/exceptions/tags/class_InvalidTagException.php new file mode 100644 index 000000000..7b8876431 --- /dev/null +++ b/application/hub/exceptions/tags/class_InvalidTagException.php @@ -0,0 +1,45 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class InvalidTagException extends FrameworkException { + /** + * The super constructor for all exceptions + * + * @param $messageArray Error message array + * @param $code Error code + * @return void + */ + public function __construct (array $messageArray, $code) { + // Construct the message + $message = sprintf("[%s] Tag %s is invalid.", + $messageArray[0]->__toString(), + $messageArray[1] + ); + + // Call parent exception constructor + parent::__construct($message, $code); + } +} + +// [EOF] +?> diff --git a/application/hub/interfaces/discovery/.htaccess b/application/hub/interfaces/discovery/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/interfaces/discovery/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/interfaces/discovery/class_DiscoverableRecipient.php b/application/hub/interfaces/discovery/class_DiscoverableRecipient.php new file mode 100644 index 000000000..5badfb48a --- /dev/null +++ b/application/hub/interfaces/discovery/class_DiscoverableRecipient.php @@ -0,0 +1,42 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +interface DiscoverableRecipient extends FrameworkInterface { + /** + * Tries to discover all recipients for given package data + * + * @param $packageData Raw package data array + * @return void + */ + function discoverRecipients (array $packageData); + + /** + * "Getter" for recipient iterator + * + * @return $iteratorInstance An instance of a Iterateable object + */ + function getIterator (); +} + +// [EOF] +?> diff --git a/application/hub/interfaces/discovery/class_DiscoverableSocket.php b/application/hub/interfaces/discovery/class_DiscoverableSocket.php new file mode 100644 index 000000000..889f4aeb0 --- /dev/null +++ b/application/hub/interfaces/discovery/class_DiscoverableSocket.php @@ -0,0 +1,36 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +interface DiscoverableSocket extends FrameworkInterface { + /** + * Tries to discover the right socket for given package data and returns a + * matching socket resource. + * + * @param $packageData Raw package data array + * @return $socketResource A valid socket resource + */ + function discoverSocket (array $packageData); +} + +// [EOF] +?> diff --git a/application/hub/interfaces/package/class_Deliverable.php b/application/hub/interfaces/package/class_Deliverable.php index 6f2028d27..c3f75ae57 100644 --- a/application/hub/interfaces/package/class_Deliverable.php +++ b/application/hub/interfaces/package/class_Deliverable.php @@ -48,7 +48,23 @@ interface Deliverable extends FrameworkInterface { * @return void * @throws NoTargetException If no target can't be determined */ - function deliverEnqueuedPackage (); + function declareEnqueuedPackage (); + + /** + * Checks wether a package has been declared + * + * @return $isDeclared Wether a package is declared + */ + function isPackageDeclared (); + + /** + * Delivers the next declared package. Only one package per time will be sent + * because this may take time and slows down the whole delivery + * infrastructure. + * + * @return void + */ + function deliverDeclaredPackage (); } // [EOF] diff --git a/application/hub/interfaces/tags/.htaccess b/application/hub/interfaces/tags/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/interfaces/tags/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/interfaces/tags/class_Tagable.php b/application/hub/interfaces/tags/class_Tagable.php new file mode 100644 index 000000000..c00b71010 --- /dev/null +++ b/application/hub/interfaces/tags/class_Tagable.php @@ -0,0 +1,28 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +interface Tagable extends FrameworkInterface { +} + +// [EOF] +?> diff --git a/application/hub/main/class_Base b/application/hub/main/class_Base index 5e48c51be..8a2710e02 100644 --- a/application/hub/main/class_Base +++ b/application/hub/main/class_Base @@ -1,6 +1,6 @@ * @version 0.0.0 diff --git a/application/hub/main/discovery/.htaccess b/application/hub/main/discovery/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/discovery/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/discovery/package/.htaccess b/application/hub/main/discovery/package/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/discovery/package/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/discovery/package/class_PackageRecipientDiscovery.php b/application/hub/main/discovery/package/class_PackageRecipientDiscovery.php new file mode 100644 index 000000000..6cf473d2a --- /dev/null +++ b/application/hub/main/discovery/package/class_PackageRecipientDiscovery.php @@ -0,0 +1,97 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class PackageRecipientDiscovery extends BaseDiscovery implements DiscoverableRecipient, Registerable { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Create an instance of this class + * + * @return $discoveryInstance An instance of this discovery class + */ + public final static function createPackageRecipientDiscovery () { + // Get an instance of this class + $discoveryInstance = new PackageRecipientDiscovery(); + + // Output debug message + $discoveryInstance->debugOutput('RECIPIENT-DISCOVERY: Initialized.'); + + // Return the prepared instance + return $discoveryInstance; + } + + /** + * Tries to discover all recipients for given package data + * + * @param $packageData Raw package data array + * @return void + */ + public function discoverRecipients (array $packageData) { + // Get recipients list instance + $listInstance = RecipientListFactory::createRecipientListInstance(); + + // We do some rudimentary checks but this might be a bit ugly + switch ($packageData['recipient']) { + // All upper hubs, these are currently the bootstrap nodes and later on prepended list-nodes + case NetworkPackage::NETWORK_TARGET_UPPER_HUBS: + // Get all bootstrap nodes + foreach (explode(';', $this->getConfigInstance()->getConfigEntry('hub_bootstrap_nodes')) as $node) { + // Add the entry + $listInstance->addEntry('ip_port', $node); + } // END - foreach + break; + + // This may be a direct recipient (hub's session id) + default: + $this->partialStub('Please add code handling direct recipients.'); + break; + } // END - switch + } + + /** + * "Getter" for recipient iterator + * + * @return $iteratorInstance An instance of a Iterateable object + */ + public function getIterator () { + // Get list instance + $listInstance = RecipientListFactory::createRecipientListInstance(); + + // Get iterator from it + $iteratorInstance = $listInstance->getIterator(); + + // Return it + return $iteratorInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/discovery/socket/.htaccess b/application/hub/main/discovery/socket/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/discovery/socket/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/discovery/socket/class_PackageSocketDiscovery.php b/application/hub/main/discovery/socket/class_PackageSocketDiscovery.php new file mode 100644 index 000000000..8903a43e2 --- /dev/null +++ b/application/hub/main/discovery/socket/class_PackageSocketDiscovery.php @@ -0,0 +1,77 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class PackageSocketDiscovery extends BaseDiscovery implements DiscoverableSocket, Registerable { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Create an instance of this class + * + * @return $discoveryInstance An instance of this discovery class + */ + public final static function createPackageSocketDiscovery () { + // Get an instance of this class + $discoveryInstance = new PackageSocketDiscovery(); + + // Output debug message + $discoveryInstance->debugOutput('SOCKET-DISCOVERY: Initialized.'); + + // Return the prepared instance + return $discoveryInstance; + } + + /** + * Tries to discover the right socket for given package data and returns a + * matching socket resource for that protocol. + * + * @param $packageData Raw package data array + * @return $socketResource A valid socket resource + */ + public function discoverSocket (array $packageData) { + // First we need a tags instance + $tagsInstance = PackageTagsFactory::createPackageTagsInstance(); + + /* + * We need to decide here which socket (TCP or UDP) should be used for + * the actual data transmission. In this process we will find out if + * the recipient of this package has already a known (registered) socket + * and if so we can re-use it. If there is no socket registered, we try + * to make a new connection (TCP or UDP) to the given IP:port. + */ + $protocolName = $tagsInstance->chooseProtocolFromPackageData($packageData); + + // Abort here + die(__METHOD__ . ':' . $protocolName . "\n"); + } +} + +// [EOF] +?> diff --git a/application/hub/main/factories/discovery/.htaccess b/application/hub/main/factories/discovery/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/factories/discovery/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/factories/discovery/class_PackageDiscoveryFactory.php b/application/hub/main/factories/discovery/class_PackageDiscoveryFactory.php new file mode 100644 index 000000000..c9e653623 --- /dev/null +++ b/application/hub/main/factories/discovery/class_PackageDiscoveryFactory.php @@ -0,0 +1,61 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class PackageDiscoveryFactory extends ObjectFactory { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Returns a singleton network package instance. If an instance is found in + * the registry it will be returned, else a new instance is created and + * stored in the same registry entry. + * + * @return $discoveryInstance A package discovery instance + */ + public static final function createPackageDiscoveryInstance () { + // Do we have an instance in the registry? + if (Registry::getRegistry()->instanceExists('package_discovery')) { + // Then use this instance + $discoveryInstance = Registry::getRegistry()->getInstance('package_discovery'); + } else { + // Create a new instance + $discoveryInstance = ObjectFactory::createObjectByConfiguredName('package_recipient_discovery_class'); + + // Set the instance in registry for further use + Registry::getRegistry()->addInstance('package_discovery', $discoveryInstance); + } + + // Return the instance + return $discoveryInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/factories/discovery/class_SocketDiscoveryFactory.php b/application/hub/main/factories/discovery/class_SocketDiscoveryFactory.php new file mode 100644 index 000000000..1a0663fc2 --- /dev/null +++ b/application/hub/main/factories/discovery/class_SocketDiscoveryFactory.php @@ -0,0 +1,61 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class SocketDiscoveryFactory extends ObjectFactory { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Returns a singleton network socket instance. If an instance is found in + * the registry it will be returned, else a new instance is created and + * stored in the same registry entry. + * + * @return $discoveryInstance A socket discovery instance + */ + public static final function createSocketDiscoveryInstance () { + // Do we have an instance in the registry? + if (Registry::getRegistry()->instanceExists('socket_discovery')) { + // Then use this instance + $discoveryInstance = Registry::getRegistry()->getInstance('socket_discovery'); + } else { + // Create a new instance + $discoveryInstance = ObjectFactory::createObjectByConfiguredName('socket_discovery_class'); + + // Set the instance in registry for further use + Registry::getRegistry()->addInstance('socket_discovery', $discoveryInstance); + } + + // Return the instance + return $discoveryInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/factories/lists/.htaccess b/application/hub/main/factories/lists/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/factories/lists/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/factories/lists/class_RecipientListFactory.php b/application/hub/main/factories/lists/class_RecipientListFactory.php new file mode 100644 index 000000000..9b589fad2 --- /dev/null +++ b/application/hub/main/factories/lists/class_RecipientListFactory.php @@ -0,0 +1,61 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class RecipientListFactory extends ObjectFactory { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Returns a singleton network package instance. If an instance is found in + * the registry it will be returned, else a new instance is created and + * stored in the same registry entry. + * + * @return $listInstance A recipient list instance + */ + public static final function createRecipientListInstance () { + // Do we have an instance in the registry? + if (Registry::getRegistry()->instanceExists('recipient_list')) { + // Then use this instance + $listInstance = Registry::getRegistry()->getInstance('recipient_list'); + } else { + // Create a new instance + $listInstance = ObjectFactory::createObjectByConfiguredName('recipient_list_class'); + + // Set the instance in registry for further use + Registry::getRegistry()->addInstance('recipient_list', $listInstance); + } + + // Return the instance + return $listInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/factories/package/class_NetworkPackageFactory.php b/application/hub/main/factories/package/class_NetworkPackageFactory.php index 43de8df49..9d6bd30eb 100644 --- a/application/hub/main/factories/package/class_NetworkPackageFactory.php +++ b/application/hub/main/factories/package/class_NetworkPackageFactory.php @@ -22,6 +22,16 @@ * along with this program. If not, see . */ class NetworkPackageFactory extends ObjectFactory { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + /** * Returns a singleton network package instance. If an instance is found in * the registry it will be returned, else a new instance is created and @@ -56,15 +66,7 @@ class NetworkPackageFactory extends ObjectFactory { // Return the instance return $packageInstance; } - - /** - * Protected constructor - * - * @return void - */ - protected function __construct () { - // Call parent constructor - parent::__construct(__CLASS__); - } } + +// [EOF] ?> diff --git a/application/hub/main/factories/states/class_StateFactory.php b/application/hub/main/factories/states/class_StateFactory.php index c726543e7..f39e0cbf3 100644 --- a/application/hub/main/factories/states/class_StateFactory.php +++ b/application/hub/main/factories/states/class_StateFactory.php @@ -22,6 +22,16 @@ * along with this program. If not, see . */ class StateFactory extends ObjectFactory { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + /** * Creates an instance of a configurable node state and sets it in the * given node instance. @@ -43,15 +53,7 @@ class StateFactory extends ObjectFactory { // For any purposes, return the state instance return $stateInstance; } - - /** - * Protected constructor - * - * @return void - */ - protected function __construct () { - // Call parent constructor - parent::__construct(__CLASS__); - } } + +// [EOF] ?> diff --git a/application/hub/main/factories/tags/.htaccess b/application/hub/main/factories/tags/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/factories/tags/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/factories/tags/class_PackageTagsFactory.php b/application/hub/main/factories/tags/class_PackageTagsFactory.php new file mode 100644 index 000000000..4d3a80a2e --- /dev/null +++ b/application/hub/main/factories/tags/class_PackageTagsFactory.php @@ -0,0 +1,61 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class PackageTagsFactory extends ObjectFactory { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Returns a singleton network package instance. If an instance is found in + * the registry it will be returned, else a new instance is created and + * stored in the same registry entry. + * + * @return $packageInstance A network package instance + */ + public static final function createPackageTagsInstance () { + // Do we have an instance in the registry? + if (Registry::getRegistry()->instanceExists('package_tags')) { + // Then use this instance + $packageInstance = Registry::getRegistry()->getInstance('package_tags'); + } else { + // Now prepare the tags instance + $packageInstance = ObjectFactory::createObjectByConfiguredName('package_tags_class'); + + // Set the instance in registry for further use + Registry::getRegistry()->addInstance('package_tags', $packageInstance); + } + + // Return the instance + return $packageInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php b/application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php index bedded4e7..e916fbce1 100644 --- a/application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php +++ b/application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php @@ -23,6 +23,11 @@ * along with this program. If not, see . */ class HubDescriptorHelper extends BaseHubHelper { + /** + * An array with all tags for network packages + */ + private $packageTags = array('announcement'); + /** * Protected constructor * @@ -69,16 +74,15 @@ class HubDescriptorHelper extends BaseHubHelper { // Disable language support $templateInstance->enableLanguageSupport(false); - // Enable compacting/rewriting of the XML to save bandwidth from XML - // comments. This is expensive and should be avoided in general. + /* + * Enable compacting/rewriting of the XML to save bandwidth from XML + * comments. This is expensive and should be avoided in general. + */ $templateInstance->enableXmlCompacting(); // Set it for later use $this->setTemplateInstance($templateInstance); - // Get an XML parser instance - $parserInstance = ObjectFactory::createObjectByConfiguredName('xml_parser_class', array($this->getTemplateInstance())); - // Read the XML descriptor $this->getTemplateInstance()->loadAnnouncementTemplate('self_announcement'); @@ -108,6 +112,15 @@ class HubDescriptorHelper extends BaseHubHelper { // Next, feed the content in. The network package class is a pipe-through class. $packageInstance->enqueueRawDataFromTemplate($this); } + + /** + * Getter for package tags in a simple array + * + * @return $tags An array with all tags for the currently handled package + */ + public final function getPackageTags () { + return $this->packageTags; + } } // [EOF] diff --git a/application/hub/main/helper/hub/class_ b/application/hub/main/helper/hub/class_ index 4ddf295bf..845c5a996 100644 --- a/application/hub/main/helper/hub/class_ +++ b/application/hub/main/helper/hub/class_ @@ -45,6 +45,12 @@ class Hub???Helper extends BaseHubHelper { // Return the prepared instance return $helperInstance; } + + /** + * "Getter" for package tags in a simple array + * + * @return $tags An array with all tags for the currently handled package + */ } // [EOF] diff --git a/application/hub/main/listener/tcp/class_TcpListener.php b/application/hub/main/listener/tcp/class_TcpListener.php index 2e9a54bb3..1149a734b 100644 --- a/application/hub/main/listener/tcp/class_TcpListener.php +++ b/application/hub/main/listener/tcp/class_TcpListener.php @@ -58,7 +58,7 @@ class TcpListener extends BaseListener implements Listenable { * @return void * @throws InvalidSocketException Thrown if the socket could not be initialized */ - public function initListener() { + public function initListener () { // Create a streaming socket, of type TCP/IP $mainSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); diff --git a/application/hub/main/listener/udp/class_UdpListener.php b/application/hub/main/listener/udp/class_UdpListener.php index 6b806ff9d..1f34a8b1a 100644 --- a/application/hub/main/listener/udp/class_UdpListener.php +++ b/application/hub/main/listener/udp/class_UdpListener.php @@ -58,22 +58,54 @@ class UdpListener extends BaseListener implements Listenable { * @return void * @throws InvalidSocketException Thrown if the socket is invalid or an * error was detected. - * @todo stream_socket_server() was declared slow by some user comments. - * @todo Please rewrite it to socket_create() and its brothers. */ - public function initListener() { + public function initListener () { // Try to open a UDP socket - $socket = stream_socket_server('udp://' . $this->getListenAddress() . ':' . $this->getListenPort(), $errno, $errstr, STREAM_SERVER_BIND); + $mainSocket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); // Is the socket a valid resource or do we have any error? - if ((!is_resource($socket)) || ($errno > 0)) { + if (!is_resource($mainSocket)) { // Then throw an InvalidSocketException - throw new InvalidSocketException(array($this, gettype($socket), $errno, $errstr), BaseListener::EXCEPTION_INVALID_SOCKET); + throw new InvalidSocketException(array($this, gettype($mainSocket), $errno, $errstr), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // Set the option to reuse the port + $this->debugOutput('LISTENER: Setting re-use address option.'); + if (!socket_set_option($mainSocket, SOL_SOCKET, SO_REUSEADDR, 1)) { + // Get socket error code for verification + $socketError = socket_last_error($mainSocket); + + // Get error message + $errorMessage = socket_strerror($socketError); + + // Shutdown this socket + $this->shutdownSocket($mainSocket); + + // And throw again + throw new InvalidSocketException(array($this, gettype($mainSocket), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); + } // END - if + + // "Bind" the socket to the given address, on given port so this means + // that all connections on this port are now our resposibility to + // send/recv data, disconnect, etc.. + $this->debugOutput('LISTENER: Binding to address ' . $this->getListenAddress() . ':' . $this->getListenPort()); + if (!socket_bind($mainSocket, $this->getListenAddress(), $this->getListenPort())) { + // Get socket error code for verification + $socketError = socket_last_error($mainSocket); + + // Get error message + $errorMessage = socket_strerror($socketError); + + // Shutdown this socket + $this->shutdownSocket($mainSocket); + + // And throw again + throw new InvalidSocketException(array($this, gettype($mainSocket), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); } // END - if // Now, we want non-blocking mode $this->debugOutput('LISTENER: Setting non-blocking mode.'); - if (!stream_set_blocking($socket, false)) { + if (!socket_set_nonblock($mainSocket)) { // Get socket error code for verification $socketError = socket_last_error($socket); @@ -81,14 +113,14 @@ class UdpListener extends BaseListener implements Listenable { $errorMessage = socket_strerror($socketError); // Shutdown this socket - $this->shutdownSocket($socket); + $this->shutdownSocket($mainSocket); // And throw again - throw new InvalidSocketException(array($this, gettype($socket), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); + throw new InvalidSocketException(array($this, gettype($mainSocket), $socketError, $errorMessage), BaseListener::EXCEPTION_INVALID_SOCKET); } // END - if // Remember the socket in our class - $this->registerServerSocketResource($socket); + $this->registerServerSocketResource($mainSocket); // Output message $this->debugOutput('LISTENER: UDP listener now ready on IP ' . $this->getListenAddress() . ', port ' . $this->getListenPort() . ' for service.'); @@ -102,16 +134,36 @@ class UdpListener extends BaseListener implements Listenable { */ public function doListen() { // Read a package and determine the client - $pkt = trim(stream_socket_recvfrom($this->getSocketResource(), 1500, 0, $peer)); + $amount = @socket_recvfrom($this->getSocketResource(), $pkt, 1500, 0, $peer, $port); + + // Get last error + $lastError = socket_last_error($this->getSocketResource()); + + // Do we have an error at the line? + if ($lastError == 11) { + /* + * This (resource temporary unavailable) can be safely ignored on + * "listening" UDP ports. If we don't clear the error here, our UDP + * "listener" won't read any packages except if the UDP sender + * starts the transmission before this "listener came up... + */ + socket_clear_error($this->getSocketResource()); + + // Skip further processing + return; + } elseif ($lastError > 0) { + // Other error detected + $this->debugOutput('LISTENER: Error detected: ' . socket_strerror($lastError)); - // Zero sized packages/peer names are usual in non-blocking mode - if ((empty($pkt)) || (trim($peer) == '')) { - // Skip here + // Skip further processing + return; + } elseif ((empty($pkt)) || (trim($peer) == '')) { + // Zero sized packages/peer names are usual in non-blocking mode return; } // END - if // Debug only - $this->debugOutput('LISTENER: Handling UDP package with size ' . strlen($pkt) . ' from peer ' . $peer); + $this->debugOutput('LISTENER: Handling UDP package with size ' . strlen($pkt) . ' from peer ' . $peer . ':' . $port); } } diff --git a/application/hub/main/lists/recipient/.htaccess b/application/hub/main/lists/recipient/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/lists/recipient/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/lists/recipient/class_RecipientList.php b/application/hub/main/lists/recipient/class_RecipientList.php new file mode 100644 index 000000000..f5d3b4f98 --- /dev/null +++ b/application/hub/main/lists/recipient/class_RecipientList.php @@ -0,0 +1,57 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class RecipientList extends BaseList implements Listable, Registerable { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates an instance of this class + * + * @return $listInstance An instance a Listable class + */ + public final static function createRecipientList () { + // Get new instance + $listInstance = new RecipientList(); + + // Add groups: + // 1.) ip:port combinations + $listInstance->addGroup('ip_port'); + + // 2.) Session ids + $listInstance->addGroup('session_id'); + + // Return the prepared instance + return $listInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/package/class_NetworkPackage.php b/application/hub/main/package/class_NetworkPackage.php index 4f86f8840..f009ef73b 100644 --- a/application/hub/main/package/class_NetworkPackage.php +++ b/application/hub/main/package/class_NetworkPackage.php @@ -36,15 +36,42 @@ */ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registerable { /** - * Package mask for compressing package data + * Package mask for compressing package data: + * 1.) Compressor extension + * 2.) Raw package data + * 3.) Tags, seperated by semicolons, no semicolon is required if only one tag is needed + * 4.) Checksum */ - const PACKAGE_MASK = '%s:%s:%s'; + const PACKAGE_MASK = '%s:%s:%s:%s'; + + /** + * Seperator for the above mask + */ + const PACKAGE_MASK_SEPERATOR = ':'; + + /** + * Array indexes for above mask, start with zero + */ + const INDEX_COMPRESSOR_EXTENSION = 0; + const INDEX_PACKAGE_DATA = 1; + const INDEX_TAGS = 2; + const INDEX_CHECKSUM = 3; + + /** + * Tags seperator + */ + const PACKAGE_TAGS_SEPERATOR = ';'; /** * Stacker name for "undeclared" packages */ const STACKER_NAME_UNDECLARED = 'undeclared'; + /** + * Stacker name for "declared" packages (which are ready to send out) + */ + const STACKER_NAME_DECLARED = 'declared'; + /** * Network target (alias): 'upper hubs' */ @@ -77,16 +104,104 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe // Get new instance $packageInstance = new NetworkPackage(); - // Now set the compressor instance if set - if ($compressorInstance instanceof Compressor) { - // Okay, set it - $packageInstance->setCompressorInstance($compressorInstance); - } // END - if + // Now set the compressor instance + $packageInstance->setCompressorInstance($compressorInstance); // Return the prepared instance return $packageInstance; } + /** + * "Getter" for hash from given content and helper instance + * + * @param $content Raw package content + * @param $helperInstance A BaseHubHelper instance + * @return $hash Hash for given package content + */ + private function getHashFromContent ($content, BaseHubHelper $helperInstance) { + // Create the hash + // @TODO crc32 is not good, but it needs to be fast + $hash = crc32( + $content . + ':' . + $helperInstance->getNodeInstance()->getSessionId() . + ':' . + $this->getCompressorInstance()->getCompressorExtension() + ); + + // And return it + return $hash; + } + + /** + * Delivers the given raw package data. + * + * @param $packageData Raw package data in an array + * @return void + */ + private function deliverPackage (array $packageData) { + /* + * We need to disover every recipient, just in case we have a + * multi-recipient entry like 'upper' is. 'all' may be a not so good + * target because it causes an overload on the network and may be + * abused for attacking the network with large packages. + */ + $discoveryInstance = PackageDiscoveryFactory::createPackageDiscoveryInstance(); + + // Discover all recipients, this may throw an exception + $discoveryInstance->discoverRecipients($packageData); + + // Now get an iterator + $iteratorInstance = $discoveryInstance->getIterator(); + + // ... and begin iteration + while ($iteratorInstance->valid()) { + // Get current entry + $currentRecipient = $iteratorInstance->current(); + + // Debug message + $this->debugOutput('PACKAGE: Package declared for recipient ' . $currentRecipient); + + // Set the recipient + $packageData['recipient'] = $currentRecipient; + + // And enqueue it to the writer class + $this->getStackerInstance()->pushNamed(self::STACKER_NAME_DECLARED, $packageData); + + // Skip to next entry + $iteratorInstance->next(); + } // END - while + + // Clean-up the list + $discoveryInstance->clearRecipients(); + } + + /** + * Sends a raw package out + * + * @param $packageData Raw package data in an array + * @return void + */ + private function sendRawPackage (array $packageData) { + /* + * This package may become big, depending on the shared object size or + * delivered message size which shouldn't be so long (to save + * bandwidth). Because of the nature of the used protocol (TCP) we need + * to split it up into smaller pieces to fit it into a TCP frame. + * + * So first we need (again) a discovery class but now a protocol + * discovery to choose the right socket resource. The discovery class + * should take a look at the raw package data itself and then decide + * which (configurable!) protocol should be used for that type of + * package. + */ + $discoveryInstance = SocketDiscoveryFactory::createSocketDiscoveryInstance(); + + // Now discover the right protocol + $socketResource = $discoveryInstance->discoverSocket($packageData); + die($socketResource); + } + /** * "Enqueues" raw content into this delivery class by reading the raw content * from given template instance and pushing it on the 'undeclared' stack. @@ -103,9 +218,14 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe // Add magic in front of it and hash behind it, including BASE64 encoding $content = sprintf(self::PACKAGE_MASK, + // 1.) Compressor's extension $this->getCompressorInstance()->getCompressorExtension(), + // 2.) Raw package content, encoded with BASE64 base64_encode($content), - crc32($content) // @TODO Not so good, but needs to be fast! + // 3.) Tags + implode(self::PACKAGE_TAGS_SEPERATOR, $helperInstance->getPackageTags()), + // 4.) Checksum + $this->getHashFromContent($content, $helperInstance) ); // Now prepare the temporary array and push it on the 'undeclared' stack @@ -129,6 +249,19 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe return $isEnqueued; } + /** + * Checks wether a package has been declared + * + * @return $isDeclared Wether a package is declared + */ + public function isPackageDeclared () { + // Check wether the stacker is not empty + $isDeclared = (($this->getStackerInstance()->isStackInitialized(self::STACKER_NAME_DECLARED)) && (!$this->getStackerInstance()->isStackEmpty(self::STACKER_NAME_DECLARED))); + + // Return the result + return $isDeclared; + } + /** * Delivers an enqueued package to the stated destination. If a non-session * id is provided, recipient resolver is being asked (and instanced once). @@ -139,7 +272,7 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe * @return void * @throws NoTargetException If no target can't be determined */ - public function deliverEnqueuedPackage () { + public function declareEnqueuedPackage () { // Make sure this method isn't working if there is no package enqueued if (!$this->isPackageEnqueued()) { // This is not fatal but should be avoided @@ -157,6 +290,31 @@ class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registe // And remove it finally $this->getStackerInstance()->popNamed(self::STACKER_NAME_UNDECLARED); } + + /** + * Delivers the next declared package. Only one package per time will be sent + * because this may take time and slows down the whole delivery + * infrastructure. + * + * @return void + */ + public function deliverDeclaredPackage () { + // Sanity check if we have packages declared + if (!$this->isPackageDeclared()) { + // This is not fatal but should be avoided + // @TODO Add some logging here + return; + } // END - if + + // Get the package again + $packageData = $this->getStackerInstance()->getNamed(self::STACKER_NAME_DECLARED); + + // And send it + $this->sendRawPackage($packageData); + + // And remove it finally + $this->getStackerInstance()->popNamed(self::STACKER_NAME_DECLARED); + } } // [EOF] diff --git a/application/hub/main/registry/.htaccess b/application/hub/main/registry/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/registry/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/registry/objects/.htaccess b/application/hub/main/registry/objects/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/registry/objects/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/registry/objects/class_ObjectTypeRegistry.php b/application/hub/main/registry/objects/class_ObjectTypeRegistry.php new file mode 100644 index 000000000..0f8c0e1ad --- /dev/null +++ b/application/hub/main/registry/objects/class_ObjectTypeRegistry.php @@ -0,0 +1,71 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class ObjectTypeRegistry extends BaseRegistry implements Register { + /** + * Instance of this class + */ + private static $registryInstance = null; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Singleton method, we really only need one instance of this class. + * + * @return $registryInstance Instance of this class + */ + public final static function createObjectTypeRegistry () { + // Is an instance there? + if (is_null(self::$registryInstance)) { + // Not yet, so create one + self::$registryInstance = new ObjectTypeRegistry(); + } // END - if + + // Return the instance + return self::$registryInstance; + } + + /** + * Getter for iterator instance from this registry + * + * @return $iteratorInstance An instance of a Iterator class + */ + public function getIterator () { + // Prepare a default iterator + $iteratorInstance = ObjectFactory::createObjectByConfiguredName('object_type_iterator_class', array($this)); + + // And return it + return $iteratorInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/tags/.htaccess b/application/hub/main/tags/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/tags/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/tags/class_ b/application/hub/main/tags/class_ new file mode 100644 index 000000000..0c8ff2563 --- /dev/null +++ b/application/hub/main/tags/class_ @@ -0,0 +1,50 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class ???Tags extends BaseTags implements Tagable { + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + } + + /** + * Creates an instance of this class + * + * @return $tagsInstance An instance of a Tagable class + */ + public final static function create???Tags () { + // Get new instance + $tagsInstance = new ???Tags(); + + // Return the prepared instance + return $tagsInstance; + } +} + +// [EOF] +?> diff --git a/application/hub/main/tags/class_BaseTags.php b/application/hub/main/tags/class_BaseTags.php new file mode 100644 index 000000000..12e67708f --- /dev/null +++ b/application/hub/main/tags/class_BaseTags.php @@ -0,0 +1,62 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class BaseTags extends BaseHubSystem implements Registerable { + /** + * An array with all tags + */ + private $tags = array(); + + /** + * Protected constructor + * + * @param $className Name of the class + * @return void + */ + protected function __construct ($className) { + // Call parent constructor + parent::__construct($className); + } + + /** + * Setter for whole tags array + * + * @param $tags A new simple array with tags + * @return void + */ + protected final function setTags (array $tags) { + $this->tags = $tags; + } + + /** + * Getter for whole tags array + * + * @return $tags A new simple array with tags + */ + protected final function getTags () { + return $this->tags; + } +} + +// [EOF] +?> diff --git a/application/hub/main/tags/package/.htaccess b/application/hub/main/tags/package/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/tags/package/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/tags/package/class_PackageTags.php b/application/hub/main/tags/package/class_PackageTags.php new file mode 100644 index 000000000..a8fd09a25 --- /dev/null +++ b/application/hub/main/tags/package/class_PackageTags.php @@ -0,0 +1,164 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class PackageTags extends BaseTags implements Tagable { + // Exception codes + const EXCEPTION_INVALID_TAG = 0x160; + + /** + * Last found protocol + */ + private $lastProtocol = 'invalid'; + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + + // Init the object registry + $this->initObjectRegistry(); + } + + /** + * Creates an instance of this class + * + * @return $tagsInstance An instance of a Tagable class + */ + public final static function createPackageTags () { + // Get new instance + $tagsInstance = new PackageTags(); + + // Return the prepared instance + return $tagsInstance; + } + + /** + * Loads the XML file (our "object registry") and saves an instance for faster re-use + * + * @return void + */ + private function initObjectRegistry () { + // Output debug message + $this->debugOutput('TAGS: Initializing object registry - START'); + + // Get the application instance + $appInstance = Registry::getRegistry()->getInstance('app'); + + // Get a XML template instance + $templateInstance = ObjectFactory::createObjectByConfiguredName('object_registry_template_class', array($appInstance)); + + // Disable language support + $templateInstance->enableLanguageSupport(false); + + /* + * Enable compacting/rewriting of the XML to save bandwidth from XML + * comments. This is expensive and should be avoided in general. + */ + $templateInstance->enableXmlCompacting(); + + // Set it for later use + $this->setTemplateInstance($templateInstance); + + // Read the XML file + $this->getTemplateInstance()->loadObjectRegistryTemplate('object_registry'); + + // Render the XML content + $this->getTemplateInstance()->renderXmlContent(); + + // Output debug message + $this->debugOutput('TAGS: Initializing object registry - FINISHED'); + } + + /** + * Extracts the tags from given package data + * + * @param $packageData Raw package data + * @return void + */ + private function extractTagsFromPackageData (array $packageData) { + /* + * We take a look at the tags (in most cases only one is needed) so + * first we need the content data splitted up into all it's parts. + */ + $contentData = explode(NetworkPackage::PACKAGE_MASK_SEPERATOR, $packageData['content']); + + // Get the tags and store them locally + $this->setTags(explode(NetworkPackage::PACKAGE_TAGS_SEPERATOR, $contentData[NetworkPackage::INDEX_TAGS])); + } + + /** + * Verifies all tags by looking them up in an XML file. This method is + * the key method to make sure only known objects are being distributed and + * shared over the whole hub-network. So if the "tag" (let's better say + * object type) isn't found in that XML the package won't be distributed. + * + * @return void + * @throws InvalidTagException If a provided tag from the package data is invalid + */ + private function verifyAllTags () { + // Get the registry + $objectRegistryInstance = ObjectFactory::createObjectByConfiguredName('object_type_registry_class'); + + // "Walk" over all tags + foreach ($this->getTags() as $tag) { + // Get an array from this tag + $entry = $objectRegistryInstance->getArrayFromKey($tag); + + // If the array is empty, the entry is invalid! + if (count($entry) == 0) { + // Invalid entry found + throw new InvalidTagException(array($this, $tag), self::EXCEPTION_INVALID_TAG); + } // END - if + + // Now save the last discovered protocol + $this->lastProtocol = $entry['object-protocol']; + } // END - foreach + } + + /** + * Chooses the right protocol from given package data + * + * @param $packageData Raw package data + * @return $protocolName Name of the choosen procotol + */ + public function chooseProtocolFromPackageData (array $packageData) { + // Extract the tags + $this->extractTagsFromPackageData($packageData); + + // Now we need to verify every single tag + $this->verifyAllTags(); + + // Use the last found protocol for transmission + $protocolName = $this->lastProtocol; + + // Return it + return $protocolName; + } +} + +// [EOF] +?> diff --git a/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php b/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php index ae454ed25..9ff649d31 100644 --- a/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php +++ b/application/hub/main/tasks/network/class_NetworkPackageWriterTask.php @@ -67,9 +67,12 @@ class NetworkPackageWriterTask extends BaseTask implements Taskable, Visitable { // Do we have something to deliver? if ($packageInstance->isPackageEnqueued()) { - // Okay, then deliver this package - $packageInstance->deliverEnqueuedPackage(); - } // END - if + // Okay, then deliver (better discover its recipients) this package + $packageInstance->declareEnqueuedPackage(); + } elseif ($packageInstance->isPackageDeclared()) { + // Finally deliver a package + $packageInstance->deliverDeclaredPackage(); + } } } diff --git a/application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php b/application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php index 78eb61c47..76c399b64 100644 --- a/application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php +++ b/application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php @@ -1,6 +1,6 @@ * @version 0.0.0 @@ -104,9 +104,6 @@ class AnnouncementTemplateEngine extends BaseTemplateEngine implements Compileab throw new BasePathReadProtectedException(array($templateInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH); } - // Get configuration instance - $configInstance = FrameworkConfiguration::getInstance(); - // Set the base path $templateInstance->setTemplateBasePath($templateBasePath); @@ -115,11 +112,11 @@ class AnnouncementTemplateEngine extends BaseTemplateEngine implements Compileab $templateInstance->setFileIoInstance($ioInstance); // Set template extensions - $templateInstance->setRawTemplateExtension($configInstance->getConfigEntry('raw_template_extension')); - $templateInstance->setCodeTemplateExtension($configInstance->getConfigEntry('announcement_template_extension')); + $templateInstance->setRawTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('raw_template_extension')); + $templateInstance->setCodeTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('announcement_template_extension')); // Absolute output path for compiled templates - $templateInstance->setCompileOutputPath($configInstance->getConfigEntry('base_path') . $configInstance->getConfigEntry('compile_output_path')); + $templateInstance->setCompileOutputPath($templateInstance->getConfigInstance()->getConfigEntry('base_path') . $templateInstance->getConfigInstance()->getConfigEntry('compile_output_path')); // Init a variable stacker $stackerInstance = ObjectFactory::createObjectByConfiguredName('announcement_stacker_class'); @@ -194,7 +191,7 @@ class AnnouncementTemplateEngine extends BaseTemplateEngine implements Compileab */ public function startElement ($resource, $element, array $attributes) { // Initial method name which will never be called... - $methodName = 'initMenu'; + $methodName = 'initAnnouncement'; // Make the element name lower-case $element = strtolower($element); @@ -210,7 +207,7 @@ class AnnouncementTemplateEngine extends BaseTemplateEngine implements Compileab } elseif (in_array($element, $this->getSubNodes())) { // Sub node found $methodName = 'start' . $this->convertToClassName($element); - } elseif ($element != 'menu') { + } else { // Invalid node name found throw new InvalidXmlNodeException(array($this, $element, $attributes), XmlParser::EXCEPTION_XML_NODE_UNKNOWN); } @@ -300,21 +297,7 @@ class AnnouncementTemplateEngine extends BaseTemplateEngine implements Compileab * @return $fqfn Full-qualified file name of the menu cache */ public function getMenuCacheFqfn () { - // Get the FQFN ready - $fqfn = sprintf("%s%s%s/%s.%s", - $this->getConfigInstance()->getConfigEntry('base_path'), - $this->getGenericBasePath(), - 'menus/_cache', - md5( - $this->getMenuInstance()->getMenuName() . ':' . - $this->__toString() . ':' . - $this->getMenuInstance()->__toString() - ), - $this->getMenuInstance()->getMenuType() - ); - - // Return it - return $fqfn; + $this->partialStub('Please implement this method.'); } /** diff --git a/application/hub/main/template/objects/.htaccess b/application/hub/main/template/objects/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/main/template/objects/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/main/template/objects/class_ObjectRegistryTemplateEngine.php b/application/hub/main/template/objects/class_ObjectRegistryTemplateEngine.php new file mode 100644 index 000000000..01217b339 --- /dev/null +++ b/application/hub/main/template/objects/class_ObjectRegistryTemplateEngine.php @@ -0,0 +1,456 @@ + + * @version 0.0.0 + * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Core Developer Team + * @license GNU GPL 3.0 or any newer version + * @link http://www.ship-simu.org + * @todo This template engine does not make use of setTemplateType() + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class ObjectRegistryTemplateEngine extends BaseTemplateEngine implements CompileableTemplate { + /** + * Instance for the object registry + */ + private $objectRegistryInstance = null; + + /** + * Main nodes in the XML tree ('menu' is ignored) + */ + private $mainNodes = array( + 'object-registry' + ); + + /** + * Sub nodes in the XML tree + */ + private $subNodes = array( + 'object-list', + 'object-list-entry', + 'object-name', + 'object-recipient-limitation', + 'object-max-spread', + 'object-protocol' + ); + + /** + * Current main node + */ + private $curr = array(); + + /** + * Content from dependency + */ + private $dependencyContent = array(); + + /** + * Protected constructor + * + * @return void + */ + protected function __construct () { + // Call parent constructor + parent::__construct(__CLASS__); + + // Init object type registry instance + $this->objectRegistryInstance = ObjectFactory::createObjectByConfiguredName('object_type_registry_class'); + } + + /** + * Creates an instance of the class TemplateEngine and prepares it for usage + * + * @param $appInstance A manageable application + * @return $templateInstance An instance of TemplateEngine + * @throws BasePathIsEmptyException If the provided $templateBasePath is empty + * @throws InvalidBasePathStringException If $templateBasePath is no string + * @throws BasePathIsNoDirectoryException If $templateBasePath is no + * directory or not found + * @throws BasePathReadProtectedException If $templateBasePath is + * read-protected + */ + public final static function createObjectRegistryTemplateEngine (ManageableApplication $appInstance) { + // Get a new instance + $templateInstance = new ObjectRegistryTemplateEngine(); + + // Get language and file I/O instances from application + $langInstance = $appInstance->getLanguageInstance(); + $ioInstance = $appInstance->getFileIoInstance(); + + // Determine base path + $templateBasePath = $templateInstance->getConfigInstance()->getConfigEntry('application_base_path') . $appInstance->getRequestInstance()->getRequestElement('app') . '/'; + + // Is the base path valid? + if (empty($templateBasePath)) { + // Base path is empty + throw new BasePathIsEmptyException($templateInstance, self::EXCEPTION_UNEXPECTED_EMPTY_STRING); + } elseif (!is_string($templateBasePath)) { + // Is not a string + throw new InvalidBasePathStringException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_STRING); + } elseif (!is_dir($templateBasePath)) { + // Is not a path + throw new BasePathIsNoDirectoryException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_PATH_NAME); + } elseif (!is_readable($templateBasePath)) { + // Is not readable + throw new BasePathReadProtectedException(array($templateInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH); + } + + // Set the base path + $templateInstance->setTemplateBasePath($templateBasePath); + + // Set the language and IO instances + $templateInstance->setLanguageInstance($langInstance); + $templateInstance->setFileIoInstance($ioInstance); + + // Set template extensions + $templateInstance->setRawTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('raw_template_extension')); + $templateInstance->setCodeTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('object_registry_template_extension')); + + // Absolute output path for compiled templates + $templateInstance->setCompileOutputPath($templateInstance->getConfigInstance()->getConfigEntry('base_path') . $templateInstance->getConfigInstance()->getConfigEntry('compile_output_path')); + + // Init a variable stacker + $stackerInstance = ObjectFactory::createObjectByConfiguredName('object_registry_stacker_class'); + + // Set it + $templateInstance->setStackerInstance($stackerInstance); + + // Return the prepared instance + return $templateInstance; + } + + /** + * Load a specified object_registry template into the engine + * + * @param $template The object_registry template we shall load which is + * located in 'object_registry' by default + * @return void + */ + public function loadObjectRegistryTemplate ($template) { + // Set template type + $this->setTemplateType($this->getConfigInstance()->getConfigEntry('object_registry_template_type')); + + // Load the special template + $this->loadTemplate($template); + } + + /** + * Getter for current main node + * + * @return $currMainNode Current main node + */ + public final function getCurrMainNode () { + return $this->curr['main_node']; + } + + /** + * Setter for current main node + * + * @param $element Element name to set as current main node + * @return $currMainNode Current main node + */ + private final function setCurrMainNode ($element) { + $this->curr['main_node'] = (string) $element; + } + + /** + * Getter for main node array + * + * @return $mainNodes Array with valid main node names + */ + public final function getMainNodes () { + return $this->mainNodes; + } + + /** + * Getter for sub node array + * + * @return $subNodes Array with valid sub node names + */ + public final function getSubNodes () { + return $this->subNodes; + } + + /** + * Handles the start element of an XML resource + * + * @param $resource XML parser resource (currently ignored) + * @param $element The element we shall handle + * @param $attributes All attributes + * @return void + * @throws InvalidXmlNodeException If an unknown/invalid XML node name was found + */ + public function startElement ($resource, $element, array $attributes) { + // Initial method name which will never be called... + $methodName = 'initObjectRegistry'; + + // Make the element name lower-case + $element = strtolower($element); + + // Is the element a main node? + //* DEBUG: */ echo "START: >".$element."<
\n"; + if (in_array($element, $this->getMainNodes())) { + // Okay, main node found! + $methodName = 'start' . $this->convertToClassName($element); + + // Set it + $this->setCurrMainNode($element); + } elseif (in_array($element, $this->getSubNodes())) { + // Sub node found + $methodName = 'start' . $this->convertToClassName($element); + } else { + // Invalid node name found + throw new InvalidXmlNodeException(array($this, $element, $attributes), XmlParser::EXCEPTION_XML_NODE_UNKNOWN); + } + + // Call method + call_user_func_array(array($this, $methodName), $attributes); + } + + /** + * Ends the main or sub node by sending out the gathered data + * + * @param $resource An XML resource pointer (currently ignored) + * @param $nodeName Name of the node we want to finish + * @return void + * @throws XmlNodeMismatchException If current main node mismatches the closing one + */ + public function endElement ($resource, $nodeName) { + // Make all lower-case + $nodeName = strtolower($nodeName); + + // Does this match with current main node? + //* DEBUG: */ echo "END: >".$nodeName."<
\n"; + if (($nodeName != $this->getCurrMainNode()) && (in_array($nodeName, $this->getMainNodes()))) { + // Did not match! + throw new XmlNodeMismatchException (array($this, $nodeName, $this->getCurrMainNode()), XmlParser::EXCEPTION_XML_NODE_MISMATCH); + } // END - if + + // Construct method name + $methodName = 'finish' . $this->convertToClassName($nodeName); + + // Call the corresponding method + //* DEBUG: */ echo "call: ".$methodName."
\n"; + call_user_func_array(array($this, $methodName), array()); + } + + /** + * Currently not used + * + * @param $resource XML parser resource (currently ignored) + * @param $characters Characters to handle + * @return void + * @todo Find something useful with this! + */ + public function characterHandler ($resource, $characters) { + // Trim all spaces away + $characters = trim($characters); + + // Is this string empty? + if (empty($characters)) { + // Then skip it silently + return false; + } // END - if + + // Get current XML node name as an array index + $nodeName = $this->getStackerInstance()->getNamed('object_registry'); + + // Is the node name 'object-name'? + if ($nodeName == 'object-name') { + // Output debug message + $this->debugOutput('TAGS: Adding object type ' . $characters . ' to registry.'); + } // END - if + + // Add it to the registry + $this->objectRegistryInstance->addEntry($nodeName, $characters); + } + + /** + * Handles the template dependency for given node + * + * @param $node The node we should load a dependency template + * @param $templateDependency A template to load to satisfy dependencies + * @return void + */ + private function handleTemplateDependency ($node, $templateDependency) { + // Is the template dependency set? + if ((!empty($templateDependency)) && (!isset($this->dependencyContent[$node]))) { + // Get a temporay menu template instance + $templateInstance = ObjectFactory::createObjectByConfiguredName('object_registry_template_class', array($this->getApplicationInstance())); + + // Then load it + $templateInstance->loadObjectRegistryTemplate($templateDependency); + + // Get an XmlParser instance + $templateInstance->renderXmlContent(); + + // Parse the template's content contents + $this->dependencyContent[$node] = $templateInstance->getRawTemplateData(); + } // END - if + } + + /** + * Getter for cache file (FQFN) + * + * @return $fqfn Full-qualified file name of the menu cache + */ + public function getObjectRegistryCacheFqfn () { + $this->partialStub('Please implement this method.'); + } + + /** + * Starts the object-registry + * + * @return void + */ + private function startObjectRegistry () { + // Push the node name on the stacker + $this->getStackerInstance()->pushNamed('object_registry', 'object-registry'); + } + + /** + * Starts the object-list + * + * @return void + */ + private function startObjectList () { + // Push the node name on the stacker + $this->getStackerInstance()->pushNamed('object_registry', 'object-list'); + } + + /** + * Starts the object-list-entry + * + * @return void + */ + private function startObjectListEntry () { + // Push the node name on the stacker + $this->getStackerInstance()->pushNamed('object_registry', 'object-list'); + } + + /** + * Starts the object-name + * + * @return void + */ + private function startObjectName () { + // Push the node name on the stacker + $this->getStackerInstance()->pushNamed('object_registry', 'object-name'); + } + + /** + * Starts the object-recipient-limitation + * + * @return void + */ + private function startObjectRecipientLimitation () { + // Push the node name on the stacker + $this->getStackerInstance()->pushNamed('object_registry', 'object-recipient-limitation'); + } + + /** + * Starts the object-max-spread + * + * @return void + */ + private function startObjectMaxSpread () { + // Push the node name on the stacker + $this->getStackerInstance()->pushNamed('object_registry', 'object-max-spread'); + } + + /** + * Starts the object-protocol + * + * @return void + */ + private function startObjectProtocol () { + // Push the node name on the stacker + $this->getStackerInstance()->pushNamed('object_registry', 'object-protocol'); + } + + /** + * Finishes the object-protocol + * + * @return void + */ + private function finishObjectProtocol () { + // Pop the last entry + $this->getStackerInstance()->popNamed('object_registry'); + } + + /** + * Finishes the object-max-spread + * + * @return void + */ + private function finishObjectMaxSpread () { + // Pop the last entry + $this->getStackerInstance()->popNamed('object_registry'); + } + + /** + * Finishes the object-recipient-limitation + * + * @return void + */ + private function finishObjectRecipientLimitation () { + // Pop the last entry + $this->getStackerInstance()->popNamed('object_registry'); + } + + /** + * Finishes the object-name + * + * @return void + */ + private function finishObjectName () { + // Pop the last entry + $this->getStackerInstance()->popNamed('object_registry'); + } + + /** + * Finishes the object-list-entry + * + * @return void + */ + private function finishObjectListEntry () { + // Pop the last entry + $this->getStackerInstance()->popNamed('object_registry'); + } + + /** + * Finishes the object-list + * + * @return void + */ + private function finishObjectList () { + // Pop the last entry + $this->getStackerInstance()->popNamed('object_registry'); + } + + /** + * Finishes the object-registry + * + * @return void + */ + private function finishObjectRegistry () { + // Pop the last entry + $this->getStackerInstance()->popNamed('object_registry'); + } +} + +// [EOF] +?> diff --git a/application/hub/templates/xml/announcement/self_announcement.xml b/application/hub/templates/xml/announcement/self_announcement.xml index 8d740d1b7..264f54d2c 100644 --- a/application/hub/templates/xml/announcement/self_announcement.xml +++ b/application/hub/templates/xml/announcement/self_announcement.xml @@ -44,8 +44,5 @@ along with this program. If not, see {?session_id?} - - - diff --git a/application/hub/templates/xml/object_registry/.htaccess b/application/hub/templates/xml/object_registry/.htaccess new file mode 100644 index 000000000..3a4288278 --- /dev/null +++ b/application/hub/templates/xml/object_registry/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/application/hub/templates/xml/object_registry/object_registry.xml b/application/hub/templates/xml/object_registry/object_registry.xml new file mode 100644 index 000000000..6c0b7d9d9 --- /dev/null +++ b/application/hub/templates/xml/object_registry/object_registry.xml @@ -0,0 +1,61 @@ + + + + + + + + + announcement + + upper + + 1 + + tcp + + + diff --git a/docs/README b/docs/README index 5a8950ed8..a2313e883 100644 --- a/docs/README +++ b/docs/README @@ -12,11 +12,11 @@ root directory of this script: php index.php app=hub Another other (later added) parameters should be added after app=hub in the same -way due to the "design" of the inc/includes.php script. We need to change that -anyway. +way due to the "design" of the inc/includes.php script. This file is somewhat +deprecated anyway. -If you want to e.g. temporarily try out an other 'node mode' just add a parameter -'mode=???' to the above command by '???' can be one of the following: +If you want to try out an other 'node mode' just add a parameter 'mode=???' to +the above command by '???' can be one of the following: mode=regular - The default mode for joining the hub network as a regular node. This mode doesn't have to be entered manually unless you @@ -41,7 +41,21 @@ mode=master - A master-node holds a list of known nodes and which types of 2.) Current development notices: -------------------------------------------------------------------------------- -These modes are currently not yet finished. If you try an invalid out you now -get a nice and muich smaller error message. We still need to add a 'help' -command-line parameter and many more. This should be done with a nice helper -class and not just 'hey, my code runs' code. +These modes are currently not yet finished. If you try an invalid out you get a +nice small error message. Still this script lacks of a 'help' command-line +parameter and many more. This should be done with a nice helper class and not +just 'hey, my code runs' code. + +-------------------------------------------------------------------------------- +3.) Why the name "hub" +-------------------------------------------------------------------------------- + +This software is simply called "hub". This has a simple reason that this is, +first, the "working title" for it. And second, I have found no better name than +"Generic Object Sharing Hub" for this. I would not shortcut it to "Gosh" or +"GNU Gosh" or such other title, because the word "gosh" is english and +completely misleading. + +So if you have a really good ("selling") name, please send it to me: +roland[at]mxchange[dot]org or webmaster[at]ship-simu[dot]org if you prefer +webmaster accounts... ;-) diff --git a/docs/TODOs.txt b/docs/TODOs.txt index 93aca1a83..300e0e5d9 100644 --- a/docs/TODOs.txt +++ b/docs/TODOs.txt @@ -17,16 +17,14 @@ ./application/hub/main/handler/network/udp/class_UdpNetworkPackageHandler.php:55: * @todo 0% ./application/hub/main/handler/tasks/class_TaskHandler.php:133: // @TODO Messurement can be added around this call ./application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php:10: * @todo Find an interface for hub helper -./application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php:57: * @todo Rewrite the ->renderXmlContent() call to no arguments +./application/hub/main/helper/hub/announcement/class_HubDescriptorHelper.php:62: * @todo Rewrite the ->renderXmlContent() call to no arguments ./application/hub/main/iterator/network/class_NetworkListenIterator.php:10: * @todo This current implementation is not recommended, use a ./application/hub/main/iterator/network/class_NetworkListenIterator.php:11: * @todo latency-based iteration or similar approaches ./application/hub/main/iterator/pool/handler/class_HandlerPoolIterator.php:10: * @todo This current implementation is not recommended, use a ./application/hub/main/iterator/pool/handler/class_HandlerPoolIterator.php:11: * @todo latency-based iteration or similar approaches ./application/hub/main/iterator/pool/tasks/class_TaskPoolIterator.php:10: * @todo This current implementation is not recommended, use a ./application/hub/main/iterator/pool/tasks/class_TaskPoolIterator.php:11: * @todo latency-based iteration or similar approaches -./application/hub/main/listener/udp/class_UdpListener.php:101: * @todo ~50% done -./application/hub/main/listener/udp/class_UdpListener.php:61: * @todo stream_socket_server() was declared slow by some user comments. -./application/hub/main/listener/udp/class_UdpListener.php:62: * @todo Please rewrite it to socket_create() and its brothers. +./application/hub/main/listener/udp/class_UdpListener.php:133: * @todo ~50% done ./application/hub/main/lists/class_BaseList.php:264: // @TODO Extend this somehow? ./application/hub/main/nodes/boot/class_HubBootNode.php:119: // @TODO Add some filters here ./application/hub/main/nodes/boot/class_HubBootNode.php:58: * @todo add some more special bootstrap things for this boot node @@ -43,9 +41,10 @@ ./application/hub/main/nodes/regular/class_HubRegularNode.php:58: * @todo Implement this method ./application/hub/main/nodes/regular/class_HubRegularNode.php:68: * @todo Unfinished method ./application/hub/main/nodes/regular/class_HubRegularNode.php:91: // @TODO Add some filters here -./application/hub/main/package/class_NetworkPackage.php:108: crc32($content) // @TODO Not so good, but needs to be fast! -./application/hub/main/package/class_NetworkPackage.php:146: // @TODO Add some logging here +./application/hub/main/package/class_NetworkPackage.php:123: // @TODO crc32 is not good, but it needs to be fast ./application/hub/main/package/class_NetworkPackage.php:22: * @todo Needs to add functionality for handling the object's type +./application/hub/main/package/class_NetworkPackage.php:279: // @TODO Add some logging here +./application/hub/main/package/class_NetworkPackage.php:305: // @TODO Add some logging here ./application/hub/main/resolver/state/network/class_NetworkStateResolver.php:67: * @todo ~30% done ./application/hub/main/resolver/state/network/class_NetworkStateResolver.php:76: // @TODO On some systems it is 134, on some 107? ./application/hub/main/resolver/state/network/class_NetworkStateResolver.php:86: // @TODO We need to somehow detect the state/status of the remote peer and still maintain good speed. @@ -55,17 +54,19 @@ ./application/hub/main/tasks/hub/ping/class_HubPingTask.php:63: * @todo 0% ./application/hub/main/tasks/hub/update/class_HubUpdateCheckTask.php:53: * @todo 0% ./application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php:10: * @todo This template engine does not make use of setTemplateType() -./application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php:256: * @todo Find something useful with this! +./application/hub/main/template/announcement/class_AnnouncementTemplateEngine.php:253: * @todo Find something useful with this! +./application/hub/main/template/objects/class_ObjectRegistryTemplateEngine.php:10: * @todo This template engine does not make use of setTemplateType() +./application/hub/main/template/objects/class_ObjectRegistryTemplateEngine.php:255: * @todo Find something useful with this! ./application/hub/main/visitor/tasks/class_ActiveTaskVisitor.php:94: * @todo Does a query needs to perform some actions as an active task? ./application/hub/main/visitor/tasks/class_ShutdownTaskVisitor.php:89: * @todo Does a query needs to perform some actions as an active task? ./inc/classes/exceptions/main/class_MissingMethodException.php:13: * @todo Try to rewrite user/guest login classes and mark this exception as deprecated ./inc/classes/exceptions/main/class_NoConfigEntryException.php:10: * @todo Rename this class to NoFoundEntryException ./inc/classes/interfaces/class_FrameworkInterface.php:11: * @todo Find a better name for this interface -./inc/classes/main/class_BaseFrameworkSystem.php:1112: * @todo Write a logging mechanism for productive mode -./inc/classes/main/class_BaseFrameworkSystem.php:1126: // @TODO Finish this part! -./inc/classes/main/class_BaseFrameworkSystem.php:134: // @todo Try to clean these constants up -./inc/classes/main/class_BaseFrameworkSystem.php:215: * @todo This is old code. Do we still need this old lost code? -./inc/classes/main/class_BaseFrameworkSystem.php:283: * @todo SearchableResult and UpdateableResult shall have a super interface to use here +./inc/classes/main/class_BaseFrameworkSystem.php:1117: * @todo Write a logging mechanism for productive mode +./inc/classes/main/class_BaseFrameworkSystem.php:1131: // @TODO Finish this part! +./inc/classes/main/class_BaseFrameworkSystem.php:139: // @todo Try to clean these constants up +./inc/classes/main/class_BaseFrameworkSystem.php:220: * @todo This is old code. Do we still need this old lost code? +./inc/classes/main/class_BaseFrameworkSystem.php:288: * @todo SearchableResult and UpdateableResult shall have a super interface to use here ./inc/classes/main/commands/web/class_WebLoginAreaCommand.php:64: * @todo Add some stuff here: Some personal data, app/game related data ./inc/classes/main/commands/web/class_WebProblemCommand.php:58: * @todo 0% done ./inc/classes/main/commands/web/class_WebStatusCommand.php:58: * @todo 0% done @@ -114,7 +115,7 @@ ./inc/classes/main/mailer/debug/class_DebugMailer.php:124: * @todo 0% done ./inc/classes/main/menu/class_BaseMenu.php:59: // @TODO Should we log it here? We should, because it will be silently ignored. ./inc/classes/main/output/class_ConsoleOutput.php:56: // @TODO Need to rewrite this to $requestInstance->addHeader() -./inc/classes/main/parser/xml/class_XmlParser.php:70: // @TODO We need to find a fallback solution here +./inc/classes/main/parser/xml/class_XmlParser.php:76: // @TODO We need to find a fallback solution here ./inc/classes/main/points/class_UserPoints.php:100: * @todo Finish loading part of points ./inc/classes/main/request/console/class_ConsoleRequest.php:115: // @TODO There are no cookies on console ./inc/classes/main/request/console/class_ConsoleRequest.php:55: * @todo Needs to be implemented @@ -139,14 +140,14 @@ ./inc/classes/main/template/class_BaseTemplateEngine.php:955: * @todo Unfinished work or don't die here. ./inc/classes/main/template/class_BaseTemplateEngine.php:972: // @TODO Non-string found so we need some deeper analysis... ./inc/classes/main/template/console/class_ConsoleTemplateEngine.php:10: * @todo This template engine does not make use of setTemplateType() -./inc/classes/main/template/image/class_ImageTemplateEngine.php:224: * @todo Find something usefull with this! -./inc/classes/main/template/image/class_ImageTemplateEngine.php:244: * @todo Add cache creation here +./inc/classes/main/template/image/class_ImageTemplateEngine.php:221: * @todo Find something usefull with this! +./inc/classes/main/template/image/class_ImageTemplateEngine.php:241: * @todo Add cache creation here ./inc/classes/main/template/mail/class_MailTemplateEngine.php:10: * @todo This template engine does not make use of setTemplateType() -./inc/classes/main/template/mail/class_MailTemplateEngine.php:237: * @todo Add cache creation here -./inc/classes/main/template/mail/class_MailTemplateEngine.php:247: * @todo Should we call back the mailer class here? -./inc/classes/main/template/mail/class_MailTemplateEngine.php:328: * @todo 0% done -./inc/classes/main/template/menu/class_MenuTemplateEngine.php:276: * @todo Find something useful with this! -./inc/classes/main/template/menu/class_MenuTemplateEngine.php:322: * @todo Add cache creation here +./inc/classes/main/template/mail/class_MailTemplateEngine.php:234: * @todo Add cache creation here +./inc/classes/main/template/mail/class_MailTemplateEngine.php:244: * @todo Should we call back the mailer class here? +./inc/classes/main/template/mail/class_MailTemplateEngine.php:325: * @todo 0% done +./inc/classes/main/template/menu/class_MenuTemplateEngine.php:273: * @todo Find something useful with this! +./inc/classes/main/template/menu/class_MenuTemplateEngine.php:319: * @todo Add cache creation here ./inc/classes/main/user/class_BaseUser.php:308: * @todo Try to make this method more generic so we can move it in BaseFrameworkSystem ./inc/classes/main/user/class_BaseUser.php:80: * @todo Find a way of casting here. "(int)" might destroy the user id > 32766 ./inc/classes/main/user/member/class_Member.php:84: * @todo Add more ways over creating user classes -- 2.39.2