]> git.mxchange.org Git - hub.git/blob - application/hub/main/template/announcement/class_XmlAnnouncementTemplateEngine.php
224014728671107eff9233ecd792eae0eaead2bf
[hub.git] / application / hub / main / template / announcement / class_XmlAnnouncementTemplateEngine.php
1 <?php
2 /**
3  * An Announcement template engine class for XML templates
4  *
5  * @author              Roland Haeder <webmaster@ship-simu.org>
6  * @version             0.0.0
7  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Core Developer Team
8  * @license             GNU GPL 3.0 or any newer version
9  * @link                http://www.ship-simu.org
10  * @todo                This template engine does not make use of setTemplateType()
11  *
12  * This program is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program. If not, see <http://www.gnu.org/licenses/>.
24  */
25 class XmlAnnouncementTemplateEngine extends BaseTemplateEngine implements CompileableTemplate, Registerable {
26         /**
27          * Some XML nodes must be available for later data extraction
28          */
29         const ANNOUNCEMENT_DATA_SESSION_ID  = 'session-id';
30         const ANNOUNCEMENT_DATA_NODE_STATUS = 'node-status';
31         const ANNOUNCEMENT_DATA_EXTERNAL_IP = 'external-ip';
32         const ANNOUNCEMENT_DATA_INTERNAL_IP = 'internal-ip';
33         const ANNOUNCEMENT_DATA_TCP_PORT    = 'tcp-port';
34         const ANNOUNCEMENT_DATA_UDP_PORT    = 'udp-port';
35
36         /**
37          * Main nodes in the XML tree
38          */
39         private $mainNodes = array(
40                 'announcement',
41         );
42
43         /**
44          * Sub nodes in the XML tree
45          */
46         private $subNodes = array();
47
48         /**
49          * Current main node
50          */
51         private $curr = array();
52
53         /**
54          * Content from dependency
55          */
56         private $dependencyContent = array();
57
58         /**
59          * Protected constructor
60          *
61          * @return      void
62          */
63         protected function __construct () {
64                 // Call parent constructor
65                 parent::__construct(__CLASS__);
66
67                 // Init array
68                 $this->subNodes = array(
69                         'announcement-data',
70                         'listener',
71                         self::ANNOUNCEMENT_DATA_NODE_STATUS,
72                         self::ANNOUNCEMENT_DATA_TCP_PORT,
73                         self::ANNOUNCEMENT_DATA_UDP_PORT,
74                         self::ANNOUNCEMENT_DATA_SESSION_ID,
75                         self::ANNOUNCEMENT_DATA_EXTERNAL_IP,
76                         self::ANNOUNCEMENT_DATA_INTERNAL_IP,
77                         'object-type-list',
78                 );
79         }
80
81         /**
82          * Creates an instance of the class TemplateEngine and prepares it for usage
83          *
84          * @return      $templateInstance               An instance of TemplateEngine
85          * @throws      BasePathIsEmptyException                If the provided $templateBasePath is empty
86          * @throws      InvalidBasePathStringException  If $templateBasePath is no string
87          * @throws      BasePathIsNoDirectoryException  If $templateBasePath is no
88          *                                                                                      directory or not found
89          * @throws      BasePathReadProtectedException  If $templateBasePath is
90          *                                                                                      read-protected
91          */
92         public static final function createXmlAnnouncementTemplateEngine () {
93                 // Get a new instance
94                 $templateInstance = new XmlAnnouncementTemplateEngine();
95
96                 // Get the application instance from registry
97                 $applicationInstance = Registry::getRegistry()->getInstance('app');
98
99                 // Determine base path
100                 $templateBasePath = $templateInstance->getConfigInstance()->getConfigEntry('application_base_path') . $applicationInstance->getRequestInstance()->getRequestElement('app') . '/';
101
102                 // Is the base path valid?
103                 if (empty($templateBasePath)) {
104                         // Base path is empty
105                         throw new BasePathIsEmptyException($templateInstance, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
106                 } elseif (!is_string($templateBasePath)) {
107                         // Is not a string
108                         throw new InvalidBasePathStringException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_STRING);
109                 } elseif (!is_dir($templateBasePath)) {
110                         // Is not a path
111                         throw new BasePathIsNoDirectoryException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_PATH_NAME);
112                 } elseif (!is_readable($templateBasePath)) {
113                         // Is not readable
114                         throw new BasePathReadProtectedException(array($templateInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH);
115                 }
116
117                 // Set the base path
118                 $templateInstance->setTemplateBasePath($templateBasePath);
119
120                 // Set template extensions
121                 $templateInstance->setRawTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('raw_template_extension'));
122                 $templateInstance->setCodeTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('node_message_template_extension'));
123
124                 // Absolute output path for compiled templates
125                 $templateInstance->setCompileOutputPath($templateInstance->getConfigInstance()->getConfigEntry('base_path') . $templateInstance->getConfigInstance()->getConfigEntry('compile_output_path'));
126
127                 // Init a variable stacker
128                 $stackerInstance = ObjectFactory::createObjectByConfiguredName('node_announcement_stacker_class');
129
130                 // Set it
131                 $templateInstance->setStackerInstance($stackerInstance);
132
133                 // Return the prepared instance
134                 return $templateInstance;
135         }
136
137         /**
138          * Load a specified announcement template into the engine
139          *
140          * @param       $template       The announcement template we shall load which is
141          *                                              located in 'announcement' by default
142          * @return      void
143          */
144         public function loadAnnouncementTemplate ($template = 'self_announcement') {
145                 // Set template type
146                 $this->setTemplateType($this->getConfigInstance()->getConfigEntry('node_announcement_template_type'));
147
148                 // Load the special template
149                 $this->loadTemplate($template);
150         }
151
152         /**
153          * Getter for current main node
154          *
155          * @return      $currMainNode   Current main node
156          */
157         public final function getCurrMainNode () {
158                 return $this->curr['main_node'];
159         }
160
161         /**
162          * Setter for current main node
163          *
164          * @param       $element                Element name to set as current main node
165          * @return      $currMainNode   Current main node
166          */
167         private final function setCurrMainNode ($element) {
168                 $this->curr['main_node'] = (string) $element;
169         }
170
171         /**
172          * Getter for main node array
173          *
174          * @return      $mainNodes      Array with valid main node names
175          */
176         public final function getMainNodes () {
177                 return $this->mainNodes;
178         }
179
180         /**
181          * Getter for sub node array
182          *
183          * @return      $subNodes       Array with valid sub node names
184          */
185         public final function getSubNodes () {
186                 return $this->subNodes;
187         }
188
189         /**
190          * Handles the start element of an XML resource
191          *
192          * @param       $resource               XML parser resource (currently ignored)
193          * @param       $element                The element we shall handle
194          * @param       $attributes             All attributes
195          * @return      void
196          * @throws      InvalidXmlNodeException         If an unknown/invalid XML node name was found
197          */
198         public function startElement ($resource, $element, array $attributes) {
199                 // Initial method name which will never be called...
200                 $methodName = 'initAnnouncement';
201
202                 // Make the element name lower-case
203                 $element = strtolower($element);
204
205                 // Is the element a main node?
206                 //* DEBUG: */ echo "START: &gt;".$element."&lt;<br />\n";
207                 if (in_array($element, $this->getMainNodes())) {
208                         // Okay, main node found!
209                         $methodName = 'start' . $this->convertToClassName($element);
210
211                         // Set it
212                         $this->setCurrMainNode($element);
213                 } elseif (in_array($element, $this->getSubNodes())) {
214                         // Sub node found
215                         $methodName = 'start' . $this->convertToClassName($element);
216                 } else {
217                         // Invalid node name found
218                         throw new InvalidXmlNodeException(array($this, $element, $attributes), XmlParser::EXCEPTION_XML_NODE_UNKNOWN);
219                 }
220
221                 // Call method
222                 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
223                 call_user_func_array(array($this, $methodName), $attributes);
224         }
225
226         /**
227          * Ends the main or sub node by sending out the gathered data
228          *
229          * @param       $resource       An XML resource pointer (currently ignored)
230          * @param       $nodeName       Name of the node we want to finish
231          * @return      void
232          * @throws      XmlNodeMismatchException        If current main node mismatches the closing one
233          */
234         public function endElement ($resource, $nodeName) {
235                 // Make all lower-case
236                 $nodeName = strtolower($nodeName);
237
238                 // Does this match with current main node?
239                 //* DEBUG: */ echo "END: &gt;".$nodeName."&lt;<br />\n";
240                 if (($nodeName != $this->getCurrMainNode()) && (in_array($nodeName, $this->getMainNodes()))) {
241                         // Did not match!
242                         throw new XmlNodeMismatchException (array($this, $nodeName, $this->getCurrMainNode()), XmlParser::EXCEPTION_XML_NODE_MISMATCH);
243                 } // END - if
244
245                 // Construct method name
246                 $methodName = 'finish' . $this->convertToClassName($nodeName);
247
248                 // Call the corresponding method
249                 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
250                 call_user_func_array(array($this, $methodName), array());
251         }
252
253         /**
254          * Currently not used
255          *
256          * @param       $resource               XML parser resource (currently ignored)
257          * @param       $characters             Characters to handle
258          * @return      void
259          */
260         public function characterHandler ($resource, $characters) {
261                 // Trim all spaces away
262                 $characters = trim($characters);
263
264                 // Is this string empty?
265                 if (empty($characters)) {
266                         // Then skip it silently
267                         return false;
268                 } // END - if
269
270                 /*
271                  * Assign the found characters to variable and use the last entry from
272                  * stack as the name.
273                  */
274                 parent::assignVariable($this->getStackerInstance()->getNamed('announcement'), $characters);
275         }
276
277         /**
278          * Handles the template dependency for given node
279          *
280          * @param       $node                                   The node we should load a dependency template
281          * @param       $templateDependency             A template to load to satisfy dependencies
282          * @return      void
283          */
284         private function handleTemplateDependency ($node, $templateDependency) {
285                 // Is the template dependency set?
286                 if ((!empty($templateDependency)) && (!isset($this->dependencyContent[$node]))) {
287                         // Get a temporay template instance
288                         $templateInstance = XmlTemplateEngineFactory::createXmlTemplateEngineInstance('node_announcement_template_class');
289
290                         // Then load it
291                         $templateInstance->loadAnnouncementTemplate($templateDependency);
292
293                         // Parse the XML content
294                         $templateInstance->renderXmlContent();
295
296                         // Save the parsed raw content in our dependency array
297                         $this->dependencyContent[$node] = $templateInstance->getRawTemplateData();
298                 } // END - if
299         }
300
301         /**
302          * Read announcement variables by calling readVariable() with 'general' as
303          * variable stack.
304          *
305          * @param       $key    Key to read from
306          * @return      $value  Value from variable
307          */
308         public function readAnnouncementData ($key) {
309                 // Read the variable
310                 $value = parent::readVariable($key, 'general');
311
312                 // Return value
313                 return $value;
314         }
315
316         /**
317          * Getter for cache file (FQFN)
318          *
319          * @return      $fqfn   Full-qualified file name of the menu cache
320          */
321         public function getMenuCacheFqfn () {
322                 $this->partialStub('Please implement this method.');
323         }
324
325         /**
326          * Starts the announcement
327          *
328          * @return      void
329          */
330         private function startAnnouncement () {
331                 // Push the node name on the stacker
332                 $this->getStackerInstance()->pushNamed('announcement', 'announcement');
333         }
334
335         /**
336          * Starts the announcement data
337          *
338          * @return      void
339          */
340         private function startAnnouncementData () {
341                 // Push the node name on the stacker
342                 $this->getStackerInstance()->pushNamed('announcement', 'announcement-data');
343         }
344
345         /**
346          * Starts the node status
347          *
348          * @return      void
349          */
350         private function startNodeStatus () {
351                 // Push the node name on the stacker
352                 $this->getStackerInstance()->pushNamed('announcement', self::ANNOUNCEMENT_DATA_NODE_STATUS);
353         }
354
355         /**
356          * Starts the listener
357          *
358          * @return      void
359          */
360         private function startListener () {
361                 // Push the node name on the stacker
362                 $this->getStackerInstance()->pushNamed('announcement', 'listener');
363         }
364
365         /**
366          * Starts the TCP port
367          *
368          * @return      void
369          */
370         private function startTcpPort () {
371                 // Push the node name on the stacker
372                 $this->getStackerInstance()->pushNamed('announcement', self::ANNOUNCEMENT_DATA_TCP_PORT);
373         }
374
375         /**
376          * Starts the UDP port
377          *
378          * @return      void
379          */
380         private function startUdpPort () {
381                 // Push the node name on the stacker
382                 $this->getStackerInstance()->pushNamed('announcement', self::ANNOUNCEMENT_DATA_UDP_PORT);
383         }
384
385         /**
386          * Starts the session id
387          *
388          * @return      void
389          */
390         private function startSessionId () {
391                 // Push the node name on the stacker
392                 $this->getStackerInstance()->pushNamed('announcement', self::ANNOUNCEMENT_DATA_SESSION_ID);
393         }
394
395         /**
396          * Starts the public ip
397          *
398          * @return      void
399          */
400         private function startExternalIp () {
401                 // Push the node name on the stacker
402                 $this->getStackerInstance()->pushNamed('announcement', self::ANNOUNCEMENT_DATA_EXTERNAL_IP);
403         }
404
405         /**
406          * Starts the private ip
407          *
408          * @return      void
409          */
410         private function startInternalIp () {
411                 // Push the node name on the stacker
412                 $this->getStackerInstance()->pushNamed('announcement', self::ANNOUNCEMENT_DATA_INTERNAL_IP);
413         }
414
415         /**
416          * Starts the object type list
417          *
418          * @return      void
419          */
420         private function startObjectTypeList () {
421                 // Push the node name on the stacker
422                 $this->getStackerInstance()->pushNamed('announcement', 'object-type-list');
423         }
424
425         /**
426          * Starts the object type
427          *
428          * @return      void
429          */
430         private function startObjectType () {
431                 // Push the node name on the stacker
432                 $this->getStackerInstance()->pushNamed('announcement', 'object-type');
433         }
434
435         /**
436          * Finishes the object type
437          *
438          * @return      void
439          */
440         private function finishObjectType () {
441                 // Pop the last entry
442                 $this->getStackerInstance()->popNamed('announcement');
443         }
444
445         /**
446          * Finishes the object type list
447          *
448          * @return      void
449          */
450         private function finishObjectTypeList () {
451                 // Pop the last entry
452                 $this->getStackerInstance()->popNamed('announcement');
453         }
454
455         /**
456          * Finishes the session id
457          *
458          * @return      void
459          */
460         private function finishSessionId () {
461                 // Pop the last entry
462                 $this->getStackerInstance()->popNamed('announcement');
463         }
464
465         /**
466          * Finishes the private ip
467          *
468          * @return      void
469          */
470         private function finishInternalIp () {
471                 // Pop the last entry
472                 $this->getStackerInstance()->popNamed('announcement');
473         }
474
475         /**
476          * Finishes the public ip
477          *
478          * @return      void
479          */
480         private function finishExternalIp () {
481                 // Pop the last entry
482                 $this->getStackerInstance()->popNamed('announcement');
483         }
484
485         /**
486          * Finishes the UDP port
487          *
488          * @return      void
489          */
490         private function finishUdpPort () {
491                 // Pop the last entry
492                 $this->getStackerInstance()->popNamed('announcement');
493         }
494
495         /**
496          * Finishes the TCP port
497          *
498          * @return      void
499          */
500         private function finishTcpPort () {
501                 // Pop the last entry
502                 $this->getStackerInstance()->popNamed('announcement');
503         }
504
505         /**
506          * Finishes the listener
507          *
508          * @return      void
509          */
510         private function finishListener () {
511                 // Pop the last entry
512                 $this->getStackerInstance()->popNamed('announcement');
513         }
514
515         /**
516          * Finishes the node status
517          *
518          * @return      void
519          */
520         private function finishNodeStatus () {
521                 // Pop the last entry
522                 $this->getStackerInstance()->popNamed('announcement');
523         }
524
525         /**
526          * Finishes the announcement data
527          *
528          * @return      void
529          */
530         private function finishAnnouncementData () {
531                 // Pop the last entry
532                 $this->getStackerInstance()->popNamed('announcement');
533         }
534
535         /**
536          * Finishes the announcement
537          *
538          * @return      void
539          */
540         private function finishAnnouncement () {
541                 // Pop the last entry
542                 $this->getStackerInstance()->popNamed('announcement');
543         }
544 }
545
546 // [EOF]
547 ?>