Clover coverage report - dom4j - 1.5
Coverage timestamp: vr sep 3 2004 20:47:03 GMT+01:00
file stats: LOC: 2.329   Methods: 115
NCLOC: 1.088   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AbstractElement.java 38,2% 47,9% 53% 45,8%
coverage coverage
 1    /*
 2    * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
 3    *
 4    * This software is open source.
 5    * See the bottom of this file for the licence.
 6    *
 7    * $Id: AbstractElement.java,v 1.77 2004/06/25 12:34:49 maartenc Exp $
 8    */
 9   
 10    package org.dom4j.tree;
 11   
 12    import java.io.IOException;
 13    import java.io.StringWriter;
 14    import java.io.Writer;
 15    import java.util.ArrayList;
 16    import java.util.Collections;
 17    import java.util.Iterator;
 18    import java.util.List;
 19    import java.util.Map;
 20   
 21    import org.dom4j.Attribute;
 22    import org.dom4j.CDATA;
 23    import org.dom4j.CharacterData;
 24    import org.dom4j.Comment;
 25    import org.dom4j.Document;
 26    import org.dom4j.DocumentFactory;
 27    import org.dom4j.Element;
 28    import org.dom4j.Entity;
 29    import org.dom4j.IllegalAddException;
 30    import org.dom4j.Namespace;
 31    import org.dom4j.Node;
 32    import org.dom4j.ProcessingInstruction;
 33    import org.dom4j.QName;
 34    import org.dom4j.Text;
 35    import org.dom4j.Visitor;
 36    import org.dom4j.io.XMLWriter;
 37    import org.xml.sax.Attributes;
 38   
 39    /** <p><code>AbstractElement</code> is an abstract base class for
 40    * tree implementors to use for implementation inheritence.</p>
 41    *
 42    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 43    * @version $Revision: 1.77 $
 44    */
 45   
 46    public abstract class AbstractElement
 47    extends AbstractBranch
 48    implements Element {
 49   
 50    /** The <code>DocumentFactory</code> instance used by default */
 51   
 52    private static final DocumentFactory DOCUMENT_FACTORY =
 53    DocumentFactory.getInstance();
 54   
 55    protected static final List EMPTY_LIST = Collections.EMPTY_LIST;
 56   
 57    protected static final Iterator EMPTY_ITERATOR = EMPTY_LIST.iterator();
 58   
 59    protected static final boolean VERBOSE_TOSTRING = false;
 60   
 61    protected static final boolean USE_STRINGVALUE_SEPARATOR = false;
 62   
 63  184660 public AbstractElement() {
 64   
 65    }
 66   
 67  187576 public short getNodeType() {
 68   
 69  187576 return ELEMENT_NODE;
 70   
 71    }
 72   
 73  0 public boolean isRootElement() {
 74   
 75  0 Document document = getDocument();
 76   
 77  0 if (document != null) {
 78   
 79  0 Element root = document.getRootElement();
 80   
 81  0 if (root == this) {
 82   
 83  0 return true;
 84   
 85    }
 86   
 87    }
 88   
 89  0 return false;
 90   
 91    }
 92   
 93  2 public void setName(String name) {
 94   
 95  2 setQName(getDocumentFactory().createQName(name));
 96   
 97    }
 98   
 99  0 public void setNamespace(Namespace namespace) {
 100   
 101  0 setQName(getDocumentFactory().createQName(getName(), namespace));
 102   
 103    }
 104   
 105    /** Returns the XPath expression to match this Elements name
 106    * which is getQualifiedName() if there is a namespace prefix defined or
 107    * if no namespace is present then it is getName() or if a namespace is defined
 108    * with no prefix then the expression is *[name()='X'] where X = getName().
 109    */
 110   
 111  132 public String getXPathNameStep() {
 112   
 113  132 String uri = getNamespaceURI();
 114   
 115  132 if (uri == null || uri.length() == 0) {
 116   
 117  112 return getName();
 118   
 119    }
 120   
 121  20 String prefix = getNamespacePrefix();
 122   
 123  20 if (prefix == null || prefix.length() == 0) {
 124   
 125  16 return "*[name()='" + getName() + "']";
 126   
 127    }
 128   
 129  4 return getQualifiedName();
 130   
 131    }
 132   
 133  62 public String getPath(Element context) {
 134   
 135  62 if (this == context) {
 136  2 return ".";
 137    }
 138   
 139  60 Element parent = getParent();
 140   
 141  60 if (parent == null) {
 142   
 143  22 return "/" + getXPathNameStep();
 144   
 145    }
 146   
 147  38 else if (parent == context) {
 148   
 149  14 return getXPathNameStep();
 150   
 151    }
 152   
 153  24 return parent.getPath(context) + "/" + getXPathNameStep();
 154   
 155    }
 156   
 157  72 public String getUniquePath(Element context) {
 158   
 159  72 Element parent = getParent();
 160   
 161  72 if (parent == null) {
 162   
 163  26 return "/" + getXPathNameStep();
 164   
 165    }
 166   
 167  46 StringBuffer buffer = new StringBuffer();
 168   
 169  46 if (parent != context) {
 170   
 171  32 buffer.append(parent.getUniquePath(context));
 172   
 173  32 buffer.append("/");
 174   
 175    }
 176   
 177  46 buffer.append(getXPathNameStep());
 178   
 179  46 List mySiblings = parent.elements(getQName());
 180   
 181  46 if (mySiblings.size() > 1) {
 182   
 183  26 int idx = mySiblings.indexOf(this);
 184   
 185  26 if (idx >= 0) {
 186   
 187  26 buffer.append("[");
 188   
 189  26 buffer.append(Integer.toString(++idx));
 190   
 191  26 buffer.append("]");
 192   
 193    }
 194   
 195    }
 196   
 197  46 return buffer.toString();
 198   
 199    }
 200   
 201  4134 public String asXML() {
 202   
 203  4134 try {
 204   
 205  4134 StringWriter out = new StringWriter();
 206   
 207  4134 XMLWriter writer = new XMLWriter(out, outputFormat);
 208   
 209  4134 writer.write(this);
 210   
 211  4134 return out.toString();
 212   
 213    }
 214   
 215    catch (IOException e) {
 216   
 217  0 throw new RuntimeException(
 218    "Wierd IOException while generating textual representation: " + e.getMessage());
 219   
 220    }
 221   
 222    }
 223   
 224  0 public void write(Writer out) throws IOException {
 225   
 226  0 XMLWriter writer = new XMLWriter(out, outputFormat);
 227   
 228  0 writer.write(this);
 229   
 230    }
 231   
 232    /** <p><code>accept</code> method is the <code>Visitor Pattern</code> method.
 233    * </p>
 234    *
 235    * @param visitor <code>Visitor</code> is the visitor.
 236    */
 237   
 238  0 public void accept(Visitor visitor) {
 239   
 240  0 visitor.visit(this);
 241   
 242    // visit attributes
 243   
 244  0 for (int i = 0, size = attributeCount(); i < size; i++) {
 245   
 246  0 Attribute attribute = attribute(i);
 247   
 248  0 visitor.visit(attribute);
 249   
 250    }
 251   
 252    // visit content
 253   
 254  0 for (int i = 0, size = nodeCount(); i < size; i++) {
 255   
 256  0 Node node = node(i);
 257   
 258  0 node.accept(visitor);
 259   
 260    }
 261   
 262    }
 263   
 264  152670 public String toString() {
 265   
 266  152670 String uri = getNamespaceURI();
 267   
 268  152670 if (uri != null && uri.length() > 0) {
 269   
 270  4864 if (VERBOSE_TOSTRING) {
 271   
 272  0 return super.toString()
 273    + " [Element: <"
 274    + getQualifiedName()
 275    + " uri: "
 276    + uri
 277    + " attributes: "
 278    + attributeList()
 279    + " content: "
 280    + contentList()
 281    + " />]";
 282   
 283    }
 284   
 285    else {
 286   
 287  4864 return super.toString()
 288    + " [Element: <"
 289    + getQualifiedName()
 290    + " uri: "
 291    + uri
 292    + " attributes: "
 293    + attributeList()
 294    + "/>]";
 295   
 296    }
 297   
 298    }
 299   
 300    else {
 301   
 302  147806 if (VERBOSE_TOSTRING) {
 303   
 304  0 return super.toString()
 305    + " [Element: <"
 306    + getQualifiedName()
 307    + " attributes: "
 308    + attributeList()
 309    + " content: "
 310    + contentList()
 311    + " />]";
 312   
 313    }
 314   
 315    else {
 316   
 317  147806 return super.toString()
 318    + " [Element: <"
 319    + getQualifiedName()
 320    + " attributes: "
 321    + attributeList()
 322    + "/>]";
 323   
 324    }
 325   
 326    }
 327   
 328    }
 329   
 330    // QName methods
 331   
 332    //-------------------------------------------------------------------------
 333   
 334  229238 public Namespace getNamespace() {
 335   
 336  229238 return getQName().getNamespace();
 337   
 338    }
 339   
 340  168722 public String getName() {
 341   
 342  168722 return getQName().getName();
 343   
 344    }
 345   
 346  15462 public String getNamespacePrefix() {
 347   
 348  15462 return getQName().getNamespacePrefix();
 349   
 350    }
 351   
 352  327070 public String getNamespaceURI() {
 353   
 354  327070 return getQName().getNamespaceURI();
 355   
 356    }
 357   
 358  217966 public String getQualifiedName() {
 359   
 360  217966 return getQName().getQualifiedName();
 361   
 362    }
 363   
 364  0 public Object getData() {
 365   
 366  0 return getText();
 367   
 368    }
 369   
 370  0 public void setData(Object data) {
 371   
 372    // ignore this method
 373   
 374    }
 375   
 376    // Node methods
 377   
 378    //-------------------------------------------------------------------------
 379   
 380  0 public Node node(int index) {
 381   
 382  0 if (index >= 0) {
 383   
 384  0 List list = contentList();
 385   
 386  0 if (index >= list.size()) {
 387   
 388  0 return null;
 389   
 390    }
 391   
 392  0 Object node = list.get(index);
 393   
 394  0 if (node != null) {
 395   
 396  0 if (node instanceof Node) {
 397   
 398  0 return (Node) node;
 399   
 400    }
 401   
 402    else {
 403   
 404  0 return getDocumentFactory().createText(node.toString());
 405   
 406    }
 407   
 408    }
 409   
 410    }
 411   
 412  0 return null;
 413   
 414    }
 415   
 416  0 public int indexOf(Node node) {
 417   
 418  0 return contentList().indexOf(node);
 419   
 420    }
 421   
 422  2 public int nodeCount() {
 423   
 424  2 return contentList().size();
 425   
 426    }
 427   
 428  0 public Iterator nodeIterator() {
 429   
 430  0 return contentList().iterator();
 431   
 432    }
 433   
 434    // Element methods
 435   
 436    //-------------------------------------------------------------------------
 437   
 438  0 public Element element(String name) {
 439   
 440  0 List list = contentList();
 441   
 442  0 int size = list.size();
 443   
 444  0 for (int i = 0; i < size; i++) {
 445   
 446  0 Object object = list.get(i);
 447   
 448  0 if (object instanceof Element) {
 449   
 450  0 Element element = (Element) object;
 451   
 452  0 if (name.equals(element.getName())) {
 453   
 454  0 return element;
 455   
 456    }
 457   
 458    }
 459   
 460    }
 461   
 462  0 return null;
 463   
 464    }
 465   
 466  0 public Element element(QName qName) {
 467   
 468  0 List list = contentList();
 469   
 470  0 int size = list.size();
 471   
 472  0 for (int i = 0; i < size; i++) {
 473   
 474  0 Object object = list.get(i);
 475   
 476  0 if (object instanceof Element) {
 477   
 478  0 Element element = (Element) object;
 479   
 480  0 if (qName.equals(element.getQName())) {
 481   
 482  0 return element;
 483   
 484    }
 485   
 486    }
 487   
 488    }
 489   
 490  0 return null;
 491   
 492    }
 493   
 494  0 public Element element(String name, Namespace namespace) {
 495   
 496  0 return element(getDocumentFactory().createQName(name, namespace));
 497   
 498    }
 499   
 500  168 public List elements() {
 501   
 502  168 List list = contentList();
 503   
 504  168 BackedList answer = createResultList();
 505   
 506  168 int size = list.size();
 507   
 508  168 for (int i = 0; i < size; i++) {
 509   
 510  724 Object object = list.get(i);
 511   
 512  724 if (object instanceof Element) {
 513   
 514  298 answer.addLocal(object);
 515   
 516    }
 517   
 518    }
 519   
 520  168 return answer;
 521   
 522    }
 523   
 524  402 public List elements(String name) {
 525   
 526  402 List list = contentList();
 527   
 528  402 BackedList answer = createResultList();
 529   
 530  402 int size = list.size();
 531   
 532  402 for (int i = 0; i < size; i++) {
 533   
 534  3958 Object object = list.get(i);
 535   
 536  3958 if (object instanceof Element) {
 537   
 538  1826 Element element = (Element) object;
 539   
 540  1826 if (name.equals(element.getName())) {
 541   
 542  696 answer.addLocal(element);
 543   
 544    }
 545   
 546    }
 547   
 548    }
 549   
 550  402 return answer;
 551   
 552    }
 553   
 554  27978 public List elements(QName qName) {
 555   
 556  27978 List list = contentList();
 557   
 558  27978 BackedList answer = createResultList();
 559   
 560  27978 int size = list.size();
 561   
 562  27978 for (int i = 0; i < size; i++) {
 563   
 564  84084 Object object = list.get(i);
 565   
 566  84084 if (object instanceof Element) {
 567   
 568  29434 Element element = (Element) object;
 569   
 570  29434 if (qName.equals(element.getQName())) {
 571   
 572  7356 answer.addLocal(element);
 573   
 574    }
 575   
 576    }
 577   
 578    }
 579   
 580  27978 return answer;
 581   
 582    }
 583   
 584  0 public List elements(String name, Namespace namespace) {
 585   
 586  0 return elements(getDocumentFactory().createQName(name, namespace));
 587   
 588    }
 589   
 590  128 public Iterator elementIterator() {
 591   
 592  128 List list = elements();
 593   
 594  128 return list.iterator();
 595   
 596    }
 597   
 598  382 public Iterator elementIterator(String name) {
 599   
 600  382 List list = elements(name);
 601   
 602  382 return list.iterator();
 603   
 604    }
 605   
 606  27940 public Iterator elementIterator(QName qName) {
 607   
 608  27940 List list = elements(qName);
 609   
 610  27940 return list.iterator();
 611   
 612    }
 613   
 614  0 public Iterator elementIterator(String name, Namespace namespace) {
 615   
 616  0 return elementIterator(getDocumentFactory().createQName(name, namespace));
 617   
 618    }
 619   
 620    // Attribute methods
 621   
 622    //-------------------------------------------------------------------------
 623   
 624  0 public List attributes() {
 625   
 626  0 return new ContentListFacade(this, attributeList());
 627   
 628    }
 629   
 630  0 public Iterator attributeIterator() {
 631   
 632  0 return attributeList().iterator();
 633   
 634    }
 635   
 636  0 public Attribute attribute(int index) {
 637   
 638  0 return (Attribute) attributeList().get(index);
 639   
 640    }
 641   
 642  2 public int attributeCount() {
 643   
 644  2 return attributeList().size();
 645   
 646    }
 647   
 648  0 public Attribute attribute(String name) {
 649   
 650  0 List list = attributeList();
 651   
 652  0 int size = list.size();
 653   
 654  0 for (int i = 0; i < size; i++) {
 655   
 656  0 Attribute attribute = (Attribute) list.get(i);
 657   
 658  0 if (name.equals(attribute.getName())) {
 659   
 660  0 return attribute;
 661   
 662    }
 663   
 664    }
 665   
 666  0 return null;
 667   
 668    }
 669   
 670  0 public Attribute attribute(QName qName) {
 671   
 672  0 List list = attributeList();
 673   
 674  0 int size = list.size();
 675   
 676  0 for (int i = 0; i < size; i++) {
 677   
 678  0 Attribute attribute = (Attribute) list.get(i);
 679   
 680  0 if (qName.equals(attribute.getQName())) {
 681   
 682  0 return attribute;
 683   
 684    }
 685   
 686    }
 687   
 688  0 return null;
 689   
 690    }
 691   
 692  0 public Attribute attribute(String name, Namespace namespace) {
 693   
 694  0 return attribute(getDocumentFactory().createQName(name, namespace));
 695   
 696    }
 697   
 698    /** This method provides a more optimal way of setting all the attributes
 699    * on an Element particularly for use in {@link org.dom4j.io.SAXReader}.
 700    */
 701   
 702  168738 public void setAttributes(
 703    Attributes attributes,
 704    NamespaceStack namespaceStack,
 705    boolean noNamespaceAttributes) {
 706   
 707    // now lets add all attribute values
 708   
 709  168738 int size = attributes.getLength();
 710   
 711  168738 if (size > 0) {
 712   
 713  13712 DocumentFactory factory = getDocumentFactory();
 714   
 715  13712 if (size == 1) {
 716   
 717    // allow lazy construction of the List of Attributes
 718   
 719  10720 String attributeQualifiedName = attributes.getQName(0);
 720   
 721  10720 if (noNamespaceAttributes || !attributeQualifiedName.startsWith("xmlns")) {
 722   
 723  10704 String attributeURI = attributes.getURI(0);
 724   
 725  10704 String attributeLocalName = attributes.getLocalName(0);
 726   
 727  10704 String attributeValue = attributes.getValue(0);
 728   
 729  10704 QName attributeQName =
 730    namespaceStack.getAttributeQName(
 731    attributeURI,
 732    attributeLocalName,
 733    attributeQualifiedName);
 734   
 735  10704 add(factory.createAttribute(this, attributeQName, attributeValue));
 736   
 737    }
 738   
 739    }
 740   
 741    else {
 742   
 743  2992 List list = attributeList(size);
 744   
 745  2992 list.clear();
 746   
 747  2992 for (int i = 0; i < size; i++) {
 748   
 749    // optimised to avoid the call to attribute(QName) to
 750   
 751    // lookup an attribute for a given QName
 752   
 753  7828 String attributeQualifiedName = attributes.getQName(i);
 754   
 755  7828 if (noNamespaceAttributes || !attributeQualifiedName.startsWith("xmlns")) {
 756   
 757  7818 String attributeURI = attributes.getURI(i);
 758   
 759  7818 String attributeLocalName = attributes.getLocalName(i);
 760   
 761  7818 String attributeValue = attributes.getValue(i);
 762   
 763  7818 QName attributeQName =
 764    namespaceStack.getAttributeQName(
 765    attributeURI,
 766    attributeLocalName,
 767    attributeQualifiedName);
 768   
 769  7818 Attribute attribute =
 770    factory.createAttribute(this, attributeQName, attributeValue);
 771   
 772  7818 list.add(attribute);
 773   
 774  7818 childAdded(attribute);
 775   
 776    }
 777   
 778    }
 779   
 780    }
 781   
 782    }
 783   
 784    }
 785   
 786  3798 public String attributeValue(String name) {
 787   
 788  3798 Attribute attrib = attribute(name);
 789   
 790  3798 if (attrib == null) {
 791   
 792  978 return null;
 793   
 794    }
 795   
 796    else {
 797   
 798  2820 return attrib.getValue();
 799   
 800    }
 801   
 802    }
 803   
 804  8 public String attributeValue(QName qName) {
 805   
 806  8 Attribute attrib = attribute(qName);
 807   
 808  8 if (attrib == null) {
 809   
 810  4 return null;
 811   
 812    }
 813   
 814    else {
 815   
 816  4 return attrib.getValue();
 817   
 818    }
 819   
 820    }
 821   
 822  14 public String attributeValue(String name, String defaultValue) {
 823   
 824  14 String answer = attributeValue(name);
 825   
 826  14 return (answer != null) ? answer : defaultValue;
 827   
 828    }
 829   
 830  0 public String attributeValue(QName qName, String defaultValue) {
 831   
 832  0 String answer = attributeValue(qName);
 833   
 834  0 return (answer != null) ? answer : defaultValue;
 835   
 836    }
 837   
 838    /**
 839    * @deprecated As of version 0.5. Please use
 840    * {@link #addAttribute(String,String)} instead.
 841    * WILL BE REMOVED IN dom4j-1.6 !!
 842    **/
 843  0 public void setAttributeValue(String name, String value) {
 844   
 845  0 addAttribute(name, value);
 846   
 847    }
 848   
 849    /**
 850    * @deprecated As of version 0.5. Please use
 851    * {@link #addAttribute(String,String)} instead.
 852    * WILL BE REMOVED IN dom4j-1.6 !!
 853    **/
 854  0 public void setAttributeValue(QName qName, String value) {
 855   
 856  0 addAttribute(qName, value);
 857   
 858    }
 859   
 860  0 public void add(Attribute attribute) {
 861   
 862  0 if (attribute.getParent() != null) {
 863   
 864  0 String message =
 865    "The Attribute already has an existing parent \""
 866    + attribute.getParent().getQualifiedName()
 867    + "\"";
 868   
 869  0 throw new IllegalAddException(this, attribute, message);
 870   
 871    }
 872   
 873  0 if (attribute.getValue() == null) {
 874   
 875    // try remove a previous attribute with the same
 876   
 877    // name since adding an attribute with a null value
 878   
 879    // is equivalent to removing it.
 880   
 881  0 Attribute oldAttribute = attribute(attribute.getQName());
 882   
 883  0 if (oldAttribute != null) {
 884   
 885  0 remove(oldAttribute);
 886   
 887    }
 888   
 889    }
 890   
 891    else {
 892   
 893  0 attributeList().add(attribute);
 894   
 895  0 childAdded(attribute);
 896   
 897    }
 898   
 899    }
 900   
 901  0 public boolean remove(Attribute attribute) {
 902   
 903  0 List list = attributeList();
 904   
 905  0 boolean answer = list.remove(attribute);
 906   
 907  0 if (answer) {
 908   
 909  0 childRemoved(attribute);
 910   
 911    }
 912   
 913    else {
 914   
 915    // we may have a copy of the attribute
 916   
 917  0 Attribute copy = attribute(attribute.getQName());
 918   
 919  0 if (copy != null) {
 920   
 921  0 list.remove(copy);
 922   
 923  0 answer = true;
 924   
 925    }
 926   
 927    }
 928   
 929  0 return answer;
 930   
 931    }
 932   
 933    // Processing instruction API
 934   
 935    //-------------------------------------------------------------------------
 936   
 937  0 public List processingInstructions() {
 938   
 939  0 List list = contentList();
 940   
 941  0 BackedList answer = createResultList();
 942   
 943  0 int size = list.size();
 944   
 945  0 for (int i = 0; i < size; i++) {
 946   
 947  0 Object object = list.get(i);
 948   
 949  0 if (object instanceof ProcessingInstruction) {
 950   
 951  0 answer.addLocal(object);
 952   
 953    }
 954   
 955    }
 956   
 957  0 return answer;
 958   
 959    }
 960   
 961  0 public List processingInstructions(String target) {
 962   
 963  0 List list = contentList();
 964   
 965  0 BackedList answer = createResultList();
 966   
 967  0 int size = list.size();
 968   
 969  0 for (int i = 0; i < size; i++) {
 970   
 971  0 Object object = list.get(i);
 972   
 973  0 if (object instanceof ProcessingInstruction) {
 974   
 975  0 ProcessingInstruction pi = (ProcessingInstruction) object;
 976   
 977  0 if (target.equals(pi.getName())) {
 978   
 979  0 answer.addLocal(pi);
 980   
 981    }
 982   
 983    }
 984   
 985    }
 986   
 987  0 return answer;
 988   
 989    }
 990   
 991  0 public ProcessingInstruction processingInstruction(String target) {
 992   
 993  0 List list = contentList();
 994   
 995  0 int size = list.size();
 996   
 997  0 for (int i = 0; i < size; i++) {
 998   
 999  0 Object object = list.get(i);
 1000   
 1001  0 if (object instanceof ProcessingInstruction) {
 1002   
 1003  0 ProcessingInstruction pi = (ProcessingInstruction) object;
 1004   
 1005  0 if (target.equals(pi.getName())) {
 1006   
 1007  0 return pi;
 1008   
 1009    }
 1010   
 1011    }
 1012   
 1013    }
 1014   
 1015  0 return null;
 1016   
 1017    }
 1018   
 1019  0 public boolean removeProcessingInstruction(String target) {
 1020   
 1021  0 List list = contentList();
 1022   
 1023  0 for (Iterator iter = list.iterator(); iter.hasNext();) {
 1024   
 1025  0 Object object = iter.next();
 1026   
 1027  0 if (object instanceof ProcessingInstruction) {
 1028   
 1029  0 ProcessingInstruction pi = (ProcessingInstruction) object;
 1030   
 1031  0 if (target.equals(pi.getName())) {
 1032   
 1033  0 iter.remove();
 1034   
 1035  0 return true;
 1036   
 1037    }
 1038   
 1039    }
 1040   
 1041    }
 1042   
 1043  0 return false;
 1044   
 1045    }
 1046   
 1047    // Content Model methods
 1048   
 1049    //-------------------------------------------------------------------------
 1050   
 1051  4 public Node getXPathResult(int index) {
 1052   
 1053  4 Node answer = node(index);
 1054   
 1055  4 if (answer != null && !answer.supportsParent()) {
 1056   
 1057  0 return answer.asXPathResult(this);
 1058   
 1059    }
 1060   
 1061  4 return answer;
 1062   
 1063    }
 1064   
 1065  1190 public Element addAttribute(String name, String value) {
 1066   
 1067    // adding a null value is equivalent to removing the attribute
 1068   
 1069  1190 Attribute attribute = attribute(name);
 1070   
 1071  1190 if (value != null) {
 1072   
 1073  1184 if (attribute == null) {
 1074   
 1075  1182 add(getDocumentFactory().createAttribute(this, name, value));
 1076   
 1077    }
 1078   
 1079  2 else if (attribute.isReadOnly()) {
 1080   
 1081  0 remove(attribute);
 1082   
 1083  0 add(getDocumentFactory().createAttribute(this, name, value));
 1084   
 1085    }
 1086   
 1087    else {
 1088   
 1089  2 attribute.setValue(value);
 1090   
 1091    }
 1092   
 1093    }
 1094   
 1095  6 else if (attribute != null) {
 1096   
 1097  4 remove(attribute);
 1098   
 1099    }
 1100   
 1101  1190 return this;
 1102   
 1103    }
 1104   
 1105  5690 public Element addAttribute(QName qName, String value) {
 1106   
 1107    // adding a null value is equivalent to removing the attribute
 1108   
 1109  5690 Attribute attribute = attribute(qName);
 1110   
 1111  5690 if (value != null) {
 1112   
 1113  5686 if (attribute == null) {
 1114   
 1115  5686 add(getDocumentFactory().createAttribute(this, qName, value));
 1116   
 1117    }
 1118   
 1119  0 else if (attribute.isReadOnly()) {
 1120   
 1121  0 remove(attribute);
 1122   
 1123  0 add(getDocumentFactory().createAttribute(this, qName, value));
 1124   
 1125    }
 1126   
 1127    else {
 1128   
 1129  0 attribute.setValue(value);
 1130   
 1131    }
 1132   
 1133    }
 1134   
 1135  4 else if (attribute != null) {
 1136   
 1137  2 remove(attribute);
 1138   
 1139    }
 1140   
 1141  5690 return this;
 1142   
 1143    }
 1144   
 1145  168 public Element addCDATA(String cdata) {
 1146   
 1147  168 CDATA node = getDocumentFactory().createCDATA(cdata);
 1148   
 1149  168 addNewNode(node);
 1150   
 1151  168 return this;
 1152   
 1153    }
 1154   
 1155  918 public Element addComment(String comment) {
 1156   
 1157  918 Comment node = getDocumentFactory().createComment(comment);
 1158   
 1159  918 addNewNode(node);
 1160   
 1161  918 return this;
 1162   
 1163    }
 1164   
 1165  1220 public Element addElement(String name) {
 1166   
 1167  1220 DocumentFactory factory = getDocumentFactory();
 1168   
 1169  1220 int index = name.indexOf(":");
 1170   
 1171  1220 String prefix = "";
 1172   
 1173  1220 String localName = name;
 1174   
 1175  1220 Namespace namespace = null;
 1176   
 1177  1220 if (index > 0) {
 1178   
 1179  4 prefix = name.substring(0, index);
 1180   
 1181  4 localName = name.substring(index + 1);
 1182   
 1183  4 namespace = getNamespaceForPrefix(prefix);
 1184   
 1185  4 if (namespace == null) {
 1186   
 1187  0 throw new IllegalAddException(
 1188    "No such namespace prefix: "
 1189    + prefix
 1190    + " is in scope on: "
 1191    + this
 1192    + " so cannot add element: "
 1193    + name);
 1194   
 1195    }
 1196   
 1197    }
 1198   
 1199    else {
 1200   
 1201  1216 namespace = getNamespaceForPrefix("");
 1202   
 1203    }
 1204   
 1205  1220 Element node;
 1206   
 1207  1220 if (namespace != null) {
 1208   
 1209  1220 QName qname = factory.createQName(localName, namespace);
 1210   
 1211  1220 node = factory.createElement(qname);
 1212   
 1213    }
 1214   
 1215    else {
 1216   
 1217  0 node = factory.createElement(name);
 1218   
 1219    }
 1220   
 1221  1220 addNewNode(node);
 1222   
 1223  1220 return node;
 1224   
 1225    }
 1226   
 1227  8 public Element addEntity(String name, String text) {
 1228   
 1229  8 Entity node = getDocumentFactory().createEntity(name, text);
 1230   
 1231  8 addNewNode(node);
 1232   
 1233  8 return this;
 1234   
 1235    }
 1236   
 1237  18 public Element addNamespace(String prefix, String uri) {
 1238   
 1239  18 Namespace node = getDocumentFactory().createNamespace(prefix, uri);
 1240   
 1241  18 addNewNode(node);
 1242   
 1243  18 return this;
 1244   
 1245    }
 1246   
 1247  2 public Element addProcessingInstruction(String target, String data) {
 1248   
 1249  2 ProcessingInstruction node =
 1250    getDocumentFactory().createProcessingInstruction(target, data);
 1251   
 1252  2 addNewNode(node);
 1253   
 1254  2 return this;
 1255   
 1256    }
 1257   
 1258  0 public Element addProcessingInstruction(String target, Map data) {
 1259   
 1260  0 ProcessingInstruction node =
 1261    getDocumentFactory().createProcessingInstruction(target, data);
 1262   
 1263  0 addNewNode(node);
 1264   
 1265  0 return this;
 1266   
 1267    }
 1268   
 1269  212902 public Element addText(String text) {
 1270   
 1271  212902 Text node = getDocumentFactory().createText(text);
 1272   
 1273  212902 addNewNode(node);
 1274   
 1275  212902 return this;
 1276   
 1277    }
 1278   
 1279    // polymorphic node methods
 1280   
 1281  714 public void add(Node node) {
 1282   
 1283  714 switch (node.getNodeType()) {
 1284   
 1285  254 case ELEMENT_NODE :
 1286   
 1287  254 add((Element) node);
 1288   
 1289  254 break;
 1290   
 1291  0 case ATTRIBUTE_NODE :
 1292   
 1293  0 add((Attribute) node);
 1294   
 1295  0 break;
 1296   
 1297  442 case TEXT_NODE :
 1298   
 1299  442 add((Text) node);
 1300   
 1301  442 break;
 1302   
 1303  0 case CDATA_SECTION_NODE :
 1304   
 1305  0 add((CDATA) node);
 1306   
 1307  0 break;
 1308   
 1309  0 case ENTITY_REFERENCE_NODE :
 1310   
 1311  0 add((Entity) node);
 1312   
 1313  0 break;
 1314   
 1315  0 case PROCESSING_INSTRUCTION_NODE :
 1316   
 1317  0 add((ProcessingInstruction) node);
 1318   
 1319  0 break;
 1320   
 1321  6 case COMMENT_NODE :
 1322   
 1323  6 add((Comment) node);
 1324   
 1325  6 break;
 1326   
 1327    /* XXXX: to do!
 1328    case DOCUMENT_TYPE_NODE:
 1329    add((DocumentType) node);
 1330    break;
 1331    */
 1332   
 1333  12 case NAMESPACE_NODE :
 1334   
 1335  12 add((Namespace) node);
 1336   
 1337  12 break;
 1338   
 1339  0 default :
 1340   
 1341  0 invalidNodeTypeAddException(node);
 1342   
 1343    }
 1344   
 1345    }
 1346   
 1347  3030 public boolean remove(Node node) {
 1348   
 1349  3030 switch (node.getNodeType()) {
 1350   
 1351  3026 case ELEMENT_NODE :
 1352   
 1353  3026 return remove((Element) node);
 1354   
 1355  4 case ATTRIBUTE_NODE :
 1356   
 1357  4 return remove((Attribute) node);
 1358   
 1359  0 case TEXT_NODE :
 1360   
 1361  0 return remove((Text) node);
 1362   
 1363  0 case CDATA_SECTION_NODE :
 1364   
 1365  0 return remove((CDATA) node);
 1366   
 1367  0 case ENTITY_REFERENCE_NODE :
 1368   
 1369  0 return remove((Entity) node);
 1370   
 1371  0 case PROCESSING_INSTRUCTION_NODE :
 1372   
 1373  0 return remove((ProcessingInstruction) node);
 1374   
 1375  0 case COMMENT_NODE :
 1376   
 1377  0 return remove((Comment) node);
 1378   
 1379    /*
 1380    case DOCUMENT_TYPE_NODE:
 1381    return remove((DocumentType) node);
 1382    */
 1383   
 1384  0 case NAMESPACE_NODE :
 1385   
 1386  0 return remove((Namespace) node);
 1387   
 1388  0 default :
 1389   
 1390  0 return false;
 1391   
 1392    }
 1393   
 1394    }
 1395   
 1396    // typesafe versions using node classes
 1397   
 1398  0 public void add(CDATA cdata) {
 1399   
 1400  0 addNode(cdata);
 1401   
 1402    }
 1403   
 1404  6 public void add(Comment comment) {
 1405   
 1406  6 addNode(comment);
 1407   
 1408    }
 1409   
 1410  174630 public void add(Element element) {
 1411   
 1412  174630 addNode(element);
 1413   
 1414    }
 1415   
 1416  0 public void add(Entity entity) {
 1417   
 1418  0 addNode(entity);
 1419   
 1420    }
 1421   
 1422  11854 public void add(Namespace namespace) {
 1423   
 1424  11854 addNode(namespace);
 1425   
 1426    }
 1427   
 1428  0 public void add(ProcessingInstruction pi) {
 1429   
 1430  0 addNode(pi);
 1431   
 1432    }
 1433   
 1434  442 public void add(Text text) {
 1435   
 1436  442 addNode(text);
 1437   
 1438    }
 1439   
 1440  0 public boolean remove(CDATA cdata) {
 1441   
 1442  0 return removeNode(cdata);
 1443   
 1444    }
 1445   
 1446  0 public boolean remove(Comment comment) {
 1447   
 1448  0 return removeNode(comment);
 1449   
 1450    }
 1451   
 1452  3026 public boolean remove(Element element) {
 1453   
 1454  3026 return removeNode(element);
 1455   
 1456    }
 1457   
 1458  0 public boolean remove(Entity entity) {
 1459   
 1460  0 return removeNode(entity);
 1461   
 1462    }
 1463   
 1464  6 public boolean remove(Namespace namespace) {
 1465   
 1466  6 return removeNode(namespace);
 1467   
 1468    }
 1469   
 1470  0 public boolean remove(ProcessingInstruction pi) {
 1471   
 1472  0 return removeNode(pi);
 1473   
 1474    }
 1475   
 1476  3696 public boolean remove(Text text) {
 1477   
 1478  3696 return removeNode(text);
 1479   
 1480    }
 1481   
 1482    // Helper methods
 1483   
 1484    //-------------------------------------------------------------------------
 1485   
 1486  0 public boolean hasMixedContent() {
 1487   
 1488  0 List content = contentList();
 1489   
 1490  0 if (content == null || content.isEmpty() || content.size() < 2) {
 1491   
 1492  0 return false;
 1493   
 1494    }
 1495   
 1496  0 Class prevClass = null;
 1497   
 1498  0 for (Iterator iter = content.iterator(); iter.hasNext();) {
 1499   
 1500  0 Object object = iter.next();
 1501   
 1502  0 Class newClass = object.getClass();
 1503   
 1504  0 if (newClass != prevClass) {
 1505   
 1506  0 if (prevClass != null) {
 1507   
 1508  0 return true;
 1509   
 1510    }
 1511   
 1512  0 prevClass = newClass;
 1513   
 1514    }
 1515   
 1516    }
 1517   
 1518  0 return false;
 1519   
 1520    }
 1521   
 1522  4 public boolean isTextOnly() {
 1523   
 1524  4 List content = contentList();
 1525   
 1526  4 if (content == null || content.isEmpty()) {
 1527   
 1528  0 return true;
 1529   
 1530    }
 1531   
 1532  4 for (Iterator iter = content.iterator(); iter.hasNext();) {
 1533   
 1534  4 Object object = iter.next();
 1535   
 1536  4 if (!(object instanceof CharacterData) && !(object instanceof String)) {
 1537   
 1538  2 return false;
 1539   
 1540    }
 1541   
 1542    }
 1543   
 1544  2 return true;
 1545   
 1546    }
 1547   
 1548  4026 public void setText(String text) {
 1549   
 1550    /* remove all text nodes */
 1551  4026 List allContent = contentList();
 1552  4026 if (allContent != null) {
 1553  4026 Iterator it = allContent.iterator();
 1554  4026 while (it.hasNext()) {
 1555  18 Node node = (Node) it.next();
 1556  18 switch (node.getNodeType()) {
 1557  0 case CDATA_SECTION_NODE:
 1558    //case ENTITY_NODE:
 1559  0 case ENTITY_REFERENCE_NODE:
 1560  16 case TEXT_NODE:
 1561  16 it.remove();
 1562    }
 1563    }
 1564    }
 1565   
 1566  4026 addText(text);
 1567   
 1568    }
 1569   
 1570  0 public String getStringValue() {
 1571   
 1572  0 List list = contentList();
 1573   
 1574  0 int size = list.size();
 1575   
 1576  0 if (size > 0) {
 1577   
 1578  0 if (size == 1) {
 1579   
 1580    // optimised to avoid StringBuffer creation
 1581   
 1582  0 return getContentAsStringValue(list.get(0));
 1583   
 1584    }
 1585   
 1586    else {
 1587   
 1588  0 StringBuffer buffer = new StringBuffer();
 1589   
 1590  0 for (int i = 0; i < size; i++) {
 1591   
 1592  0 Object node = list.get(i);
 1593   
 1594  0 String string = getContentAsStringValue(node);
 1595   
 1596  0 if (string.length() > 0) {
 1597   
 1598  0 if (USE_STRINGVALUE_SEPARATOR) {
 1599   
 1600  0 if (buffer.length() > 0) {
 1601   
 1602  0 buffer.append(' ');
 1603   
 1604    }
 1605   
 1606    }
 1607   
 1608  0 buffer.append(string);
 1609   
 1610    }
 1611   
 1612    }
 1613   
 1614  0 return buffer.toString();
 1615   
 1616    }
 1617   
 1618    }
 1619   
 1620  0 return "";
 1621   
 1622    }
 1623   
 1624    /**
 1625    * Puts all <code>Text</code> nodes in the full depth of the sub-tree
 1626    * underneath this <code>Node</code>, including attribute nodes, into a
 1627    * "normal" form where only structure (e.g., elements, comments,
 1628    * processing instructions, CDATA sections, and entity references)
 1629    * separates <code>Text</code> nodes, i.e., there are neither adjacent
 1630    * <code>Text</code> nodes nor empty <code>Text</code> nodes. This can
 1631    * be used to ensure that the DOM view of a document is the same as if
 1632    * it were saved and re-loaded, and is useful when operations (such as
 1633    * XPointer lookups) that depend on a particular document tree
 1634    * structure are to be used.In cases where the document contains
 1635    * <code>CDATASections</code>, the normalize operation alone may not be
 1636    * sufficient, since XPointers do not differentiate between
 1637    * <code>Text</code> nodes and <code>CDATASection</code> nodes.
 1638    * @since DOM Level 2
 1639    */
 1640   
 1641  76216 public void normalize() {
 1642   
 1643  76216 List content = contentList();
 1644   
 1645  76216 Text previousText = null;
 1646   
 1647  76216 int i = 0;
 1648   
 1649  76216 while (i < content.size()) {
 1650   
 1651  220352 Node node = (Node) content.get(i);
 1652   
 1653  220352 if (node instanceof Text) {
 1654   
 1655  142156 Text text = (Text) node;
 1656   
 1657  142156 if (previousText != null) {
 1658   
 1659  3696 previousText.appendText(text.getText());
 1660   
 1661  3696 remove(text);
 1662   
 1663    }
 1664   
 1665    else {
 1666   
 1667  138460 String value = text.getText();
 1668   
 1669    // only remove empty Text nodes, not whitespace nodes
 1670   
 1671    //if ( value == null || value.trim().length() <= 0 ) {
 1672   
 1673  138460 if (value == null || value.length() <= 0) {
 1674   
 1675  0 remove(text);
 1676   
 1677    }
 1678   
 1679    else {
 1680   
 1681  138460 previousText = text;
 1682   
 1683  138460 i++;
 1684   
 1685    }
 1686   
 1687    }
 1688   
 1689    }
 1690   
 1691    else {
 1692   
 1693  78196 if (node instanceof Element) {
 1694   
 1695  76008 Element element = (Element) node;
 1696   
 1697  76008 element.normalize();
 1698   
 1699    }
 1700   
 1701  78196 previousText = null;
 1702   
 1703  78196 i++;
 1704   
 1705    }
 1706   
 1707    }
 1708   
 1709    }
 1710   
 1711  0 public String elementText(String name) {
 1712   
 1713  0 Element element = element(name);
 1714   
 1715  0 return (element != null) ? element.getText() : null;
 1716   
 1717    }
 1718   
 1719  0 public String elementText(QName qName) {
 1720   
 1721  0 Element element = element(qName);
 1722   
 1723  0 return (element != null) ? element.getText() : null;
 1724   
 1725    }
 1726   
 1727  0 public String elementTextTrim(String name) {
 1728   
 1729  0 Element element = element(name);
 1730   
 1731  0 return (element != null) ? element.getTextTrim() : null;
 1732   
 1733    }
 1734   
 1735  0 public String elementTextTrim(QName qName) {
 1736   
 1737  0 Element element = element(qName);
 1738   
 1739  0 return (element != null) ? element.getTextTrim() : null;
 1740   
 1741    }
 1742   
 1743    // add to me content from another element
 1744   
 1745    // analagous to the addAll(collection) methods in Java 2 collections
 1746   
 1747  260 public void appendAttributes(Element element) {
 1748   
 1749  260 for (int i = 0, size = element.attributeCount(); i < size; i++) {
 1750   
 1751  116 Attribute attribute = element.attribute(i);
 1752   
 1753  116 if (attribute.supportsParent()) {
 1754   
 1755  116 addAttribute(attribute.getQName(), attribute.getValue());
 1756   
 1757    }
 1758   
 1759    else {
 1760   
 1761  0 add(attribute);
 1762   
 1763    }
 1764   
 1765    }
 1766   
 1767    }
 1768   
 1769    /** <p>This returns a deep clone of this element.
 1770    * The new element is detached from its parent, and getParent() on the
 1771    * clone will return null.</p>
 1772    *
 1773    * @return the clone of this element
 1774    */
 1775   
 1776    /*
 1777    public Object clone() {
 1778    Element clone = createElement(getQName());
 1779    clone.appendAttributes(this);
 1780    clone.appendContent(this);
 1781    return clone;
 1782    }
 1783    */
 1784   
 1785  10 public Element createCopy() {
 1786   
 1787  10 Element clone = createElement(getQName());
 1788   
 1789  10 clone.appendAttributes(this);
 1790   
 1791  10 clone.appendContent(this);
 1792   
 1793  10 return clone;
 1794   
 1795    }
 1796   
 1797  0 public Element createCopy(String name) {
 1798   
 1799  0 Element clone = createElement(name);
 1800   
 1801  0 clone.appendAttributes(this);
 1802   
 1803  0 clone.appendContent(this);
 1804   
 1805  0 return clone;
 1806   
 1807    }
 1808   
 1809  0 public Element createCopy(QName qName) {
 1810   
 1811  0 Element clone = createElement(qName);
 1812   
 1813  0 clone.appendAttributes(this);
 1814   
 1815  0 clone.appendContent(this);
 1816   
 1817  0 return clone;
 1818   
 1819    }
 1820   
 1821  14010 public QName getQName(String qualifiedName) {
 1822   
 1823  14010 String prefix = "";
 1824   
 1825  14010 String localName = qualifiedName;
 1826   
 1827  14004 int index = qualifiedName.indexOf(":");
 1828   
 1829  14010 if (index > 0) {
 1830   
 1831  10008 prefix = qualifiedName.substring(0, index);
 1832   
 1833  10008 localName = qualifiedName.substring(index + 1);
 1834   
 1835    }
 1836   
 1837  14010 Namespace namespace = getNamespaceForPrefix(prefix);
 1838   
 1839  14010 if (namespace != null) {
 1840   
 1841  14010 return getDocumentFactory().createQName(localName, namespace);
 1842   
 1843    }
 1844   
 1845    else {
 1846   
 1847  0 return getDocumentFactory().createQName(localName);
 1848   
 1849    }
 1850   
 1851    }
 1852   
 1853  0 public Namespace getNamespaceForPrefix(String prefix) {
 1854   
 1855  0 if (prefix == null) {
 1856   
 1857  0 prefix = "";
 1858   
 1859    }
 1860   
 1861  0 if (prefix.equals(getNamespacePrefix())) {
 1862   
 1863  0 return getNamespace();
 1864   
 1865    }
 1866   
 1867  0 else if (prefix.equals("xml")) {
 1868   
 1869  0 return Namespace.XML_NAMESPACE;
 1870   
 1871    }
 1872   
 1873    else {
 1874   
 1875  0 List list = contentList();
 1876   
 1877  0 int size = list.size();
 1878   
 1879  0 for (int i = 0; i < size; i++) {
 1880   
 1881  0 Object object = list.get(i);
 1882   
 1883  0 if (object instanceof Namespace) {
 1884   
 1885  0 Namespace namespace = (Namespace) object;
 1886   
 1887  0 if (prefix.equals(namespace.getPrefix())) {
 1888   
 1889  0 return namespace;
 1890   
 1891    }
 1892   
 1893    }
 1894   
 1895    }
 1896   
 1897    }
 1898   
 1899  0 Element parent = getParent();
 1900   
 1901  0 if (parent != null) {
 1902   
 1903  0 Namespace answer = parent.getNamespaceForPrefix(prefix);
 1904   
 1905  0 if (answer != null) {
 1906   
 1907  0 return answer;
 1908   
 1909    }
 1910   
 1911    }
 1912   
 1913  0 if (prefix == null || prefix.length() <= 0) {
 1914   
 1915  0 return Namespace.NO_NAMESPACE;
 1916   
 1917    }
 1918   
 1919  0 return null;
 1920   
 1921    }
 1922   
 1923  0 public Namespace getNamespaceForURI(String uri) {
 1924   
 1925  0 if (uri == null || uri.length() <= 0) {
 1926   
 1927  0 return Namespace.NO_NAMESPACE;
 1928   
 1929    }
 1930   
 1931  0 else if (uri.equals(getNamespaceURI())) {
 1932   
 1933  0 return getNamespace();
 1934   
 1935    }
 1936   
 1937    else {
 1938   
 1939  0 List list = contentList();
 1940   
 1941  0 int size = list.size();
 1942   
 1943  0 for (int i = 0; i < size; i++) {
 1944   
 1945  0 Object object = list.get(i);
 1946   
 1947  0 if (object instanceof Namespace) {
 1948   
 1949  0 Namespace namespace = (Namespace) object;
 1950   
 1951  0 if (uri.equals(namespace.getURI())) {
 1952   
 1953  0 return namespace;
 1954   
 1955    }
 1956   
 1957    }
 1958   
 1959    }
 1960   
 1961  0 return null;
 1962   
 1963    }
 1964   
 1965    }
 1966   
 1967  2 public List getNamespacesForURI(String uri) {
 1968   
 1969  2 BackedList answer = createResultList();
 1970   
 1971    // if (getNamespaceURI().equals(uri)) {
 1972    //
 1973    // answer.addLocal(getNamespace());
 1974    //
 1975    // }
 1976   
 1977  2 List list = contentList();
 1978   
 1979  2 int size = list.size();
 1980   
 1981  2 for (int i = 0; i < size; i++) {
 1982   
 1983  8 Object object = list.get(i);
 1984   
 1985  8 if ((object instanceof Namespace)
 1986   
 1987    && ((Namespace) object).getURI().equals(uri)) {
 1988   
 1989  4 answer.addLocal(object);
 1990   
 1991    }
 1992   
 1993    }
 1994   
 1995  2 return answer;
 1996   
 1997    }
 1998   
 1999  0 public List declaredNamespaces() {
 2000   
 2001  0 BackedList answer = createResultList();
 2002   
 2003    // if (getNamespaceURI().length() > 0) {
 2004    //
 2005    // answer.addLocal(getNamespace());
 2006    //
 2007    // }
 2008    //
 2009  0 List list = contentList();
 2010   
 2011  0 int size = list.size();
 2012   
 2013  0 for (int i = 0; i < size; i++) {
 2014   
 2015  0 Object object = list.get(i);
 2016   
 2017  0 if (object instanceof Namespace) {
 2018   
 2019  0 answer.addLocal(object);
 2020   
 2021    }
 2022   
 2023    }
 2024   
 2025  0 return answer;
 2026   
 2027    }
 2028   
 2029  0 public List additionalNamespaces() {
 2030   
 2031  0 List list = contentList();
 2032   
 2033  0 int size = list.size();
 2034   
 2035  0 BackedList answer = createResultList();
 2036   
 2037  0 for (int i = 0; i < size; i++) {
 2038   
 2039  0 Object object = list.get(i);
 2040   
 2041  0 if (object instanceof Namespace) {
 2042   
 2043  0 Namespace namespace = (Namespace) object;
 2044   
 2045  0 if (! namespace.equals(getNamespace())) {
 2046   
 2047  0 answer.addLocal(namespace);
 2048    }
 2049   
 2050    }
 2051   
 2052    }
 2053   
 2054  0 return answer;
 2055   
 2056    }
 2057   
 2058  0 public List additionalNamespaces(String defaultNamespaceURI) {
 2059   
 2060  0 List list = contentList();
 2061   
 2062  0 BackedList answer = createResultList();
 2063   
 2064  0 int size = list.size();
 2065   
 2066  0 for (int i = 0; i < size; i++) {
 2067   
 2068  0 Object object = list.get(i);
 2069   
 2070  0 if (object instanceof Namespace) {
 2071   
 2072  0 Namespace namespace = (Namespace) object;
 2073   
 2074  0 if (!defaultNamespaceURI.equals(namespace.getURI())) {
 2075   
 2076  0 answer.addLocal(namespace);
 2077   
 2078    }
 2079   
 2080    }
 2081   
 2082    }
 2083   
 2084  0 return answer;
 2085   
 2086    }
 2087   
 2088    // Implementation helper methods
 2089   
 2090    //-------------------------------------------------------------------------
 2091   
 2092    /** Ensures that the list of attributes has the given size */
 2093   
 2094  0 public void ensureAttributesCapacity(int minCapacity) {
 2095   
 2096  0 if (minCapacity > 1) {
 2097   
 2098  0 List list = attributeList();
 2099   
 2100  0 if (list instanceof ArrayList) {
 2101   
 2102  0 ArrayList arrayList = (ArrayList) list;
 2103   
 2104  0 arrayList.ensureCapacity(minCapacity);
 2105   
 2106    }
 2107   
 2108    }
 2109   
 2110    }
 2111   
 2112    // Implementation methods
 2113   
 2114    //-------------------------------------------------------------------------
 2115   
 2116  0 protected Element createElement(String name) {
 2117   
 2118  0 return getDocumentFactory().createElement(name);
 2119   
 2120    }
 2121   
 2122  8 protected Element createElement(QName qName) {
 2123   
 2124  8 return getDocumentFactory().createElement(qName);
 2125   
 2126    }
 2127   
 2128  186942 protected void addNode(Node node) {
 2129   
 2130  186942 if (node.getParent() != null) {
 2131   
 2132    // XXX: could clone here
 2133   
 2134  2 String message =
 2135    "The Node already has an existing parent of \""
 2136    + node.getParent().getQualifiedName()
 2137    + "\"";
 2138   
 2139  2 throw new IllegalAddException(this, node, message);
 2140   
 2141    }
 2142   
 2143  186940 addNewNode(node);
 2144   
 2145    }
 2146   
 2147  16 protected void addNode(int index, Node node) {
 2148   
 2149  16 if (node.getParent() != null) {
 2150   
 2151    // XXX: could clone here
 2152   
 2153  2 String message =
 2154    "The Node already has an existing parent of \""
 2155    + node.getParent().getQualifiedName()
 2156    + "\"";
 2157   
 2158  2 throw new IllegalAddException(this, node, message);
 2159   
 2160    }
 2161   
 2162  14 addNewNode(index, node);
 2163   
 2164    }
 2165   
 2166    /** Like addNode() but does not require a parent check */
 2167   
 2168  0 protected void addNewNode(Node node) {
 2169   
 2170  0 contentList().add(node);
 2171   
 2172  0 childAdded(node);
 2173   
 2174    }
 2175   
 2176  14 protected void addNewNode(int index, Node node) {
 2177   
 2178  14 contentList().add(index, node);
 2179   
 2180  14 childAdded(node);
 2181   
 2182    }
 2183   
 2184  0 protected boolean removeNode(Node node) {
 2185   
 2186  0 boolean answer = contentList().remove(node);
 2187   
 2188  0 if (answer) {
 2189   
 2190  0 childRemoved(node);
 2191   
 2192    }
 2193   
 2194  0 return answer;
 2195   
 2196    }
 2197   
 2198    /** Called when a new child node is added to
 2199    * create any parent relationships
 2200    */
 2201   
 2202  427598 protected void childAdded(Node node) {
 2203   
 2204  427598 if (node != null) {
 2205   
 2206  427598 node.setParent(this);
 2207   
 2208    }
 2209   
 2210    }
 2211   
 2212  6754 protected void childRemoved(Node node) {
 2213   
 2214  6754 if (node != null) {
 2215   
 2216  6754 node.setParent(null);
 2217   
 2218  6754 node.setDocument(null);
 2219   
 2220    }
 2221   
 2222    }
 2223   
 2224    /** @return the internal List used to store attributes or
 2225    * creates one if one is not available
 2226    */
 2227   
 2228    protected abstract List attributeList();
 2229   
 2230    /** @return the internal List used to store attributes or
 2231    * creates one with the specified size if one is not available
 2232    */
 2233   
 2234    protected abstract List attributeList(int attributeCount);
 2235   
 2236  2 protected DocumentFactory getDocumentFactory() {
 2237   
 2238  2 QName qName = getQName();
 2239   
 2240    // QName might be null as we might not have been constructed yet
 2241   
 2242  2 if (qName != null) {
 2243   
 2244  0 DocumentFactory factory = qName.getDocumentFactory();
 2245   
 2246  0 if (factory != null) {
 2247   
 2248  0 return factory;
 2249   
 2250    }
 2251   
 2252    }
 2253   
 2254  2 return DOCUMENT_FACTORY;
 2255   
 2256    }
 2257   
 2258    /** A Factory Method pattern which creates
 2259    * a List implementation used to store attributes
 2260    */
 2261   
 2262  52080 protected List createAttributeList() {
 2263   
 2264  52080 return createAttributeList(DEFAULT_CONTENT_LIST_SIZE);
 2265   
 2266    }
 2267   
 2268    /** A Factory Method pattern which creates
 2269    * a List implementation used to store attributes
 2270    */
 2271   
 2272  55072 protected List createAttributeList(int size) {
 2273   
 2274  55072 return new ArrayList(size);
 2275   
 2276    }
 2277   
 2278  125938 protected Iterator createSingleIterator(Object result) {
 2279   
 2280  125938 return new SingleIterator(result);
 2281   
 2282    }
 2283   
 2284    }
 2285   
 2286    /*
 2287    * Redistribution and use of this software and associated documentation
 2288    * ("Software"), with or without modification, are permitted provided
 2289    * that the following conditions are met:
 2290    *
 2291    * 1. Redistributions of source code must retain copyright
 2292    * statements and notices. Redistributions must also contain a
 2293    * copy of this document.
 2294    *
 2295    * 2. Redistributions in binary form must reproduce the
 2296    * above copyright notice, this list of conditions and the
 2297    * following disclaimer in the documentation and/or other
 2298    * materials provided with the distribution.
 2299    *
 2300    * 3. The name "DOM4J" must not be used to endorse or promote
 2301    * products derived from this Software without prior written
 2302    * permission of MetaStuff, Ltd. For written permission,
 2303    * please contact dom4j-info@metastuff.com.
 2304    *
 2305    * 4. Products derived from this Software may not be called "DOM4J"
 2306    * nor may "DOM4J" appear in their names without prior written
 2307    * permission of MetaStuff, Ltd. DOM4J is a registered
 2308    * trademark of MetaStuff, Ltd.
 2309    *
 2310    * 5. Due credit should be given to the DOM4J Project -
 2311    * http://www.dom4j.org
 2312    *
 2313    * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
 2314    * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 2315    * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 2316    * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 2317    * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 2318    * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 2319    * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 2320    * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 2321    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 2322    * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 2323    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 2324    * OF THE POSSIBILITY OF SUCH DAMAGE.
 2325    *
 2326    * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
 2327    *
 2328    * $Id: AbstractElement.java,v 1.77 2004/06/25 12:34:49 maartenc Exp $
 2329    */