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.Collections;
    11  import java.util.Iterator;
    12  import java.util.List;
    13
    14  import org.dom4j.Document;
    15  import org.dom4j.DocumentFactory;
    16  import org.dom4j.DocumentType;
    17  import org.dom4j.Element;
    18  import org.dom4j.IllegalAddException;
    19  import org.dom4j.Node;
    20  import org.dom4j.ProcessingInstruction;
    21
    22  import org.xml.sax.EntityResolver;
    23
    24  /***
    25   * <p>
    26   * <code>DefaultDocument</code> is the default DOM4J default implementation of
    27   * an XML document.
    28   * </p>
    29   *
    30   * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
    31   * @version $Revision: 1.34 $
    32   */
    33  public class DefaultDocument extends AbstractDocument {
    34      protected static final List EMPTY_LIST = Collections.EMPTY_LIST;
    35
    36      protected static final Iterator EMPTY_ITERATOR = EMPTY_LIST.iterator();
    37
    38      /*** The name of the document */
    39      private String name;
    40
    41      /*** The root element of this document */
    42      private Element rootElement;
    43
    44      /***
    45       * Store the contents of the document as a lazily created <code>List</code>
    46       */
    47      private List content;
    48
    49      /*** The document type for this document */
    50      private DocumentType docType;
    51
    52      /*** The document factory used by default */
    53      private DocumentFactory documentFactory = DocumentFactory.getInstance();
    54
    55      /*** The resolver of URIs */
    56      private transient EntityResolver entityResolver;
    57
    58      public DefaultDocument() {
    59      }
    60
    61      public DefaultDocument(String name) {
    62          this.name = name;
    63      }
    64
    65      public DefaultDocument(Element rootElement) {
    66          this.rootElement = rootElement;
    67      }
    68
    69      public DefaultDocument(DocumentType docType) {
    70          this.docType = docType;
    71      }
    72
    73      public DefaultDocument(Element rootElement, DocumentType docType) {
    74          this.rootElement = rootElement;
    75          this.docType = docType;
    76      }
    77
    78      public DefaultDocument(String name, Element rootElement,
    79              DocumentType docType) {
    80          this.name = name;
    81          this.rootElement = rootElement;
    82          this.docType = docType;
    83      }
    84
    85      public String getName() {
    86          return name;
    87      }
    88
    89      public void setName(String name) {
    90          this.name = name;
    91      }
    92
    93      public Element getRootElement() {
    94          return rootElement;
    95      }
    96
    97      public DocumentType getDocType() {
    98          return docType;
    99      }
    100
    101     public void setDocType(DocumentType docType) {
    102         this.docType = docType;
    103     }
    104
    105     public Document addDocType(String docTypeName, String publicId,
    106             String systemId) {
    107         setDocType(getDocumentFactory().createDocType(docTypeName, publicId,
    108                 systemId));
    109
    110         return this;
    111     }
    112
    113     public String getXMLEncoding() {
    114         return encoding;
    115     }
    116
    117     public EntityResolver getEntityResolver() {
    118         return entityResolver;
    119     }
    120
    121     public void setEntityResolver(EntityResolver entityResolver) {
    122         this.entityResolver = entityResolver;
    123     }
    124
    125     public Object clone() {
    126         DefaultDocument document = (DefaultDocument) super.clone();
    127         document.rootElement = null;
    128         document.content = null;
    129         document.appendContent(this);
    130
    131         return document;
    132     }
    133
    134     public List processingInstructions() {
    135         List source = contentList();
    136         List answer = createResultList();
    137         int size = source.size();
    138
    139         for (int i = 0; i < size; i++) {
    140             Object object = source.get(i);
    141
    142             if (object instanceof ProcessingInstruction) {
    143                 answer.add(object);
    144             }
    145         }
    146
    147         return answer;
    148     }
    149
    150     public List processingInstructions(String target) {
    151         List source = contentList();
    152         List answer = createResultList();
    153         int size = source.size();
    154
    155         for (int i = 0; i < size; i++) {
    156             Object object = source.get(i);
    157
    158             if (object instanceof ProcessingInstruction) {
    159                 ProcessingInstruction pi = (ProcessingInstruction) object;
    160
    161                 if (target.equals(pi.getName())) {
    162                     answer.add(pi);
    163                 }
    164             }
    165         }
    166
    167         return answer;
    168     }
    169
    170     public ProcessingInstruction processingInstruction(String target) {
    171         List source = contentList();
    172         int size = source.size();
    173
    174         for (int i = 0; i < size; i++) {
    175             Object object = source.get(i);
    176
    177             if (object instanceof ProcessingInstruction) {
    178                 ProcessingInstruction pi = (ProcessingInstruction) object;
    179
    180                 if (target.equals(pi.getName())) {
    181                     return pi;
    182                 }
    183             }
    184         }
    185
    186         return null;
    187     }
    188
    189     public boolean removeProcessingInstruction(String target) {
    190         List source = contentList();
    191
    192         for (Iterator iter = source.iterator(); iter.hasNext();) {
    193             Object object = iter.next();
    194
    195             if (object instanceof ProcessingInstruction) {
    196                 ProcessingInstruction pi = (ProcessingInstruction) object;
    197
    198                 if (target.equals(pi.getName())) {
    199                     iter.remove();
    200
    201                     return true;
    202                 }
    203             }
    204         }
    205
    206         return false;
    207     }
    208
    209     public void setContent(List content) {
    210         rootElement = null;
    211         contentRemoved();
    212
    213         if (content instanceof ContentListFacade) {
    214             content = ((ContentListFacade) content).getBackingList();
    215         }
    216
    217         if (content == null) {
    218             this.content = null;
    219         } else {
    220             int size = content.size();
    221             List newContent = createContentList(size);
    222
    223             for (int i = 0; i < size; i++) {
    224                 Object object = content.get(i);
    225
    226                 if (object instanceof Node) {
    227                     Node node = (Node) object;
    228                     Document doc = node.getDocument();
    229
    230                     if ((doc != null) && (doc != this)) {
    231                         node = (Node) node.clone();
    232                     }
    233
    234                     if (node instanceof Element) {
    235                         if (rootElement == null) {
    236                             rootElement = (Element) node;
    237                         } else {
    238                             throw new IllegalAddException(
    239                                     "A document may only "
    240                                             + "contain one root " + "element: "
    241                                             + content);
    242                         }
    243                     }
    244
    245                     newContent.add(node);
    246                     childAdded(node);
    247                 }
    248             }
    249
    250             this.content = newContent;
    251         }
    252     }
    253
    254     public void clearContent() {
    255         contentRemoved();
    256         content = null;
    257         rootElement = null;
    258     }
    259
    260     public void setDocumentFactory(DocumentFactory documentFactory) {
    261         this.documentFactory = documentFactory;
    262     }
    263
    264     // Implementation methods
    265     // -------------------------------------------------------------------------
    266     protected List contentList() {
    267         if (content == null) {
    268             content = createContentList();
    269
    270             if (rootElement != null) {
    271                 content.add(rootElement);
    272             }
    273         }
    274
    275         return content;
    276     }
    277
    278     protected void addNode(Node node) {
    279         if (node != null) {
    280             Document document = node.getDocument();
    281
    282             if ((document != null) && (document != this)) {
    283                 // XXX: could clone here
    284                 String message = "The Node already has an existing document: "
    285                         + document;
    286                 throw new IllegalAddException(this, node, message);
    287             }
    288
    289             contentList().add(node);
    290             childAdded(node);
    291         }
    292     }
    293
    294     protected void addNode(int index, Node node) {
    295         if (node != null) {
    296             Document document = node.getDocument();
    297
    298             if ((document != null) && (document != this)) {
    299                 // XXX: could clone here
    300                 String message = "The Node already has an existing document: "
    301                         + document;
    302                 throw new IllegalAddException(this, node, message);
    303             }
    304
    305             contentList().add(index, node);
    306             childAdded(node);
    307         }
    308     }
    309
    310     protected boolean removeNode(Node node) {
    311         if (node == rootElement) {
    312             rootElement = null;
    313         }
    314
    315         if (contentList().remove(node)) {
    316             childRemoved(node);
    317
    318             return true;
    319         }
    320
    321         return false;
    322     }
    323
    324     protected void rootElementAdded(Element element) {
    325         this.rootElement = element;
    326         element.setDocument(this);
    327     }
    328
    329     protected DocumentFactory getDocumentFactory() {
    330         return documentFactory;
    331     }
    332 }
    333
    334 /*
    335  * Redistribution and use of this software and associated documentation
    336  * ("Software"), with or without modification, are permitted provided that the
    337  * following conditions are met:
    338  *
    339  * 1. Redistributions of source code must retain copyright statements and
    340  * notices. Redistributions must also contain a copy of this document.
    341  *
    342  * 2. Redistributions in binary form must reproduce the above copyright notice,
    343  * this list of conditions and the following disclaimer in the documentation
    344  * and/or other materials provided with the distribution.
    345  *
    346  * 3. The name "DOM4J" must not be used to endorse or promote products derived
    347  * from this Software without prior written permission of MetaStuff, Ltd. For
    348  * written permission, please contact dom4j-info@metastuff.com.
    349  *
    350  * 4. Products derived from this Software may not be called "DOM4J" nor may
    351  * "DOM4J" appear in their names without prior written permission of MetaStuff,
    352  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
    353  *
    354  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
    355  *
    356  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
    357  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    358  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    359  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
    360  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    361  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    362  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    363  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    364  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    365  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    366  * POSSIBILITY OF SUCH DAMAGE.
    367  *
    368  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
    369  */