Coverage Report - org.jaxen.JaxenHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
JaxenHandler
96%
165/172
93%
14/15
1.226
 
 1  
 /*
 2  
  * $Header$
 3  
  * $Revision: 1132 $
 4  
  * $Date: 2006-03-30 05:53:11 -0800 (Thu, 30 Mar 2006) $
 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 1132 2006-03-30 13:53:11Z elharo $
 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  15351
     {
 96  15351
         this.stack        = new LinkedList();
 97  15351
         this.xpathFactory = new DefaultXPathFactory();
 98  15351
     }
 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  125
         this.xpathFactory = xpathFactory;
 108  125
     }
 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  144474
         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  15326
         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  15511
         if ( shouldSimplify && ! this.simplified )
 149  
         {
 150  15326
             this.xpath.simplify();
 151  15326
             this.simplified = true;
 152  
         }
 153  
 
 154  15511
         return this.xpath;
 155  
     }
 156  
 
 157  
     public void startXPath()
 158  
     {
 159  15551
         this.simplified = false;
 160  15551
         pushFrame();
 161  15551
     }
 162  
     
 163  
     public void endXPath() throws JaxenException
 164  
     {
 165  15366
         this.xpath = getXPathFactory().createXPath( (Expr) pop() );
 166  15366
         popFrame();
 167  15366
     }
 168  
 
 169  
     public void startPathExpr()
 170  
     {
 171  37373
         pushFrame();
 172  37373
     }
 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  37168
         if ( stackSize() == 2 )
 196  
         {
 197  265
             locationPath = (LocationPath) pop();
 198  265
             filterExpr   = (FilterExpr) pop();
 199  
         }
 200  
         else
 201  
         {
 202  36903
             popped = pop();
 203  
 
 204  36903
             if ( popped instanceof LocationPath )
 205  
             {
 206  13472
                 locationPath = (LocationPath) popped;
 207  13472
                 filterExpr   = null;
 208  
             }
 209  
             else
 210  
             {
 211  23431
                 locationPath = null;
 212  23431
                 filterExpr   = (FilterExpr) popped;
 213  
             }
 214  
         }
 215  37168
         popFrame();
 216  
 
 217  37168
         push( getXPathFactory().createPathExpr( filterExpr,
 218  
                                                locationPath ) );
 219  37168
     }
 220  
 
 221  
     public void startAbsoluteLocationPath() throws JaxenException
 222  
     {
 223  7936
         pushFrame();
 224  
 
 225  7936
         push( getXPathFactory().createAbsoluteLocationPath() );
 226  7936
     }
 227  
 
 228  
     public void endAbsoluteLocationPath() throws JaxenException
 229  
     {
 230  7826
         endLocationPath();
 231  7826
     }
 232  
 
 233  
     public void startRelativeLocationPath() throws JaxenException
 234  
     {
 235  5921
         pushFrame();
 236  
 
 237  5921
         push( getXPathFactory().createRelativeLocationPath() );
 238  5921
     }
 239  
 
 240  
     public void endRelativeLocationPath() throws JaxenException
 241  
     {
 242  5911
         endLocationPath();
 243  5911
     }
 244  
 
 245  
     protected void endLocationPath() throws JaxenException 
 246  
     {
 247  13737
         LocationPath path = (LocationPath) peekFrame().removeFirst();
 248  
 
 249  13737
         addSteps( path,
 250  
                   popFrame().iterator() );
 251  
 
 252  13737
         push( path );
 253  13737
     }
 254  
 
 255  
     protected void addSteps(LocationPath locationPath,
 256  
                           Iterator stepIter)
 257  
     {
 258  36747
         while ( stepIter.hasNext() )
 259  
         {
 260  23010
             locationPath.addStep( (Step) stepIter.next() );
 261  
         }
 262  13737
     }
 263  
 
 264  
     public void startNameStep(int axis,
 265  
                               String prefix,
 266  
                               String localName) throws JaxenException
 267  
     {
 268  18934
         pushFrame();
 269  
 
 270  18934
         push( getXPathFactory().createNameStep( axis,
 271  
                                                prefix,
 272  
                                                localName ) );
 273  18934
     }
 274  
 
 275  
     public void endNameStep() 
 276  
     {
 277  18894
         endStep();
 278  18894
     }
 279  
     
 280  
     public void startTextNodeStep(int axis) throws JaxenException
 281  
     {
 282  
         //System.err.println("startTextNodeStep()");
 283  390
         pushFrame();
 284  
         
 285  390
         push( getXPathFactory().createTextNodeStep( axis ) );
 286  390
     }
 287  
     
 288  
     public void endTextNodeStep()
 289  
     {
 290  390
         endStep();
 291  390
     }
 292  
 
 293  
     public void startCommentNodeStep(int axis) throws JaxenException
 294  
     {
 295  225
         pushFrame();
 296  
 
 297  225
         push( getXPathFactory().createCommentNodeStep( axis ) );
 298  225
     }
 299  
 
 300  
     public void endCommentNodeStep()
 301  
     {
 302  225
         endStep();
 303  225
     }
 304  
         
 305  
     public void startAllNodeStep(int axis) throws JaxenException
 306  
     {
 307  3238
         pushFrame();
 308  
 
 309  3238
         push( getXPathFactory().createAllNodeStep( axis ) );
 310  3238
     }
 311  
 
 312  
     public void endAllNodeStep()
 313  
     {
 314  3238
         endStep();
 315  3238
     }
 316  
 
 317  
     public void startProcessingInstructionNodeStep(int axis,
 318  
                                                    String name) throws JaxenException
 319  
     {
 320  358
         pushFrame();
 321  
 
 322  358
         push( getXPathFactory().createProcessingInstructionNodeStep( axis,
 323  
                                                                     name ) );
 324  358
     }
 325  
     
 326  
     public void endProcessingInstructionNodeStep()
 327  
     {
 328  358
         endStep();
 329  358
     }
 330  
 
 331  
     protected void endStep()
 332  
     {
 333  23105
         Step step = (Step) peekFrame().removeFirst();
 334  
 
 335  23105
         addPredicates( step,
 336  
                        popFrame().iterator() );
 337  
 
 338  23105
         push( step );
 339  23105
     }
 340  
     
 341  
     public void startPredicate()
 342  
     {
 343  3413
         pushFrame();
 344  3413
     }
 345  
     
 346  
     public void endPredicate() throws JaxenException
 347  
     {
 348  3373
         Predicate predicate = getXPathFactory().createPredicate( (Expr) pop() );
 349  
 
 350  3373
         popFrame();
 351  
 
 352  3373
         push( predicate );
 353  3373
     }
 354  
 
 355  
     public void startFilterExpr() 
 356  
     {
 357  23746
         pushFrame();
 358  23746
     }
 359  
 
 360  
     public void endFilterExpr() throws JaxenException
 361  
     {
 362  23706
         Expr expr = (Expr) peekFrame().removeFirst();
 363  
         
 364  23706
         FilterExpr filter = getXPathFactory().createFilterExpr( expr );
 365  
 
 366  23706
         Iterator predIter = popFrame().iterator();
 367  
 
 368  23706
         addPredicates( filter,
 369  
                        predIter );
 370  
 
 371  23706
         push( filter );
 372  23706
     }
 373  
 
 374  
     protected void addPredicates(Predicated obj,
 375  
                                Iterator predIter)
 376  
     {
 377  50184
         while ( predIter.hasNext() )
 378  
         {
 379  3373
             obj.addPredicate( (Predicate) predIter.next() );
 380  
         }
 381  46811
     }
 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  30223
     }
 393  
 
 394  
     public void endOrExpr(boolean create) throws JaxenException
 395  
     {
 396  
 
 397  30018
         if ( create )
 398  
         {
 399  48
             Expr rhs = (Expr) pop();
 400  48
             Expr lhs = (Expr) pop();
 401  
 
 402  48
             push( getXPathFactory().createOrExpr( lhs,
 403  
                                                  rhs ) );
 404  
         }
 405  30018
     }
 406  
 
 407  
     public void startAndExpr()
 408  
     {
 409  30843
     }
 410  
 
 411  
     public void endAndExpr(boolean create) throws JaxenException
 412  
     {
 413  
 
 414  30638
         if ( create )
 415  
         {
 416  
 
 417  620
             Expr rhs = (Expr) pop();
 418  620
             Expr lhs = (Expr) pop();
 419  
 
 420  620
             push( getXPathFactory().createAndExpr( lhs,
 421  
                                                   rhs ) );
 422  
         }
 423  30638
     }
 424  
 
 425  
     public void startEqualityExpr()
 426  
     {
 427  3175
     }
 428  
 
 429  
     public void endEqualityExpr(int operator) throws JaxenException
 430  
     {
 431  
 
 432  3175
         if ( operator != Operator.NO_OP )
 433  
         {
 434  
             
 435  3175
             Expr rhs = (Expr) pop();
 436  3175
             Expr lhs = (Expr) pop();
 437  
             
 438  3175
             push( getXPathFactory().createEqualityExpr( lhs,
 439  
                                                         rhs,
 440  
                                                         operator ) );
 441  
         }
 442  3175
     }
 443  
 
 444  
     public void startRelationalExpr()
 445  
     {
 446  1145
     }
 447  
 
 448  
     public void endRelationalExpr(int operator) throws JaxenException
 449  
     {
 450  
 
 451  1145
         if ( operator != Operator.NO_OP )
 452  
         {
 453  
 
 454  1145
             Expr rhs = (Expr) pop();
 455  1145
             Expr lhs = (Expr) pop();
 456  
 
 457  1145
             push( getXPathFactory().createRelationalExpr( lhs,
 458  
                                                          rhs,
 459  
                                                          operator ) );
 460  
         }
 461  1145
     }
 462  
 
 463  
     public void startAdditiveExpr()
 464  
     {
 465  1265
     }
 466  
 
 467  
     public void endAdditiveExpr(int operator) throws JaxenException
 468  
     {
 469  
 
 470  1260
         if ( operator != Operator.NO_OP )
 471  
         {
 472  
             
 473  1260
             Expr rhs = (Expr) pop();
 474  1260
             Expr lhs = (Expr) pop();
 475  
             
 476  1260
             push( getXPathFactory().createAdditiveExpr( lhs,
 477  
                                                         rhs,
 478  
                                                         operator ) );
 479  
         }
 480  1260
     }
 481  
 
 482  
     public void startMultiplicativeExpr()
 483  
     {
 484  945
     }
 485  
 
 486  
     public void endMultiplicativeExpr(int operator) throws JaxenException
 487  
     {
 488  
 
 489  945
         if ( operator != Operator.NO_OP )
 490  
         {
 491  
 
 492  945
             Expr rhs = (Expr) pop();
 493  945
             Expr lhs = (Expr) pop();
 494  
             
 495  945
             push( getXPathFactory().createMultiplicativeExpr( lhs,
 496  
                                                              rhs,
 497  
                                                              operator ) );
 498  
         }
 499  945
     }
 500  
 
 501  
     public void startUnaryExpr()
 502  
     {
 503  340
      }
 504  
 
 505  
     public void endUnaryExpr(int operator) throws JaxenException
 506  
     {
 507  
 
 508  340
         if ( operator != Operator.NO_OP )
 509  
         {
 510  340
             push( getXPathFactory().createUnaryExpr( (Expr) pop(),
 511  
                                                     operator ) );
 512  
         }
 513  340
     }
 514  
 
 515  
     public void startUnionExpr() 
 516  
     {
 517  37373
     }
 518  
 
 519  
     public void endUnionExpr(boolean create) throws JaxenException
 520  
     {
 521  
 
 522  37168
         if ( create )
 523  
         {
 524  
 
 525  100
             Expr rhs = (Expr) pop();
 526  100
             Expr lhs = (Expr) pop();
 527  
 
 528  100
             push( getXPathFactory().createUnionExpr( lhs,
 529  
                                                     rhs ) );
 530  
         }
 531  37168
     }
 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  7883
         push( getXPathFactory().createNumberExpr( number ) );
 541  7883
     }
 542  
 
 543  
     public void literal(String literal) throws JaxenException
 544  
     {
 545  5514
         push( getXPathFactory().createLiteralExpr( literal ) );
 546  5514
     }
 547  
 
 548  
     public void variableReference(String prefix,
 549  
                                   String variableName) throws JaxenException
 550  
     {
 551  195
         push( getXPathFactory().createVariableReferenceExpr( prefix,
 552  
                                                              variableName ) );
 553  195
     }
 554  
 
 555  
     public void startFunction(String prefix,
 556  
                               String functionName) throws JaxenException
 557  
     {
 558  6634
         pushFrame();
 559  6634
         push( getXPathFactory().createFunctionCallExpr( prefix,
 560  
                                                         functionName ) );
 561  6634
     }
 562  
 
 563  
     public void endFunction()
 564  
     {
 565  6614
         FunctionCallExpr function = (FunctionCallExpr) peekFrame().removeFirst();
 566  
 
 567  6614
         addParameters( function,
 568  
                        popFrame().iterator() );
 569  
 
 570  6614
         push( function );
 571  6614
     }
 572  
 
 573  
     protected void addParameters(FunctionCallExpr function,
 574  
                                Iterator paramIter)
 575  
     {
 576  14185
         while ( paramIter.hasNext() )
 577  
         {
 578  7571
             function.addParameter( (Expr) paramIter.next() );
 579  
         }
 580  6614
     }
 581  
 
 582  
     protected int stackSize()
 583  
     {
 584  37168
         return peekFrame().size();
 585  
     }
 586  
 
 587  
     protected void push(Object obj)
 588  
     {
 589  172564
         peekFrame().addLast( obj );
 590  172564
     }
 591  
 
 592  
     protected Object pop()
 593  
     {
 594  71098
         return peekFrame().removeLast();
 595  
     }
 596  
 
 597  
     protected boolean canPop()
 598  
     {
 599  0
         return ( peekFrame().size() > 0 );
 600  
     }
 601  
 
 602  
     protected void pushFrame()
 603  
     {
 604  123719
         this.stack.addLast( new LinkedList() );
 605  123719
     }
 606  
 
 607  
     protected LinkedList popFrame()
 608  
     {
 609  123069
         return (LinkedList) this.stack.removeLast();
 610  
     }
 611  
 
 612  
     protected LinkedList peekFrame()
 613  
     {
 614  347992
         return (LinkedList) this.stack.getLast();
 615  
     }
 616  
 }