##### Coverage Report - org.jaxen.pattern.PatternParser

Classes in this File | Line Coverage | Branch Coverage | Complexity
PatternParser |
83% |
92% |
| 6.833333333333333;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 |  |