1 package com.icl.saxon.expr; 2 import com.icl.saxon.Context; 3 import com.icl.saxon.om.NodeInfo; 4 import com.icl.saxon.om.NodeEnumeration; 5 import com.icl.saxon.om.AxisEnumeration; 6 import com.icl.saxon.sort.QuickSort; 7 import com.icl.saxon.sort.Sortable; 8 import com.icl.saxon.sort.NodeOrderComparer; 9 import java.util.Vector; 10 import org.w3c.dom.NodeList; 11 import org.w3c.dom.Node; 12 13 19 20 public final class NodeSetExtent extends NodeSetValue 21 implements Sortable, org.w3c.dom.NodeList { 22 private NodeInfo[] value; 23 private int length; 24 private boolean sorted; private boolean reverseSorted; private NodeOrderComparer comparer; 28 31 32 public NodeSetExtent(NodeOrderComparer comparer) { 33 this.comparer = comparer; 34 this.value = new NodeInfo[0]; 35 length = 0; 36 sorted = true; 37 reverseSorted = true; 38 } 39 40 45 46 public NodeSetExtent(NodeInfo[] nodes, NodeOrderComparer comparer) { 47 this.value = nodes; 48 this.length = nodes.length; 49 sorted = length<2; 50 reverseSorted = length<2; 51 this.comparer = comparer; 52 } 53 54 55 60 61 public NodeSetExtent(Vector nodes, NodeOrderComparer comparer) { 62 value = new NodeInfo[nodes.size()]; 63 for (int i=0; i<nodes.size(); i++) { 64 value[i] = (NodeInfo)nodes.elementAt(i); 65 } 66 length = nodes.size(); 67 sorted = length<2; 68 reverseSorted = length<2; 69 this.comparer = comparer; 70 } 71 72 79 80 public NodeSetExtent(NodeEnumeration enum, NodeOrderComparer comparer) throws XPathException { 81 this.comparer = comparer; 82 int size = 20; 83 value = new NodeInfo[size]; 92 int i = 0; 93 while (enum.hasMoreElements()) { 94 if (i>=size) { 95 size *= 2; 96 NodeInfo newarray[] = new NodeInfo[size]; 97 System.arraycopy(value, 0, newarray, 0, i); 98 value = newarray; 99 } 100 value[i++] = enum.nextElement(); 101 } 102 sorted = enum.isSorted() || i<2; 103 reverseSorted = enum.isReverseSorted() || i<2; 104 length = i; 105 } 106 107 113 114 public void append(NodeInfo node) { 115 reverseSorted = false; 116 if (value.length < length + 1) { 117 NodeInfo[] newval = new NodeInfo[(length==0 ? 10 : length * 2)]; 118 System.arraycopy(value, 0, newval, 0, length); 119 value = newval; 120 } 121 if (length>0 && value[length-1].isSameNode(node)) { 122 return; 123 } else { 124 value[length++] = node; 125 } 126 } 127 128 131 132 public Expression simplify() { 133 if (length==0) { 134 return new EmptyNodeSet(); 135 } else if (length==1) { 136 return new SingletonNodeSet(value[0]); 137 } else { 138 return this; 139 } 140 } 141 142 143 149 150 public void setSorted(boolean isSorted) { 151 sorted = isSorted; 152 } 153 154 159 160 public boolean isSorted() { 161 return sorted; 162 } 163 164 169 170 public String asString() { 171 return (length>0 ? getFirst().getStringValue() : ""); 172 } 173 174 178 179 public boolean asBoolean() throws XPathException { 180 return (length>0); 181 } 182 183 187 188 public int getCount() { 189 sort(); 190 return length; 191 } 192 193 200 201 public NodeSetValue sort() { 202 if (length<2) sorted=true; 203 if (sorted) return this; 204 205 if (reverseSorted) { 206 207 NodeInfo[] array = new NodeInfo[length]; 208 for (int n=0; n<length; n++) { 209 array[n] = value[length-n-1]; 210 } 211 value = array; 212 sorted = true; 213 reverseSorted = false; 214 215 } else { 216 218 QuickSort.sort(this, 0, length-1); 219 220 224 int j=1; 225 for(int i=1; i<length; i++) { 226 if (!value[i].isSameNode(value[i-1])) { 227 value[j++] = value[i]; 228 } 229 } 230 length = j; 231 232 sorted = true; 233 reverseSorted = false; 234 } 235 return this; 236 } 237 238 242 243 public NodeInfo getFirst() { 244 if (length==0) return null; 245 if (sorted) return value[0]; 246 247 NodeInfo first = value[0]; 249 for(int i=1; i<length; i++) { 250 if (comparer.compare(value[i], first) < 0) { 251 first = value[i]; 252 } 253 } 254 return first; 255 } 256 257 263 264 public NodeInfo selectFirst(Context context) { 265 return getFirst(); 266 } 267 268 271 272 public NodeEnumeration enumerate() { 273 return new NodeSetValueEnumeration(); 274 } 275 276 278 281 282 public int getLength() { 283 return getCount(); 284 } 285 286 289 290 public Node item(int index) { 291 sort(); 292 if (length>index && (value[index] instanceof Node)) { 293 return (Node)(value[index]); 294 } else { 295 return null; 296 } 297 } 298 299 303 304 public int compare(int a, int b) { 305 return comparer.compare(value[a], value[b]); 306 } 307 308 311 312 public void swap(int a, int b) { 313 NodeInfo temp = value[a]; 314 value[a] = value[b]; 315 value[b] = temp; 316 } 317 318 321 322 private class NodeSetValueEnumeration implements AxisEnumeration, LastPositionFinder { 323 324 int index=0; 325 326 public NodeSetValueEnumeration() { 327 index = 0; 328 } 330 331 public boolean hasMoreElements() { 332 return index<length; 334 } 335 336 public NodeInfo nextElement() { 337 return value[index++]; 339 } 340 341 public boolean isSorted() { 342 return sorted; 343 } 344 345 public boolean isReverseSorted() { 346 return reverseSorted; 347 } 348 349 public boolean isPeer() { 350 return false; 351 } 352 353 public int getLastPosition() { 354 return length; 355 } 356 } 357 358 } 359 360 379 | Popular Tags |