3 * An Announcement template engine class
5 * @author Roland Haeder <webmaster@ship-simu.org>
7 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009, 2010 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()
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.
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.
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/>.
25 class AnnouncementTemplateEngine extends BaseTemplateEngine implements CompileableTemplate {
27 * Main nodes in the XML tree ('menu' is ignored)
29 private $mainNodes = array(
34 * Sub nodes in the XML tree
36 private $subNodes = array(
52 private $curr = array();
55 * Content from dependency
57 private $dependencyContent = array();
60 * Protected constructor
64 protected function __construct () {
65 // Call parent constructor
66 parent::__construct(__CLASS__);
70 * Creates an instance of the class TemplateEngine and prepares it for usage
72 * @param $appInstance A manageable application
73 * @return $templateInstance An instance of TemplateEngine
74 * @throws BasePathIsEmptyException If the provided $templateBasePath is empty
75 * @throws InvalidBasePathStringException If $templateBasePath is no string
76 * @throws BasePathIsNoDirectoryException If $templateBasePath is no
77 * directory or not found
78 * @throws BasePathReadProtectedException If $templateBasePath is
81 public final static function createAnnouncementTemplateEngine (ManageableApplication $appInstance) {
83 $templateInstance = new AnnouncementTemplateEngine();
85 // Get language and file I/O instances from application
86 $langInstance = $appInstance->getLanguageInstance();
87 $ioInstance = $appInstance->getFileIoInstance();
89 // Determine base path
90 $templateBasePath = $templateInstance->getConfigInstance()->getConfigEntry('application_base_path') . $appInstance->getRequestInstance()->getRequestElement('app') . '/';
92 // Is the base path valid?
93 if (empty($templateBasePath)) {
95 throw new BasePathIsEmptyException($templateInstance, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
96 } elseif (!is_string($templateBasePath)) {
98 throw new InvalidBasePathStringException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_STRING);
99 } elseif (!is_dir($templateBasePath)) {
101 throw new BasePathIsNoDirectoryException(array($templateInstance, $templateBasePath), self::EXCEPTION_INVALID_PATH_NAME);
102 } elseif (!is_readable($templateBasePath)) {
104 throw new BasePathReadProtectedException(array($templateInstance, $templateBasePath), self::EXCEPTION_READ_PROTECED_PATH);
108 $templateInstance->setTemplateBasePath($templateBasePath);
110 // Set the language and IO instances
111 $templateInstance->setLanguageInstance($langInstance);
112 $templateInstance->setFileIoInstance($ioInstance);
114 // Set template extensions
115 $templateInstance->setRawTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('raw_template_extension'));
116 $templateInstance->setCodeTemplateExtension($templateInstance->getConfigInstance()->getConfigEntry('announcement_template_extension'));
118 // Absolute output path for compiled templates
119 $templateInstance->setCompileOutputPath($templateInstance->getConfigInstance()->getConfigEntry('base_path') . $templateInstance->getConfigInstance()->getConfigEntry('compile_output_path'));
121 // Init a variable stacker
122 $stackerInstance = ObjectFactory::createObjectByConfiguredName('announcement_stacker_class');
125 $templateInstance->setStackerInstance($stackerInstance);
127 // Return the prepared instance
128 return $templateInstance;
132 * Load a specified announcement template into the engine
134 * @param $template The announcement template we shall load which is
135 * located in 'announcement' by default
138 public function loadAnnouncementTemplate ($template = 'self_announcement') {
140 $this->setTemplateType($this->getConfigInstance()->getConfigEntry('announcement_template_type'));
142 // Load the special template
143 $this->loadTemplate($template);
147 * Getter for current main node
149 * @return $currMainNode Current main node
151 public final function getCurrMainNode () {
152 return $this->curr['main_node'];
156 * Setter for current main node
158 * @param $element Element name to set as current main node
159 * @return $currMainNode Current main node
161 private final function setCurrMainNode ($element) {
162 $this->curr['main_node'] = (string) $element;
166 * Getter for main node array
168 * @return $mainNodes Array with valid main node names
170 public final function getMainNodes () {
171 return $this->mainNodes;
175 * Getter for sub node array
177 * @return $subNodes Array with valid sub node names
179 public final function getSubNodes () {
180 return $this->subNodes;
184 * Handles the start element of an XML resource
186 * @param $resource XML parser resource (currently ignored)
187 * @param $element The element we shall handle
188 * @param $attributes All attributes
190 * @throws InvalidXmlNodeException If an unknown/invalid XML node name was found
192 public function startElement ($resource, $element, array $attributes) {
193 // Initial method name which will never be called...
194 $methodName = 'initAnnouncement';
196 // Make the element name lower-case
197 $element = strtolower($element);
199 // Is the element a main node?
200 //* DEBUG: */ echo "START: >".$element."<<br />\n";
201 if (in_array($element, $this->getMainNodes())) {
202 // Okay, main node found!
203 $methodName = 'start' . $this->convertToClassName($element);
206 $this->setCurrMainNode($element);
207 } elseif (in_array($element, $this->getSubNodes())) {
209 $methodName = 'start' . $this->convertToClassName($element);
211 // Invalid node name found
212 throw new InvalidXmlNodeException(array($this, $element, $attributes), XmlParser::EXCEPTION_XML_NODE_UNKNOWN);
216 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
217 call_user_func_array(array($this, $methodName), $attributes);
221 * Ends the main or sub node by sending out the gathered data
223 * @param $resource An XML resource pointer (currently ignored)
224 * @param $nodeName Name of the node we want to finish
226 * @throws XmlNodeMismatchException If current main node mismatches the closing one
228 public function endElement ($resource, $nodeName) {
229 // Make all lower-case
230 $nodeName = strtolower($nodeName);
232 // Does this match with current main node?
233 //* DEBUG: */ echo "END: >".$nodeName."<<br />\n";
234 if (($nodeName != $this->getCurrMainNode()) && (in_array($nodeName, $this->getMainNodes()))) {
236 throw new XmlNodeMismatchException (array($this, $nodeName, $this->getCurrMainNode()), XmlParser::EXCEPTION_XML_NODE_MISMATCH);
239 // Construct method name
240 $methodName = 'finish' . $this->convertToClassName($nodeName);
242 // Call the corresponding method
243 //* DEBUG: */ echo "call: ".$methodName."<br />\n";
244 call_user_func_array(array($this, $methodName), array());
250 * @param $resource XML parser resource (currently ignored)
251 * @param $characters Characters to handle
253 * @todo Find something useful with this!
255 public function characterHandler ($resource, $characters) {
256 // Trim all spaces away
257 $characters = trim($characters);
259 // Is this string empty?
260 if (empty($characters)) {
261 // Then skip it silently
265 // Assign the found characters to variable and use the last entry from
267 parent::assignVariable($this->getStackerInstance()->getNamed('announcement'), $characters);
271 * Handles the template dependency for given node
273 * @param $node The node we should load a dependency template
274 * @param $templateDependency A template to load to satisfy dependencies
277 private function handleTemplateDependency ($node, $templateDependency) {
278 // Is the template dependency set?
279 if ((!empty($templateDependency)) && (!isset($this->dependencyContent[$node]))) {
280 // Get a temporay menu template instance
281 $templateInstance = ObjectFactory::createObjectByConfiguredName('announcement_template_class', array($this->getApplicationInstance()));
284 $templateInstance->loadAnnouncementTemplate($templateDependency);
286 // Get an XmlParser instance
287 $templateInstance->renderXmlContent();
289 // Parse the template's content contents
290 $this->dependencyContent[$node] = $templateInstance->getRawTemplateData();
295 * Getter for cache file (FQFN)
297 * @return $fqfn Full-qualified file name of the menu cache
299 public function getMenuCacheFqfn () {
300 $this->partialStub('Please implement this method.');
304 * Starts the announcement
308 private function startAnnouncement () {
309 // Push the node name on the stacker
310 $this->getStackerInstance()->pushNamed('announcement', 'announcement');
314 * Starts the announcement data
318 private function startAnnouncementData () {
319 // Push the node name on the stacker
320 $this->getStackerInstance()->pushNamed('announcement', 'announcement-data');
328 private function startNodeId () {
329 // Push the node name on the stacker
330 $this->getStackerInstance()->pushNamed('announcement', 'node-id');
334 * Starts the node status
338 private function startNodeStatus () {
339 // Push the node name on the stacker
340 $this->getStackerInstance()->pushNamed('announcement', 'node-status');
344 * Starts the listener
348 private function startListener () {
349 // Push the node name on the stacker
350 $this->getStackerInstance()->pushNamed('announcement', 'listener');
354 * Starts the client listener
358 private function startClientListener () {
359 // Push the node name on the stacker
360 $this->getStackerInstance()->pushNamed('announcement', 'client-listener');
364 * Starts the hub listener
368 private function startHubListener () {
369 // Push the node name on the stacker
370 $this->getStackerInstance()->pushNamed('announcement', 'hub-listener');
374 * Starts the TCP port
378 private function startTcpPort () {
379 // Push the node name on the stacker
380 $this->getStackerInstance()->pushNamed('announcement', 'tcp-port');
384 * Starts the UDP port
388 private function startUdpPort () {
389 // Push the node name on the stacker
390 $this->getStackerInstance()->pushNamed('announcement', 'udp-port');
394 * Starts the session id
398 private function startSessionId () {
399 // Push the node name on the stacker
400 $this->getStackerInstance()->pushNamed('announcement', 'session-id');
404 * Starts the object type list
408 private function startObjectTypeList () {
409 // Push the node name on the stacker
410 $this->getStackerInstance()->pushNamed('announcement', 'object-type-list');
414 * Starts the object type
418 private function startObjectType () {
419 // Push the node name on the stacker
420 $this->getStackerInstance()->pushNamed('announcement', 'object-type');
424 * Finishes the object type
428 private function finishObjectType () {
429 // Pop the last entry
430 $this->getStackerInstance()->popNamed('announcement');
434 * Finishes the object type list
438 private function finishObjectTypeList () {
439 // Pop the last entry
440 $this->getStackerInstance()->popNamed('announcement');
444 * Finishes the session id
448 private function finishSessionId () {
449 // Pop the last entry
450 $this->getStackerInstance()->popNamed('announcement');
454 * Finishes the UDP port
458 private function finishUdpPort () {
459 // Pop the last entry
460 $this->getStackerInstance()->popNamed('announcement');
464 * Finishes the TCP port
468 private function finishTcpPort () {
469 // Pop the last entry
470 $this->getStackerInstance()->popNamed('announcement');
474 * Finishes the hub listener
478 private function finishHubListener () {
479 // Pop the last entry
480 $this->getStackerInstance()->popNamed('announcement');
484 * Finishes the client listener
488 private function finishClientListener () {
489 // Pop the last entry
490 $this->getStackerInstance()->popNamed('announcement');
494 * Finishes the listener
498 private function finishListener () {
499 // Pop the last entry
500 $this->getStackerInstance()->popNamed('announcement');
504 * Finishes the node status
508 private function finishNodeStatus () {
509 // Pop the last entry
510 $this->getStackerInstance()->popNamed('announcement');
514 * Finishes the node id
518 private function finishNodeId () {
519 // Pop the last entry
520 $this->getStackerInstance()->popNamed('announcement');
524 * Finishes the announcement data
528 private function finishAnnouncementData () {
529 // Pop the last entry
530 $this->getStackerInstance()->popNamed('announcement');
534 * Finishes the announcement
538 private function finishAnnouncement () {
539 // Pop the last entry
540 $this->getStackerInstance()->popNamed('announcement');