Coverage Report - org.jaxen.pattern.PatternParser
 
Classes in this File Line Coverage Branch Coverage Complexity
PatternParser
83%
75/90
73%
41/56
7.167
 
 1  
 /*
 2  
  * $Header$
 3  
  * $Revision$
 4  
  * $Date$
 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$
 46  
  */
 47  
 
 48  
 
 49  
 package org.jaxen.pattern;
 50  
 
 51  
 import java.util.Iterator;
 52  
 import java.util.List;
 53  
 import java.util.ListIterator;
 54  
 
 55  
 import org.jaxen.JaxenException;
 56  
 import org.jaxen.JaxenHandler;
 57  
 import org.jaxen.expr.DefaultAllNodeStep;
 58  
 import org.jaxen.expr.DefaultCommentNodeStep;
 59  
 import org.jaxen.expr.DefaultFilterExpr;
 60  
 import org.jaxen.expr.DefaultNameStep;
 61  
 import org.jaxen.expr.DefaultProcessingInstructionNodeStep;
 62  
 import org.jaxen.expr.DefaultStep;
 63  
 import org.jaxen.expr.DefaultTextNodeStep;
 64  
 import org.jaxen.expr.DefaultXPathFactory;
 65  
 import org.jaxen.expr.Expr;
 66  
 import org.jaxen.expr.FilterExpr;
 67  
 import org.jaxen.expr.LocationPath;
 68  
 import org.jaxen.expr.Predicate;
 69  
 import org.jaxen.expr.PredicateSet;
 70  
 import org.jaxen.expr.Step;
 71  
 import org.jaxen.expr.UnionExpr;
 72  
 import org.jaxen.saxpath.Axis;
 73  
 import org.jaxen.saxpath.XPathReader;
 74  
 import org.jaxen.saxpath.helpers.XPathReaderFactory;
 75  
 
 76  
 
 77  
 /** <code>PatternParser</code> is a helper class for parsing
 78  
   * XSLT patterns
 79  
   *
 80  
   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 81  
   * @deprecated will be removed in Jaxen 2.0
 82  
   */
 83  0
 public class PatternParser 
 84  
 {
 85  
     private static final boolean TRACE = false;
 86  
     private static final boolean USE_HANDLER = false;
 87  
     public static Pattern parse(String text) throws JaxenException, org.jaxen.saxpath.SAXPathException
 88  
     {
 89  
         if ( USE_HANDLER )
 90  
         {
 91  
             XPathReader reader = XPathReaderFactory.createReader();
 92  
             PatternHandler handler = new PatternHandler();       
 93  
             
 94  
             handler.setXPathFactory( new DefaultXPathFactory() );            
 95  
             reader.setXPathHandler( handler );
 96  
             reader.parse( text );
 97  
             
 98  
             return handler.getPattern();
 99  
         }
 100  
         else
 101  
         {
 102  46
             XPathReader reader = XPathReaderFactory.createReader();
 103  46
             JaxenHandler handler = new JaxenHandler();
 104  
             
 105  46
             handler.setXPathFactory( new DefaultXPathFactory() );            
 106  46
             reader.setXPathHandler( handler );
 107  46
             reader.parse( text );
 108  
 
 109  46
             Pattern pattern = convertExpr( handler.getXPathExpr().getRootExpr() );
 110  46
             return pattern.simplify();
 111  
         }
 112  
     }
 113  
     
 114  
     protected static Pattern convertExpr(Expr expr) throws JaxenException 
 115  
     {
 116  
         if ( TRACE )
 117  
         {
 118  
             System.out.println( "Converting: " + expr + " into a pattern." );
 119  
         }
 120  
         
 121  58
         if ( expr instanceof LocationPath )
 122  
         {
 123  52
             return convertExpr( (LocationPath) expr );
 124  
         }
 125  6
         else if ( expr instanceof FilterExpr )
 126  
         {
 127  0
             LocationPathPattern answer = new LocationPathPattern();
 128  0
             answer.addFilter( (FilterExpr) expr );
 129  0
             return answer;
 130  
         }
 131  6
         else if ( expr instanceof UnionExpr )
 132  
         {
 133  6
             UnionExpr unionExpr = (UnionExpr) expr;
 134  6
             Pattern lhs = convertExpr( unionExpr.getLHS() );
 135  6
             Pattern rhs = convertExpr( unionExpr.getRHS() );
 136  6
             return new UnionPattern( lhs, rhs );
 137  
         }
 138  
         else 
 139  
         {
 140  0
             LocationPathPattern answer = new LocationPathPattern();
 141  0
             answer.addFilter( new DefaultFilterExpr( expr,
 142  
                                 new PredicateSet()) );
 143  0
             return answer;
 144  
         }
 145  
     }
 146  
     
 147  
     protected static LocationPathPattern convertExpr(LocationPath locationPath) throws JaxenException
 148  
     {
 149  52
         LocationPathPattern answer = new LocationPathPattern();        
 150  
         //answer.setAbsolute( locationPath.isAbsolute() );
 151  52
         List steps = locationPath.getSteps();
 152  
         
 153  
         // go through steps backwards
 154  52
         LocationPathPattern path = answer;
 155  52
         boolean first = true;
 156  52
         for ( ListIterator iter = steps.listIterator( steps.size() ); iter.hasPrevious(); ) 
 157  
         {
 158  72
             Step step = (Step) iter.previous();
 159  72
             if ( first )
 160  
             {
 161  48
                 first = false;
 162  48
                 path = convertStep( path, step );
 163  
             }
 164  
             else
 165  
             {
 166  24
                 if ( navigationStep( step ) ) 
 167  
                 {
 168  24
                     LocationPathPattern parent = new LocationPathPattern();
 169  24
                     int axis = step.getAxis();
 170  24
                     if ( axis == Axis.DESCENDANT || axis == Axis.DESCENDANT_OR_SELF )
 171  
                     {
 172  4
                         path.setAncestorPattern( parent );
 173  
                     }
 174  
                     else
 175  
                     {
 176  20
                         path.setParentPattern( parent );
 177  
                     }
 178  24
                     path = parent;
 179  
                 }
 180  24
                 path = convertStep( path, step );
 181  
             }
 182  72
         }
 183  52
         if ( locationPath.isAbsolute() )
 184  
         {
 185  8
             LocationPathPattern parent = new LocationPathPattern( NodeTypeTest.DOCUMENT_TEST );
 186  8
             path.setParentPattern( parent );
 187  
         }
 188  52
         return answer;
 189  
     }   
 190  
     
 191  
     protected static LocationPathPattern convertStep(LocationPathPattern path, Step step) throws JaxenException
 192  
     {
 193  72
         if ( step instanceof DefaultAllNodeStep )
 194  
         {
 195  4
             int axis = step.getAxis();
 196  4
             if ( axis == Axis.ATTRIBUTE )
 197  
             {
 198  0
                 path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
 199  
             }
 200  
             else 
 201  
             {
 202  4
                 path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
 203  
             }
 204  4
         }
 205  68
         else if ( step instanceof DefaultCommentNodeStep )
 206  
         {
 207  0
             path.setNodeTest( NodeTypeTest.COMMENT_TEST );
 208  
         }
 209  68
         else if ( step instanceof DefaultProcessingInstructionNodeStep )
 210  
         {
 211  0
             path.setNodeTest( NodeTypeTest.PROCESSING_INSTRUCTION_TEST );
 212  
         }
 213  68
         else if ( step instanceof DefaultTextNodeStep )
 214  
         {
 215  4
             path.setNodeTest( TextNodeTest.SINGLETON );
 216  
         }
 217  64
         else if ( step instanceof DefaultCommentNodeStep )
 218  
         {
 219  0
             path.setNodeTest( NodeTypeTest.COMMENT_TEST );
 220  
         }
 221  64
         else if ( step instanceof DefaultNameStep )
 222  
         {
 223  64
             DefaultNameStep nameStep = (DefaultNameStep) step;
 224  64
             String localName = nameStep.getLocalName();
 225  64
             String prefix = nameStep.getPrefix();
 226  64
             int axis = nameStep.getAxis();
 227  64
             short nodeType = Pattern.ELEMENT_NODE;
 228  64
             if ( axis == Axis.ATTRIBUTE )
 229  
             {
 230  4
                 nodeType = Pattern.ATTRIBUTE_NODE;
 231  
             }
 232  64
             if ( nameStep.isMatchesAnyName() )
 233  
             {
 234  16
                 if ( prefix.length() == 0 || prefix.equals( "*" ) ) 
 235  
                 {
 236  14
                     if ( axis == Axis.ATTRIBUTE )
 237  
                     {
 238  4
                         path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
 239  
                     }
 240  
                     else 
 241  
                     {
 242  10
                         path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
 243  
                     }
 244  
                 }
 245  
                 else 
 246  
                 {
 247  2
                     path.setNodeTest( new NamespaceTest( prefix, nodeType ) );
 248  
                 }
 249  
             }
 250  
             else 
 251  
             {
 252  48
                 path.setNodeTest( new NameTest( localName, nodeType ) );
 253  
                 // XXXX: should support namespace in the test too
 254  
             }
 255  64
             return convertDefaultStep(path, nameStep);
 256  
         }
 257  0
         else if ( step instanceof DefaultStep )
 258  
         {
 259  0
             return convertDefaultStep(path, (DefaultStep) step);
 260  
         }
 261  
         else 
 262  
         {
 263  0
             throw new JaxenException( "Cannot convert: " + step + " to a Pattern" );            
 264  
         }
 265  8
         return path;
 266  
     }
 267  
     
 268  
     protected static LocationPathPattern convertDefaultStep(LocationPathPattern path, DefaultStep step) throws JaxenException
 269  
     {
 270  64
         List predicates = step.getPredicates();
 271  64
         if ( ! predicates.isEmpty() ) 
 272  
         {
 273  10
             FilterExpr filter = new DefaultFilterExpr(new PredicateSet());
 274  10
             for ( Iterator iter = predicates.iterator(); iter.hasNext(); )
 275  
             {
 276  10
                 filter.addPredicate( (Predicate) iter.next() );
 277  
             }
 278  10
             path.addFilter( filter );
 279  
         }         
 280  64
         return path;
 281  
     }
 282  
     
 283  
     protected static boolean navigationStep( Step step )
 284  
     {
 285  24
         if ( step instanceof DefaultNameStep )
 286  
         {
 287  20
             return true;
 288  
         }
 289  
         else
 290  6
         if ( step.getClass().equals( DefaultStep.class ) )
 291  
         {
 292  0
             return ! step.getPredicates().isEmpty();
 293  
         }
 294  
         else 
 295  
         {
 296  4
             return true;
 297  
         }
 298  
     }
 299  
 
 300  
 }
 301