1 22 23 package org.xquark.xpath; 24 25 import java.util.*; 26 27 import org.xml.sax.ContentHandler ; 28 import org.xml.sax.SAXException ; 29 30 34 public abstract class XTreeNode implements Cloneable { 35 private static final String RCSRevision = "$Revision: 1.2 $"; 36 private static final String RCSName = "$Name: $"; 37 38 protected XTree tree; 39 40 protected XNode XModelNode; 41 44 protected XTreeNode parent; 45 46 private HashMap children; 47 48 protected PathExpr location = null; 49 50 61 protected XTreeNode(XTree tree, XTreeNode parent, String namespace, String localName, byte type) { 62 XModelNode = new XNode(namespace, localName, type); 63 set(tree, parent); 64 } 65 66 71 public XTreeNode getParent() { 72 return parent; 73 } 74 75 79 public XTree getTree() { 80 return tree; 81 } 82 83 87 public Collection getChildren() { 88 if (children == null) 89 return null; 90 return children.values(); 91 } 92 93 100 public final String getExpandedName() { 101 return XModelNode.getExpandedName(); 102 } 103 104 108 public final String getLocalName() { 109 return XModelNode.getLocalName(); 110 } 111 112 116 public String getNamespace() { 117 return XModelNode.getNamespace(); 118 } 119 120 124 public byte getType() { 125 return XModelNode.getType(); 126 } 127 128 132 public XNode getHashKey() { 133 return XModelNode; 134 } 135 136 140 public boolean isLeaf() { 141 return (children == null); 142 } 143 144 148 public int getDepth() { 149 if (location == null) 150 return 0; 151 else 152 return getLocation().getSteps().size(); 153 } 154 155 160 public final void addChild(XTreeNode child) { 161 if (children == null) children = new HashMap(); 163 children.put(child.getHashKey(), child); 164 child.setParent(this); 165 } 166 167 172 public final void merge(XTreeNode node) { 173 if (node.children != null) { 174 Iterator it = node.children.keySet().iterator(); 175 while (it.hasNext()) { 176 XNode key = ((XTreeNode) it.next()).getHashKey(); 177 XTreeNode child = getChild(key); 178 if (child == null) 179 this.addChild(node.getChild(key)); 180 else 181 child.merge(node.getChild(key)); 182 } 183 } 184 } 185 186 190 public final XTreeNode removeChild(XNode pattern) { 191 if (children != null) 192 return (XTreeNode) children.remove(getChild(pattern)); 193 return null; 194 } 195 196 199 public final void remove() { 200 if (parent != null) 201 parent.removeChild(XModelNode); 202 } 203 204 209 public final XTreeNode getChild(XNode pattern) { 210 if (children == null) 211 return null; 212 return (XTreeNode) children.get(pattern); 213 } 214 215 221 public final PathExpr getLocation() { 222 if (location == null) { 223 if (getParent() == null) return null; 225 location = new PathExprImpl(); 226 } else return location; 228 229 for (XTreeNode node = this; node.getType() != NodeKind.NONE; node = (XTreeNode) node.getParent()) { 231 switch (node.getType()) { 232 case NodeKind.NAMESPACE : 233 location.getSteps().add(0, new StepExprImpl(Axis.NAMESPACE, node.getHashKey())); 234 break; 235 case NodeKind.ATTRIBUTE : 236 location.getSteps().add(0, new StepExprImpl(Axis.ATTRIBUTE, node.getHashKey())); 237 break; 238 default : location.getSteps().add(0, new StepExprImpl(node.getHashKey())); 240 } 241 } 242 return location; 243 } 244 245 250 public final Collection navigate(StepExpr step) { 251 Collection result = null; 252 253 byte axis = step.getAxis(); 254 255 switch (axis) { 256 case Axis.SELF : 257 result = new ArrayList(1); 258 if (step.match(XModelNode)) 259 result.add(this); 260 break; 261 262 case Axis.NONE : 263 case Axis.CHILD : 264 case Axis.ATTRIBUTE : 265 case Axis.NAMESPACE : 266 return getChildren(step); 267 268 case Axis.PARENT : 269 result = new ArrayList(1); 270 result.add(getParent()); 271 break; 272 273 case Axis.ANCESTOR_OR_SELF : 274 result = getAncestors(step); 275 if (step.match(XModelNode)) 276 result.add(this); 277 break; 278 279 case Axis.ANCESTOR : 280 return getAncestors(step); 281 282 case Axis.DESCENDANT : 283 return getDescendants(step); 284 285 case Axis.DESCENDANT_OR_SELF : 286 result = getDescendants(step); 287 if (step.match(XModelNode)) 288 result.add(this); 289 break; 290 291 case Axis.PRECEDING : 292 return getPreceding(step); 293 294 case Axis.PRECEDING_SIBLING : 295 return getPrecedingSibling(step); 296 297 case Axis.FOLLOWING : 298 return getFollowing(step); 299 300 case Axis.FOLLOWING_SIBLING : 301 return getFollowingSibling(step); 302 303 } 306 307 return result; 308 } 309 310 317 public final Collection prune(ArrayList location) { 318 357 358 361 372 373 Set result = new HashSet(); 374 375 if (location.size() == 0) { 376 if (this.getType() != NodeKind.NONE) 377 result.add(this); 378 return result; 380 } 381 382 Collection set = navigate((StepExpr) location.get(0)); 383 384 387 ArrayList l = (ArrayList) location.clone(); 388 389 if (l.size() > 0) 390 l.remove(0); 391 else { 392 if (set != null) 393 result.addAll(set); 394 return result; 396 } 397 398 Object [] nodes = set.toArray(); 399 for (int i = 0; i < nodes.length; i++) { 400 XTreeNode node = (XTreeNode) nodes[i]; 401 Collection tmp = node.prune(l); 403 result.addAll(tmp); 404 } 405 return result; 407 } 408 409 418 public final Collection pruneGroup(ArrayList location) { 419 Set result = new HashSet(); 420 Set group = new HashSet(); 421 422 if (location.size() == 0) { 423 428 result.add(this); return result; 431 } 432 433 Collection set = navigate((StepExpr) location.get(0)); 434 435 438 ArrayList l = (ArrayList) location.clone(); 439 440 if (l.size() > 0) 441 l.remove(0); 442 else { 443 if (set != null) { 444 group.add(set); 445 result.add(group); 446 } 447 return result; 448 } 449 450 Object [] nodes = set.toArray(); 451 for (int i = 0; i < nodes.length; i++) { 452 XTreeNode node = (XTreeNode) nodes[i]; 453 if (node != null); 455 { 456 Collection c = node.pruneGroup(l); 457 if ((c != null) && (c.size() > 0)) 458 result.add(node.pruneGroup(l)); 459 } 460 } 461 return result; 462 } 463 464 470 private static final String LS = System.getProperty("line.separator"); 471 public final String toString(int indent) { 472 StringBuffer sb = new StringBuffer (); 473 sb.append(LS); 474 for (int i=0;i<indent;i++) sb.append(' '); 475 sb.append(this.getNamespace()); 476 sb.append(":"); 477 sb.append(this.getLocalName()); 478 sb.append(" "); 479 sb.append(toString()); 480 481 if (children != null) { 482 Iterator it = getChildren().iterator(); 483 484 while (it.hasNext()) { 485 XTreeNode child = (XTreeNode) it.next(); 486 sb.append(child.toString(indent + 1)); 487 } 488 } 489 return sb.toString(); 490 } 491 492 497 public Object clone() { 498 XTreeNode node = null; 499 try { 500 node = (XTreeNode) super.clone(); 501 node.XModelNode = (XNode) XModelNode.clone(); 502 if (children != null) { 503 node.children = new HashMap(); 504 Iterator it = children.values().iterator(); 505 while (it.hasNext()) { 506 node.addChild((XTreeNode) ((XTreeNode) it.next()).clone()); 507 } 508 } 509 } catch (CloneNotSupportedException e) {} 510 return node; 511 } 512 513 520 public XTreeNode duplicate(XTreeNode root, XTreeBuilder factory) { 521 if (children != null) { 522 Iterator it = children.values().iterator(); 523 XTreeNode child; 524 while (it.hasNext()) { 525 child = (XTreeNode) it.next(); 526 XTreeNode duplicate = factory.createNamedNode(root, child.getNamespace(), child.getLocalName(), child.getType()).customizeDuplicate(child); 527 child.duplicate(duplicate, factory); 528 } 531 } 532 return root; 533 } 534 535 540 protected XTreeNode customizeDuplicate(XTreeNode original) { 541 return this; 543 } 544 545 553 protected void toXML(ContentHandler handler) throws SAXException { 554 String display = toString(); 555 handler.characters(display.toCharArray(), 0, display.length()); 556 } 557 558 571 public XTreeNode getDescendant(PathExpr e) { 572 if (e == null) { 573 return this; 574 } 575 576 XTreeNode result = this; 577 578 for (int i = 0; i < e.getSteps().size(); i++) { 579 StepExpr step = e.getStep(i); 580 byte axis = step.getAxis(); 581 switch (axis) { 582 case Axis.ATTRIBUTE : 583 case Axis.CHILD : 584 result = result.getChild(step.getXNode()); 585 break; 586 587 case Axis.SELF : 588 break; 589 590 case Axis.PARENT : 591 result = result.getParent(); 592 break; 593 594 default : 595 throw new RuntimeException ("Navigation axis [" + axis + "] not handled by this method."); 596 } 597 598 if (result == null) { 599 break; 600 } 601 } 602 return result; 603 } 604 605 private void set(XTree tree, XTreeNode parent) { 609 this.tree = tree; 610 if (parent != null) 611 parent.addChild(this); 612 } 613 614 private void setParent(XTreeNode parent) { 615 this.parent = parent; 616 location = null; 617 } 618 619 626 630 633 private Collection getChildren(StepExpr step) { 634 ArrayList set = new ArrayList(); 635 if (children == null) 636 return set; 637 Iterator it = children.values().iterator(); 638 while (it.hasNext()) { 639 XTreeNode child = (XTreeNode) it.next(); 640 if (step.match(child.getHashKey())) 641 set.add(child); 642 } 643 return set; 644 } 645 646 649 private Collection getAncestors(StepExpr step) { 650 ArrayList ancestors = new ArrayList(); 651 652 XTreeNode ancestor = (XTreeNode) getParent(); 653 while (ancestor != null) { 654 if (ancestor.getHashKey().match(step)) 655 ancestors.add(ancestor); 656 ancestor = (XTreeNode) ancestor.getParent(); 657 } 658 return ancestors; 659 } 660 661 664 private Collection getDescendants(StepExpr step) { 665 ArrayList descendants = new ArrayList(); 666 if (children == null) 667 return descendants; 668 669 Iterator it = children.values().iterator(); 670 while (it.hasNext()) { 671 XTreeNode child = (XTreeNode) it.next(); 672 673 if (child.XModelNode.type != NodeKind.ELEMENT) { 674 continue; 675 } 676 677 if (step.match(child.getHashKey())) { 678 descendants.add(child); 679 } 680 descendants.addAll(child.getDescendants(step)); 681 } 682 return descendants; 684 } 685 686 691 private Collection getPreceding(StepExpr step) { 692 throw new UnsupportedOperationException (); 693 } 694 695 private Collection getPrecedingSibling(StepExpr step) { 696 throw new UnsupportedOperationException (); 697 } 698 699 private Collection getFollowing(StepExpr step) { 700 throw new UnsupportedOperationException (); 701 } 702 703 private Collection getFollowingSibling(StepExpr step) { 704 throw new UnsupportedOperationException (); 705 } 706 707 } 708 | Popular Tags |