001 /*
002 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.xml.transform.dom;
027
028 import javax.xml.transform.Result;
029 import org.w3c.dom.Node;
030
031 /**
032 * <p>Acts as a holder for a transformation result tree in the form of a Document Object Model (DOM) tree.</p>
033 *
034 * <p>If no output DOM source is set, the transformation will create a Document node as the holder for the result of the transformation,
035 * which may be retrieved with {@link #getNode()}.</p>
036 *
037 * @author <a href="Jeff.Suttor@Sun.com">Jeff Suttor</a>
038 * @version $Revision: 1.2 $, $Date: 2005/06/10 03:50:39 $
039 */
040 public class DOMResult implements Result {
041
042 /** <p>If {@link javax.xml.transform.TransformerFactory#getFeature}
043 * returns <code>true</code> when passed this value as an argument,
044 * the <code>Transformer</code> supports <code>Result</code> output of this type.</p>
045 */
046 public static final String FEATURE = "http://javax.xml.transform.dom.DOMResult/feature";
047
048 /**
049 * <p>Zero-argument default constructor.</p>
050 *
051 * <p><code>node</code>,
052 * <code>siblingNode</code> and
053 * <code>systemId</code>
054 * will be set to <code>null</code>.</p>
055 */
056 public DOMResult() {
057 setNode(null);
058 setNextSibling(null);
059 setSystemId(null);
060 }
061
062 /**
063 * <p>Use a DOM node to create a new output target.</p>
064 *
065 * <p>In practice, the node should be
066 * a {@link org.w3c.dom.Document} node,
067 * a {@link org.w3c.dom.DocumentFragment} node, or
068 * a {@link org.w3c.dom.Element} node.
069 * In other words, a node that accepts children.</p>
070 *
071 * <p><code>siblingNode</code> and
072 * <code>systemId</code>
073 * will be set to <code>null</code>.</p>
074 *
075 * @param node The DOM node that will contain the result tree.
076 */
077 public DOMResult(Node node) {
078 setNode(node);
079 setNextSibling(null);
080 setSystemId(null);
081 }
082
083 /**
084 * <p>Use a DOM node to create a new output target with the specified System ID.<p>
085 *
086 * <p>In practice, the node should be
087 * a {@link org.w3c.dom.Document} node,
088 * a {@link org.w3c.dom.DocumentFragment} node, or
089 * a {@link org.w3c.dom.Element} node.
090 * In other words, a node that accepts children.</p>
091 *
092 * <p><code>siblingNode</code> will be set to <code>null</code>.</p>
093 *
094 * @param node The DOM node that will contain the result tree.
095 * @param systemId The system identifier which may be used in association with this node.
096 */
097 public DOMResult(Node node, String systemId) {
098 setNode(node);
099 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(
140 "Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
141 }
142
143 // nextSibling contained by node?
144 if ((node.compareDocumentPosition(nextSibling) & Node.DOCUMENT_POSITION_CONTAINED_BY) == 0) {
145 throw new IllegalArgumentException(
146 "Cannot create a DOMResult when the nextSibling is not contained by the node.");
147 }
148 }
149
150 setNode(node);
151 setNextSibling(nextSibling);
152 setSystemId(null);
153 }
154
155 /**
156 * <p>Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before and
157 * the specified System ID.</p>
158 *
159 * <p>In practice, <code>node</code> and <code>nextSibling</code> should be
160 * a {@link org.w3c.dom.Document} node,
161 * a {@link org.w3c.dom.DocumentFragment} node, or a
162 * {@link org.w3c.dom.Element} node.
163 * In other words, a node that accepts children.</p>
164 *
165 * <p>Use <code>nextSibling</code> to specify the child node
166 * where the result nodes should be inserted before.
167 * If <code>nextSibling</code> is not a sibling of <code>node</code>,
168 * then an <code>IllegalArgumentException</code> is thrown.
169 * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>,
170 * then an <code>IllegalArgumentException</code> is thrown.
171 * If <code>nextSibling</code> is <code>null</code>,
172 * then the behavior is the same as calling {@link #DOMResult(Node node, String systemId)},
173 * i.e. append the result nodes as the last child of the specified node and use the specified System ID.</p>
174 *
175 * @param node The DOM node that will contain the result tree.
176 * @param nextSibling The child node where the result nodes should be inserted before.
177 * @param systemId The system identifier which may be used in association with this node.
178 *
179 * @throws IllegalArgumentException If <code>nextSibling</code> is not a
180 * sibling of <code>node</code> or
181 * <code>node</code> is <code>null</code> and <code>nextSibling</code>
182 * is not <code>null</code>.
183 *
184 * @since 1.5
185 */
186 public DOMResult(Node node, Node nextSibling, String systemId) {
187
188 // does the corrent parent/child relationship exist?
189 if (nextSibling != null) {
190 // cannot be a sibling of a null node
191 if (node == null) {
192 throw new IllegalArgumentException(
193 "Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
194 }
195
196 // nextSibling contained by node?
197 if ((node.compareDocumentPosition(nextSibling) & Node.DOCUMENT_POSITION_CONTAINED_BY) == 0) {
198 throw new IllegalArgumentException(
199 "Cannot create a DOMResult when the nextSibling is not contained by the node.");
200 }
201 }
202
203 setNode(node);
204 setNextSibling(nextSibling);
205 setSystemId(systemId);
206 }
207
208 /**
209 * <p>Set the node that will contain the result DOM tree.<p>
210 *
211 * <p>In practice, the node should be
212 * a {@link org.w3c.dom.Document} node,
213 * a {@link org.w3c.dom.DocumentFragment} node, or
214 * a {@link org.w3c.dom.Element} node.
215 * In other words, a node that accepts children.</p>
216 *
217 * <p>An <code>IllegalStateException</code> is thrown if
218 * <code>nextSibling</code> is not <code>null</code> and
219 * <code>node</code> is not a parent of <code>nextSibling</code>.
220 * An <code>IllegalStateException</code> is thrown if <code>node</code> is <code>null</code> and
221 * <code>nextSibling</code> is not <code>null</code>.</p>
222 *
223 * @param node The node to which the transformation will be appended.
224 *
225 * @throws IllegalStateException If <code>nextSibling</code> is not
226 * <code>null</code> and
227 * <code>nextSibling</code> is not a child of <code>node</code> or
228 * <code>node</code> is <code>null</code> and
229 * <code>nextSibling</code> is not <code>null</code>.
230 */
231 public void setNode(Node node) {
232 // does the corrent parent/child relationship exist?
233 if (nextSibling != null) {
234 // cannot be a sibling of a null node
235 if (node == null) {
236 throw new IllegalStateException(
237 "Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
238 }
239
240 // nextSibling contained by node?
241 if ((node.compareDocumentPosition(nextSibling) & Node.DOCUMENT_POSITION_CONTAINED_BY) == 0) {
242 throw new IllegalArgumentException(
243 "Cannot create a DOMResult when the nextSibling is not contained by the node.");
244 }
245 }
246
247 this .node = node;
248 }
249
250 /**
251 * <p>Get the node that will contain the result DOM tree.</p>
252 *
253 * <p>If no node was set via
254 * {@link #DOMResult(Node node)},
255 * {@link #DOMResult(Node node, String systeId)},
256 * {@link #DOMResult(Node node, Node nextSibling)},
257 * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or
258 * {@link #setNode(Node node)},
259 * then the node will be set by the transformation, and may be obtained from this method once the transformation is complete.
260 * Calling this method before the transformation will return <code>null</code>.</p>
261 *
262 * @return The node to which the transformation will be appended.
263 */
264 public Node getNode() {
265 return node;
266 }
267
268 /**
269 * <p>Set the child node before which the result nodes will be inserted.</p>
270 *
271 * <p>Use <code>nextSibling</code> to specify the child node
272 * before which the result nodes should be inserted.
273 * If <code>nextSibling</code> is not a descendant of <code>node</code>,
274 * then an <code>IllegalArgumentException</code> is thrown.
275 * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>,
276 * then an <code>IllegalStateException</code> is thrown.
277 * If <code>nextSibling</code> is <code>null</code>,
278 * then the behavior is the same as calling {@link #DOMResult(Node node)},
279 * i.e. append the result nodes as the last child of the specified <code>node</code>.</p>
280 *
281 * @param nextSibling The child node before which the result nodes will be inserted.
282 *
283 * @throws IllegalArgumentException If <code>nextSibling</code> is not a
284 * descendant of <code>node</code>.
285 * @throws IllegalStateException If <code>node</code> is <code>null</code>
286 * and <code>nextSibling</code> is not <code>null</code>.
287 *
288 * @since 1.5
289 */
290 public void setNextSibling(Node nextSibling) {
291
292 // does the corrent parent/child relationship exist?
293 if (nextSibling != null) {
294 // cannot be a sibling of a null node
295 if (node == null) {
296 throw new IllegalStateException(
297 "Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
298 }
299
300 // nextSibling contained by node?
301 if ((node.compareDocumentPosition(nextSibling) & Node.DOCUMENT_POSITION_CONTAINED_BY) == 0) {
302 throw new IllegalArgumentException(
303 "Cannot create a DOMResult when the nextSibling is not contained by the node.");
304 }
305 }
306
307 this .nextSibling = nextSibling;
308 }
309
310 /**
311 * <p>Get the child node before which the result nodes will be inserted.</p>
312 *
313 * <p>If no node was set via
314 * {@link #DOMResult(Node node, Node nextSibling)},
315 * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or
316 * {@link #setNextSibling(Node nextSibling)},
317 * then <code>null</code> will be returned.</p>
318 *
319 * @return The child node before which the result nodes will be inserted.
320 *
321 * @since 1.5
322 */
323 public Node getNextSibling() {
324 return nextSibling;
325 }
326
327 /**
328 * <p>Set the systemId that may be used in association with the node.</p>
329 *
330 * @param systemId The system identifier as a URI string.
331 */
332 public void setSystemId(String systemId) {
333 this .systemId = systemId;
334 }
335
336 /**
337 * <p>Get the System Identifier.</p>
338 *
339 * <p>If no System ID was set via
340 * {@link #DOMResult(Node node, String systemId)},
341 * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or
342 * {@link #setSystemId(String systemId)},
343 * then <code>null</code> will be returned.</p>
344 *
345 * @return The system identifier.
346 */
347 public String getSystemId() {
348 return systemId;
349 }
350
351 //////////////////////////////////////////////////////////////////////
352 // Internal state.
353 //////////////////////////////////////////////////////////////////////
354
355 /**
356 * <p>The node to which the transformation will be appended.</p>
357 */
358 private Node node = null;
359
360 /**
361 * <p>The child node before which the result nodes will be inserted.</p>
362 *
363 * @since 1.5
364 */
365 private Node nextSibling = null;
366
367 /**
368 * <p>The System ID that may be used in association with the node.</p>
369 */
370 private String systemId = null;
371 }
|