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@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 */ DOMResult()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 */ DOMResult(Node node)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 */ DOMResult(Node node, String systemId)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 */ DOMResult(Node node, Node nextSibling)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 */ DOMResult(Node node, Node nextSibling, String systemId)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 */ setNode(Node node)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 */ getNode()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 */ setNextSibling(Node nextSibling)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 */ getNextSibling()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 */ setSystemId(String systemId)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 */ getSystemId()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