KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jaxen > pattern > PatternParser


1 /*
2  * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/PatternParser.java,v 1.15 2005/04/09 14:16:22 elharo Exp $
3  * $Revision: 1.15 $
4  * $Date: 2005/04/09 14:16:22 $
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.15 2005/04/09 14:16:22 elharo Exp $
60  */

61
62
63 package org.jaxen.pattern;
64
65 import java.util.Iterator JavaDoc;
66 import java.util.List JavaDoc;
67 import java.util.ListIterator JavaDoc;
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 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 JavaDoc 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             XPathReader reader = XPathReaderFactory.createReader();
116             JaxenHandler handler = new JaxenHandler();
117             
118             handler.setXPathFactory( new DefaultXPathFactory() );
119             reader.setXPathHandler( handler );
120             reader.parse( text );
121
122             Pattern pattern = convertExpr( handler.getXPathExpr().getRootExpr() );
123             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         if ( expr instanceof LocationPath )
135         {
136             return convertExpr( (LocationPath) expr );
137         }
138         else if ( expr instanceof FilterExpr )
139         {
140             LocationPathPattern answer = new LocationPathPattern();
141             answer.addFilter( (FilterExpr) expr );
142             return answer;
143         }
144         else if ( expr instanceof UnionExpr )
145         {
146             UnionExpr unionExpr = (UnionExpr) expr;
147             Pattern lhs = convertExpr( unionExpr.getLHS() );
148             Pattern rhs = convertExpr( unionExpr.getRHS() );
149             return new UnionPattern( lhs, rhs );
150         }
151         else
152         {
153             LocationPathPattern answer = new LocationPathPattern();
154             answer.addFilter( new DefaultFilterExpr( expr,
155                                 new PredicateSet()) );
156             return answer;
157         }
158     }
159     
160     protected static LocationPathPattern convertExpr(LocationPath locationPath) throws JaxenException
161     {
162         LocationPathPattern answer = new LocationPathPattern();
163         //answer.setAbsolute( locationPath.isAbsolute() );
164
List JavaDoc steps = locationPath.getSteps();
165         
166         // go through steps backwards
167
LocationPathPattern path = answer;
168         boolean first = true;
169         for ( ListIterator JavaDoc iter = steps.listIterator( steps.size() ); iter.hasPrevious(); )
170         {
171             Step step = (Step) iter.previous();
172             if ( first )
173             {
174                 first = false;
175                 path = convertStep( path, step );
176             }
177             else
178             {
179                 if ( navigationStep( step ) )
180                 {
181                     LocationPathPattern parent = new LocationPathPattern();
182                     int axis = step.getAxis();
183                     if ( axis == Axis.DESCENDANT || axis == Axis.DESCENDANT_OR_SELF )
184                     {
185                         path.setAncestorPattern( parent );
186                     }
187                     else
188                     {
189                         path.setParentPattern( parent );
190                     }
191                     path = parent;
192                 }
193                 path = convertStep( path, step );
194             }
195         }
196         if ( locationPath.isAbsolute() )
197         {
198             LocationPathPattern parent = new LocationPathPattern( NodeTypeTest.DOCUMENT_TEST );
199             path.setParentPattern( parent );
200         }
201         return answer;
202     }
203     
204     protected static LocationPathPattern convertStep(LocationPathPattern path, Step step) throws JaxenException
205     {
206         if ( step instanceof DefaultAllNodeStep )
207         {
208             int axis = step.getAxis();
209             if ( axis == Axis.ATTRIBUTE )
210             {
211                 path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
212             }
213             else
214             {
215                 path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
216             }
217         }
218         else if ( step instanceof DefaultCommentNodeStep )
219         {
220             path.setNodeTest( NodeTypeTest.COMMENT_TEST );
221         }
222         else if ( step instanceof DefaultProcessingInstructionNodeStep )
223         {
224             path.setNodeTest( NodeTypeTest.PROCESSING_INSTRUCTION_TEST );
225         }
226         else if ( step instanceof DefaultTextNodeStep )
227         {
228             path.setNodeTest( TextNodeTest.SINGLETON );
229         }
230         else if ( step instanceof DefaultCommentNodeStep )
231         {
232             path.setNodeTest( NodeTypeTest.COMMENT_TEST );
233         }
234         else if ( step instanceof DefaultNameStep )
235         {
236             DefaultNameStep nameStep = (DefaultNameStep) step;
237             String JavaDoc localName = nameStep.getLocalName();
238             String JavaDoc prefix = nameStep.getPrefix();
239             int axis = nameStep.getAxis();
240             short nodeType = Pattern.ELEMENT_NODE;
241             if ( axis == Axis.ATTRIBUTE )
242             {
243                 nodeType = Pattern.ATTRIBUTE_NODE;
244             }
245             if ( nameStep.isMatchesAnyName() )
246             {
247                 if ( prefix.length() == 0 || prefix.equals( "*" ) )
248                 {
249                     if ( axis == Axis.ATTRIBUTE )
250                     {
251                         path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
252                     }
253                     else
254                     {
255                         path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
256                     }
257                 }
258                 else
259                 {
260                     path.setNodeTest( new NamespaceTest( prefix, nodeType ) );
261                 }
262             }
263             else
264             {
265                 path.setNodeTest( new NameTest( localName, nodeType ) );
266                 // XXXX: should support namespace in the test too
267
}
268             return convertDefaultStep(path, nameStep);
269         }
270         else if ( step instanceof DefaultStep )
271         {
272             return convertDefaultStep(path, (DefaultStep) step);
273         }
274         else
275         {
276             throw new JaxenException( "Cannot convert: " + step + " to a Pattern" );
277         }
278         return path;
279     }
280     
281     protected static LocationPathPattern convertDefaultStep(LocationPathPattern path, DefaultStep step) throws JaxenException
282     {
283         List JavaDoc predicates = step.getPredicates();
284         if ( ! predicates.isEmpty() )
285         {
286             DefaultFilterExpr filter = new DefaultFilterExpr(new PredicateSet());
287             for ( Iterator JavaDoc iter = predicates.iterator(); iter.hasNext(); )
288             {
289                 filter.addPredicate( (Predicate) iter.next() );
290             }
291             path.addFilter( filter );
292         }
293         return path;
294     }
295     
296     protected static boolean navigationStep( Step step )
297     {
298         if ( step instanceof DefaultNameStep )
299         {
300             return true;
301         }
302         else
303         if ( step.getClass().equals( DefaultStep.class ) )
304         {
305             return ! step.getPredicates().isEmpty();
306         }
307         else
308         {
309             return true;
310         }
311     }
312
313 }
314
315
Popular Tags