1 16 package org.apache.commons.jxpath.ri.axes; 17 18 import java.util.Iterator ; 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 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 pred = nameTestExpression.computeValue(parentContext); 56 String propertyName = InfoSetUtil.stringValue(pred); 57 58 boolean ok = false; 67 String 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 pred = expression.computeValue(parentContext); 82 if (pred instanceof Iterator ) { 83 if (!((Iterator ) pred).hasNext()) { 84 return false; 85 } 86 pred = ((Iterator ) pred).next(); 87 } 88 89 if (pred instanceof NodePointer) { 90 pred = ((NodePointer) pred).getNode(); 91 } 92 93 if (pred instanceof Number ) { 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 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 |