View Javadoc

    1   /*
    2    * Copyright 2001-2005 (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
    8   package org.dom4j.tree;
    9
    10  import java.util.ArrayList;
    11  import java.util.Iterator;
    12  import java.util.List;
    13
    14  import org.dom4j.Attribute;
    15  import org.dom4j.Branch;
    16  import org.dom4j.Document;
    17  import org.dom4j.DocumentFactory;
    18  import org.dom4j.Element;
    19  import org.dom4j.IllegalAddException;
    20  import org.dom4j.Namespace;
    21  import org.dom4j.Node;
    22  import org.dom4j.ProcessingInstruction;
    23  import org.dom4j.QName;
    24
    25  /***
    26   * <p>
    27   * <code>DefaultElement</code> is the default DOM4J default implementation of
    28   * an XML element.
    29   * </p>
    30   *
    31   * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
    32   * @version $Revision: 1.59 $
    33   */
    34  public class DefaultElement extends AbstractElement {
    35      /*** The <code>DocumentFactory</code> instance used by default */
    36      private static final transient DocumentFactory DOCUMENT_FACTORY =
    37              DocumentFactory.getInstance();
    38
    39      /*** The <code>QName</code> for this element */
    40      private QName qname;
    41
    42      /***
    43       * Stores the parent branch of this node which is either a Document if this
    44       * element is the root element in a document, or another Element if it is a
    45       * child of the root document, or null if it has not been added to a
    46       * document yet.
    47       */
    48      private Branch parentBranch;
    49
    50      /***
    51       * Stores null for no content, a Node for a single content node or a List
    52       * for multiple content nodes. The List will be lazily constructed when
    53       * required.
    54       */
    55      private Object content;
    56
    57      /*** Lazily constructes list of attributes */
    58      private Object attributes;
    59
    60      public DefaultElement(String name) {
    61          this.qname = DOCUMENT_FACTORY.createQName(name);
    62      }
    63
    64      public DefaultElement(QName qname) {
    65          this.qname = qname;
    66      }
    67
    68      public DefaultElement(QName qname, int attributeCount) {
    69          this.qname = qname;
    70
    71          if (attributeCount > 1) {
    72              this.attributes = new ArrayList(attributeCount);
    73          }
    74      }
    75
    76      public DefaultElement(String name, Namespace namespace) {
    77          this.qname = DOCUMENT_FACTORY.createQName(name, namespace);
    78      }
    79
    80      public Element getParent() {
    81          Element result = null;
    82
    83          if (parentBranch instanceof Element) {
    84              result = (Element) parentBranch;
    85          }
    86
    87          return result;
    88      }
    89
    90      public void setParent(Element parent) {
    91          if (parentBranch instanceof Element || (parent != null)) {
    92              parentBranch = parent;
    93          }
    94      }
    95
    96      public Document getDocument() {
    97          if (parentBranch instanceof Document) {
    98              return (Document) parentBranch;
    99          } else if (parentBranch instanceof Element) {
    100             Element parent = (Element) parentBranch;
    101
    102             return parent.getDocument();
    103         }
    104
    105         return null;
    106     }
    107
    108     public void setDocument(Document document) {
    109         if (parentBranch instanceof Document || (document != null)) {
    110             parentBranch = document;
    111         }
    112     }
    113
    114     public boolean supportsParent() {
    115         return true;
    116     }
    117
    118     public QName getQName() {
    119         return qname;
    120     }
    121
    122     public void setQName(QName name) {
    123         this.qname = name;
    124     }
    125
    126     public String getText() {
    127         final Object contentShadow = content;
    128
    129         if (contentShadow instanceof List) {
    130             return super.getText();
    131         } else {
    132             if (contentShadow != null) {
    133                 return getContentAsText(contentShadow);
    134             } else {
    135                 return "";
    136             }
    137         }
    138     }
    139
    140     public String getStringValue() {
    141         final Object contentShadow = content;
    142
    143         if (contentShadow instanceof List) {
    144             List list = (List) contentShadow;
    145
    146             int size = list.size();
    147
    148             if (size > 0) {
    149                 if (size == 1) {
    150                     // optimised to avoid StringBuffer creation
    151                     return getContentAsStringValue(list.get(0));
    152                 } else {
    153                     StringBuffer buffer = new StringBuffer();
    154
    155                     for (int i = 0; i < size; i++) {
    156                         Object node = list.get(i);
    157
    158                         String string = getContentAsStringValue(node);
    159
    160                         if (string.length() > 0) {
    161                             if (USE_STRINGVALUE_SEPARATOR) {
    162                                 if (buffer.length() > 0) {
    163                                     buffer.append(' ');
    164                                 }
    165                             }
    166
    167                             buffer.append(string);
    168                         }
    169                     }
    170
    171                     return buffer.toString();
    172                 }
    173             }
    174         } else {
    175             if (contentShadow != null) {
    176                 return getContentAsStringValue(contentShadow);
    177             }
    178         }
    179
    180         return "";
    181     }
    182
    183     public Object clone() {
    184         DefaultElement answer = (DefaultElement) super.clone();
    185
    186         if (answer != this) {
    187             answer.content = null;
    188
    189             answer.attributes = null;
    190
    191             answer.appendAttributes(this);
    192
    193             answer.appendContent(this);
    194         }
    195
    196         return answer;
    197     }
    198
    199     public Namespace getNamespaceForPrefix(String prefix) {
    200         if (prefix == null) {
    201             prefix = "";
    202         }
    203
    204         if (prefix.equals(getNamespacePrefix())) {
    205             return getNamespace();
    206         } else if (prefix.equals("xml")) {
    207             return Namespace.XML_NAMESPACE;
    208         } else {
    209             final Object contentShadow = content;
    210
    211             if (contentShadow instanceof List) {
    212                 List list = (List) contentShadow;
    213
    214                 int size = list.size();
    215
    216                 for (int i = 0; i < size; i++) {
    217                     Object object = list.get(i);
    218
    219                     if (object instanceof Namespace) {
    220                         Namespace namespace = (Namespace) object;
    221
    222                         if (prefix.equals(namespace.getPrefix())) {
    223                             return namespace;
    224                         }
    225                     }
    226                 }
    227             } else if (contentShadow instanceof Namespace) {
    228                 Namespace namespace = (Namespace) contentShadow;
    229
    230                 if (prefix.equals(namespace.getPrefix())) {
    231                     return namespace;
    232                 }
    233             }
    234         }
    235
    236         Element parent = getParent();
    237
    238         if (parent != null) {
    239             Namespace answer = parent.getNamespaceForPrefix(prefix);
    240
    241             if (answer != null) {
    242                 return answer;
    243             }
    244         }
    245
    246         if ((prefix == null) || (prefix.length() <= 0)) {
    247             return Namespace.NO_NAMESPACE;
    248         }
    249
    250         return null;
    251     }
    252
    253     public Namespace getNamespaceForURI(String uri) {
    254         if ((uri == null) || (uri.length() <= 0)) {
    255             return Namespace.NO_NAMESPACE;
    256         } else if (uri.equals(getNamespaceURI())) {
    257             return getNamespace();
    258         } else {
    259             final Object contentShadow = content;
    260
    261             if (contentShadow instanceof List) {
    262                 List list = (List) contentShadow;
    263
    264                 int size = list.size();
    265
    266                 for (int i = 0; i < size; i++) {
    267                     Object object = list.get(i);
    268
    269                     if (object instanceof Namespace) {
    270                         Namespace namespace = (Namespace) object;
    271
    272                         if (uri.equals(namespace.getURI())) {
    273                             return namespace;
    274                         }
    275                     }
    276                 }
    277             } else if (contentShadow instanceof Namespace) {
    278                 Namespace namespace = (Namespace) contentShadow;
    279
    280                 if (uri.equals(namespace.getURI())) {
    281                     return namespace;
    282                 }
    283             }
    284
    285             Element parent = getParent();
    286
    287             if (parent != null) {
    288                 return parent.getNamespaceForURI(uri);
    289             }
    290
    291             return null;
    292         }
    293     }
    294
    295     public List declaredNamespaces() {
    296         BackedList answer = createResultList();
    297
    298         // if (getNamespaceURI().length() > 0) {
    299         //
    300         // answer.addLocal(getNamespace());
    301         //
    302         // }
    303         final Object contentShadow = content;
    304
    305         if (contentShadow instanceof List) {
    306             List list = (List) contentShadow;
    307
    308             int size = list.size();
    309
    310             for (int i = 0; i < size; i++) {
    311                 Object object = list.get(i);
    312
    313                 if (object instanceof Namespace) {
    314                     answer.addLocal(object);
    315                 }
    316             }
    317         } else {
    318             if (contentShadow instanceof Namespace) {
    319                 answer.addLocal(contentShadow);
    320             }
    321         }
    322
    323         return answer;
    324     }
    325
    326     public List additionalNamespaces() {
    327         final Object contentShadow = content;
    328
    329         if (contentShadow instanceof List) {
    330             List list = (List) contentShadow;
    331
    332             int size = list.size();
    333
    334             BackedList answer = createResultList();
    335
    336             for (int i = 0; i < size; i++) {
    337                 Object object = list.get(i);
    338
    339                 if (object instanceof Namespace) {
    340                     Namespace namespace = (Namespace) object;
    341
    342                     if (!namespace.equals(getNamespace())) {
    343                         answer.addLocal(namespace);
    344                     }
    345                 }
    346             }
    347
    348             return answer;
    349         } else {
    350             if (contentShadow instanceof Namespace) {
    351                 Namespace namespace = (Namespace) contentShadow;
    352
    353                 if (namespace.equals(getNamespace())) {
    354                     return createEmptyList();
    355                 }
    356
    357                 return createSingleResultList(namespace);
    358             } else {
    359                 return createEmptyList();
    360             }
    361         }
    362     }
    363
    364     public List additionalNamespaces(String defaultNamespaceURI) {
    365         final Object contentShadow = content;
    366
    367         if (contentShadow instanceof List) {
    368             List list = (List) contentShadow;
    369
    370             BackedList answer = createResultList();
    371
    372             int size = list.size();
    373
    374             for (int i = 0; i < size; i++) {
    375                 Object object = list.get(i);
    376
    377                 if (object instanceof Namespace) {
    378                     Namespace namespace = (Namespace) object;
    379
    380                     if (!defaultNamespaceURI.equals(namespace.getURI())) {
    381                         answer.addLocal(namespace);
    382                     }
    383                 }
    384             }
    385
    386             return answer;
    387         } else {
    388             if (contentShadow instanceof Namespace) {
    389                 Namespace namespace = (Namespace) contentShadow;
    390
    391                 if (!defaultNamespaceURI.equals(namespace.getURI())) {
    392                     return createSingleResultList(namespace);
    393                 }
    394             }
    395         }
    396
    397         return createEmptyList();
    398     }
    399
    400     // Processing instruction API
    401     public List processingInstructions() {
    402         final Object contentShadow = content;
    403
    404         if (contentShadow instanceof List) {
    405             List list = (List) contentShadow;
    406
    407             BackedList answer = createResultList();
    408
    409             int size = list.size();
    410
    411             for (int i = 0; i < size; i++) {
    412                 Object object = list.get(i);
    413
    414                 if (object instanceof ProcessingInstruction) {
    415                     answer.addLocal(object);
    416                 }
    417             }
    418
    419             return answer;
    420         } else {
    421             if (contentShadow instanceof ProcessingInstruction) {
    422                 return createSingleResultList(contentShadow);
    423             }
    424
    425             return createEmptyList();
    426         }
    427     }
    428
    429     public List processingInstructions(String target) {
    430         final Object shadow = content;
    431
    432         if (shadow instanceof List) {
    433             List list = (List) shadow;
    434
    435             BackedList answer = createResultList();
    436
    437             int size = list.size();
    438
    439             for (int i = 0; i < size; i++) {
    440                 Object object = list.get(i);
    441
    442                 if (object instanceof ProcessingInstruction) {
    443                     ProcessingInstruction pi = (ProcessingInstruction) object;
    444
    445                     if (target.equals(pi.getName())) {
    446                         answer.addLocal(pi);
    447                     }
    448                 }
    449             }
    450
    451             return answer;
    452         } else {
    453             if (shadow instanceof ProcessingInstruction) {
    454                 ProcessingInstruction pi = (ProcessingInstruction) shadow;
    455
    456                 if (target.equals(pi.getName())) {
    457                     return createSingleResultList(pi);
    458                 }
    459             }
    460
    461             return createEmptyList();
    462         }
    463     }
    464
    465     public ProcessingInstruction processingInstruction(String target) {
    466         final Object shadow = content;
    467
    468         if (shadow instanceof List) {
    469             List list = (List) shadow;
    470
    471             int size = list.size();
    472
    473             for (int i = 0; i < size; i++) {
    474                 Object object = list.get(i);
    475
    476                 if (object instanceof ProcessingInstruction) {
    477                     ProcessingInstruction pi = (ProcessingInstruction) object;
    478
    479                     if (target.equals(pi.getName())) {
    480                         return pi;
    481                     }
    482                 }
    483             }
    484         } else {
    485             if (shadow instanceof ProcessingInstruction) {
    486                 ProcessingInstruction pi = (ProcessingInstruction) shadow;
    487
    488                 if (target.equals(pi.getName())) {
    489                     return pi;
    490                 }
    491             }
    492         }
    493
    494         return null;
    495     }
    496
    497     public boolean removeProcessingInstruction(String target) {
    498         final Object shadow = content;
    499
    500         if (shadow instanceof List) {
    501             List list = (List) shadow;
    502
    503             for (Iterator iter = list.iterator(); iter.hasNext();) {
    504                 Object object = iter.next();
    505
    506                 if (object instanceof ProcessingInstruction) {
    507                     ProcessingInstruction pi = (ProcessingInstruction) object;
    508
    509                     if (target.equals(pi.getName())) {
    510                         iter.remove();
    511
    512                         return true;
    513                     }
    514                 }
    515             }
    516         } else {
    517             if (shadow instanceof ProcessingInstruction) {
    518                 ProcessingInstruction pi = (ProcessingInstruction) shadow;
    519
    520                 if (target.equals(pi.getName())) {
    521                     this.content = null;
    522
    523                     return true;
    524                 }
    525             }
    526         }
    527
    528         return false;
    529     }
    530
    531     public Element element(String name) {
    532         final Object contentShadow = content;
    533
    534         if (contentShadow instanceof List) {
    535             List list = (List) contentShadow;
    536
    537             int size = list.size();
    538
    539             for (int i = 0; i < size; i++) {
    540                 Object object = list.get(i);
    541
    542                 if (object instanceof Element) {
    543                     Element element = (Element) object;
    544
    545                     if (name.equals(element.getName())) {
    546                         return element;
    547                     }
    548                 }
    549             }
    550         } else {
    551             if (contentShadow instanceof Element) {
    552                 Element element = (Element) contentShadow;
    553
    554                 if (name.equals(element.getName())) {
    555                     return element;
    556                 }
    557             }
    558         }
    559
    560         return null;
    561     }
    562
    563     public Element element(QName qName) {
    564         final Object contentShadow = content;
    565
    566         if (contentShadow instanceof List) {
    567             List list = (List) contentShadow;
    568
    569             int size = list.size();
    570
    571             for (int i = 0; i < size; i++) {
    572                 Object object = list.get(i);
    573
    574                 if (object instanceof Element) {
    575                     Element element = (Element) object;
    576
    577                     if (qName.equals(element.getQName())) {
    578                         return element;
    579                     }
    580                 }
    581             }
    582         } else {
    583             if (contentShadow instanceof Element) {
    584                 Element element = (Element) contentShadow;
    585
    586                 if (qName.equals(element.getQName())) {
    587                     return element;
    588                 }
    589             }
    590         }
    591
    592         return null;
    593     }
    594
    595     public Element element(String name, Namespace namespace) {
    596         return element(getDocumentFactory().createQName(name, namespace));
    597     }
    598
    599     public void setContent(List content) {
    600         contentRemoved();
    601
    602         if (content instanceof ContentListFacade) {
    603             content = ((ContentListFacade) content).getBackingList();
    604         }
    605
    606         if (content == null) {
    607             this.content = null;
    608         } else {
    609             int size = content.size();
    610
    611             List newContent = createContentList(size);
    612
    613             for (int i = 0; i < size; i++) {
    614                 Object object = content.get(i);
    615
    616                 if (object instanceof Node) {
    617                     Node node = (Node) object;
    618                     Element parent = node.getParent();
    619
    620                     if ((parent != null) && (parent != this)) {
    621                         node = (Node) node.clone();
    622                     }
    623
    624                     newContent.add(node);
    625                     childAdded(node);
    626                 } else if (object != null) {
    627                     String text = object.toString();
    628                     Node node = getDocumentFactory().createText(text);
    629                     newContent.add(node);
    630                     childAdded(node);
    631                 }
    632             }
    633
    634             this.content = newContent;
    635         }
    636     }
    637
    638     public void clearContent() {
    639         if (content != null) {
    640             contentRemoved();
    641
    642             content = null;
    643         }
    644     }
    645
    646     public Node node(int index) {
    647         if (index >= 0) {
    648             final Object contentShadow = content;
    649             Object node;
    650
    651             if (contentShadow instanceof List) {
    652                 List list = (List) contentShadow;
    653
    654                 if (index >= list.size()) {
    655                     return null;
    656                 }
    657
    658                 node = list.get(index);
    659             } else {
    660                 node = (index == 0) ? contentShadow : null;
    661             }
    662
    663             if (node != null) {
    664                 if (node instanceof Node) {
    665                     return (Node) node;
    666                 } else {
    667                     return new DefaultText(node.toString());
    668                 }
    669             }
    670         }
    671
    672         return null;
    673     }
    674
    675     public int indexOf(Node node) {
    676         final Object contentShadow = content;
    677
    678         if (contentShadow instanceof List) {
    679             List list = (List) contentShadow;
    680
    681             return list.indexOf(node);
    682         } else {
    683             if ((contentShadow != null) && contentShadow.equals(node)) {
    684                 return 0;
    685             } else {
    686                 return -1;
    687             }
    688         }
    689     }
    690
    691     public int nodeCount() {
    692         final Object contentShadow = content;
    693
    694         if (contentShadow instanceof List) {
    695             List list = (List) contentShadow;
    696
    697             return list.size();
    698         } else {
    699             return (contentShadow != null) ? 1 : 0;
    700         }
    701     }
    702
    703     public Iterator nodeIterator() {
    704         final Object contentShadow = content;
    705
    706         if (contentShadow instanceof List) {
    707             List list = (List) contentShadow;
    708
    709             return list.iterator();
    710         } else {
    711             if (contentShadow != null) {
    712                 return createSingleIterator(contentShadow);
    713             } else {
    714                 return EMPTY_ITERATOR;
    715             }
    716         }
    717     }
    718
    719     public List attributes() {
    720         return new ContentListFacade(this, attributeList());
    721     }
    722
    723     public void setAttributes(List attributes) {
    724         if (attributes instanceof ContentListFacade) {
    725             attributes = ((ContentListFacade) attributes).getBackingList();
    726         }
    727
    728         this.attributes = attributes;
    729     }
    730
    731     public Iterator attributeIterator() {
    732         final Object attributesShadow = this.attributes;
    733
    734         if (attributesShadow instanceof List) {
    735             List list = (List) attributesShadow;
    736
    737             return list.iterator();
    738         } else if (attributesShadow != null) {
    739             return createSingleIterator(attributesShadow);
    740         } else {
    741             return EMPTY_ITERATOR;
    742         }
    743     }
    744
    745     public Attribute attribute(int index) {
    746         final Object attributesShadow = this.attributes;
    747
    748         if (attributesShadow instanceof List) {
    749             List list = (List) attributesShadow;
    750
    751             return (Attribute) list.get(index);
    752         } else if ((attributesShadow != null) && (index == 0)) {
    753             return (Attribute) attributesShadow;
    754         } else {
    755             return null;
    756         }
    757     }
    758
    759     public int attributeCount() {
    760         final Object attributesShadow = this.attributes;
    761
    762         if (attributesShadow instanceof List) {
    763             List list = (List) attributesShadow;
    764
    765             return list.size();
    766         } else {
    767             return (attributesShadow != null) ? 1 : 0;
    768         }
    769     }
    770
    771     public Attribute attribute(String name) {
    772         final Object attributesShadow = this.attributes;
    773
    774         if (attributesShadow instanceof List) {
    775             List list = (List) attributesShadow;
    776
    777             int size = list.size();
    778
    779             for (int i = 0; i < size; i++) {
    780                 Attribute attribute = (Attribute) list.get(i);
    781
    782                 if (name.equals(attribute.getName())) {
    783                     return attribute;
    784                 }
    785             }
    786         } else if (attributesShadow != null) {
    787             Attribute attribute = (Attribute) attributesShadow;
    788
    789             if (name.equals(attribute.getName())) {
    790                 return attribute;
    791             }
    792         }
    793
    794         return null;
    795     }
    796
    797     public Attribute attribute(QName qName) {
    798         final Object attributesShadow = this.attributes;
    799
    800         if (attributesShadow instanceof List) {
    801             List list = (List) attributesShadow;
    802
    803             int size = list.size();
    804
    805             for (int i = 0; i < size; i++) {
    806                 Attribute attribute = (Attribute) list.get(i);
    807
    808                 if (qName.equals(attribute.getQName())) {
    809                     return attribute;
    810                 }
    811             }
    812         } else if (attributesShadow != null) {
    813             Attribute attribute = (Attribute) attributesShadow;
    814
    815             if (qName.equals(attribute.getQName())) {
    816                 return attribute;
    817             }
    818         }
    819
    820         return null;
    821     }
    822
    823     public Attribute attribute(String name, Namespace namespace) {
    824         return attribute(getDocumentFactory().createQName(name, namespace));
    825     }
    826
    827     public void add(Attribute attribute) {
    828         if (attribute.getParent() != null) {
    829             String message = "The Attribute already has an existing parent \""
    830                     + attribute.getParent().getQualifiedName() + "\"";
    831
    832             throw new IllegalAddException(this, attribute, message);
    833         }
    834
    835         if (attribute.getValue() == null) {
    836             // try remove a previous attribute with the same
    837             // name since adding an attribute with a null value
    838             // is equivalent to removing it.
    839             Attribute oldAttribute = attribute(attribute.getQName());
    840
    841             if (oldAttribute != null) {
    842                 remove(oldAttribute);
    843             }
    844         } else {
    845             if (attributes == null) {
    846                 attributes = attribute;
    847             } else {
    848                 attributeList().add(attribute);
    849             }
    850
    851             childAdded(attribute);
    852         }
    853     }
    854
    855     public boolean remove(Attribute attribute) {
    856         boolean answer = false;
    857         final Object attributesShadow = this.attributes;
    858
    859         if (attributesShadow instanceof List) {
    860             List list = (List) attributesShadow;
    861
    862             answer = list.remove(attribute);
    863
    864             if (!answer) {
    865                 // we may have a copy of the attribute
    866                 Attribute copy = attribute(attribute.getQName());
    867
    868                 if (copy != null) {
    869                     list.remove(copy);
    870
    871                     answer = true;
    872                 }
    873             }
    874         } else if (attributesShadow != null) {
    875             if (attribute.equals(attributesShadow)) {
    876                 this.attributes = null;
    877
    878                 answer = true;
    879             } else {
    880                 // we may have a copy of the attribute
    881                 Attribute other = (Attribute) attributesShadow;
    882
    883                 if (attribute.getQName().equals(other.getQName())) {
    884                     attributes = null;
    885
    886                     answer = true;
    887                 }
    888             }
    889         }
    890
    891         if (answer) {
    892             childRemoved(attribute);
    893         }
    894
    895         return answer;
    896     }
    897
    898     // Implementation methods
    899     // -------------------------------------------------------------------------
    900     protected void addNewNode(Node node) {
    901         final Object contentShadow = content;
    902
    903         if (contentShadow == null) {
    904             this.content = node;
    905         } else {
    906             if (contentShadow instanceof List) {
    907                 List list = (List) contentShadow;
    908
    909                 list.add(node);
    910             } else {
    911                 List list = createContentList();
    912
    913                 list.add(contentShadow);
    914
    915                 list.add(node);
    916
    917                 this.content = list;
    918             }
    919         }
    920
    921         childAdded(node);
    922     }
    923
    924     protected boolean removeNode(Node node) {
    925         boolean answer = false;
    926         final Object contentShadow = content;
    927
    928         if (contentShadow != null) {
    929             if (contentShadow == node) {
    930                 this.content = null;
    931
    932                 answer = true;
    933             } else if (contentShadow instanceof List) {
    934                 List list = (List) contentShadow;
    935
    936                 answer = list.remove(node);
    937             }
    938         }
    939
    940         if (answer) {
    941             childRemoved(node);
    942         }
    943
    944         return answer;
    945     }
    946
    947     protected List contentList() {
    948         final Object contentShadow = content;
    949
    950         if (contentShadow instanceof List) {
    951             return (List) contentShadow;
    952         } else {
    953             List list = createContentList();
    954
    955             if (contentShadow != null) {
    956                 list.add(contentShadow);
    957             }
    958
    959             this.content = list;
    960
    961             return list;
    962         }
    963     }
    964
    965     protected List attributeList() {
    966         final Object attributesShadow = this.attributes;
    967
    968         if (attributesShadow instanceof List) {
    969             return (List) attributesShadow;
    970         } else if (attributesShadow != null) {
    971             List list = createAttributeList();
    972
    973             list.add(attributesShadow);
    974
    975             this.attributes = list;
    976
    977             return list;
    978         } else {
    979             List list = createAttributeList();
    980
    981             this.attributes = list;
    982
    983             return list;
    984         }
    985     }
    986
    987     protected List attributeList(int size) {
    988         final Object attributesShadow = this.attributes;
    989
    990         if (attributesShadow instanceof List) {
    991             return (List) attributesShadow;
    992         } else if (attributesShadow != null) {
    993             List list = createAttributeList(size);
    994
    995             list.add(attributesShadow);
    996
    997             this.attributes = list;
    998
    999             return list;
    1000         } else {
    1001             List list = createAttributeList(size);
    1002
    1003             this.attributes = list;
    1004
    1005             return list;
    1006         }
    1007     }
    1008
    1009     protected void setAttributeList(List attributeList) {
    1010         this.attributes = attributeList;
    1011     }
    1012
    1013     protected DocumentFactory getDocumentFactory() {
    1014         DocumentFactory factory = qname.getDocumentFactory();
    1015
    1016         return (factory != null) ? factory : DOCUMENT_FACTORY;
    1017     }
    1018 }
    1019
    1020 /*
    1021  * Redistribution and use of this software and associated documentation
    1022  * ("Software"), with or without modification, are permitted provided that the
    1023  * following conditions are met:
    1024  *
    1025  * 1. Redistributions of source code must retain copyright statements and
    1026  * notices. Redistributions must also contain a copy of this document.
    1027  *
    1028  * 2. Redistributions in binary form must reproduce the above copyright notice,
    1029  * this list of conditions and the following disclaimer in the documentation
    1030  * and/or other materials provided with the distribution.
    1031  *
    1032  * 3. The name "DOM4J" must not be used to endorse or promote products derived
    1033  * from this Software without prior written permission of MetaStuff, Ltd. For
    1034  * written permission, please contact dom4j-info@metastuff.com.
    1035  *
    1036  * 4. Products derived from this Software may not be called "DOM4J" nor may
    1037  * "DOM4J" appear in their names without prior written permission of MetaStuff,
    1038  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
    1039  *
    1040  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
    1041  *
    1042  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
    1043  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1044  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1045  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
    1046  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    1047  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    1048  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    1049  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    1050  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1051  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    1052  * POSSIBILITY OF SUCH DAMAGE.
    1053  *
    1054  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
    1055  */