1 16 19 package org.apache.xalan.transformer; 20 21 import java.text.CollationKey ; 22 import java.util.Vector ; 23 24 import javax.xml.transform.TransformerException ; 25 26 import org.apache.xml.dtm.DTM; 27 import org.apache.xml.dtm.DTMIterator; 28 import org.apache.xpath.XPathContext; 29 import org.apache.xpath.objects.XNodeSet; 30 import org.apache.xpath.objects.XObject; 31 32 36 public class NodeSorter 37 { 38 39 40 XPathContext m_execContext; 41 42 43 Vector m_keys; 45 50 57 public NodeSorter(XPathContext p) 58 { 59 m_execContext = p; 60 } 61 62 71 public void sort(DTMIterator v, Vector keys, XPathContext support) 72 throws javax.xml.transform.TransformerException 73 { 74 75 m_keys = keys; 76 77 int n = v.getLength(); 79 80 84 Vector nodes = new Vector (); 87 88 for (int i = 0; i < n; i++) 89 { 90 NodeCompareElem elem = new NodeCompareElem(v.item(i)); 91 92 nodes.addElement(elem); 93 } 94 95 Vector scratchVector = new Vector (); 96 97 mergesort(nodes, scratchVector, 0, n - 1, support); 98 99 for (int i = 0; i < n; i++) 101 { 102 v.setItem(((NodeCompareElem) nodes.elementAt(i)).m_node, i); 103 } 104 v.setCurrentPos(0); 105 106 } 110 111 124 int compare( 125 NodeCompareElem n1, NodeCompareElem n2, int kIndex, XPathContext support) 126 throws TransformerException 127 { 128 129 int result = 0; 130 NodeSortKey k = (NodeSortKey) m_keys.elementAt(kIndex); 131 132 if (k.m_treatAsNumbers) 133 { 134 double n1Num, n2Num; 135 136 if (kIndex == 0) 137 { 138 n1Num = ((Double ) n1.m_key1Value).doubleValue(); 139 n2Num = ((Double ) n2.m_key1Value).doubleValue(); 140 } 141 else if (kIndex == 1) 142 { 143 n1Num = ((Double ) n1.m_key2Value).doubleValue(); 144 n2Num = ((Double ) n2.m_key2Value).doubleValue(); 145 } 146 147 153 else 154 { 155 156 XObject r1 = k.m_selectPat.execute(m_execContext, n1.m_node, 158 k.m_namespaceContext); 159 XObject r2 = k.m_selectPat.execute(m_execContext, n2.m_node, 160 k.m_namespaceContext); 161 n1Num = r1.num(); 162 163 n2Num = r2.num(); 167 } 169 170 if ((n1Num == n2Num) && ((kIndex + 1) < m_keys.size())) 171 { 172 result = compare(n1, n2, kIndex + 1, support); 173 } 174 else 175 { 176 double diff; 177 if (Double.isNaN(n1Num)) 178 { 179 if (Double.isNaN(n2Num)) 180 diff = 0.0; 181 else 182 diff = -1; 183 } 184 else if (Double.isNaN(n2Num)) 185 diff = 1; 186 else 187 diff = n1Num - n2Num; 188 189 result = (int) ((diff < 0.0) 191 ? (k.m_descending ? 1 : -1) 192 : (diff > 0.0) ? (k.m_descending ? -1 : 1) : 0); 193 } 194 } else 196 { 197 CollationKey n1String, n2String; 198 199 if (kIndex == 0) 200 { 201 n1String = (CollationKey ) n1.m_key1Value; 202 n2String = (CollationKey ) n2.m_key1Value; 203 } 204 else if (kIndex == 1) 205 { 206 n1String = (CollationKey ) n1.m_key2Value; 207 n2String = (CollationKey ) n2.m_key2Value; 208 } 209 210 216 else 217 { 218 219 XObject r1 = k.m_selectPat.execute(m_execContext, n1.m_node, 221 k.m_namespaceContext); 222 XObject r2 = k.m_selectPat.execute(m_execContext, n2.m_node, 223 k.m_namespaceContext); 224 225 n1String = k.m_col.getCollationKey(r1.str()); 226 n2String = k.m_col.getCollationKey(r2.str()); 227 } 228 229 result = n1String.compareTo(n2String); 232 233 if (k.m_caseOrderUpper) 235 { 236 String tempN1 = n1String.getSourceString().toLowerCase(); 237 String tempN2 = n2String.getSourceString().toLowerCase(); 238 239 if (tempN1.equals(tempN2)) 240 { 241 242 result = result == 0 ? 0 : -result; 244 } 245 } 246 247 if (k.m_descending) 249 { 250 result = -result; 251 } 252 } 254 if (0 == result) 255 { 256 if ((kIndex + 1) < m_keys.size()) 257 { 258 result = compare(n1, n2, kIndex + 1, support); 259 } 260 } 261 262 if (0 == result) 263 { 264 265 DTM dtm = support.getDTM(n1.m_node); result = dtm.isNodeAfter(n1.m_node, n2.m_node) ? -1 : 1; 271 272 } 274 275 return result; 276 } 277 278 293 void mergesort(Vector a, Vector b, int l, int r, XPathContext support) 294 throws TransformerException 295 { 296 297 if ((r - l) > 0) 298 { 299 int m = (r + l) / 2; 300 301 mergesort(a, b, l, m, support); 302 mergesort(a, b, m + 1, r, support); 303 304 int i, j, k; 305 306 for (i = m; i >= l; i--) 307 { 308 309 if (i >= b.size()) 312 b.insertElementAt(a.elementAt(i), i); 313 else 314 b.setElementAt(a.elementAt(i), i); 315 } 316 317 i = l; 318 319 for (j = (m + 1); j <= r; j++) 320 { 321 322 if (r + m + 1 - j >= b.size()) 324 b.insertElementAt(a.elementAt(j), r + m + 1 - j); 325 else 326 b.setElementAt(a.elementAt(j), r + m + 1 - j); 327 } 328 329 j = r; 330 331 int compVal; 332 333 for (k = l; k <= r; k++) 334 { 335 336 if (i == j) 338 compVal = -1; 339 else 340 compVal = compare((NodeCompareElem) b.elementAt(i), 341 (NodeCompareElem) b.elementAt(j), 0, support); 342 343 if (compVal < 0) 344 { 345 346 a.setElementAt(b.elementAt(i), k); 348 349 i++; 350 } 351 else if (compVal > 0) 352 { 353 354 a.setElementAt(b.elementAt(j), k); 356 357 j--; 358 } 359 } 360 } 361 } 362 363 379 380 436 437 454 459 class NodeCompareElem 460 { 461 462 463 int m_node; 464 465 469 int maxkey = 2; 470 471 475 476 Object m_key1Value; 477 478 479 Object m_key2Value; 480 481 489 NodeCompareElem(int node) throws javax.xml.transform.TransformerException 490 { 491 m_node = node; 492 493 if (!m_keys.isEmpty()) 494 { 495 NodeSortKey k1 = (NodeSortKey) m_keys.elementAt(0); 496 XObject r = k1.m_selectPat.execute(m_execContext, node, 497 k1.m_namespaceContext); 498 499 double d; 500 501 if (k1.m_treatAsNumbers) 502 { 503 d = r.num(); 504 505 m_key1Value = new Double (d); 507 } 508 else 509 { 510 m_key1Value = k1.m_col.getCollationKey(r.str()); 511 } 512 513 if (r.getType() == XObject.CLASS_NODESET) 514 { 515 DTMIterator ni = ((XNodeSet)r).iterRaw(); 517 int current = ni.getCurrentNode(); 518 if(DTM.NULL == current) 519 current = ni.nextNode(); 520 521 524 } 526 527 if (m_keys.size() > 1) 528 { 529 NodeSortKey k2 = (NodeSortKey) m_keys.elementAt(1); 530 531 XObject r2 = k2.m_selectPat.execute(m_execContext, node, 532 k2.m_namespaceContext); 533 534 if (k2.m_treatAsNumbers) { 535 d = r2.num(); 536 m_key2Value = new Double (d); 537 } else { 538 m_key2Value = k2.m_col.getCollationKey(r2.str()); 539 } 540 } 541 542 552 } } 554 } } 556 | Popular Tags |