KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/LocationPathPattern.java,v 1.13 2003/06/29 18:01:52 ssanders Exp $
3  * $Revision: 1.13 $
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: LocationPathPattern.java,v 1.13 2003/06/29 18:01:52 ssanders Exp $
60  */

61
62 package org.jaxen.pattern;
63
64 import java.util.ArrayList JavaDoc;
65 import java.util.Iterator JavaDoc;
66 import java.util.List JavaDoc;
67
68 import org.jaxen.Context;
69 import org.jaxen.JaxenException;
70 import org.jaxen.Navigator;
71 import org.jaxen.expr.FilterExpr;
72 import org.jaxen.util.SingletonList;
73
74 /** <p><code>LocationPathPattern</code> matches any node using a
75   * location path such as A/B/C.
76   * The parentPattern and ancestorPattern properties are used to
77   * chain location path patterns together</p>
78   *
79   * @author <a HREF="mailto:jstrachan@apache.org">James Strachan</a>
80   * @version $Revision: 1.13 $
81   */

82 public class LocationPathPattern extends Pattern {
83
84     /** The node test to perform on this step of the path */
85     private NodeTest nodeTest = AnyNodeTest.getInstance();
86     
87     /** Patterns matching my parent node */
88     private Pattern parentPattern;
89     
90     /** Patterns matching one of my ancestors */
91     private Pattern ancestorPattern;
92         
93     /** The filters to match against */
94     private List JavaDoc filters;
95
96     /** Whether this lcoation path is absolute or not */
97     private boolean absolute;
98     
99     
100     public LocationPathPattern()
101     {
102     }
103
104     public LocationPathPattern(NodeTest nodeTest)
105     {
106         this.nodeTest = nodeTest;
107     }
108
109     public Pattern simplify()
110     {
111         if ( parentPattern != null )
112         {
113             parentPattern = parentPattern.simplify();
114         }
115         if ( ancestorPattern != null )
116         {
117             ancestorPattern = ancestorPattern.simplify();
118         }
119         if ( filters == null )
120         {
121             if ( parentPattern == null && ancestorPattern == null )
122             {
123                 return nodeTest;
124             }
125             if ( parentPattern != null && ancestorPattern == null )
126             {
127                 if ( nodeTest instanceof AnyNodeTest )
128                 {
129                     return parentPattern;
130                 }
131             }
132         }
133         return this;
134     }
135     
136     /** Adds a filter to this pattern
137      */

138     public void addFilter(FilterExpr filter)
139     {
140         if ( filters == null )
141         {
142             filters = new ArrayList JavaDoc();
143         }
144         filters.add( filter );
145     }
146     
147     /** Adds a pattern for the parent of the current
148      * context node used in this pattern.
149      */

150     public void setParentPattern(Pattern parentPattern)
151     {
152         this.parentPattern = parentPattern;
153     }
154     
155     /** Adds a pattern for an ancestor of the current
156      * context node used in this pattern.
157      */

158     public void setAncestorPattern(Pattern ancestorPattern)
159     {
160         this.ancestorPattern = ancestorPattern;
161     }
162     
163     /** Allows the NodeTest to be set
164      */

165     public void setNodeTest(NodeTest nodeTest) throws JaxenException
166     {
167         if ( this.nodeTest instanceof AnyNodeTest )
168         {
169             this.nodeTest = nodeTest;
170         }
171         else
172         {
173             throw new JaxenException( "Attempt to overwrite nodeTest: " + this.nodeTest + " with: " + nodeTest );
174         }
175     }
176     
177     /** @return true if the pattern matches the given node
178       */

179     public boolean matches( Object JavaDoc node, Context context ) throws JaxenException
180     {
181         Navigator navigator = context.getNavigator();
182
183 /*
184         if ( isAbsolute() )
185         {
186             node = navigator.getDocumentNode( node );
187         }
188 */

189         if (! nodeTest.matches(node, context) )
190         {
191             return false;
192         }
193         
194         if (parentPattern != null)
195         {
196             Object JavaDoc parent = navigator.getParentNode( node );
197             if ( parent == null )
198             {
199                 return false;
200             }
201             if ( ! parentPattern.matches( parent, context ) )
202             {
203                 return false;
204             }
205         }
206
207         if (ancestorPattern != null) {
208             Object JavaDoc ancestor = navigator.getParentNode( node );
209             while (true)
210             {
211                 if ( ancestorPattern.matches( ancestor, context ) )
212                 {
213                     break;
214                 }
215                 if ( ancestor == null )
216                 {
217                     return false;
218                 }
219                 if ( navigator.isDocument( ancestor ) )
220                 {
221                     return false;
222                 }
223                 ancestor = navigator.getParentNode( ancestor );
224             }
225         }
226         
227         if (filters != null)
228         {
229             List JavaDoc list = new SingletonList(node);
230
231             context.setNodeSet( list );
232             
233             // XXXX: filters aren't positional, so should we clone context?
234

235             boolean answer = true;
236
237             for (Iterator JavaDoc iter = filters.iterator(); iter.hasNext(); )
238             {
239                 FilterExpr filter = (FilterExpr) iter.next();
240
241                 if ( ! filter.asBoolean( context ) )
242                 {
243                     answer = false;
244                     break;
245                 }
246             }
247             // restore context
248

249             context.setNodeSet( list );
250
251             return answer;
252         }
253         return true;
254     }
255     
256     public double getPriority()
257     {
258         if ( filters != null )
259         {
260             return 0.5;
261         }
262         return nodeTest.getPriority();
263     }
264
265
266     public short getMatchType()
267     {
268         return nodeTest.getMatchType();
269     }
270     
271     public String JavaDoc getText()
272     {
273         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
274         if ( absolute )
275         {
276             buffer.append( "/" );
277         }
278         if (ancestorPattern != null)
279         {
280             String JavaDoc text = ancestorPattern.getText();
281             if ( text.length() > 0 )
282             {
283                 buffer.append( text );
284                 buffer.append( "//" );
285             }
286         }
287         if (parentPattern != null)
288         {
289             String JavaDoc text = parentPattern.getText();
290             if ( text.length() > 0 )
291             {
292                 buffer.append( text );
293                 buffer.append( "/" );
294             }
295         }
296         buffer.append( nodeTest.getText() );
297         
298         if ( filters != null )
299         {
300             buffer.append( "[" );
301             for (Iterator JavaDoc iter = filters.iterator(); iter.hasNext(); )
302             {
303                 FilterExpr filter = (FilterExpr) iter.next();
304                 buffer.append( filter.getText() );
305             }
306             buffer.append( "]" );
307         }
308         return buffer.toString();
309     }
310     
311     public String JavaDoc toString()
312     {
313         return super.toString() + "[ absolute: " + absolute + " parent: " + parentPattern + " ancestor: "
314             + ancestorPattern + " filters: " + filters + " nodeTest: "
315             + nodeTest + " ]";
316     }
317     
318     public boolean isAbsolute()
319     {
320         return absolute;
321     }
322     
323     public void setAbsolute(boolean absolute)
324     {
325         this.absolute = absolute;
326     }
327     
328     public boolean hasAnyNodeTest()
329     {
330         return nodeTest instanceof AnyNodeTest;
331     }
332         
333 }
334
Popular Tags