1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jxpath.ri.compiler;
19
20 import org.apache.commons.jxpath.ri.EvalContext;
21 import org.apache.commons.jxpath.ri.axes.InitialContext;
22 import org.apache.commons.jxpath.ri.axes.NodeSetContext;
23 import org.apache.commons.jxpath.ri.axes.PredicateContext;
24 import org.apache.commons.jxpath.ri.axes.SimplePathInterpreter;
25 import org.apache.commons.jxpath.ri.axes.UnionContext;
26 import org.apache.commons.jxpath.ri.model.NodePointer;
27
28
29
30
31
32 public class ExpressionPath extends Path {
33
34 private final Expression expression;
35 private final Expression[] predicates;
36 private boolean basicKnown;
37 private boolean basic;
38
39
40
41
42
43
44
45
46 public ExpressionPath(final Expression expression, final Expression[] predicates, final Step[] steps) {
47 super(steps);
48 this.expression = expression;
49 this.predicates = predicates;
50 }
51
52 @Override
53 public Object compute(final EvalContext context) {
54 return expressionPath(context, false);
55 }
56
57
58
59
60
61
62 @Override
63 public boolean computeContextDependent() {
64 if (expression.isContextDependent()) {
65 return true;
66 }
67 if (predicates != null) {
68 for (final Expression predicate : predicates) {
69 if (predicate.isContextDependent()) {
70 return true;
71 }
72 }
73 }
74 return super.computeContextDependent();
75 }
76
77 @Override
78 public Object computeValue(final EvalContext context) {
79 return expressionPath(context, true);
80 }
81
82
83
84
85
86
87
88
89 protected Object expressionPath(final EvalContext evalContext, final boolean firstMatch) {
90 final Object value = expression.compute(evalContext);
91 EvalContext context;
92 if (value instanceof InitialContext) {
93
94
95 context = (InitialContext) value;
96 } else if (value instanceof EvalContext) {
97
98
99 context = new UnionContext(evalContext, new EvalContext[] { (EvalContext) value });
100 } else {
101 context = evalContext.getRootContext().getConstantContext(value);
102 }
103 if (firstMatch && isSimpleExpressionPath() && !(context instanceof NodeSetContext)) {
104 final EvalContext ctx = context;
105 final NodePointer ptr = (NodePointer) ctx.getSingleNodePointer();
106 if (ptr != null && (ptr.getIndex() == NodePointer.WHOLE_COLLECTION || predicates == null || predicates.length == 0)) {
107 return SimplePathInterpreter.interpretSimpleExpressionPath(evalContext, ptr, predicates, getSteps());
108 }
109 }
110 if (predicates != null) {
111 for (int j = 0; j < predicates.length; j++) {
112 if (j != 0) {
113 context = new UnionContext(context, new EvalContext[] { context });
114 }
115 context = new PredicateContext(context, predicates[j]);
116 }
117 }
118 return firstMatch ? (Object) getSingleNodePointerForSteps(context) : evalSteps(context);
119 }
120
121
122
123
124
125
126 public Expression getExpression() {
127 return expression;
128 }
129
130
131
132
133
134
135 public Expression[] getPredicates() {
136 return predicates;
137 }
138
139
140
141
142
143
144 public synchronized boolean isSimpleExpressionPath() {
145 if (!basicKnown) {
146 basicKnown = true;
147 basic = isSimplePath() && areBasicPredicates(getPredicates());
148 }
149 return basic;
150 }
151
152 @Override
153 public String toString() {
154 final StringBuilder buffer = new StringBuilder();
155 if (expression instanceof CoreOperation || expression instanceof ExpressionPath || expression instanceof LocationPath) {
156 buffer.append('(');
157 buffer.append(expression);
158 buffer.append(')');
159 } else {
160 buffer.append(expression);
161 }
162 if (predicates != null) {
163 for (final Expression predicate : predicates) {
164 buffer.append('[');
165 buffer.append(predicate);
166 buffer.append(']');
167 }
168 }
169 final Step[] steps = getSteps();
170 if (steps != null) {
171 for (final Step step : steps) {
172 buffer.append("/");
173 buffer.append(step);
174 }
175 }
176 return buffer.toString();
177 }
178 }