View Javadoc

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