KickJava   Java API By Example, From Geeks To Geeks.

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


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.ri.EvalContext;
19 import org.apache.commons.jxpath.ri.axes.InitialContext;
20 import org.apache.commons.jxpath.ri.axes.NodeSetContext;
21 import org.apache.commons.jxpath.ri.axes.PredicateContext;
22 import org.apache.commons.jxpath.ri.axes.SimplePathInterpreter;
23 import org.apache.commons.jxpath.ri.axes.UnionContext;
24 import org.apache.commons.jxpath.ri.model.NodePointer;
25
26 /**
27  * An element of the parse tree that represents an expression path, which is a
28  * path that starts with an expression like a function call: <code>getFoo(.)
29  * /bar</code>.
30  *
31  * @author Dmitri Plotnikov
32  * @version $Revision: 1.11 $ $Date: 2004/02/29 14:17:39 $
33  */

34 public class ExpressionPath extends Path {
35
36     private Expression expression;
37     private Expression predicates[];
38
39     private boolean basicKnown = false;
40     private boolean basic;
41
42     public ExpressionPath(
43         Expression expression,
44         Expression[] predicates,
45         Step[] steps)
46     {
47         super(steps);
48         this.expression = expression;
49         this.predicates = predicates;
50     }
51
52     public Expression getExpression() {
53         return expression;
54     }
55
56     /**
57      * Predicates are the expressions in brackets that may follow
58      * the root expression of the path.
59      */

60     public Expression[] getPredicates() {
61         return predicates;
62     }
63
64     /**
65      * Returns true if the root expression or any of the
66      * predicates or the path steps are context dependent.
67      */

68     public boolean computeContextDependent() {
69         if (expression.isContextDependent()) {
70             return true;
71         }
72         if (predicates != null) {
73             for (int i = 0; i < predicates.length; i++) {
74                 if (predicates[i].isContextDependent()) {
75                     return true;
76                 }
77             }
78         }
79         return super.computeContextDependent();
80     }
81
82     /**
83      * Recognized paths formatted as <code>$x[3]/foo[2]</code>. The
84      * evaluation of such "simple" paths is optimized and streamlined.
85      */

86     public boolean isSimpleExpressionPath() {
87         if (!basicKnown) {
88             basicKnown = true;
89             basic = isSimplePath() && areBasicPredicates(getPredicates());
90         }
91         return basic;
92     }
93
94     public String JavaDoc toString() {
95         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
96         if (expression instanceof CoreOperation
97             || expression instanceof ExpressionPath
98             || expression instanceof LocationPath) {
99             buffer.append('(');
100             buffer.append(expression);
101             buffer.append(')');
102         }
103         else {
104             buffer.append(expression);
105         }
106         if (predicates != null) {
107             for (int i = 0; i < predicates.length; i++) {
108                 buffer.append('[');
109                 buffer.append(predicates[i]);
110                 buffer.append(']');
111             }
112         }
113
114         Step steps[] = getSteps();
115         if (steps != null) {
116             for (int i = 0; i < steps.length; i++) {
117                 buffer.append("/");
118                 buffer.append(steps[i]);
119             }
120         }
121         return buffer.toString();
122     }
123
124     public Object JavaDoc compute(EvalContext context) {
125         return expressionPath(context, false);
126     }
127
128     public Object JavaDoc computeValue(EvalContext context) {
129         return expressionPath(context, true);
130     }
131
132     /**
133      * Walks an expression path (a path that starts with an expression)
134      */

135     protected Object JavaDoc expressionPath(
136         EvalContext evalContext,
137         boolean firstMatch)
138     {
139         Object JavaDoc value = expression.compute(evalContext);
140         EvalContext context;
141         if (value instanceof InitialContext) {
142             // This is an optimization. We can avoid iterating through a
143
// collection if the context bean is in fact one.
144
context = (InitialContext) value;
145         }
146         else if (value instanceof EvalContext) {
147             // UnionContext will collect all values from the "value" context
148
// and treat the whole thing as a big collection.
149
context =
150                 new UnionContext(
151                     evalContext,
152                     new EvalContext[] {(EvalContext) value });
153         }
154         else {
155             context = evalContext.getRootContext().getConstantContext(value);
156         }
157
158         if (firstMatch
159             && isSimpleExpressionPath()
160             && !(context instanceof NodeSetContext)) {
161             EvalContext ctx = context;
162             NodePointer ptr = (NodePointer) ctx.getSingleNodePointer();
163             if (ptr != null
164                 && (ptr.getIndex() == NodePointer.WHOLE_COLLECTION
165                     || predicates == null
166                     || predicates.length == 0)) {
167                 return SimplePathInterpreter.interpretSimpleExpressionPath(
168                     evalContext,
169                     ptr,
170                     predicates,
171                     getSteps());
172             }
173         }
174         if (predicates != null) {
175             for (int j = 0; j < predicates.length; j++) {
176                 context = new PredicateContext(context, predicates[j]);
177             }
178         }
179         if (firstMatch) {
180             return getSingleNodePointerForSteps(context);
181         }
182         else {
183             return evalSteps(context);
184         }
185     }
186 }
Popular Tags