| [ Index ] |
PHP Cross Reference of Web Application Component Toolkit |
[Summary view] [Print] [Text view]
1 <?php 2 //-------------------------------------------------------------------------------- 3 // Copyright 2003 Procata, Inc. 4 // Released under the LGPL license (http://www.gnu.org/copyleft/lesser.html) 5 //-------------------------------------------------------------------------------- 6 /** 7 * @package WACT_TEMPLATE 8 * @version $Id: parserstate.inc.php,v 1.41 2004/11/18 04:22:46 jeffmoore Exp $ 9 */ 10 //-------------------------------------------------------------------------------- 11 /** 12 * Load array_change_key_case as needed 13 */ 14 if (!function_exists('array_change_key_case')) { 15 require_once WACT_ROOT . 'util/phpcompat/array_change_key_case.php'; 16 } 17 18 /** 19 * Base state handler for the SourceFileParser. Handles plain text 20 * @see http://wact.sourceforge.net/index.php/BaseParsingState 21 * @access public 22 * @package WACT_TEMPLATE 23 */ 24 class BaseParsingState { 25 /** 26 * Instance of SourceFileParser 27 * @var SourceFileParser 28 * @access private 29 */ 30 var $Parser; 31 32 /** 33 * Used to locate position within document 34 * @access private 35 */ 36 var $Locator; 37 38 /** 39 * Instance of TreeBuilder 40 * @var TreeBuilder 41 * @access private 42 */ 43 var $TreeBuilder; 44 45 /** 46 * @param SourceFileParser 47 * @access protected 48 */ 49 function BaseParsingState(&$Parser, &$TreeBuilder) { 50 $this->Parser = & $Parser; 51 $this->TreeBuilder = & $TreeBuilder; 52 } 53 54 /** 55 * @param Locator 56 * @access protected 57 */ 58 function setDocumentLocator(&$locator) { 59 $this->Locator =& $locator; 60 } 61 62 /** 63 * Attribute syntax Error Handler 64 * @param string tag content 65 * @access public 66 */ 67 function invalidAttributeSyntax() { 68 RaiseError('compiler', 'INVALID_ATTRIBUTE_SYNTAX', array( 69 'file' => $this->Locator->getPublicId(), 70 'line' => $this->Locator->getLineNumber())); 71 } 72 73 } 74 75 /** 76 * Handler for component parsing state 77 * @see http://wact.sourceforge.net/index.php/ComponentParsingState 78 * @access public 79 * @access WACT_TEMPLATE 80 */ 81 class ComponentParsingState extends BaseParsingState { 82 /** 83 * Instance of TagDictionary 84 * @var TagDictionary 85 * @access private 86 */ 87 var $TagDictionary; 88 89 /** 90 * @param SourceFileParser 91 * @access public 92 */ 93 function ComponentParsingState(&$Parser, &$TreeBuilder, &$TagDictionary) { 94 parent::BaseParsingState($Parser, $TreeBuilder); 95 $this->TagDictionary =& $TagDictionary; 96 } 97 98 function getAttributeString($attrs) { 99 $attrib_str = ''; 100 foreach ( $attrs as $key => $value ) { 101 if (strcasecmp($key, PARSER_TRIGGER_ATTR_NAME) == 0 ) { 102 continue; 103 } 104 105 $attrib_str .= ' ' . $key; 106 if (!is_null($value)) { 107 if (strpos($value, '"') === FALSE) { 108 $attrib_str .= '="' . $value . '"'; 109 } else { 110 $attrib_str .= '=\'' . $value . '\''; 111 } 112 } 113 } 114 return $attrib_str; 115 } 116 117 /** 118 * Handle opening tags 119 * @param string tag name 120 * @param array tag attributes 121 * @access public 122 */ 123 function startElement($tag, $attrs) { 124 125 $lower_attributes = array_change_key_case($attrs, CASE_LOWER); 126 if ( isset($lower_attributes[PARSER_TRIGGER_ATTR_NAME]) && 127 strpos($lower_attributes[PARSER_TRIGGER_ATTR_NAME], '{$') !== FALSE) { 128 RaiseError('compiler', 'ILLEGALVARREFINATTR', array( 129 'tag' => $tag, 130 'attribute' => $name, 131 'file' => $this->Locator->getPublicId(), 132 'line' => $this->Locator->getLineNumber())); 133 } 134 135 $TagInfo =& $this->TagDictionary->findComponent($tag, $lower_attributes, FALSE, $this->TreeBuilder->Component); 136 if (is_object($TagInfo)) { 137 $TagInfo->load(); 138 139 // Assign current component to parent reference 140 $this->TreeBuilder->openBranch($TagInfo, $tag, $attrs, FALSE, $this->Locator); 141 142 // Switch to literal state as required 143 if ( $this->TreeBuilder->Component->preParse() == PARSER_FORBID_PARSING) { 144 $this->Parser->changeToLiteralParsingState($tag); 145 } 146 147 // Cleanup for components that have no closing tag 148 if ( $TagInfo->EndTag == ENDTAG_FORBIDDEN ) { 149 $this->TreeBuilder->closeBranch(FALSE); 150 $this->Parser->changeToComponentParsingState(); 151 } 152 } else { 153 if (strcasecmp($this->TreeBuilder->Component->tag, $tag) == 0 ) { 154 $this->TreeBuilder->Component->plainTagCount++; 155 } 156 $this->TreeBuilder->addContent($this->Locator, 157 '<' . $tag . $this->getAttributeString($attrs) . '>'); 158 } 159 } 160 161 /** 162 * Handle closing tags 163 * @param string tag name 164 * @access public 165 */ 166 function endElement($tag) { 167 $TagInfo =& $this->TagDictionary->getTagInfo($tag); 168 if (is_object($TagInfo) && $TagInfo->EndTag == ENDTAG_FORBIDDEN) { 169 RaiseError('compiler', 'UNEXPECTEDCLOSE2', array( 170 'tag' => $TagInfo->Tag, 171 'file' => $this->Locator->getPublicId(), 172 'line' => $this->Locator->getLineNumber())); 173 } 174 if ( strcasecmp($this->TreeBuilder->Component->tag, $tag) == 0 ) { 175 // See bug 906138 - it's just a plain tag not the close of a ServerTagComponentTag 176 if ($this->TreeBuilder->Component->plainTagCount != 0 ) { 177 $this->TreeBuilder->Component->plainTagCount--; 178 $this->TreeBuilder->addTextNode('</' . $tag . '>'); 179 } else { 180 $this->TreeBuilder->closeBranch(TRUE); 181 } 182 } else { 183 $this->TreeBuilder->addTextNode('</' . $tag . '>'); 184 } 185 } 186 187 /** 188 * Handle empty tags 189 * @param string tag name 190 * @param array tag attributes 191 * @access public 192 */ 193 function emptyElement($tag, $attrs) { 194 $lower_attributes = array_change_key_case($attrs, CASE_LOWER); 195 if ( isset($lower_attributes[PARSER_TRIGGER_ATTR_NAME]) && 196 strpos($lower_attributes[PARSER_TRIGGER_ATTR_NAME], '{$') !== FALSE) { 197 RaiseError('compiler', 'ILLEGALVARREFINATTR', array( 198 'tag' => $this->Component->tag, 199 'attribute' => $name, 200 'file' => $this->Locator->getPublicId(), 201 'line' => $this->Locator->getLineNumber())); 202 } 203 204 $TagInfo =& $this->TagDictionary->findComponent($tag, $lower_attributes, TRUE, $this->TreeBuilder->Component); 205 if (is_object($TagInfo)) { 206 $TagInfo->load(); 207 208 // Assign current component to parent reference 209 $this->TreeBuilder->openBranch($TagInfo, $tag, $attrs, TRUE, $this->Locator); 210 211 // Switch to literal state as required 212 if ( $this->TreeBuilder->Component->preParse() == PARSER_FORBID_PARSING) { 213 $this->Parser->changeToLiteralParsingState($tag); 214 } 215 216 // Cleanup for components that have no closing tag 217 if ( $TagInfo->EndTag == ENDTAG_FORBIDDEN ) { 218 $this->Parser->changeToComponentParsingState(); 219 $this->TreeBuilder->closeBranch(FALSE); 220 } else { 221 $this->TreeBuilder->closeBranch(TRUE); 222 } 223 } else { 224 $this->TreeBuilder->addContent($this->Locator, 225 '<' . $tag . $this->getAttributeString($attrs) . ' />'); 226 } 227 } 228 229 /** 230 * Handle tag content 231 * @param string tag content 232 * @access public 233 */ 234 function characters($text) { 235 $this->TreeBuilder->addContent($this->Locator, $text); 236 } 237 238 /** 239 * Handle tag content 240 * @param string tag content 241 * @access public 242 */ 243 function cdata($text) { 244 $this->TreeBuilder->addContent($this->Locator, '<![CDATA[' . $text . ']]>'); 245 } 246 247 /** 248 * Handle processing instructions 249 * @param string target processor 250 * @param string instruction 251 * @access public 252 */ 253 function processingInstruction($target, $instruction) { 254 $this->TreeBuilder->addProcessingInstructionNode($target, $instruction); 255 } 256 257 /** 258 * Handle JSP / ASP markup 259 * @param string content 260 * @access public 261 */ 262 function jasp($text) { 263 // Name of method is not good in this case 264 $this->TreeBuilder->addContent($this->Locator, '<%' . $text . '%>'); 265 } 266 267 /** 268 * Handle XML escape sequences 269 * @param string content of escape 270 * @access public 271 */ 272 function escape($text) { 273 $this->TreeBuilder->addContent($this->Locator, '<!' . $text . '>'); 274 } 275 276 /** 277 * Handle doctype 278 * @param string content of doctype 279 * @access public 280 */ 281 function doctype($text) { 282 $this->TreeBuilder->addContent($this->Locator, '<!' . $text . '>'); 283 } 284 285 /** 286 * Handle XML comments 287 * @param string content of comment 288 * @access public 289 */ 290 function comment($text) { 291 // Name of method is not good in this case 292 $this->TreeBuilder->addContent($this->Locator, '<!--' . $text . '-->'); 293 } 294 295 /** 296 * Handle EOF Error 297 * @param string tag content 298 * @access public 299 */ 300 function unexpectedEOF($text) { 301 // Ignore the error and treat the rest of the file like data 302 $this->TreeBuilder->addContent($this->Locator, $text); 303 } 304 305 /** 306 * Entity syntax Error Handler 307 * @param string tag content 308 * @access public 309 */ 310 function invalidEntitySyntax($text) { 311 // Ignore the error and treat the rest of the file like data 312 $this->TreeBuilder->addContent($this->Locator, $text); 313 } 314 315 } 316 317 /** 318 * Handler for the literal parsing state 319 * @see http://wact.sourceforge.net/index.php/LiteralParsingState 320 * @access public 321 * @access WACT_TEMPLATE 322 */ 323 class LiteralParsingState extends BaseParsingState { 324 /** 325 * Name of the literal tag 326 * @var string 327 * @access public 328 */ 329 var $literalTag; 330 331 /** 332 * @param SourceFileParser 333 * @access public 334 */ 335 function LiteralParsingState(&$Parser, &$TreeBuilder) { 336 parent::BaseParsingState($Parser, $TreeBuilder); 337 } 338 339 function getAttributeString($attrs) { 340 $attrib_str = ''; 341 foreach ( $attrs as $key => $value ) { 342 $attrib_str .= ' ' . $key; 343 if (!is_null($value)) { 344 if (strpos($value, '"') === FALSE) { 345 $attrib_str .= '="' . $value . '"'; 346 } else { 347 $attrib_str .= '=\'' . $value . '\''; 348 } 349 } 350 } 351 return $attrib_str; 352 } 353 354 /** 355 * Handle opening tags 356 * @param string tag name 357 * @param array tag attributes 358 * @access public 359 */ 360 function startElement($tag, $attrs) { 361 $this->TreeBuilder->addTextNode('<' . $tag . $this->getAttributeString($attrs) . '>'); 362 } 363 364 /** 365 * Handle closing tags 366 * @param string tag name 367 * @param boolean empty tag or not 368 * @access public 369 */ 370 function endElement($tag) { 371 if ( $this->literalTag == $tag ) { 372 $this->TreeBuilder->closeBranch(TRUE); 373 $this->Parser->changeToComponentParsingState(); 374 } else { 375 $this->TreeBuilder->addTextNode('</' . $tag . '>'); 376 } 377 } 378 379 /** 380 * Handle empty tags 381 * @param string tag name 382 * @param array tag attributes 383 * @access public 384 */ 385 function emptyElement($tag, $attrs) { 386 $this->TreeBuilder->addTextNode('<' . $tag . $this->getAttributeString($attrs) . ' />'); 387 } 388 389 /** 390 * Handle tag content 391 * @param string tag content 392 * @access public 393 * @abstract 394 */ 395 function characters($text) { 396 $this->TreeBuilder->addTextNode($text); 397 } 398 399 /** 400 * Handle tag content 401 * @param string tag content 402 * @access public 403 */ 404 function cdata($text) { 405 $this->TreeBuilder->addTextNode('<![CDATA[' . $text . ']]>'); 406 } 407 408 /** 409 * Handle processing instructions 410 * @param string target processor 411 * @param string instruction 412 * @access public 413 */ 414 function processingInstruction($target, $instruction) { 415 $this->TreeBuilder->addTextNode('<?' . $target . ' ' . $instruction . '?>'); 416 } 417 418 /** 419 * Handle JSP / ASP markup 420 * @param string content 421 * @access public 422 */ 423 function jasp($text) { 424 $this->TreeBuilder->addTextNode('<%' . $text . '%>'); 425 } 426 427 /** 428 * Handle XML escape sequences 429 * @param string content of escape 430 * @access public 431 */ 432 function escape($text) { 433 $this->TreeBuilder->addTextNode('<!' . $text . '>'); 434 } 435 436 /** 437 * Handle XML comments 438 * @param string content of comment 439 * @access public 440 */ 441 function comment($text) { 442 $this->TreeBuilder->addTextNode('<!--' . $text . '-->'); 443 } 444 445 /** 446 * Handle doctype 447 * @param string content of escape 448 * @access public 449 */ 450 function doctype($text) { 451 $this->TreeBuilder->addTextNode('<!' . $text . '>'); 452 } 453 454 /** 455 * Handle EOF error 456 * @param string tag content 457 * @access public 458 * @abstract 459 */ 460 function unexpectedEOF($text) { 461 // Ignore the error and treat the rest of the file like data 462 $this->TreeBuilder->addTextNode($text); 463 } 464 465 /** 466 * Entity syntax Error Handler 467 * @param string tag content 468 * @access public 469 * @abstract 470 */ 471 function invalidEntitySyntax($text) { 472 // Ignore the error and treat the rest of the file like data 473 $this->TreeBuilder->addTextNode($text); 474 } 475 476 } 477 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Sun Nov 28 19:36:09 2004 | Cross-referenced by PHPXref 0.5 |