]> git.mxchange.org Git - hub.git/blob - application/hub/main/package/class_NetworkPackage.php
Handling outgoing network packages basicly finished (but not the sending part itself)
[hub.git] / application / hub / main / package / class_NetworkPackage.php
1 <?php
2 /**
3  * A NetworkPackage class. This class implements the Deliverable class because
4  * all network packages should be deliverable to other nodes. It further
5  * provides methods for reading raw content from template engines and feeding it
6  * to the stacker for undeclared packages.
7  *
8  * The factory method requires you to provide a compressor class (which must
9  * implement the Compressor interface). If you don't want any compression (not
10  * adviceable due to increased network load), please use the NullCompressor
11  * class and encode it with BASE64 for a more error-free transfer over the
12  * Internet.
13  *
14  * For performance reasons, this class should only be instantiated once and then
15  * used as a "pipe-through" class.
16  *
17  * @author              Roland Haeder <webmaster@ship-simu.org>
18  * @version             0.0.0
19  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 Hub Developer Team
20  * @license             GNU GPL 3.0 or any newer version
21  * @link                http://www.ship-simu.org
22  * @todo                Needs to add functionality for handling the object's type
23  *
24  * This program is free software: you can redistribute it and/or modify
25  * it under the terms of the GNU General Public License as published by
26  * the Free Software Foundation, either version 3 of the License, or
27  * (at your option) any later version.
28  *
29  * This program is distributed in the hope that it will be useful,
30  * but WITHOUT ANY WARRANTY; without even the implied warranty of
31  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32  * GNU General Public License for more details.
33  *
34  * You should have received a copy of the GNU General Public License
35  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
36  */
37 class NetworkPackage extends BaseFrameworkSystem implements Deliverable, Registerable {
38         /**
39          * Package mask for compressing package data
40          */
41         const PACKAGE_MASK = '%s:%s:%s';
42
43         /**
44          * Stacker name for "undeclared" packages
45          */
46         const STACKER_NAME_UNDECLARED = 'undeclared';
47
48         /**
49          * Network target (alias): 'upper hubs'
50          */
51         const NETWORK_TARGET_UPPER_HUBS = 'upper';
52
53         /**
54          * Protected constructor
55          *
56          * @return      void
57          */
58         protected function __construct () {
59                 // Call parent constructor
60                 parent::__construct(__CLASS__);
61
62                 // We need to initialize a stack here for our packages even those
63                 // which have no recipient address and stamp... ;-)
64                 $stackerInstance = ObjectFactory::createObjectByConfiguredName('package_stacker_class');
65
66                 // At last, set it in this class
67                 $this->setStackerInstance($stackerInstance);
68         }
69
70         /**
71          * Creates an instance of this class
72          *
73          * @param       $compressorInstance             A Compressor instance for compressing the content
74          * @return      $packageInstance                An instance of a Deliverable class
75          */
76         public final static function createNetworkPackage (Compressor $compressorInstance) {
77                 // Get new instance
78                 $packageInstance = new NetworkPackage();
79
80                 // Now set the compressor instance if set
81                 if ($compressorInstance instanceof Compressor) {
82                         // Okay, set it
83                         $packageInstance->setCompressorInstance($compressorInstance);
84                 } // END - if
85
86                 // Return the prepared instance
87                 return $packageInstance;
88         }
89
90         /**
91          * "Enqueues" raw content into this delivery class by reading the raw content
92          * from given template instance and pushing it on the 'undeclared' stack.
93          *
94          * @param       $helperInstance         A BaseHubHelper instance
95          * @return      void
96          */
97         public function enqueueRawDataFromTemplate (BaseHubHelper $helperInstance) {
98                 // Get the raw content ...
99                 $content = $helperInstance->getTemplateInstance()->getRawTemplateData();
100
101                 // ... and compress it
102                 $content = $this->getCompressorInstance()->compressStream($content);
103
104                 // Add magic in front of it and hash behind it, including BASE64 encoding
105                 $content = sprintf(self::PACKAGE_MASK,
106                         $this->getCompressorInstance()->getCompressorExtension(),
107                         base64_encode($content),
108                         crc32($content) // @TODO Not so good, but needs to be fast!
109                 );
110
111                 // Now prepare the temporary array and push it on the 'undeclared' stack
112                 $this->getStackerInstance()->pushNamed(self::STACKER_NAME_UNDECLARED, array(
113                         'sender'    => $helperInstance->getNodeInstance()->getSessionId(),
114                         'recipient' => self::NETWORK_TARGET_UPPER_HUBS,
115                         'content'   => $content,
116                 ));
117         }
118
119         /**
120          * Checks wether a package has been enqueued for delivery.
121          *
122          * @return      $isEnqueued             Wether a package is enqueued
123          */
124         public function isPackageEnqueued () {
125                 // Check wether the stacker is not empty
126                 $isEnqueued = (($this->getStackerInstance()->isStackInitialized(self::STACKER_NAME_UNDECLARED)) && (!$this->getStackerInstance()->isStackEmpty(self::STACKER_NAME_UNDECLARED)));
127
128                 // Return the result
129                 return $isEnqueued;
130         }
131
132         /**
133          * Delivers an enqueued package to the stated destination. If a non-session
134          * id is provided, recipient resolver is being asked (and instanced once).
135          * This allows that a single package is being delivered to multiple targets
136          * without enqueueing it for every target. If no target is provided or it
137          * can't be determined a NoTargetException is being thrown.
138          *
139          * @return      void
140          * @throws      NoTargetException       If no target can't be determined
141          */
142         public function deliverEnqueuedPackage () {
143                 // Make sure this method isn't working if there is no package enqueued
144                 if (!$this->isPackageEnqueued()) {
145                         // This is not fatal but should be avoided
146                         // @TODO Add some logging here
147                         return;
148                 } // END - if
149
150                 // Now we know for sure there are packages to deliver, we can start
151                 // with the first one.
152                 $packageData = $this->getStackerInstance()->getNamed(self::STACKER_NAME_UNDECLARED);
153
154                 // Finally, deliver the package
155                 $this->deliverPackage($packageData);
156
157                 // And remove it finally
158                 $this->getStackerInstance()->popNamed(self::STACKER_NAME_UNDECLARED);
159         }
160 }
161
162 // [EOF]
163 ?>