From: Roland Häder <roland@mxchange.org>
Date: Sat, 20 May 2017 18:58:26 +0000 (+0200)
Subject: Continued:
X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=70ee5799652d8be63c3eee7ac1deba49bcc37c68;p=hub.git

Continued:
- Let's use (and cache) the UNL instance instead of fetching an array from it
  and then taking parts out of it. This way is more OOP-ed
- added getExternalUnl() and getInternalUnl() as first methods
- getUnlData() is now no longer used, see first comment why
- renamed path 'unl' -> 'locator' to have it same as in interfaces
- updated target year
- updated core framework

Signed-off-by: Roland Häder <roland@mxchange.org>
---

diff --git a/application/hub/classes/database/frontend/node/class_NodeDistributedHashTableDatabaseWrapper.php b/application/hub/classes/database/frontend/node/class_NodeDistributedHashTableDatabaseWrapper.php
index ab17c3e81..b8c64aa69 100644
--- a/application/hub/classes/database/frontend/node/class_NodeDistributedHashTableDatabaseWrapper.php
+++ b/application/hub/classes/database/frontend/node/class_NodeDistributedHashTableDatabaseWrapper.php
@@ -174,13 +174,12 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem
 		// Get Universal Node Locator and "explode" it
 		$unlInstance = $nodeInstance->determineUniversalNodeLocator();
 
-		// Get UNL data from it
-		$unlData = $unlInstance->getUnlData();
+		// Get external UNL
+		$externalUnl = $unlInstance->getExternalUnl();
 
 		// Make sure both is valid
 		// @TODO Bad check on UNL, better use a proper validator
-		assert(isset($unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL]));
-		assert($unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL] !== 'invalid');
+		assert($externalUnl !== 'invalid');
 
 		// Get an array of all accepted object types
 		$objectList = $nodeInstance->getListFromAcceptedObjectTypes();
@@ -190,7 +189,7 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem
 
 		// Add public node data
 		$dataSetInstance->addCriteria(self::DB_COLUMN_NODE_MODE       , $requestInstance->getRequestElement('mode'));
-		$dataSetInstance->addCriteria(self::DB_COLUMN_EXTERNAL_ADDRESS, $unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL]);
+		$dataSetInstance->addCriteria(self::DB_COLUMN_EXTERNAL_ADDRESS, $externalUnl);
 		$dataSetInstance->addCriteria(self::DB_COLUMN_NODE_ID         , $nodeInstance->getNodeId());
 		$dataSetInstance->addCriteria(self::DB_COLUMN_SESSION_ID      , $nodeInstance->getSessionId());
 		$dataSetInstance->addCriteria(self::DB_COLUMN_PRIVATE_KEY_HASH, $nodeInstance->getPrivateKeyHash());
@@ -221,15 +220,15 @@ class NodeDistributedHashTableDatabaseWrapper extends BaseDatabaseWrapper implem
 		$nodeInstance = NodeObjectFactory::createNodeInstance();
 
 		// Get Universal Node Locator and "explode" it
-		$unlData = $nodeInstance->getUniversalNodeLocatorArray();
+		$unlInstance = $nodeInstance->determineUniversalNodeLocator();
 
 		// Make sure the external address is set and not invalid
 		// @TODO Bad check on UNL, better use a proper validator
-		assert(isset($unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL]));
-		assert($unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL] != 'invalid');
+		$externalUnl = $unlInstance->getExternalUnl();
+		assert($externalUnl != 'invalid');
 
 		// Add Universal Node Locator/node id as criteria
-		$searchInstance->addCriteria(self::DB_COLUMN_EXTERNAL_ADDRESS, $unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL]);
+		$searchInstance->addCriteria(self::DB_COLUMN_EXTERNAL_ADDRESS, $externalUnl);
 		$searchInstance->addCriteria(self::DB_COLUMN_NODE_ID         , $nodeInstance->getNodeId());
 		$searchInstance->addCriteria(self::DB_COLUMN_SESSION_ID      , $nodeInstance->getSessionId());
 		$searchInstance->setLimit(1);
