KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jxpath > ri > axes > PredicateContext


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.axes;
17
18 import java.util.Iterator JavaDoc;
19
20 import org.apache.commons.jxpath.ri.EvalContext;
21 import org.apache.commons.jxpath.ri.InfoSetUtil;
22 import org.apache.commons.jxpath.ri.compiler.Expression;
23 import org.apache.commons.jxpath.ri.compiler.NameAttributeTest;
24 import org.apache.commons.jxpath.ri.model.NodePointer;
25 import org.apache.commons.jxpath.ri.model.beans.PropertyOwnerPointer;
26 import org.apache.commons.jxpath.ri.model.beans.PropertyPointer;
27
28 /**
29  * EvalContext that checks predicates.
30  *
31  * @author Dmitri Plotnikov
32  * @version $Revision: 1.22 $ $Date: 2004/02/29 14:17:37 $
33  */

34 public class PredicateContext extends EvalContext {
35     private Expression expression;
36     private boolean done = false;
37     private Expression nameTestExpression;
38     private PropertyPointer dynamicPropertyPointer;
39
40     public PredicateContext(EvalContext parentContext, Expression expression) {
41         super(parentContext);
42         this.expression = expression;
43         if (expression instanceof NameAttributeTest) {
44             nameTestExpression =
45                 ((NameAttributeTest) expression).getNameTestExpression();
46         }
47     }
48
49     public boolean nextNode() {
50         if (done) {
51             return false;
52         }
53         while (parentContext.nextNode()) {
54             if (setupDynamicPropertyPointer()) {
55                 Object JavaDoc pred = nameTestExpression.computeValue(parentContext);
56                 String JavaDoc propertyName = InfoSetUtil.stringValue(pred);
57
58                 // At this point it would be nice to say:
59
// dynamicPropertyPointer.setPropertyName(propertyName)
60
// and then: dynamicPropertyPointer.isActual().
61
// However some PropertyPointers, e.g. DynamicPropertyPointer
62
// will declare that any property you ask for is actual.
63
// That's not acceptable for us: we really need to know
64
// if the property is currently declared. Thus,
65
// we'll need to perform a search.
66
boolean ok = false;
67                 String JavaDoc names[] = dynamicPropertyPointer.getPropertyNames();
68                 for (int i = 0; i < names.length; i++) {
69                     if (names[i].equals(propertyName)) {
70                         ok = true;
71                         break;
72                     }
73                 }
74                 if (ok) {
75                     dynamicPropertyPointer.setPropertyName(propertyName);
76                     position++;
77                     return true;
78                 }
79             }
80             else {
81                 Object JavaDoc pred = expression.computeValue(parentContext);
82                 if (pred instanceof Iterator JavaDoc) {
83                     if (!((Iterator JavaDoc) pred).hasNext()) {
84                         return false;
85                     }
86                     pred = ((Iterator JavaDoc) pred).next();
87                 }
88
89                 if (pred instanceof NodePointer) {
90                     pred = ((NodePointer) pred).getNode();
91                 }
92
93                 if (pred instanceof Number JavaDoc) {
94                     int pos = (int) InfoSetUtil.doubleValue(pred);
95                     position++;
96                     done = true;
97                     return parentContext.setPosition(pos);
98                 }
99                 else if (InfoSetUtil.booleanValue(pred)) {
100                     position++;
101                     return true;
102                 }
103             }
104         }
105         return false;
106     }
107
108     /**
109      * Used for an optimized access to dynamic properties using the
110      * "map[@name = 'name']" syntax
111      */

112     private boolean setupDynamicPropertyPointer() {
113         if (nameTestExpression == null) {
114             return false;
115         }
116
117         NodePointer parent = parentContext.getCurrentNodePointer();
118         if (parent == null) {
119             return false;
120         }
121         parent = parent.getValuePointer();
122         if (!(parent instanceof PropertyOwnerPointer)) {
123             return false;
124         }
125         dynamicPropertyPointer =
126             (PropertyPointer) ((PropertyOwnerPointer) parent)
127                 .getPropertyPointer()
128                 .clone();
129         return true;
130     }
131
132     public boolean setPosition(int position) {
133         if (nameTestExpression == null) {
134             return setPositionStandard(position);
135         }
136         else {
137             if (dynamicPropertyPointer == null) {
138                 if (!setupDynamicPropertyPointer()) {
139                     return setPositionStandard(position);
140                 }
141             }
142             if (position < 1
143                 || position > dynamicPropertyPointer.getLength()) {
144                 return false;
145             }
146             dynamicPropertyPointer.setIndex(position - 1);
147             return true;
148         }
149     }
150
151     public NodePointer getCurrentNodePointer() {
152         if (position == 0) {
153             if (!setPosition(1)) {
154                 return null;
155             }
156         }
157         if (dynamicPropertyPointer != null) {
158             return dynamicPropertyPointer.getValuePointer();
159         }
160         else {
161             return parentContext.getCurrentNodePointer();
162         }
163     }
164
165     public void reset() {
166         super.reset();
167         done = false;
168     }
169
170     public boolean nextSet() {
171         reset();
172         return parentContext.nextSet();
173     }
174
175     private boolean setPositionStandard(int position) {
176         if (this.position > position) {
177             reset();
178         }
179
180         while (this.position < position) {
181             if (!nextNode()) {
182                 return false;
183             }
184         }
185         return true;
186     }
187 }
Popular Tags