Home | History | Annotate | Download | only in dom
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 // $Id: DOMResult.java 569995 2007-08-27 04:31:06Z mrglavas $
     19 
     20 package javax.xml.transform.dom;
     21 
     22 import javax.xml.transform.Result;
     23 import org.w3c.dom.Node;
     24 
     25 /**
     26  * <p>Acts as a holder for a transformation result tree in the form of a Document Object Model (DOM) tree.</p>
     27  *
     28  * <p>If no output DOM source is set, the transformation will create a Document node as the holder for the result of the transformation,
     29  * which may be retrieved with {@link #getNode()}.</p>
     30  *
     31  * @author <a href="Jeff.Suttor (at) Sun.com">Jeff Suttor</a>
     32  * @version $Revision: 569995 $, $Date: 2007-08-26 21:31:06 -0700 (Sun, 26 Aug 2007) $
     33  */
     34 public class DOMResult implements Result {
     35 
     36     /** <p>If {@link javax.xml.transform.TransformerFactory#getFeature}
     37      * returns <code>true</code> when passed this value as an argument,
     38      * the <code>Transformer</code> supports <code>Result</code> output of this type.</p>
     39      */
     40     public static final String FEATURE = "http://javax.xml.transform.dom.DOMResult/feature";
     41 
     42     /**
     43      * <p>Zero-argument default constructor.</p>
     44      *
     45      * <p><code>node</code>,
     46      * <code>siblingNode</code> and
     47      * <code>systemId</code>
     48      * will be set to <code>null</code>.</p>
     49      */
     50     public DOMResult() {
     51         setNode(null);
     52         setNextSibling(null);
     53         setSystemId(null);
     54     }
     55 
     56     /**
     57      * <p>Use a DOM node to create a new output target.</p>
     58      *
     59      * <p>In practice, the node should be
     60      * a {@link org.w3c.dom.Document} node,
     61      * a {@link org.w3c.dom.DocumentFragment} node, or
     62      * a {@link org.w3c.dom.Element} node.
     63      * In other words, a node that accepts children.</p>
     64      *
     65      * <p><code>siblingNode</code> and
     66      * <code>systemId</code>
     67      * will be set to <code>null</code>.</p>
     68      *
     69      * @param node The DOM node that will contain the result tree.
     70      */
     71     public DOMResult(Node node) {
     72         setNode(node);
     73         setNextSibling(null);
     74         setSystemId(null);
     75     }
     76 
     77     /**
     78      * <p>Use a DOM node to create a new output target with the specified System ID.<p>
     79      *
     80      * <p>In practice, the node should be
     81      * a {@link org.w3c.dom.Document} node,
     82      * a {@link org.w3c.dom.DocumentFragment} node, or
     83      * a {@link org.w3c.dom.Element} node.
     84      * In other words, a node that accepts children.</p>
     85      *
     86      * <p><code>siblingNode</code> will be set to <code>null</code>.</p>
     87      *
     88      * @param node The DOM node that will contain the result tree.
     89      * @param systemId The system identifier which may be used in association with this node.
     90      */
     91     public DOMResult(Node node, String systemId) {
     92         setNode(node);
     93         setNextSibling(null);
     94         setSystemId(systemId);
     95     }
     96 
     97     /**
     98      * <p>Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before.</p>
     99      *
    100      * <p>In practice, <code>node</code> and <code>nextSibling</code> should be
    101      * a {@link org.w3c.dom.Document} node,
    102      * a {@link org.w3c.dom.DocumentFragment} node, or
    103      * a {@link org.w3c.dom.Element} node.
    104      * In other words, a node that accepts children.</p>
    105      *
    106      * <p>Use <code>nextSibling</code> to specify the child node
    107      * where the result nodes should be inserted before.
    108      * If <code>nextSibling</code> is not a sibling of <code>node</code>,
    109      * then an <code>IllegalArgumentException</code> is thrown.
    110      * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>,
    111      * then an <code>IllegalArgumentException</code> is thrown.
    112      * If <code>nextSibling</code> is <code>null</code>,
    113      * then the behavior is the same as calling {@link #DOMResult(Node node)},
    114      * i.e. append the result nodes as the last child of the specified <code>node</code>.</p>
    115      *
    116      * <p><code>systemId</code> will be set to <code>null</code>.</p>
    117      *
    118      * @param node The DOM node that will contain the result tree.
    119      * @param nextSibling The child node where the result nodes should be inserted before.
    120      *
    121      * @throws IllegalArgumentException If <code>nextSibling</code> is not a sibling of <code>node</code>.
    122      * @throws IllegalArgumentException If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>.
    123      *
    124      * @since 1.5
    125      */
    126     public DOMResult(Node node, Node nextSibling) {
    127 
    128         // does the corrent parent/child relationship exist?
    129         if (nextSibling != null) {
    130             // cannot be a sibling of a null node
    131             if (node == null) {
    132                 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
    133             }
    134 
    135             // nextSibling contained by node?
    136             if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) {
    137                 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node.");
    138             }
    139         }
    140 
    141         setNode(node);
    142         setNextSibling(nextSibling);
    143         setSystemId(null);
    144     }
    145 
    146     /**
    147      * <p>Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before and
    148      * the specified System ID.</p>
    149      *
    150      * <p>In practice, <code>node</code> and <code>nextSibling</code> should be
    151      * a {@link org.w3c.dom.Document} node,
    152      * a {@link org.w3c.dom.DocumentFragment} node, or a
    153      * {@link org.w3c.dom.Element} node.
    154      * In other words, a node that accepts children.</p>
    155      *
    156      * <p>Use <code>nextSibling</code> to specify the child node
    157      * where the result nodes should be inserted before.
    158      * If <code>nextSibling</code> is not a sibling of <code>node</code>,
    159      * then an <code>IllegalArgumentException</code> is thrown.
    160      * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>,
    161      * then an <code>IllegalArgumentException</code> is thrown.
    162      * If <code>nextSibling</code> is <code>null</code>,
    163      * then the behavior is the same as calling {@link #DOMResult(Node node, String systemId)},
    164      * i.e. append the result nodes as the last child of the specified node and use the specified System ID.</p>
    165      *
    166      * @param node The DOM node that will contain the result tree.
    167      * @param nextSibling The child node where the result nodes should be inserted before.
    168      * @param systemId The system identifier which may be used in association with this node.
    169      *
    170      * @throws IllegalArgumentException If <code>nextSibling</code> is not a sibling of <code>node</code>.
    171      * @throws IllegalArgumentException If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>.
    172      *
    173      * @since 1.5
    174      */
    175     public DOMResult(Node node, Node nextSibling, String systemId) {
    176 
    177         // does the current parent/child relationship exist?
    178         if (nextSibling != null) {
    179             // cannot be a sibling of a null node
    180             if (node == null) {
    181                 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
    182             }
    183 
    184             // nextSibling contained by node?
    185             if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) {
    186                 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node.");
    187             }
    188         }
    189 
    190         setNode(node);
    191         setNextSibling(nextSibling);
    192         setSystemId(systemId);
    193     }
    194 
    195     /**
    196      * <p>Set the node that will contain the result DOM tree.<p>
    197      *
    198      * <p>In practice, the node should be
    199      * a {@link org.w3c.dom.Document} node,
    200      * a {@link org.w3c.dom.DocumentFragment} node, or
    201      * a {@link org.w3c.dom.Element} node.
    202      * In other words, a node that accepts children.</p>
    203      *
    204      * <p>An <code>IllegalStateException</code> is thrown if <code>nextSibling</code> is not <code>null</code> and
    205      * <code>node</code> is not a parent of <code>nextSibling</code>.
    206      * An <code>IllegalStateException</code> is thrown if <code>node</code> is <code>null</code> and
    207      * <code>nextSibling</code> is not <code>null</code>.</p>
    208      *
    209      * @param node The node to which the transformation will be appended.
    210      *
    211      * @throws IllegalStateException If <code>nextSibling</code> is not <code>null</code> and
    212      *   <code>nextSibling</code> is not a child of <code>node</code>.
    213      * @throws IllegalStateException If <code>node</code> is <code>null</code> and
    214      *   <code>nextSibling</code> is not <code>null</code>.
    215      */
    216     public void setNode(Node node) {
    217         // does the corrent parent/child relationship exist?
    218         if (nextSibling != null) {
    219             // cannot be a sibling of a null node
    220             if (node == null) {
    221                 throw new IllegalStateException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
    222             }
    223 
    224             // nextSibling contained by node?
    225             if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) {
    226                 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node.");
    227             }
    228         }
    229 
    230         this.node = node;
    231     }
    232 
    233     /**
    234      * <p>Get the node that will contain the result DOM tree.</p>
    235      *
    236      * <p>If no node was set via
    237      * {@link #DOMResult(Node node)},
    238      * {@link #DOMResult(Node node, String systeId)},
    239      * {@link #DOMResult(Node node, Node nextSibling)},
    240      * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or
    241      * {@link #setNode(Node node)},
    242      * then the node will be set by the transformation, and may be obtained from this method once the transformation is complete.
    243      * Calling this method before the transformation will return <code>null</code>.</p>
    244      *
    245      * @return The node to which the transformation will be appended.
    246      */
    247     public Node getNode() {
    248         return node;
    249     }
    250 
    251     /**
    252      * <p>Set the child node before which the result nodes will be inserted.</p>
    253      *
    254      * <p>Use <code>nextSibling</code> to specify the child node
    255      * before which the result nodes should be inserted.
    256      * If <code>nextSibling</code> is not a descendant of <code>node</code>,
    257      * then an <code>IllegalArgumentException</code> is thrown.
    258      * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>,
    259      * then an <code>IllegalStateException</code> is thrown.
    260      * If <code>nextSibling</code> is <code>null</code>,
    261      * then the behavior is the same as calling {@link #DOMResult(Node node)},
    262      * i.e. append the result nodes as the last child of the specified <code>node</code>.</p>
    263      *
    264      * @param nextSibling The child node before which the result nodes will be inserted.
    265      *
    266      * @throws IllegalArgumentException If <code>nextSibling</code> is not a descendant of <code>node</code>.
    267      * @throws IllegalStateException If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>.
    268      *
    269      * @since 1.5
    270      */
    271     public void setNextSibling(Node nextSibling) {
    272 
    273         // does the corrent parent/child relationship exist?
    274         if (nextSibling != null) {
    275             // cannot be a sibling of a null node
    276             if (node == null) {
    277                 throw new IllegalStateException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
    278             }
    279 
    280             // nextSibling contained by node?
    281             if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) {
    282                 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node.");
    283             }
    284         }
    285 
    286         this.nextSibling = nextSibling;
    287     }
    288 
    289     /**
    290      * <p>Get the child node before which the result nodes will be inserted.</p>
    291      *
    292      * <p>If no node was set via
    293      * {@link #DOMResult(Node node, Node nextSibling)},
    294      * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or
    295      * {@link #setNextSibling(Node nextSibling)},
    296      * then <code>null</code> will be returned.</p>
    297      *
    298      * @return The child node before which the result nodes will be inserted.
    299      *
    300      * @since 1.5
    301      */
    302     public Node getNextSibling() {
    303         return nextSibling;
    304     }
    305 
    306     /**
    307      * <p>Set the systemId that may be used in association with the node.</p>
    308      *
    309      * @param systemId The system identifier as a URI string.
    310      */
    311     public void setSystemId(String systemId) {
    312         this.systemId = systemId;
    313     }
    314 
    315     /**
    316      * <p>Get the System Identifier.</p>
    317      *
    318      * <p>If no System ID was set via
    319      * {@link #DOMResult(Node node, String systemId)},
    320      * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or
    321      * {@link #setSystemId(String systemId)},
    322      * then <code>null</code> will be returned.</p>
    323      *
    324      * @return The system identifier.
    325      */
    326     public String getSystemId() {
    327         return systemId;
    328     }
    329 
    330     //////////////////////////////////////////////////////////////////////
    331     // Internal state.
    332     //////////////////////////////////////////////////////////////////////
    333 
    334     /**
    335      * <p>The node to which the transformation will be appended.</p>
    336      */
    337     private Node node = null;
    338 
    339     /**
    340      * <p>The child node before which the result nodes will be inserted.</p>
    341      *
    342      * @since 1.5
    343      */
    344     private Node nextSibling = null;
    345 
    346     /**
    347      * <p>The System ID that may be used in association with the node.</p>
    348      */
    349     private String systemId = null;
    350 }
    351