diff --git a/application/hub/classes/filter/miner/class_MinerPhpRequirementsFilter.php b/application/hub/classes/filter/miner/class_MinerPhpRequirementsFilter.php
index 4c15fe0ad..657edf861 100644
--- a/application/hub/classes/filter/miner/class_MinerPhpRequirementsFilter.php
+++ b/application/hub/classes/filter/miner/class_MinerPhpRequirementsFilter.php
@@ -77,11 +77,11 @@ class MinerPhpRequirementsFilter extends BaseMinerFilter implements Filterable {
 		// If scrypt() is not found (ext-scrypt) then the "Hubcoins reward" is not working
 		if ((extension_loaded('scrypt')) && (is_callable('scrypt'))) {
 			// Mark it as working
-			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER ext-scrypt and a callable scrypt() function found. "Hubcoin reward" feature possible.');
+			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER: ext-scrypt and a callable scrypt() function found. "Hubcoin reward" feature possible.');
 			$this->getConfigInstance()->setConfigEntry('extension_scrypt_loaded', TRUE);
 		} else {
 			// Not working (not all have ext-scrypt installed
-			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER ext-scrypt not found or scrypt() function not found. "Hubcoin reward" feature disabled.');
+			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER: ext-scrypt not found or scrypt() function not found. "Hubcoin reward" feature disabled.');
 		}
 
 		// Are all tests passed?
diff --git a/application/hub/classes/filter/node/class_NodePhpRequirementsFilter.php b/application/hub/classes/filter/node/class_NodePhpRequirementsFilter.php
index 098a5ae42..39cc86cce 100644
--- a/application/hub/classes/filter/node/class_NodePhpRequirementsFilter.php
+++ b/application/hub/classes/filter/node/class_NodePhpRequirementsFilter.php
@@ -80,21 +80,21 @@ class NodePhpRequirementsFilter extends BaseNodeFilter implements Filterable {
 		// If scrypt() is not found (ext-scrypt) then the "Hubcoins reward" is not working
 		if ((extension_loaded('scrypt')) && (is_callable('scrypt'))) {
 			// Mark it as working
-			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER ext-scrypt and a callable scrypt() function found. "Hubcoin reward" feature possible.');
+			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER: ext-scrypt and a callable scrypt() function found. "Hubcoin reward" feature possible.');
 			$this->getConfigInstance()->setConfigEntry('extension_scrypt_loaded', TRUE);
 		} else {
 			// Not working (not all have ext-scrypt installed
-			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER ext-scrypt not found or scrypt() function not found. "Hubcoin reward" feature disabled.');
+			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER: ext-scrypt not found or scrypt() function not found. "Hubcoin reward" feature disabled.');
 		}
 
 		// If uuid_create() is not found (ext-uuid) then some keys are a bit weaker
 		if ((extension_loaded('uuid')) && (is_callable('uuid_create'))) {
 			// Mark it as working
-			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER ext-uuid and a callable uuid_create() function found. UUID "entropy" available.');
+			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER: ext-uuid and a callable uuid_create() function found. UUID "entropy" available.');
 			$this->getConfigInstance()->setConfigEntry('extension_uuid_loaded', TRUE);
 		} else {
 			// Not working (not all have ext-uuid installed
-			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER ext-uuid not found or uuid_create() function not found. UUID "entropy" disabled.');
+			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('FILTER: ext-uuid not found or uuid_create() function not found. UUID "entropy" disabled.');
 		}
 
 		// Are all tests passed?
diff --git a/application/hub/classes/locator/.htaccess b/application/hub/classes/locator/.htaccess
new file mode 100644
index 000000000..3a4288278
--- /dev/null
+++ b/application/hub/classes/locator/.htaccess
@@ -0,0 +1 @@
+Deny from all
diff --git a/application/hub/classes/locator/class_UniversalNodeLocator.php b/application/hub/classes/locator/class_UniversalNodeLocator.php
new file mode 100644
index 000000000..999d95063
--- /dev/null
+++ b/application/hub/classes/locator/class_UniversalNodeLocator.php
@@ -0,0 +1,159 @@
+<?php
+// Own namespace
+namespace Hub\Locator\Node;
+
+// Import application-specific stuff
+use Hub\Database\Frontend\Node\Information\NodeInformationDatabaseWrapper;
+use Hub\Generic\BaseHubSystem;
+
+/**
+ * A class for UNLs (Universal Node Locator)
+ *
+ * @author		Roland Haeder <webmaster@ship-simu.org>
+ * @version		0.0.0
+ * @copyright	Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 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 <http://www.gnu.org/licenses/>.
+ */
+class UniversalNodeLocator extends BaseHubSystem implements LocateableNode {
+	//------- UNL parts -------
+	// Protocol
+	const UNL_PART_PROTOCOL = 'protocol';
+	// Address
+	const UNL_PART_ADDRESS  = 'address';
+	// Extra part
+	const UNL_PART_EXTRA    = 'extra';
+	// Port (if any)
+	const UNL_PART_PORT     = 'port';
+
+	/**
+	 * UNL data array
+	 */
+	private $unlData = array();
+
+	/**
+	 * Protected constructor
+	 *
+	 * @return	void
+	 */
+	protected function __construct () {
+		// Call parent constructor
+		parent::__construct(__CLASS__);
+	}
+
+	/**
+	 * Creates an instance of this class
+	 *
+	 * @param	$current		An array with "raw" data from the database layer for the UNL. This parameter is optional.
+	 * @return	$unlInstance	An instance of a LocateableNode class
+	 */
+	public final static function createUniversalNodeLocator (array $current = array()) {
+		// Get new instance
+		$unlInstance = new UniversalNodeLocator();
+
+		// Init instance
+		$unlInstance->initUniversalNodeLocator($current);
+
+		// Return the prepared instance
+		return $unlInstance;
+	}
+
+	/**
+	 * Initializes the UNL instance by givena array. If an entry is found, it
+	 * will be copied, otherwise the entry is set empty.
+	 *
+	 * @param	$current	An array with "raw" data from the database layer for the UNL. This parameter is optional.
+	 * @return	void
+	 */
+	private function initUniversalNodeLocator (array $current = array()) {
+		// Init UNL array
+		$this->unlData = array();
+
+		// Copy all found entries
+		foreach (array(
+			NodeInformationDatabaseWrapper::DB_COLUMN_NODE_ID,
+			NodeInformationDatabaseWrapper::DB_COLUMN_SESSION_ID,
+			NodeInformationDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH,
+			NodeInformationDatabaseWrapper::DB_COLUMN_NODE_MODE,
+			NodeInformationDatabaseWrapper::DB_COLUMN_INTERNAL_UNL,
+			NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL) as $key) {
+				// Init entry
+				$this->unlData[$key] = NULL;
+
+				// Is the key found?
+				if (isset($current[$key])) {
+					// The copy the entry
+					$this->unlData[$key] = $current[$key];
+				} // END - if
+		} // END - foreach
+	}
+
+	/**
+	 * Getter for UNL data array
+	 *
+	 * @return	$unlData	An array with UNL data
+	 */
+	private function getUnlData () {
+		return $this->unlData;
+	}
+
+	/**
+	 * Getter for external UNL
+	 *
+	 * @return	$externalUnl	External UNL
+	 * @throws	MissingArrayElementsException	If DB_COLUMN_EXTERNAL_UNL is missing
+	 */
+	public function getExternalUnl () {
+		// Get array
+		$unlData = $this->getUnlData();
+
+		// Is the element there?
+		if (!isset($unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL])) {
+			// Is not there
+			throw new MissingArrayElementsException(array($this, 'unlData', array(NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL)), self::EXCEPTION_ARRAY_ELEMENTS_MISSING);
+		} elseif ($unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL] == 'invalid') {
+			// Is not valid/method to early used
+			throw new BadMethodCallException(sprintf('unlData[%s] is invalid. Maybe called this method to early?', NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL));
+		}
+
+		// Return it
+		return $unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL];
+	}
+
+	/**
+	 * Getter for internal UNL
+	 *
+	 * @return	$internalUnl	Internal UNL
+	 * @throws	MissingArrayElementsException	If DB_COLUMN_INTERNAL_UNL is missing
+	 */
+	public function getInternalUnl () {
+		// Get array
+		$unlData = $this->getUnlData();
+
+		// Is the element there?
+		if (!isset($unlData[NodeInformationDatabaseWrapper::DB_COLUMN_INTERNAL_UNL])) {
+			// Is not there
+			throw new MissingArrayElementsException(array($this, 'unlData', array(NodeInformationDatabaseWrapper::DB_COLUMN_INTERNAL_UNL)), self::EXCEPTION_ARRAY_ELEMENTS_MISSING);
+		} elseif ($unlData[NodeInformationDatabaseWrapper::DB_COLUMN_INTERNAL_UNL] == 'invalid') {
+			// Is not valid/method to early used
+			throw new BadMethodCallException(sprintf('unlData[%s] is invalid. Maybe called this method to early?', NodeInformationDatabaseWrapper::DB_COLUMN_INTERNAL_UNL));
+		}
+
+		// Return it
+		return $unlData[NodeInformationDatabaseWrapper::DB_COLUMN_INTERNAL_UNL];
+	}
+
+}
diff --git a/application/hub/classes/nodes/boot/class_HubBootNode.php b/application/hub/classes/nodes/boot/class_HubBootNode.php
index 4d8dfd58c..d8acae0b6 100644
--- a/application/hub/classes/nodes/boot/class_HubBootNode.php
+++ b/application/hub/classes/nodes/boot/class_HubBootNode.php
@@ -86,7 +86,7 @@ class HubBootNode extends BaseHubNode implements NodeHelper, Registerable {
 			// Is the port the same?
 			if ($bootPort == $ourPort) {
 				// It is the same!
-				self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BOOTSTRAP: UNL matches bootstrap node ' . $this->getBootUniversalNodeLocator() . '.');
+				self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BOOTSTRAP: UNL matches bootstrap node "%s".', $this->getBootUniversalNodeLocator()));
 
 				// Now, does the mode match
 				if (FrameworkBootstrap::getRequestInstance()->getRequestElement('mode') == self::NODE_TYPE_BOOT) {
@@ -94,15 +94,15 @@ class HubBootNode extends BaseHubNode implements NodeHelper, Registerable {
 					self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BOOTSTRAP: Our node is a valid bootstrap node.');
 				} else {
 					// Output warning
-					self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BOOTSTRAP: WARNING: Mismatching mode ' . FrameworkBootstrap::getRequestInstance()->getRequestElement('mode') . '!=' . BaseHubNode::NODE_TYPE_BOOT . ' detected.');
+					self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BOOTSTRAP: WARNING: Mismatching mode %s!=%s detected.', FrameworkBootstrap::getRequestInstance()->getRequestElement('mode'), BaseHubNode::NODE_TYPE_BOOT));
 				}
 			} else {
 				// IP does match, but no port
-				self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BOOTSTRAP: WARNING: Our UNL ' . $unl . ' does match a known bootstrap-node but not the port ' . $ourPort . '/' . $bootPort . '.');
+				self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BOOTSTRAP: WARNING: Our UNL "%s" does match a known bootstrap-node but not the port %d/%d.', $unl, $ourPort, $bootPort));
 			}
 		} else {
 			// Node does not match any know bootstrap-node
-			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BOOTSTRAP: WARNING: Our UNL ' . $unl . ' does not match any known bootstrap-nodes.');
+			self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BOOTSTRAP: WARNING: Our UNL "%s" does not match any known bootstrap-nodes.', $unl));
 		}
 
 		// Enable acceptance of announcements
diff --git a/application/hub/classes/nodes/class_BaseHubNode.php b/application/hub/classes/nodes/class_BaseHubNode.php
index d3282002d..7d653a786 100644
--- a/application/hub/classes/nodes/class_BaseHubNode.php
+++ b/application/hub/classes/nodes/class_BaseHubNode.php
@@ -202,7 +202,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable, AddableCriteria {
 				$this->bootUnl = $unl;
 
 				// Output message
-				self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BOOTSTRAP: ' . __FUNCTION__ . ': UNL matches remote address ' . $unl . '.');
+				self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BOOTSTRAP: UNL matches remote address "%s".', $unl));
 
 				// Stop further searching
 				break;
@@ -217,7 +217,7 @@ class BaseHubNode extends BaseHubSystem implements Updateable, AddableCriteria {
 				$this->bootUnl = $unl;
 
 				// Output message
-				self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('BOOTSTRAP: ' . __FUNCTION__ . ': UNL matches listen address ' . $unl . '.');
+				self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('BOOTSTRAP: UNL matches listening UNL "%s".', $unl));
 
 				// Stop further searching
 				break;
@@ -237,15 +237,15 @@ class BaseHubNode extends BaseHubSystem implements Updateable, AddableCriteria {
 		// Is "cache" set?
 		if (!isset($GLOBALS[__METHOD__])) {
 			// Get the UNL array back
-			$unlData = $this->getUniversalNodeLocatorArray();
+			$unlInstance = $this->determineUniversalNodeLocator();
 
 			// There are 2 UNLs, internal and external.
 			if ($this->getConfigInstance()->getConfigEntry('allow_publish_internal_address') == 'N') {
 				// Public "external" UNL address
-				$GLOBALS[__METHOD__] = $unlData[NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL];
+				$GLOBALS[__METHOD__] = $unlInstance->getExternalUnl();
 			} else {
 				// Non-public "internal" UNL address
-				$GLOBALS[__METHOD__] = $unlData[NodeInformationDatabaseWrapper::DB_COLUMN_INTERNAL_UNL];
+				$GLOBALS[__METHOD__] = $unlInstance->getInternalUnl();
 			}
 		} // END - if
 
@@ -758,42 +758,19 @@ class BaseHubNode extends BaseHubSystem implements Updateable, AddableCriteria {
 		// Debug message
 		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NODE: CALLED!');
 
-		// Determine UNL based on this node:
-		// 1) Get discovery class
-		$discoveryInstance = ObjectFactory::createObjectByConfiguredName('unl_discovery_class');
-
-		// 2) "Determine" it
-		$unlInstance = $discoveryInstance->discoverUniversalNodeLocatorByNode($this);
-
-		// 3) Return it
-		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NODE: unlInstance= ' . $unlInstance->__toString() . ' - EXIT!');
-		return $unlInstance;
-	}
-
-	/**
-	 * "Getter" for an array of an instance of a LocateableNode class
-	 *
-	 * @return	$unlData	An array from an instance of a LocateableNode class for this node
-	 */
-	public final function getUniversalNodeLocatorArray () {
-		// Debug message
-		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NODE: CALLED!');
-
-		// Get the Universal Node Locator (UNL) instance
-		$unlInstance = $this->determineUniversalNodeLocator();
+		// Is there cache?
+		if (!isset($GLOBALS[__METHOD__])) {
+			// Determine UNL based on this node:
+			// 1) Get discovery class
+			$discoveryInstance = ObjectFactory::createObjectByConfiguredName('unl_discovery_class');
 
-		// Make sure the instance is valid
-		if (!$unlInstance instanceof LocateableNode) {
-			// No valid instance, so better debug this
-			$this->debugBackTrace('unlInstance[' . gettype($unlInstance) . ']=' . $unlInstance);
+			// 2) "Determine" it
+			$GLOBALS[__METHOD__] = $discoveryInstance->discoverUniversalNodeLocatorByNode($this);
 		} // END - if
 
-		// ... and the array from it
-		$unlData = $unlInstance->getUnlData();
-
 		// Return it
-		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NODE: EXIT!');
-		return $unlData;
+		//* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('NODE: unlInstance= ' . $GLOBALS[__METHOD__]->__toString() . ' - EXIT!');
+		return $GLOBALS[__METHOD__];
 	}
 
 	/**
diff --git a/application/hub/classes/unl/.htaccess b/application/hub/classes/unl/.htaccess
deleted file mode 100644
index 3a4288278..000000000
--- a/application/hub/classes/unl/.htaccess
+++ /dev/null
@@ -1 +0,0 @@
-Deny from all
diff --git a/application/hub/classes/unl/class_UniversalNodeLocator.php b/application/hub/classes/unl/class_UniversalNodeLocator.php
deleted file mode 100644
index 861805087..000000000
--- a/application/hub/classes/unl/class_UniversalNodeLocator.php
+++ /dev/null
@@ -1,115 +0,0 @@
-<?php
-// Own namespace
-namespace Hub\Locator\Node;
-
-// Import application-specific stuff
-use Hub\Database\Frontend\Node\Information\NodeInformationDatabaseWrapper;
-use Hub\Generic\BaseHubSystem;
-
-/**
- * A class for UNLs (Universal Node Locator)
- *
- * @author		Roland Haeder <webmaster@ship-simu.org>
- * @version		0.0.0
- * @copyright	Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 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 <http://www.gnu.org/licenses/>.
- */
-class UniversalNodeLocator extends BaseHubSystem implements LocateableNode {
-	//------- UNL parts -------
-	// Protocol
-	const UNL_PART_PROTOCOL = 'protocol';
-	// Address
-	const UNL_PART_ADDRESS  = 'address';
-	// Extra part
-	const UNL_PART_EXTRA    = 'extra';
-	// Port (if any)
-	const UNL_PART_PORT     = 'port';
-
-	/**
-	 * UNL data array
-	 */
-	private $unlData = array();
-
-	/**
-	 * Protected constructor
-	 *
-	 * @return	void
-	 */
-	protected function __construct () {
-		// Call parent constructor
-		parent::__construct(__CLASS__);
-	}
-
-	/**
-	 * Creates an instance of this class
-	 *
-	 * @param	$current		An array with "raw" data from the database layer for the UNL. This parameter is optional.
-	 * @return	$unlInstance	An instance of a LocateableNode class
-	 */
-	public final static function createUniversalNodeLocator (array $current = array()) {
-		// Get new instance
-		$unlInstance = new UniversalNodeLocator();
-
-		// Init instance
-		$unlInstance->initUniversalNodeLocator($current);
-
-		// Return the prepared instance
-		return $unlInstance;
-	}
-
-	/**
-	 * Initializes the UNL instance by givena array. If an entry is found, it
-	 * will be copied, otherwise the entry is set empty.
-	 *
-	 * @param	$current	An array with "raw" data from the database layer for the UNL. This parameter is optional.
-	 * @return	void
-	 */
-	private function initUniversalNodeLocator (array $current = array()) {
-		// Init UNL array
-		$this->unlData = array();
-
-		// Copy all found entries
-		foreach (array(
-			NodeInformationDatabaseWrapper::DB_COLUMN_NODE_ID,
-			NodeInformationDatabaseWrapper::DB_COLUMN_SESSION_ID,
-			NodeInformationDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH,
-			NodeInformationDatabaseWrapper::DB_COLUMN_NODE_MODE,
-			NodeInformationDatabaseWrapper::DB_COLUMN_INTERNAL_UNL,
-			NodeInformationDatabaseWrapper::DB_COLUMN_EXTERNAL_UNL) as $key) {
-				// Init entry
-				$this->unlData[$key] = NULL;
-
-				// Is the key found?
-				if (isset($current[$key])) {
-					// The copy the entry
-					$this->unlData[$key] = $current[$key];
-				} // END - if
-		} // END - foreach
-	}
-
-	/**
-	 * Getter for UNL data array
-	 *
-	 * @return	$unlData	An array with UNL data
-	 */
-	public final function getUnlData () {
-		return $this->unlData;
-	}
-}
-
-// [EOF]
-?>
diff --git a/application/hub/interfaces/helper/nodes/class_NodeHelper.php b/application/hub/interfaces/helper/nodes/class_NodeHelper.php
index dbac138ca..4b657345e 100644
--- a/application/hub/interfaces/helper/nodes/class_NodeHelper.php
+++ b/application/hub/interfaces/helper/nodes/class_NodeHelper.php
@@ -129,13 +129,6 @@ interface NodeHelper extends Helper, AddableCriteria {
 	 */
 	function determineUniversalNodeLocator ();
 
-	/**
-	 * "Getter for an array of an instance of a LocateableNode class
-	 *
-	 * @return	$unlData	An array of an instance of a LocateableNode class
-	 */
-	function getUniversalNodeLocatorArray ();
-
 	/**
 	 * Updates/refreshes node data (e.g. state).
 	 *
diff --git a/application/hub/interfaces/locator/class_LocateableNode.php b/application/hub/interfaces/locator/class_LocateableNode.php
index dd45658d8..c9c98454a 100644
--- a/application/hub/interfaces/locator/class_LocateableNode.php
+++ b/application/hub/interfaces/locator/class_LocateableNode.php
@@ -28,7 +28,20 @@ use Hub\Generic\HubInterface;
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 interface LocateableNode extends HubInterface {
-}
+	/**
+	 * Getter for external UNL
+	 *
+	 * @return	$externalUnl	External UNL
+	 * @throws	MissingArrayElementsException	If DB_COLUMN_EXTERNAL_UNL is missing
+	 */
+	function getExternalUnl ();
+
+	/**
+	 * Getter for internal UNL
+	 *
+	 * @return	$internalUnl	Internal UNL
+	 * @throws	MissingArrayElementsException	If DB_COLUMN_INTERNAL_UNL is missing
+	 */
+	function getInternalUnl ();
 
-// [EOF]
-?>
+}
diff --git a/contrib/update_year.sh b/contrib/update_year.sh
index 5b353ce79..a9bfc8c5d 100755
--- a/contrib/update_year.sh
+++ b/contrib/update_year.sh
@@ -1,4 +1,4 @@
 #!/bin/sh
 
 # Really lame ...
-find application/ -type f -print0 | xargs -0 sed -i 's/2015 Hub/2016 Hub/g'
+find application/ -type f -print0 | xargs -0 sed -i 's/2015 Hub/2017 Hub/g'
diff --git a/core b/core
index d9d2b0266..aa76ddf7f 160000
--- a/core
+++ b/core
@@ -1 +1 @@
-Subproject commit d9d2b0266fc21f4664087a8488d05c6d6068073b
+Subproject commit aa76ddf7f1d5d302f1d752efcd113515ecf152a2