1 /* 2 * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.xml.transform.dom; 27 28 import javax.xml.transform.Result; 29 import org.w3c.dom.Node; 30 31 /** 32 * <p>Acts as a holder for a transformation result tree in the form of a Document Object Model (DOM) tree.</p> 33 * 34 * <p>If no output DOM source is set, the transformation will create a Document node as the holder for the result of the transformation, 35 * which may be retrieved with {@link #getNode()}.</p> 36 * 37 * @author <a href="Jeff.Suttor@Sun.com">Jeff Suttor</a> 38 * @since 1.4 39 */ 40 public class DOMResult implements Result { 41 42 /** <p>If {@link javax.xml.transform.TransformerFactory#getFeature} 43 * returns <code>true</code> when passed this value as an argument, 44 * the <code>Transformer</code> supports <code>Result</code> output of this type.</p> 45 */ 46 public static final String FEATURE = "http://javax.xml.transform.dom.DOMResult/feature"; 47 48 /** 49 * <p>Zero-argument default constructor.</p> 50 * 51 * <p><code>node</code>, 52 * <code>siblingNode</code> and 53 * <code>systemId</code> 54 * will be set to <code>null</code>.</p> 55 */ 56 public DOMResult() { 57 setNode(null); 58 setNextSibling(null); 59 setSystemId(null); 60 } 61 62 /** 63 * <p>Use a DOM node to create a new output target.</p> 64 * 65 * <p>In practice, the node should be 66 * a {@link org.w3c.dom.Document} node, 67 * a {@link org.w3c.dom.DocumentFragment} node, or 68 * a {@link org.w3c.dom.Element} node. 69 * In other words, a node that accepts children.</p> 70 * 71 * <p><code>siblingNode</code> and 72 * <code>systemId</code> 73 * will be set to <code>null</code>.</p> 74 * 75 * @param node The DOM node that will contain the result tree. 76 */ 77 public DOMResult(Node node) { 78 setNode(node); 79 setNextSibling(null); 80 setSystemId(null); 81 } 82 83 /** 84 * <p>Use a DOM node to create a new output target with the specified System ID.<p> 85 * 86 * <p>In practice, the node should be 87 * a {@link org.w3c.dom.Document} node, 88 * a {@link org.w3c.dom.DocumentFragment} node, or 89 * a {@link org.w3c.dom.Element} node. 90 * In other words, a node that accepts children.</p> 91 * 92 * <p><code>siblingNode</code> will be set to <code>null</code>.</p> 93 * 94 * @param node The DOM node that will contain the result tree. 95 * @param systemId The system identifier which may be used in association with this node. 96 */ 97 public DOMResult(Node node, String systemId) { 98 setNode(node); 99 setNextSibling(null); 100 setSystemId(systemId); 101 } 102 103 /** 104 * <p>Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before.</p> 105 * 106 * <p>In practice, <code>node</code> and <code>nextSibling</code> should be 107 * a {@link org.w3c.dom.Document} node, 108 * a {@link org.w3c.dom.DocumentFragment} node, or 109 * a {@link org.w3c.dom.Element} node. 110 * In other words, a node that accepts children.</p> 111 * 112 * <p>Use <code>nextSibling</code> to specify the child node 113 * where the result nodes should be inserted before. 114 * If <code>nextSibling</code> is not a sibling of <code>node</code>, 115 * then an <code>IllegalArgumentException</code> is thrown. 116 * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>, 117 * then an <code>IllegalArgumentException</code> is thrown. 118 * If <code>nextSibling</code> is <code>null</code>, 119 * then the behavior is the same as calling {@link #DOMResult(Node node)}, 120 * i.e. append the result nodes as the last child of the specified <code>node</code>.</p> 121 * 122 * <p><code>systemId</code> will be set to <code>null</code>.</p> 123 * 124 * @param node The DOM node that will contain the result tree. 125 * @param nextSibling The child node where the result nodes should be inserted before. 126 * 127 * @throws IllegalArgumentException If <code>nextSibling</code> is not a sibling of <code>node</code> or 128 * <code>node</code> is <code>null</code> and <code>nextSibling</code> 129 * is not <code>null</code>. 130 * 131 * @since 1.5 132 */ 133 public DOMResult(Node node, Node nextSibling) { 134 135 // does the corrent parent/child relationship exist? 136 if (nextSibling != null) { 137 // cannot be a sibling of a null node 138 if (node == null) { 139 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node."); 140 } 141 142 // nextSibling contained by node? 143 if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) { 144 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node."); 145 } 146 } 147 148 setNode(node); 149 setNextSibling(nextSibling); 150 setSystemId(null); 151 } 152 153 /** 154 * <p>Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before and 155 * the specified System ID.</p> 156 * 157 * <p>In practice, <code>node</code> and <code>nextSibling</code> should be 158 * a {@link org.w3c.dom.Document} node, 159 * a {@link org.w3c.dom.DocumentFragment} node, or a 160 * {@link org.w3c.dom.Element} node. 161 * In other words, a node that accepts children.</p> 162 * 163 * <p>Use <code>nextSibling</code> to specify the child node 164 * where the result nodes should be inserted before. 165 * If <code>nextSibling</code> is not a sibling of <code>node</code>, 166 * then an <code>IllegalArgumentException</code> is thrown. 167 * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>, 168 * then an <code>IllegalArgumentException</code> is thrown. 169 * If <code>nextSibling</code> is <code>null</code>, 170 * then the behavior is the same as calling {@link #DOMResult(Node node, String systemId)}, 171 * i.e. append the result nodes as the last child of the specified node and use the specified System ID.</p> 172 * 173 * @param node The DOM node that will contain the result tree. 174 * @param nextSibling The child node where the result nodes should be inserted before. 175 * @param systemId The system identifier which may be used in association with this node. 176 * 177 * @throws IllegalArgumentException If <code>nextSibling</code> is not a 178 * sibling of <code>node</code> or 179 * <code>node</code> is <code>null</code> and <code>nextSibling</code> 180 * is not <code>null</code>. 181 * 182 * @since 1.5 183 */ 184 public DOMResult(Node node, Node nextSibling, String systemId) { 185 186 // does the corrent parent/child relationship exist? 187 if (nextSibling != null) { 188 // cannot be a sibling of a null node 189 if (node == null) { 190 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node."); 191 } 192 193 // nextSibling contained by node? 194 if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) { 195 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node."); 196 } 197 } 198 199 setNode(node); 200 setNextSibling(nextSibling); 201 setSystemId(systemId); 202 } 203 204 /** 205 * <p>Set the node that will contain the result DOM tree.<p> 206 * 207 * <p>In practice, the node should be 208 * a {@link org.w3c.dom.Document} node, 209 * a {@link org.w3c.dom.DocumentFragment} node, or 210 * a {@link org.w3c.dom.Element} node. 211 * In other words, a node that accepts children.</p> 212 * 213 * <p>An <code>IllegalStateException</code> is thrown if 214 * <code>nextSibling</code> is not <code>null</code> and 215 * <code>node</code> is not a parent of <code>nextSibling</code>. 216 * An <code>IllegalStateException</code> is thrown if <code>node</code> is <code>null</code> and 217 * <code>nextSibling</code> is not <code>null</code>.</p> 218 * 219 * @param node The node to which the transformation will be appended. 220 * 221 * @throws IllegalStateException If <code>nextSibling</code> is not 222 * <code>null</code> and 223 * <code>nextSibling</code> is not a child of <code>node</code> or 224 * <code>node</code> is <code>null</code> and 225 * <code>nextSibling</code> is not <code>null</code>. 226 */ 227 public void setNode(Node node) { 228 // does the corrent parent/child relationship exist? 229 if (nextSibling != null) { 230 // cannot be a sibling of a null node 231 if (node == null) { 232 throw new IllegalStateException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node."); 233 } 234 235 // nextSibling contained by node? 236 if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) { 237 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node."); 238 } 239 } 240 241 this.node = node; 242 } 243 244 /** 245 * <p>Get the node that will contain the result DOM tree.</p> 246 * 247 * <p>If no node was set via 248 * {@link #DOMResult(Node node)}, 249 * {@link #DOMResult(Node node, String systeId)}, 250 * {@link #DOMResult(Node node, Node nextSibling)}, 251 * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or 252 * {@link #setNode(Node node)}, 253 * then the node will be set by the transformation, and may be obtained from this method once the transformation is complete. 254 * Calling this method before the transformation will return <code>null</code>.</p> 255 * 256 * @return The node to which the transformation will be appended. 257 */ 258 public Node getNode() { 259 return node; 260 } 261 262 /** 263 * <p>Set the child node before which the result nodes will be inserted.</p> 264 * 265 * <p>Use <code>nextSibling</code> to specify the child node 266 * before which the result nodes should be inserted. 267 * If <code>nextSibling</code> is not a descendant of <code>node</code>, 268 * then an <code>IllegalArgumentException</code> is thrown. 269 * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>, 270 * then an <code>IllegalStateException</code> is thrown. 271 * If <code>nextSibling</code> is <code>null</code>, 272 * then the behavior is the same as calling {@link #DOMResult(Node node)}, 273 * i.e. append the result nodes as the last child of the specified <code>node</code>.</p> 274 * 275 * @param nextSibling The child node before which the result nodes will be inserted. 276 * 277 * @throws IllegalArgumentException If <code>nextSibling</code> is not a 278 * descendant of <code>node</code>. 279 * @throws IllegalStateException If <code>node</code> is <code>null</code> 280 * and <code>nextSibling</code> is not <code>null</code>. 281 * 282 * @since 1.5 283 */ 284 public void setNextSibling(Node nextSibling) { 285 286 // does the corrent parent/child relationship exist? 287 if (nextSibling != null) { 288 // cannot be a sibling of a null node 289 if (node == null) { 290 throw new IllegalStateException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node."); 291 } 292 293 // nextSibling contained by node? 294 if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) { 295 throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node."); 296 } 297 } 298 299 this.nextSibling = nextSibling; 300 } 301 302 /** 303 * <p>Get the child node before which the result nodes will be inserted.</p> 304 * 305 * <p>If no node was set via 306 * {@link #DOMResult(Node node, Node nextSibling)}, 307 * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or 308 * {@link #setNextSibling(Node nextSibling)}, 309 * then <code>null</code> will be returned.</p> 310 * 311 * @return The child node before which the result nodes will be inserted. 312 * 313 * @since 1.5 314 */ 315 public Node getNextSibling() { 316 return nextSibling; 317 } 318 319 /** 320 * <p>Set the systemId that may be used in association with the node.</p> 321 * 322 * @param systemId The system identifier as a URI string. 323 */ 324 public void setSystemId(String systemId) { 325 this.systemId = systemId; 326 } 327 328 /** 329 * <p>Get the System Identifier.</p> 330 * 331 * <p>If no System ID was set via 332 * {@link #DOMResult(Node node, String systemId)}, 333 * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or 334 * {@link #setSystemId(String systemId)}, 335 * then <code>null</code> will be returned.</p> 336 * 337 * @return The system identifier. 338 */ 339 public String getSystemId() { 340 return systemId; 341 } 342 343 ////////////////////////////////////////////////////////////////////// 344 // Internal state. 345 ////////////////////////////////////////////////////////////////////// 346 347 /** 348 * <p>The node to which the transformation will be appended.</p> 349 */ 350 private Node node = null; 351 352 /** 353 * <p>The child node before which the result nodes will be inserted.</p> 354 * 355 * @since 1.5 356 */ 357 private Node nextSibling = null; 358 359 /** 360 * <p>The System ID that may be used in association with the node.</p> 361 */ 362 private String systemId = null; 363 }