View Javadoc

1   /*
2    * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/PatternHandler.java,v 1.5 2003/06/29 18:01:52 ssanders Exp $
3    * $Revision: 1.5 $
4    * $Date: 2003/06/29 18:01:52 $
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: PatternHandler.java,v 1.5 2003/06/29 18:01:52 ssanders Exp $
60   */
61  
62  
63  package org.jaxen.pattern;
64  
65  import java.util.LinkedList;
66  
67  import org.jaxen.JaxenException;
68  import org.jaxen.JaxenHandler;
69  import org.jaxen.expr.Expr;
70  import org.jaxen.expr.FilterExpr;
71  import org.jaxen.saxpath.Axis;
72  
73  /*** SAXPath <code>XPathHandler</code> implementation capable
74   *  of building Jaxen expression trees which can walk various
75   *  different object models.
76   *
77   *  @author bob mcwhirter (bob@werken.com)
78   */
79  public class PatternHandler extends JaxenHandler
80  {
81      private Pattern pattern;
82      
83      public PatternHandler()
84      {
85      }
86      
87      /*** Retrieve the simplified Jaxen Pattern expression tree.
88       *
89       *  <p>
90       *  This method is only valid once <code>XPathReader.parse(...)</code>
91       *  successfully returned.
92       *  </p>
93       *
94       *  @return The Pattern expression tree.
95       */
96      public Pattern getPattern()
97      {
98          return getPattern( true );
99      }
100 
101     /*** Retrieve the Jaxen Pattern expression tree, optionally
102      *  simplified.
103      *
104      *  <p>
105      *  This method is only valid once <code>XPathReader.parse(...)</code>
106      *  successfully returned.
107      *  </p>
108      *
109      *  @return The Pattern expression tree.
110      */
111     public Pattern getPattern(boolean shouldSimplify)
112     {
113         if ( shouldSimplify && ! this.simplified )
114         {
115             //System.err.println("simplifyin....");
116             this.pattern.simplify();
117             this.simplified = true;
118         }
119 
120         return this.pattern;
121     }
122 
123     
124     
125     
126     public void endXPath() throws JaxenException
127     {
128         this.pattern = (Pattern) pop();
129 
130         System.out.println( "stack is: " + stack );
131         
132         popFrame();
133     }
134 
135     public void endPathExpr() throws JaxenException
136     {
137         //System.err.println("endPathExpr()");
138 
139         // PathExpr ::=   LocationPath
140         //              | FilterExpr
141         //              | FilterExpr / RelativeLocationPath
142         //              | FilterExpr // RelativeLocationPath
143         //
144         // If the current stack-frame has two items, it's a
145         // FilterExpr and a LocationPath (of some flavor).
146         //
147         // If the current stack-frame has one item, it's simply
148         // a FilterExpr, and more than like boils down to a
149         // primary expr of some flavor.  But that's for another
150         // method...
151 
152         LinkedList frame = popFrame();
153         
154         System.out.println( "endPathExpr(): " + frame );
155             
156         push( frame.removeFirst() );
157 /*        
158         LocationPathPattern locationPath = new LocationPathPattern();
159         push( locationPath );
160         while (! frame.isEmpty() )
161         {
162             Object filter = frame.removeLast();
163             if ( filter instanceof NodeTest ) 
164             {
165                 locationPath.setNodeTest( (NodeTest) filter );
166             }
167             else if ( filter instanceof FilterExpr )
168             {
169                 locationPath.addFilter( (FilterExpr) filter );
170             }
171             else if ( filter instanceof LocationPathPattern ) 
172             {
173                 LocationPathPattern parent = (LocationPathPattern) filter;
174                 locationPath.setParentPattern( parent );
175                 locationPath = parent;
176             }
177             else if ( filter != null ) 
178             {
179                 throw new JaxenException( "Unknown filter: " + filter );
180             }
181         }
182 */
183     }
184 
185     public void startAbsoluteLocationPath() throws JaxenException
186     {
187         //System.err.println("startAbsoluteLocationPath()");
188         pushFrame();
189 
190         push( createAbsoluteLocationPath() );
191     }
192     
193     public void endAbsoluteLocationPath() throws JaxenException
194     {
195         //System.err.println("endAbsoluteLocationPath()");
196         endLocationPath();
197     }
198 
199     public void startRelativeLocationPath() throws JaxenException
200     {
201         //System.err.println("startRelativeLocationPath()");
202         pushFrame();
203 
204         push( createRelativeLocationPath() );
205     }
206 
207     public void endRelativeLocationPath() throws JaxenException
208     {
209         //System.err.println("endRelativeLocationPath()");
210         endLocationPath();
211     }
212 
213     protected void endLocationPath() throws JaxenException
214     {
215         // start at the back, its the main pattern then add everything else as 
216         LinkedList list = popFrame();
217         
218         System.out.println( "endLocationPath: " + list );
219 
220         LocationPathPattern locationPath = (LocationPathPattern) list.removeFirst();
221         push( locationPath );
222         boolean doneNodeTest = false;
223         while ( ! list.isEmpty() )
224         {
225             Object filter = list.removeFirst();
226             if ( filter instanceof NodeTest ) 
227             {
228                 if ( doneNodeTest ) 
229                 {
230                     LocationPathPattern parent = new LocationPathPattern( (NodeTest) filter );
231                     locationPath.setParentPattern( parent );
232                     locationPath = parent;
233                     doneNodeTest = false;
234                 }   
235                 else
236                 {
237                     locationPath.setNodeTest( (NodeTest) filter );
238                 }
239             }
240             else if ( filter instanceof FilterExpr )
241             {
242                 locationPath.addFilter( (FilterExpr) filter );
243             }
244             else if ( filter instanceof LocationPathPattern ) 
245             {
246                 LocationPathPattern parent = (LocationPathPattern) filter;
247                 locationPath.setParentPattern( parent );
248                 locationPath = parent;
249                 doneNodeTest = false;
250             }
251         }
252     }
253 
254     
255     public void startNameStep(int axis,
256                               String prefix,
257                               String localName) throws JaxenException
258     {
259         //System.err.println("startNameStep(" + axis + ", " + prefix + ", " + localName + ")");
260         pushFrame();
261 
262         short nodeType = Pattern.ELEMENT_NODE;            
263         switch ( axis ) 
264         {
265             case Axis.ATTRIBUTE:
266                 nodeType = Pattern.ATTRIBUTE_NODE;
267                 break;
268             case Axis.NAMESPACE:
269                 nodeType = Pattern.NAMESPACE_NODE;
270                 break;
271         }
272         
273         if ( prefix != null && prefix.length() > 0 && ! prefix.equals( "*" ) ) 
274         {                    
275             push( new NamespaceTest( prefix, nodeType ) );
276         }
277         if ( localName != null && localName.length() > 0 && ! localName.equals( "*" ) ) 
278         {
279             push( new NameTest( localName, nodeType ) );
280         }
281     }
282 
283     public void startTextNodeStep(int axis) throws JaxenException
284     {
285         //System.err.println("startTextNodeStep()");
286         pushFrame();
287         
288         push( new NodeTypeTest( Pattern.TEXT_NODE ) );
289     }
290     
291     public void startCommentNodeStep(int axis) throws JaxenException
292     {
293         //System.err.println("startCommentNodeStep()");
294         pushFrame();
295 
296         push( new NodeTypeTest( Pattern.COMMENT_NODE ) );
297     }
298 
299     public void startAllNodeStep(int axis) throws JaxenException
300     {
301         //System.err.println("startAllNodeStep()");
302         pushFrame();
303 
304         push( AnyNodeTest.getInstance() );
305     }
306 
307     public void startProcessingInstructionNodeStep(int axis,
308                                                    String name) throws JaxenException
309     {
310         //System.err.println("startProcessingInstructionStep()");
311         pushFrame();
312 
313         // XXXX: should we throw an exception if name is present?            
314         push( new NodeTypeTest( Pattern.PROCESSING_INSTRUCTION_NODE ) );
315     }
316     
317     protected void endStep()
318     {
319         LinkedList list = popFrame();
320         if ( ! list.isEmpty() ) 
321         {
322             push( list.removeFirst() );
323             
324             if ( ! list.isEmpty() )
325             {
326                 System.out.println( "List should now be empty!" + list );
327             }
328         }
329     }
330     
331 
332     public void startUnionExpr() throws JaxenException
333     {
334         //System.err.println("startUnionExpr()");
335     }
336 
337     public void endUnionExpr(boolean create) throws JaxenException
338     {
339         //System.err.println("endUnionExpr()");
340 
341         if ( create )
342         {
343             //System.err.println("makeUnionExpr");
344 
345             Expr rhs = (Expr) pop();
346             Expr lhs = (Expr) pop();
347 
348             push( getXPathFactory().createUnionExpr( lhs,
349                                                     rhs ) );
350         }
351     }
352 
353     protected Pattern createAbsoluteLocationPath() 
354     {
355         return new LocationPathPattern( NodeTypeTest.DOCUMENT_TEST );
356     }
357 
358     protected Pattern createRelativeLocationPath() 
359     {
360         return new LocationPathPattern();
361     }
362 
363 }