Coverage Report - org.jaxen.JaxenHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
JaxenHandler
96%
170/177
93%
14/15
1.226
 
 1  
 /*
 2  
  * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/JaxenHandler.java,v 1.15 2006/03/30 13:53:11 elharo Exp $
 3  
  * $Revision: 1.15 $
 4  
  * $Date: 2006/03/30 13:53:11 $
 5  
  *
 6  
  * ====================================================================
 7  
  *
 8  
  * Copyright 2000-2002 bob mcwhirter & James Strachan.
 9  
  * All rights reserved.
 10  
  *
 11  
  * Redistribution and use in source and binary forms, with or without
 12  
  * modification, are permitted provided that the following conditions are
 13  
  * met:
 14  
  * 
 15  
  *   * Redistributions of source code must retain the above copyright
 16  
  *     notice, this list of conditions and the following disclaimer.
 17  
  * 
 18  
  *   * Redistributions in binary form must reproduce the above copyright
 19  
  *     notice, this list of conditions and the following disclaimer in the
 20  
  *     documentation and/or other materials provided with the distribution.
 21  
  * 
 22  
  *   * Neither the name of the Jaxen Project nor the names of its
 23  
  *     contributors may be used to endorse or promote products derived 
 24  
  *     from this software without specific prior written permission.
 25  
  * 
 26  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 27  
  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 28  
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 29  
  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 30  
  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 31  
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 32  
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 33  
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 34  
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 35  
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 36  
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 37  
  *
 38  
  * ====================================================================
 39  
  * This software consists of voluntary contributions made by many 
 40  
  * individuals on behalf of the Jaxen Project and was originally 
 41  
  * created by bob mcwhirter <bob@werken.com> and 
 42  
  * James Strachan <jstrachan@apache.org>.  For more information on the 
 43  
  * Jaxen Project, please see <http://www.jaxen.org/>.
 44  
  * 
 45  
  * $Id: JaxenHandler.java,v 1.15 2006/03/30 13:53:11 elharo Exp $
 46  
  */
 47  
 
 48  
 
 49  
 
 50  
 package org.jaxen;
 51  
 
 52  
 import java.util.Iterator;
 53  
 import java.util.LinkedList;
 54  
 
 55  
 import org.jaxen.expr.DefaultXPathFactory;
 56  
 import org.jaxen.expr.Expr;
 57  
 import org.jaxen.expr.FilterExpr;
 58  
 import org.jaxen.expr.FunctionCallExpr;
 59  
 import org.jaxen.expr.LocationPath;
 60  
 import org.jaxen.expr.Predicate;
 61  
 import org.jaxen.expr.Predicated;
 62  
 import org.jaxen.expr.Step;
 63  
 import org.jaxen.expr.XPathExpr;
 64  
 import org.jaxen.expr.XPathFactory;
 65  
 import org.jaxen.saxpath.Operator;
 66  
 import org.jaxen.saxpath.XPathHandler;
 67  
 
 68  
 /** SAXPath <code>XPathHandler</code> implementation capable
 69  
  *  of building Jaxen expression trees which can walk various
 70  
  *  different object models.
 71  
  *
 72  
  *  @author bob mcwhirter (bob@werken.com)
 73  
  */
 74  
 public class JaxenHandler implements XPathHandler
 75  
 {
 76  
     private XPathFactory xpathFactory;
 77  
     private XPathExpr    xpath;
 78  
     
 79  
     /**
 80  
      * ????
 81  
      */
 82  
     protected boolean simplified;
 83  
 
 84  
     /**
 85  
      * This may be changed to an ArrayList in the future (i.e. version &gt;= 1.2). 
 86  
      * You really shouldn't be accessing this field directly, but
 87  
      * if you are please try to use it as a generic List. Don't use the 
 88  
      * methods that are only available in LinkedList.
 89  
      */
 90  
     protected LinkedList stack;
 91  
 
 92  
     /** Constructor
 93  
      */
 94  
     public JaxenHandler()
 95  6118
     {
 96  6118
         this.stack        = new LinkedList();
 97  6118
         this.xpathFactory = new DefaultXPathFactory();
 98  6118
     }
 99  
     
 100  
     /** Set the Jaxen <code>XPathFactory</code> that constructs
 101  
      *  the XPath expression tree during the parse.
 102  
      *
 103  
      *  @param xpathFactory the factory to use during the parse
 104  
      */
 105  
     public void setXPathFactory(XPathFactory xpathFactory)
 106  
     {
 107  50
         this.xpathFactory = xpathFactory;
 108  50
     }
 109  
 
 110  
     /** Retrieve the Jaxen <code>XPathFactory</code> used
 111  
      *  during the parse to construct the XPath expression tree.
 112  
      *
 113  
      *  @return the <code>XPathFactory</code> used during the parse.
 114  
      */
 115  
     public XPathFactory getXPathFactory()
 116  
     {
 117  57572
         return this.xpathFactory;
 118  
     }
 119  
 
 120  
     /** Retrieve the simplified Jaxen XPath expression tree.
 121  
      *
 122  
      *  <p>
 123  
      *  This method is only valid once <code>XPathReader.parse(...)</code>
 124  
      *  successfully returned.
 125  
      *  </p>
 126  
      *
 127  
      *  @return the XPath expression tree
 128  
      */
 129  
     public XPathExpr getXPathExpr()
 130  
     {
 131  6108
         return getXPathExpr( true );
 132  
     }
 133  
 
 134  
     /** Retrieve the Jaxen XPath expression tree, optionally
 135  
      *  simplified.
 136  
      *
 137  
      *  <p>
 138  
      *  This method is only valid once <code>XPathReader.parse(...)</code>
 139  
      *  successfully returned.
 140  
      *  </p>
 141  
      *  
 142  
      *  @param shouldSimplify ????
 143  
      *
 144  
      *  @return the XPath expression tree
 145  
      */
 146  
     public XPathExpr getXPathExpr(boolean shouldSimplify)
 147  
     {
 148  6182
         if ( shouldSimplify && ! this.simplified )
 149  
         {
 150  6108
             this.xpath.simplify();
 151  6108
             this.simplified = true;
 152  
         }
 153  
 
 154  6182
         return this.xpath;
 155  
     }
 156  
 
 157  
     public void startXPath()
 158  
     {
 159  6198
         this.simplified = false;
 160  6198
         pushFrame();
 161  6198
     }
 162  
     
 163  
     public void endXPath() throws JaxenException
 164  
     {
 165  6124
         this.xpath = getXPathFactory().createXPath( (Expr) pop() );
 166  6124
         popFrame();
 167  6124
     }
 168  
 
 169  
     public void startPathExpr()
 170  
     {
 171  14898
         pushFrame();
 172  14898
     }
 173  
 
 174  
     public void endPathExpr() throws JaxenException
 175  
     {
 176  
 
 177  
         // PathExpr ::=   LocationPath
 178  
         //              | FilterExpr
 179  
         //              | FilterExpr / RelativeLocationPath
 180  
         //              | FilterExpr // RelativeLocationPath
 181  
         //
 182  
         // If the current stack-frame has two items, it's a
 183  
         // FilterExpr and a LocationPath (of some flavor).
 184  
         //
 185  
         // If the current stack-frame has one item, it's simply
 186  
         // a FilterExpr, and more than likely boils down to a
 187  
         // primary expr of some flavor.  But that's for another
 188  
         // method...
 189  
 
 190  
         FilterExpr   filterExpr;
 191  
         LocationPath locationPath;
 192  
 
 193  
         Object       popped;
 194  
 
 195  14816
         if ( stackSize() == 2 )
 196  
         {
 197  106
             locationPath = (LocationPath) pop();
 198  106
             filterExpr   = (FilterExpr) pop();
 199  106
         }
 200  
         else
 201  
         {
 202  14710
             popped = pop();
 203  
 
 204  14710
             if ( popped instanceof LocationPath )
 205  
             {
 206  5360
                 locationPath = (LocationPath) popped;
 207  5360
                 filterExpr   = null;
 208  5360
             }
 209  
             else
 210  
             {
 211  9350
                 locationPath = null;
 212  9350
                 filterExpr   = (FilterExpr) popped;
 213  
             }
 214  
         }
 215  14816
         popFrame();
 216  
 
 217  14816
         push( getXPathFactory().createPathExpr( filterExpr,
 218  
                                                locationPath ) );
 219  14816
     }
 220  
 
 221  
     public void startAbsoluteLocationPath() throws JaxenException
 222  
     {
 223  3152
         pushFrame();
 224  
 
 225  3152
         push( getXPathFactory().createAbsoluteLocationPath() );
 226  3152
     }
 227  
 
 228  
     public void endAbsoluteLocationPath() throws JaxenException
 229  
     {
 230  3108
         endLocationPath();
 231  3108
     }
 232  
 
 233  
     public void startRelativeLocationPath() throws JaxenException
 234  
     {
 235  2362
         pushFrame();
 236  
 
 237  2362
         push( getXPathFactory().createRelativeLocationPath() );
 238  2362
     }
 239  
 
 240  
     public void endRelativeLocationPath() throws JaxenException
 241  
     {
 242  2358
         endLocationPath();
 243  2358
     }
 244  
 
 245  
     protected void endLocationPath() throws JaxenException 
 246  
     {
 247  5466
         LocationPath path = (LocationPath) peekFrame().removeFirst();
 248  
 
 249  5466
         addSteps( path,
 250  
                   popFrame().iterator() );
 251  
 
 252  5466
         push( path );
 253  5466
     }
 254  
 
 255  
     protected void addSteps(LocationPath locationPath,
 256  
                           Iterator stepIter)
 257  
     {
 258  14622
         while ( stepIter.hasNext() )
 259  
         {
 260  9156
             locationPath.addStep( (Step) stepIter.next() );
 261  9156
         }
 262  5466
     }
 263  
 
 264  
     public void startNameStep(int axis,
 265  
                               String prefix,
 266  
                               String localName) throws JaxenException
 267  
     {
 268  7548
         pushFrame();
 269  
 
 270  7548
         push( getXPathFactory().createNameStep( axis,
 271  
                                                prefix,
 272  
                                                localName ) );
 273  7548
     }
 274  
 
 275  
     public void endNameStep() 
 276  
     {
 277  7532
         endStep();
 278  7532
     }
 279  
     
 280  
     public void startTextNodeStep(int axis) throws JaxenException
 281  
     {
 282  
         //System.err.println("startTextNodeStep()");
 283  156
         pushFrame();
 284  
         
 285  156
         push( getXPathFactory().createTextNodeStep( axis ) );
 286  156
     }
 287  
     
 288  
     public void endTextNodeStep()
 289  
     {
 290  156
         endStep();
 291  156
     }
 292  
 
 293  
     public void startCommentNodeStep(int axis) throws JaxenException
 294  
     {
 295  90
         pushFrame();
 296  
 
 297  90
         push( getXPathFactory().createCommentNodeStep( axis ) );
 298  90
     }
 299  
 
 300  
     public void endCommentNodeStep()
 301  
     {
 302  90
         endStep();
 303  90
     }
 304  
         
 305  
     public void startAllNodeStep(int axis) throws JaxenException
 306  
     {
 307  1276
         pushFrame();
 308  
 
 309  1276
         push( getXPathFactory().createAllNodeStep( axis ) );
 310  1276
     }
 311  
 
 312  
     public void endAllNodeStep()
 313  
     {
 314  1276
         endStep();
 315  1276
     }
 316  
 
 317  
     public void startProcessingInstructionNodeStep(int axis,
 318  
                                                    String name) throws JaxenException
 319  
     {
 320  140
         pushFrame();
 321  
 
 322  140
         push( getXPathFactory().createProcessingInstructionNodeStep( axis,
 323  
                                                                     name ) );
 324  140
     }
 325  
     
 326  
     public void endProcessingInstructionNodeStep()
 327  
     {
 328  140
         endStep();
 329  140
     }
 330  
 
 331  
     protected void endStep()
 332  
     {
 333  9194
         Step step = (Step) peekFrame().removeFirst();
 334  
 
 335  9194
         addPredicates( step,
 336  
                        popFrame().iterator() );
 337  
 
 338  9194
         push( step );
 339  9194
     }
 340  
     
 341  
     public void startPredicate()
 342  
     {
 343  1362
         pushFrame();
 344  1362
     }
 345  
     
 346  
     public void endPredicate() throws JaxenException
 347  
     {
 348  1346
         Predicate predicate = getXPathFactory().createPredicate( (Expr) pop() );
 349  
 
 350  1346
         popFrame();
 351  
 
 352  1346
         push( predicate );
 353  1346
     }
 354  
 
 355  
     public void startFilterExpr() 
 356  
     {
 357  9476
         pushFrame();
 358  9476
     }
 359  
 
 360  
     public void endFilterExpr() throws JaxenException
 361  
     {
 362  9460
         Expr expr = (Expr) peekFrame().removeFirst();
 363  
         
 364  9460
         FilterExpr filter = getXPathFactory().createFilterExpr( expr );
 365  
 
 366  9460
         Iterator predIter = popFrame().iterator();
 367  
 
 368  9460
         addPredicates( filter,
 369  
                        predIter );
 370  
 
 371  9460
         push( filter );
 372  9460
     }
 373  
 
 374  
     protected void addPredicates(Predicated obj,
 375  
                                Iterator predIter)
 376  
     {
 377  20000
         while ( predIter.hasNext() )
 378  
         {
 379  1346
             obj.addPredicate( (Predicate) predIter.next() );
 380  1346
         }
 381  18654
     }
 382  
 
 383  
     protected void returnExpr()
 384  
     {
 385  0
         Expr expr = (Expr) pop();
 386  0
         popFrame();
 387  0
         push( expr );
 388  0
     }
 389  
 
 390  
     public void startOrExpr()
 391  
     {
 392  12054
     }
 393  
 
 394  
     public void endOrExpr(boolean create) throws JaxenException
 395  
     {
 396  
 
 397  11972
         if ( create )
 398  
         {
 399  16
             Expr rhs = (Expr) pop();
 400  16
             Expr lhs = (Expr) pop();
 401  
 
 402  16
             push( getXPathFactory().createOrExpr( lhs,
 403  
                                                  rhs ) );
 404  
         }
 405  11972
     }
 406  
 
 407  
     public void startAndExpr()
 408  
     {
 409  12302
     }
 410  
 
 411  
     public void endAndExpr(boolean create) throws JaxenException
 412  
     {
 413  
 
 414  12220
         if ( create )
 415  
         {
 416  
 
 417  248
             Expr rhs = (Expr) pop();
 418  248
             Expr lhs = (Expr) pop();
 419  
 
 420  248
             push( getXPathFactory().createAndExpr( lhs,
 421  
                                                   rhs ) );
 422  
         }
 423  12220
     }
 424  
 
 425  
     public void startEqualityExpr()
 426  
     {
 427  1254
     }
 428  
 
 429  
     public void endEqualityExpr(int operator) throws JaxenException
 430  
     {
 431  
 
 432  1254
         if ( operator != Operator.NO_OP )
 433  
         {
 434  
             
 435  1254
             Expr rhs = (Expr) pop();
 436  1254
             Expr lhs = (Expr) pop();
 437  
             
 438  1254
             push( getXPathFactory().createEqualityExpr( lhs,
 439  
                                                         rhs,
 440  
                                                         operator ) );
 441  
         }
 442  1254
     }
 443  
 
 444  
     public void startRelationalExpr()
 445  
     {
 446  458
     }
 447  
 
 448  
     public void endRelationalExpr(int operator) throws JaxenException
 449  
     {
 450  
 
 451  458
         if ( operator != Operator.NO_OP )
 452  
         {
 453  
 
 454  458
             Expr rhs = (Expr) pop();
 455  458
             Expr lhs = (Expr) pop();
 456  
 
 457  458
             push( getXPathFactory().createRelationalExpr( lhs,
 458  
                                                          rhs,
 459  
                                                          operator ) );
 460  
         }
 461  458
     }
 462  
 
 463  
     public void startAdditiveExpr()
 464  
     {
 465  506
     }
 466  
 
 467  
     public void endAdditiveExpr(int operator) throws JaxenException
 468  
     {
 469  
 
 470  504
         if ( operator != Operator.NO_OP )
 471  
         {
 472  
             
 473  504
             Expr rhs = (Expr) pop();
 474  504
             Expr lhs = (Expr) pop();
 475  
             
 476  504
             push( getXPathFactory().createAdditiveExpr( lhs,
 477  
                                                         rhs,
 478  
                                                         operator ) );
 479  
         }
 480  504
     }
 481  
 
 482  
     public void startMultiplicativeExpr()
 483  
     {
 484  378
     }
 485  
 
 486  
     public void endMultiplicativeExpr(int operator) throws JaxenException
 487  
     {
 488  
 
 489  378
         if ( operator != Operator.NO_OP )
 490  
         {
 491  
 
 492  378
             Expr rhs = (Expr) pop();
 493  378
             Expr lhs = (Expr) pop();
 494  
             
 495  378
             push( getXPathFactory().createMultiplicativeExpr( lhs,
 496  
                                                              rhs,
 497  
                                                              operator ) );
 498  
         }
 499  378
     }
 500  
 
 501  
     public void startUnaryExpr()
 502  
     {
 503  136
      }
 504  
 
 505  
     public void endUnaryExpr(int operator) throws JaxenException
 506  
     {
 507  
 
 508  136
         if ( operator != Operator.NO_OP )
 509  
         {
 510  136
             push( getXPathFactory().createUnaryExpr( (Expr) pop(),
 511  
                                                     operator ) );
 512  
         }
 513  136
     }
 514  
 
 515  
     public void startUnionExpr() 
 516  
     {
 517  14898
     }
 518  
 
 519  
     public void endUnionExpr(boolean create) throws JaxenException
 520  
     {
 521  
 
 522  14816
         if ( create )
 523  
         {
 524  
 
 525  40
             Expr rhs = (Expr) pop();
 526  40
             Expr lhs = (Expr) pop();
 527  
 
 528  40
             push( getXPathFactory().createUnionExpr( lhs,
 529  
                                                     rhs ) );
 530  
         }
 531  14816
     }
 532  
 
 533  
     public void number(int number) throws JaxenException
 534  
     {
 535  0
         push( getXPathFactory().createNumberExpr( number ) );
 536  0
     }
 537  
 
 538  
     public void number(double number) throws JaxenException
 539  
     {
 540  3150
         push( getXPathFactory().createNumberExpr( number ) );
 541  3150
     }
 542  
 
 543  
     public void literal(String literal) throws JaxenException
 544  
     {
 545  2196
         push( getXPathFactory().createLiteralExpr( literal ) );
 546  2196
     }
 547  
 
 548  
     public void variableReference(String prefix,
 549  
                                   String variableName) throws JaxenException
 550  
     {
 551  78
         push( getXPathFactory().createVariableReferenceExpr( prefix,
 552  
                                                              variableName ) );
 553  78
     }
 554  
 
 555  
     public void startFunction(String prefix,
 556  
                               String functionName) throws JaxenException
 557  
     {
 558  2644
         pushFrame();
 559  2644
         push( getXPathFactory().createFunctionCallExpr( prefix,
 560  
                                                         functionName ) );
 561  2644
     }
 562  
 
 563  
     public void endFunction()
 564  
     {
 565  2636
         FunctionCallExpr function = (FunctionCallExpr) peekFrame().removeFirst();
 566  
 
 567  2636
         addParameters( function,
 568  
                        popFrame().iterator() );
 569  
 
 570  2636
         push( function );
 571  2636
     }
 572  
 
 573  
     protected void addParameters(FunctionCallExpr function,
 574  
                                Iterator paramIter)
 575  
     {
 576  5658
         while ( paramIter.hasNext() )
 577  
         {
 578  3022
             function.addParameter( (Expr) paramIter.next() );
 579  3022
         }
 580  2636
     }
 581  
 
 582  
     protected int stackSize()
 583  
     {
 584  14816
         return peekFrame().size();
 585  
     }
 586  
 
 587  
     protected void push(Object obj)
 588  
     {
 589  68744
         peekFrame().addLast( obj );
 590  68744
     }
 591  
 
 592  
     protected Object pop()
 593  
     {
 594  28324
         return peekFrame().removeLast();
 595  
     }
 596  
 
 597  
     protected boolean canPop()
 598  
     {
 599  0
         return ( peekFrame().size() > 0 );
 600  
     }
 601  
 
 602  
     protected void pushFrame()
 603  
     {
 604  49302
         this.stack.addLast( new LinkedList() );
 605  49302
     }
 606  
 
 607  
     protected LinkedList popFrame()
 608  
     {
 609  49042
         return (LinkedList) this.stack.removeLast();
 610  
     }
 611  
 
 612  
     protected LinkedList peekFrame()
 613  
     {
 614  138640
         return (LinkedList) this.stack.getLast();
 615  
     }
 616  
 }