Coverage Report - org.jaxen.pattern.PatternParser

Classes in this File Line Coverage Branch Coverage Complexity
PatternParser
83% 
92% 
6.833

 1  
 /*
 2  
  * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/PatternParser.java,v 1.17 2005/09/25 11:43:14 elharo Exp $
 3  
  * $Revision: 1.17 $
 4  
  * $Date: 2005/09/25 11:43:14 $
 5  
  *
 6  
  * ====================================================================
 7  
  *
 8  
  * Copyright (C) 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
 13  
  * are met:
 14  
  * 
 15  
  * 1. Redistributions of source code must retain the above copyright
 16  
  *    notice, this list of conditions, and the following disclaimer.
 17  
  *
 18  
  * 2. Redistributions in binary form must reproduce the above copyright
 19  
  *    notice, this list of conditions, and the disclaimer that follows 
 20  
  *    these conditions in the documentation and/or other materials 
 21  
  *    provided with the distribution.
 22  
  *
 23  
  * 3. The name "Jaxen" must not be used to endorse or promote products
 24  
  *    derived from this software without prior written permission.  For
 25  
  *    written permission, please contact license@jaxen.org.
 26  
  * 
 27  
  * 4. Products derived from this software may not be called "Jaxen", nor
 28  
  *    may "Jaxen" appear in their name, without prior written permission
 29  
  *    from the Jaxen Project Management (pm@jaxen.org).
 30  
  * 
 31  
  * In addition, we request (but do not require) that you include in the 
 32  
  * end-user documentation provided with the redistribution and/or in the 
 33  
  * software itself an acknowledgement equivalent to the following:
 34  
  *     "This product includes software developed by the
 35  
  *      Jaxen Project <http://www.jaxen.org/>."
 36  
  * Alternatively, the acknowledgment may be graphical using the logos 
 37  
  * available at http://www.jaxen.org/
 38  
  *
 39  
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 40  
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 41  
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 42  
  * DISCLAIMED.  IN NO EVENT SHALL THE Jaxen AUTHORS OR THE PROJECT
 43  
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 44  
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 45  
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 46  
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 47  
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 48  
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 49  
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 50  
  * SUCH DAMAGE.
 51  
  *
 52  
  * ====================================================================
 53  
  * This software consists of voluntary contributions made by many 
 54  
  * individuals on behalf of the Jaxen Project and was originally 
 55  
  * created by bob mcwhirter <bob@werken.com> and 
 56  
  * James Strachan <jstrachan@apache.org>.  For more information on the 
 57  
  * Jaxen Project, please see <http://www.jaxen.org/>.
 58  
  * 
 59  
  * $Id: PatternParser.java,v 1.17 2005/09/25 11:43:14 elharo Exp $
 60  
  */
 61  
 
 62  
 
 63  
 package org.jaxen.pattern;
 64  
 
 65  
 import java.util.Iterator;
 66  
 import java.util.List;
 67  
 import java.util.ListIterator;
 68  
 
 69  
 import org.jaxen.JaxenException;
 70  
 import org.jaxen.JaxenHandler;
 71  
 import org.jaxen.expr.DefaultAllNodeStep;
 72  
 import org.jaxen.expr.DefaultCommentNodeStep;
 73  
 import org.jaxen.expr.DefaultFilterExpr;
 74  
 import org.jaxen.expr.DefaultNameStep;
 75  
 import org.jaxen.expr.DefaultProcessingInstructionNodeStep;
 76  
 import org.jaxen.expr.DefaultStep;
 77  
 import org.jaxen.expr.DefaultTextNodeStep;
 78  
 import org.jaxen.expr.DefaultXPathFactory;
 79  
 import org.jaxen.expr.Expr;
 80  
 import org.jaxen.expr.FilterExpr;
 81  
 import org.jaxen.expr.LocationPath;
 82  
 import org.jaxen.expr.Predicate;
 83  
 import org.jaxen.expr.PredicateSet;
 84  
 import org.jaxen.expr.Step;
 85  
 import org.jaxen.expr.UnionExpr;
 86  
 import org.jaxen.saxpath.Axis;
 87  
 import org.jaxen.saxpath.XPathReader;
 88  
 import org.jaxen.saxpath.helpers.XPathReaderFactory;
 89  
 
 90  
 
 91  
 /** <code>PatternParser</code> is a helper class for parsing
 92  
   * XSLT patterns
 93  
   *
 94  
   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 95  
   */
 96  0
 public class PatternParser 
 97  
 {
 98  
     private static final boolean TRACE = false;
 99  
     private static final boolean USE_HANDLER = false;
 100  
     public static Pattern parse(String text) throws JaxenException, org.jaxen.saxpath.SAXPathException
 101  
     {
 102  
         if ( USE_HANDLER )
 103  
         {
 104  
             XPathReader reader = XPathReaderFactory.createReader();
 105  
             PatternHandler handler = new PatternHandler();       
 106  
             
 107  
             handler.setXPathFactory( new DefaultXPathFactory() );            
 108  
             reader.setXPathHandler( handler );
 109  
             reader.parse( text );
 110  
             
 111  
             return handler.getPattern();
 112  
         }
 113  
         else
 114  
         {
 115  138
             XPathReader reader = XPathReaderFactory.createReader();
 116  138
             JaxenHandler handler = new JaxenHandler();
 117  
             
 118  138
             handler.setXPathFactory( new DefaultXPathFactory() );            
 119  138
             reader.setXPathHandler( handler );
 120  138
             reader.parse( text );
 121  
 
 122  138
             Pattern pattern = convertExpr( handler.getXPathExpr().getRootExpr() );
 123  138
             return pattern.simplify();
 124  
         }
 125  
     }
 126  
     
 127  
     protected static Pattern convertExpr(Expr expr) throws JaxenException 
 128  
     {
 129  
         if ( TRACE )
 130  
         {
 131  
             System.out.println( "Converting: " + expr + " into a pattern." );
 132  
         }
 133  
         
 134  174
         if ( expr instanceof LocationPath )
 135  
         {
 136  156
             return convertExpr( (LocationPath) expr );
 137  
         }
 138  18
         else if ( expr instanceof FilterExpr )
 139  
         {
 140  0
             LocationPathPattern answer = new LocationPathPattern();
 141  0
             answer.addFilter( (FilterExpr) expr );
 142  0
             return answer;
 143  
         }
 144  18
         else if ( expr instanceof UnionExpr )
 145  
         {
 146  18
             UnionExpr unionExpr = (UnionExpr) expr;
 147  18
             Pattern lhs = convertExpr( unionExpr.getLHS() );
 148  18
             Pattern rhs = convertExpr( unionExpr.getRHS() );
 149  18
             return new UnionPattern( lhs, rhs );
 150  
         }
 151  
         else 
 152  
         {
 153  0
             LocationPathPattern answer = new LocationPathPattern();
 154  0
             answer.addFilter( new DefaultFilterExpr( expr,
 155  
                                 new PredicateSet()) );
 156  0
             return answer;
 157  
         }
 158  
     }
 159  
     
 160  
     protected static LocationPathPattern convertExpr(LocationPath locationPath) throws JaxenException
 161  
     {
 162  156
         LocationPathPattern answer = new LocationPathPattern();        
 163  
         //answer.setAbsolute( locationPath.isAbsolute() );
 164  156
         List steps = locationPath.getSteps();
 165  
         
 166  
         // go through steps backwards
 167  156
         LocationPathPattern path = answer;
 168  156
         boolean first = true;
 169  156
         for ( ListIterator iter = steps.listIterator( steps.size() ); iter.hasPrevious(); ) 
 170  
         {
 171  216
             Step step = (Step) iter.previous();
 172  216
             if ( first )
 173  
             {
 174  144
                 first = false;
 175  144
                 path = convertStep( path, step );
 176  
             }
 177  
             else
 178  
             {
 179  72
                 if ( navigationStep( step ) ) 
 180  
                 {
 181  72
                     LocationPathPattern parent = new LocationPathPattern();
 182  72
                     int axis = step.getAxis();
 183  72
                     if ( axis == Axis.DESCENDANT || axis == Axis.DESCENDANT_OR_SELF )
 184  
                     {
 185  12
                         path.setAncestorPattern( parent );
 186  
                     }
 187  
                     else
 188  
                     {
 189  60
                         path.setParentPattern( parent );
 190  
                     }
 191  72
                     path = parent;
 192  
                 }
 193  72
                 path = convertStep( path, step );
 194  
             }
 195  
         }
 196  156
         if ( locationPath.isAbsolute() )
 197  
         {
 198  24
             LocationPathPattern parent = new LocationPathPattern( NodeTypeTest.DOCUMENT_TEST );
 199  24
             path.setParentPattern( parent );
 200  
         }
 201  156
         return answer;
 202  
     }   
 203  
     
 204  
     protected static LocationPathPattern convertStep(LocationPathPattern path, Step step) throws JaxenException
 205  
     {
 206  216
         if ( step instanceof DefaultAllNodeStep )
 207  
         {
 208  12
             int axis = step.getAxis();
 209  12
             if ( axis == Axis.ATTRIBUTE )
 210  
             {
 211  0
                 path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
 212  
             }
 213  
             else 
 214  
             {
 215  12
                 path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
 216  
             }
 217  
         }
 218  204
         else if ( step instanceof DefaultCommentNodeStep )
 219  
         {
 220  0
             path.setNodeTest( NodeTypeTest.COMMENT_TEST );
 221  
         }
 222  204
         else if ( step instanceof DefaultProcessingInstructionNodeStep )
 223  
         {
 224  0
             path.setNodeTest( NodeTypeTest.PROCESSING_INSTRUCTION_TEST );
 225  
         }
 226  204
         else if ( step instanceof DefaultTextNodeStep )
 227  
         {
 228  12
             path.setNodeTest( TextNodeTest.SINGLETON );
 229  
         }
 230  192
         else if ( step instanceof DefaultCommentNodeStep )
 231  
         {
 232  0
             path.setNodeTest( NodeTypeTest.COMMENT_TEST );
 233  
         }
 234  192
         else if ( step instanceof DefaultNameStep )
 235  
         {
 236  192
             DefaultNameStep nameStep = (DefaultNameStep) step;
 237  192
             String localName = nameStep.getLocalName();
 238  192
             String prefix = nameStep.getPrefix();
 239  192
             int axis = nameStep.getAxis();
 240  192
             short nodeType = Pattern.ELEMENT_NODE;
 241  192
             if ( axis == Axis.ATTRIBUTE )
 242  
             {
 243  12
                 nodeType = Pattern.ATTRIBUTE_NODE;
 244  
             }
 245  192
             if ( nameStep.isMatchesAnyName() )
 246  
             {
 247  48
                 if ( prefix.length() == 0 || prefix.equals( "*" ) ) 
 248  
                 {
 249  42
                     if ( axis == Axis.ATTRIBUTE )
 250  
                     {
 251  12
                         path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
 252  
                     }
 253  
                     else 
 254  
                     {
 255  30
                         path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
 256  
                     }
 257  
                 }
 258  
                 else 
 259  
                 {
 260  6
                     path.setNodeTest( new NamespaceTest( prefix, nodeType ) );
 261  
                 }
 262  
             }
 263  
             else 
 264  
             {
 265  144
                 path.setNodeTest( new NameTest( localName, nodeType ) );
 266  
                 // XXXX: should support namespace in the test too
 267  
             }
 268  192
             return convertDefaultStep(path, nameStep);
 269  
         }
 270  0
         else if ( step instanceof DefaultStep )
 271  
         {
 272  0
             return convertDefaultStep(path, (DefaultStep) step);
 273  
         }
 274  
         else 
 275  
         {
 276  0
             throw new JaxenException( "Cannot convert: " + step + " to a Pattern" );            
 277  
         }
 278  24
         return path;
 279  
     }
 280  
     
 281  
     protected static LocationPathPattern convertDefaultStep(LocationPathPattern path, DefaultStep step) throws JaxenException
 282  
     {
 283  192
         List predicates = step.getPredicates();
 284  192
         if ( ! predicates.isEmpty() ) 
 285  
         {
 286  30
             FilterExpr filter = new DefaultFilterExpr(new PredicateSet());
 287  30
             for ( Iterator iter = predicates.iterator(); iter.hasNext(); )
 288  
             {
 289  30
                 filter.addPredicate( (Predicate) iter.next() );
 290  
             }
 291  30
             path.addFilter( filter );
 292  
         }         
 293  192
         return path;
 294  
     }
 295  
     
 296  
     protected static boolean navigationStep( Step step )
 297  
     {
 298  72
         if ( step instanceof DefaultNameStep )
 299  
         {
 300  60
             return true;
 301  
         }
 302  
         else
 303  18
         if ( step.getClass().equals( DefaultStep.class ) )
 304  
         {
 305  0
             return ! step.getPredicates().isEmpty();
 306  
         }
 307  
         else 
 308  
         {
 309  12
             return true;
 310  
         }
 311  
     }
 312  
 
 313  
 }
 314