KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jxpath > ri > compiler > Expression


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.jxpath.ri.compiler;
17
18 import org.apache.commons.jxpath.Pointer;
19 import org.apache.commons.jxpath.ri.EvalContext;
20 import org.apache.commons.jxpath.ri.model.NodePointer;
21 import org.apache.commons.jxpath.ri.QName;
22 import org.apache.commons.jxpath.util.ValueUtils;
23
24 import java.util.Collections JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Locale JavaDoc;
27
28 /**
29  * Common superclass for several types of nodes in the parse tree. Provides
30  * APIs for optimization of evaluation of expressions. Specifically, an
31  * expression only needs to executed once during the evaluation of an xpath
32  * if that expression is context-independent. Expression.isContextDependent()
33  * provides that hint.
34  *
35  * @author Dmitri Plotnikov
36  * @version $Revision: 1.10 $ $Date: 2004/02/29 14:17:38 $
37  */

38 public abstract class Expression {
39
40     protected static final Double JavaDoc ZERO = new Double JavaDoc(0);
41     protected static final Double JavaDoc ONE = new Double JavaDoc(1);
42     protected static final Double JavaDoc NOT_A_NUMBER = new Double JavaDoc(Double.NaN);
43
44     private boolean contextDependencyKnown = false;
45     private boolean contextDependent;
46
47     /**
48      * Returns true if this expression should be re-evaluated
49      * each time the current position in the context changes.
50      */

51     public boolean isContextDependent() {
52         if (!contextDependencyKnown) {
53             contextDependent = computeContextDependent();
54             contextDependencyKnown = true;
55         }
56         return contextDependent;
57     }
58
59     /**
60      * Implemented by subclasses and result is cached by isContextDependent()
61      */

62     public abstract boolean computeContextDependent();
63
64     /**
65      * Evaluates the expression. If the result is a node set, returns
66      * the first element of the node set.
67      */

68     public abstract Object JavaDoc computeValue(EvalContext context);
69     public abstract Object JavaDoc compute(EvalContext context);
70
71     public Iterator JavaDoc iterate(EvalContext context) {
72         Object JavaDoc result = compute(context);
73         if (result instanceof EvalContext) {
74             return new ValueIterator((EvalContext) result);
75         }
76         return ValueUtils.iterate(result);
77     }
78
79     public Iterator JavaDoc iteratePointers(EvalContext context) {
80         Object JavaDoc result = compute(context);
81         if (result == null) {
82             return Collections.EMPTY_LIST.iterator();
83         }
84         if (result instanceof EvalContext) {
85             return (EvalContext) result;
86         }
87         return new PointerIterator(ValueUtils.iterate(result),
88                 new QName(null, "value"),
89                 context.getRootContext().getCurrentNodePointer().getLocale());
90     }
91
92     public static class PointerIterator implements Iterator JavaDoc {
93         private Iterator JavaDoc iterator;
94         private QName qname;
95         private Locale JavaDoc locale;
96
97         /**
98          * @deprecated Use the method that takes a NamespaceManager
99          */

100         public PointerIterator(Iterator JavaDoc it, QName qname, Locale JavaDoc locale) {
101             this.iterator = it;
102             this.qname = qname;
103             this.locale = locale;
104         }
105
106         public boolean hasNext() {
107             return iterator.hasNext();
108         }
109
110         public Object JavaDoc next() {
111             Object JavaDoc o = iterator.next();
112             return NodePointer.newNodePointer(qname, o, locale);
113         }
114
115         public void remove() {
116             throw new UnsupportedOperationException JavaDoc();
117         }
118     }
119
120     public static class ValueIterator implements Iterator JavaDoc {
121         private Iterator JavaDoc iterator;
122
123         public ValueIterator(Iterator JavaDoc it) {
124             this.iterator = it;
125         }
126
127         public boolean hasNext() {
128             return iterator.hasNext();
129         }
130
131         public Object JavaDoc next() {
132             Object JavaDoc o = iterator.next();
133             if (o instanceof Pointer) {
134                 return ((Pointer) o).getValue();
135             }
136             return o;
137         }
138
139         public void remove() {
140             throw new UnsupportedOperationException JavaDoc();
141         }
142     }
143 }
Popular Tags