[ Index ]

PHP Cross Reference of Web Application Component Toolkit

title

Body

[close]

/framework/template/compiler/ -> parserstate.inc.php (source)

   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  ?>


Generated: Sun Nov 28 19:36:09 2004 Cross-referenced by PHPXref 0.5