1 package com.icl.saxon.expr; 2 import com.icl.saxon.*; 3 import com.icl.saxon.om.*; 4 import com.icl.saxon.functions.*; 5 6 import java.util.*; 7 import java.lang.Math ; 8 9 14 15 public class FilterEnumerator implements NodeEnumeration { 16 17 private NodeEnumeration base; 18 private Expression filter; 19 private int position = 0; 20 private int last = -1; 21 int min = 1; 22 int max = Integer.MAX_VALUE; 23 private NodeInfo current = null; 24 private Context filterContext; 25 private int dataType = Value.ANY; private boolean positional = false; 27 private boolean finished = false; private boolean finishAfterReject = false; 29 32 40 41 public FilterEnumerator(NodeEnumeration base, Expression filter, 42 Context context, boolean finishAfterReject) throws XPathException { 43 this.base = base; 44 this.filter = filter; 45 this.finishAfterReject = finishAfterReject; 46 47 filterContext = context.newContext(); 48 49 this.dataType = filter.getDataType(); 50 51 if (filter instanceof NumericValue) { 52 double pos = ((NumericValue)filter).asNumber(); 54 if (Math.floor(pos)==pos) { 55 min = (int)pos; 56 max = min; 57 positional = true; 58 } else { 59 finished = true; 60 } 61 } else if (filter instanceof PositionRange) { 62 min = ((PositionRange)filter).getMinPosition(); 63 max = ((PositionRange)filter).getMaxPosition(); 64 positional = true; 65 } 66 67 if (base instanceof LastPositionFinder) { 68 filterContext.setLastPositionFinder((LastPositionFinder)base); 69 } else { 70 this.base = new LookaheadEnumerator(base); 72 filterContext.setLastPositionFinder((LastPositionFinder)this.base); 73 } 74 75 current = getNextMatchingElement(); 76 } 77 78 81 82 public boolean hasMoreElements() { 83 if (finished) return false; 84 return current!=null; 85 } 86 87 90 91 public NodeInfo nextElement() throws XPathException { 92 NodeInfo node = current; 93 current = getNextMatchingElement(); 94 return node; 95 } 96 97 100 101 private NodeInfo getNextMatchingElement() throws XPathException { 102 while (!finished && base.hasMoreElements()) { 103 NodeInfo next = base.nextElement(); 104 position++; 105 if (matches(next)) { 106 return next; 107 } else if (finishAfterReject) { 108 return null; 109 } 110 } 111 return null; 112 } 113 114 117 118 private boolean matches(NodeInfo node) throws XPathException { 119 if (positional) { 120 if (position<min) { 121 return false; 122 } else if (position>max) { 123 finished = true; 124 return false; 125 } else { 126 return true; 127 } 128 } 129 filterContext.setPosition(position); 130 filterContext.setContextNode(node); 131 132 136 if (dataType==Value.NUMBER) { 137 double req = (int)filter.evaluateAsNumber(filterContext); 138 if ((double)position==req) { 139 return true; 140 } else { 141 return false; 142 } 143 } else if (dataType==Value.ANY) { 144 Value val = filter.evaluate(filterContext); 146 if (val instanceof NumericValue) { 147 return ((double)position==val.asNumber()); 148 } else { 149 return val.asBoolean(); 150 } 151 } else { 152 return filter.evaluateAsBoolean(filterContext); 154 } 155 } 156 157 160 161 public boolean isSorted() { 162 return base.isSorted(); 163 } 164 165 public boolean isReverseSorted() { 166 return base.isReverseSorted(); 167 } 168 169 172 173 public boolean isPeer() { 174 return base.isPeer(); 175 } 176 } 177 178 179 180 | Popular Tags |