KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > xpath > pattern > AbstractPattern


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.xpath.pattern;
30
31 import com.caucho.log.Log;
32 import com.caucho.xpath.Env;
33 import com.caucho.xpath.ExprEnvironment;
34 import com.caucho.xpath.XPathException;
35
36 import org.w3c.dom.Node JavaDoc;
37
38 import java.util.logging.Logger JavaDoc;
39
40 /**
41  * A node selection pattern. AbstractPatterns represent compiled XPath node selectors.
42  * They can be used to find nodes, select nodes, and test if a node matches
43  * a pattern.
44  *
45  * <p>There are two types of patterns: select patterns and match patterns.
46  * <p>Select patterns match a node relative to another node.
47  * <code>find</code> and <code>select</code> use select patterns.
48  * <p>Match patterns match a node in isolation. <code>isMatch</code> uses
49  * match patterns.
50  */

51 abstract public class AbstractPattern {
52   protected static final Logger JavaDoc log = Log.open(AbstractPattern.class);
53
54   // This is the value Axis wants
55
public static final String JavaDoc XMLNS = "http://www.w3.org/2000/xmlns/";
56   
57   protected AbstractPattern _parent;
58   protected AbstractPattern _child;
59
60   AbstractPattern(AbstractPattern parent)
61   {
62     _parent = parent;
63     
64     if (parent != null && parent._child == null)
65       parent._child = this;
66   }
67
68   /**
69    * Returns the parent pattern.
70    */

71   public AbstractPattern getParent()
72   {
73     return _parent;
74   }
75  
76   /**
77    * Returns the pattern's default priority as defined by the XSLT draft.
78    */

79   public double getPriority()
80   {
81     return 0.5;
82   }
83
84   /**
85    * Returns the name of the matching node or '*' if many nodes match.
86    *
87    * <p>The Xsl package uses this to speed template matching.
88    */

89   public String JavaDoc getNodeName()
90   {
91     return "*";
92   }
93
94   /**
95    * Returns an iterator selecting nodes in document order.
96    *
97    * @param node the starting node.
98    * @param env the variable environment.
99    *
100    * @return an iterator selecting nodes in document order.
101    */

102   public NodeIterator select(Node JavaDoc node, ExprEnvironment env)
103     throws XPathException
104   {
105     NodeIterator base = createNodeIterator(node, env, copyPosition());
106
107     if (isStrictlyAscending())
108       return base;
109     else
110       return new MergeIterator(env, base);
111   }
112
113   /**
114    * Returns an iterator selecting unique nodes. The nodes are not
115    * necessarily in document order.
116    *
117    * @param node the starting node.
118    * @param env the variable environment.
119    * @param context the context node.
120    *
121    * @return an iterator selecting unique nodes.
122    */

123   public NodeIterator selectUnique(Node JavaDoc node, ExprEnvironment env)
124     throws XPathException
125   {
126     NodeIterator base = createNodeIterator(node, env, copyPosition());
127
128     if (isUnique())
129       return base;
130     else
131       return new UniqueIterator(env, base);
132   }
133
134   /**
135    * Find any node matching the pattern.
136    *
137    * @param node the current node
138    * @param env the xpath environment
139    *
140    * @return one of the matching nodes
141    */

142   public Node JavaDoc findAny(Node JavaDoc node, ExprEnvironment env)
143     throws XPathException
144   {
145     NodeIterator base = createNodeIterator(node, env, copyPosition());
146
147     return base.nextNode();
148   }
149   
150   /**
151    * Returns true if the pattern is strictly ascending.
152    */

153   public boolean isStrictlyAscending()
154   {
155     if (_parent != null)
156       return _parent.isStrictlyAscending();
157     else
158       return false;
159   }
160   
161   /**
162    * Returns true if the pattern's iterator returns unique nodes.
163    */

164   public boolean isUnique()
165   {
166     if (_parent != null)
167       return _parent.isUnique();
168     else
169       return false;
170   }
171   
172   /**
173    * Returns true if the pattern selects a single node
174    */

175   boolean isSingleSelect()
176   {
177     if (_parent != null)
178       return _parent.isSingleSelect();
179     else
180       return false;
181   }
182   
183   /**
184    * Returns true if the pattern returns nodes on a single level.
185    */

186   boolean isSingleLevel()
187   {
188     return isSingleSelect();
189   }
190
191   /**
192    * Creates a new node iterator.
193    *
194    * @param node the starting node
195    * @param env the variable environment
196    * @param pattern the level pattern
197    *
198    * @return the node iterator
199    */

200   public NodeIterator createNodeIterator(Node JavaDoc node, ExprEnvironment env,
201                                          AbstractPattern pattern)
202     throws XPathException
203   {
204     if (_parent == null)
205       throw new RuntimeException JavaDoc(String.valueOf(this) + " " + getClass());
206     else
207       return _parent.createNodeIterator(node, env, pattern);
208   }
209
210   /**
211    * Returns the first node in the selection order.
212    *
213    * @param node the current node
214    * @param variable environment
215    *
216    * @return the first node
217    */

218   public Node JavaDoc firstNode(Node JavaDoc node, ExprEnvironment env)
219     throws XPathException
220   {
221     throw new UnsupportedOperationException JavaDoc(String.valueOf(this) + " " + getClass());
222   }
223   
224   /**
225    * Returns the last node in the selection order.
226    *
227    * @param node the current node
228    *
229    * @return the last node
230    */

231   public Node JavaDoc lastNode(Node JavaDoc node)
232   {
233     return null;
234   }
235
236   /**
237    * Returns the next node in the selection order.
238    *
239    * @param node the current node
240    * @param last the last node
241    *
242    * @return the next node
243    */

244   public Node JavaDoc nextNode(Node JavaDoc node, Node JavaDoc last)
245     throws XPathException
246   {
247     throw new UnsupportedOperationException JavaDoc();
248   }
249
250   /**
251    * The core match function test if the pattern matches the node.
252    *
253    * @param node the node to test
254    * @param env the variable environment.
255    *
256    * @return true if the node matches the pattern.
257    */

258   public abstract boolean match(Node JavaDoc node, ExprEnvironment env)
259     throws XPathException;
260
261   /**
262    * Return true if the iterator is in document-order.
263    */

264   public boolean isAscending()
265   {
266     return true;
267   }
268
269   /**
270    * Returns the position of the node in its context for a match pattern.
271    *
272    * @param node the current node
273    * @param env the variable environment
274    * @param pattern the position pattern
275    *
276    * @return the node's position.
277    */

278   public int position(Node JavaDoc node, Env env, AbstractPattern pattern)
279     throws XPathException
280   {
281     return _parent.position(node, env, pattern);
282   }
283
284   /**
285    * Returns the number of nodes in its context for a match pattern.
286    *
287    * @param node the current node
288    * @param env the variable environment
289    * @param pattern the position pattern
290    *
291    * @return the count of nodes in the match selection
292    */

293   public int count(Node JavaDoc node, Env env, AbstractPattern pattern)
294     throws XPathException
295   {
296     return _parent.count(node, env, pattern);
297   }
298
299   /**
300    * Returns the owning axis for the pattern.
301    */

302   public AbstractPattern copyAxis()
303   {
304     if (_parent != null)
305       return _parent.copyAxis();
306     else
307       return null;
308   }
309
310   /**
311    * Returns the position matching pattern.
312    */

313   public AbstractPattern copyPosition()
314   {
315     return this;
316   }
317
318   /**
319    * For string conversion, returns the string prefix corresponding to
320    * the parents.
321    */

322   protected String JavaDoc getPrefix()
323   {
324     if (_parent == null ||
325         _parent instanceof FromAny)
326       return "";
327     else if (_parent instanceof FromContext) { // check for in Filter?
328
FromContext context = (FromContext) _parent;
329
330       String JavaDoc name = "";
331       for (int i = 0; i < context.getCount(); i++) {
332         name += "../";
333       }
334       return name;
335     }
336     else if (_parent instanceof FromRoot)
337       return "/";
338     else
339       return _parent + "/";
340   }
341
342   public String JavaDoc toPatternString()
343   {
344     return toString();
345   }
346 }
347
Popular Tags