1. // $Id: DOMResult.java,v 1.4.16.5 2004/07/13 22:27:49 jsuttor Exp $
  2. /*
  3. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  4. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  5. */
  6. /*
  7. * @(#)DOMResult.java 1.15 04/07/13
  8. */
  9. package javax.xml.transform.dom;
  10. import javax.xml.transform.Result;
  11. import org.w3c.dom.Node;
  12. /**
  13. * <p>Acts as a holder for a transformation result tree in the form of a Document Object Model (DOM) tree.</p>
  14. *
  15. * <p>If no output DOM source is set, the transformation will create a Document node as the holder for the result of the transformation,
  16. * which may be retrieved with {@link #getNode()}.</p>
  17. *
  18. * @author <a href="Jeff.Suttor@Sun.com">Jeff Suttor</a>
  19. * @version $Revision: 1.4.16.5 $, $Date: 2004/07/13 22:27:49 $
  20. */
  21. public class DOMResult implements Result {
  22. /** <p>If {@link javax.xml.transform.TransformerFactory#getFeature}
  23. * returns <code>true</code> when passed this value as an argument,
  24. * the <code>Transformer</code> supports <code>Result</code> output of this type.</p>
  25. */
  26. public static final String FEATURE = "http://javax.xml.transform.dom.DOMResult/feature";
  27. /**
  28. * <p>Zero-argument default constructor.</p>
  29. *
  30. * <p><code>node</code>,
  31. * <code>siblingNode</code> and
  32. * <code>systemId</code>
  33. * will be set to <code>null</code>.</p>
  34. */
  35. public DOMResult() {
  36. setNode(null);
  37. setNextSibling(null);
  38. setSystemId(null);
  39. }
  40. /**
  41. * <p>Use a DOM node to create a new output target.</p>
  42. *
  43. * <p>In practice, the node should be
  44. * a {@link org.w3c.dom.Document} node,
  45. * a {@link org.w3c.dom.DocumentFragment} node, or
  46. * a {@link org.w3c.dom.Element} node.
  47. * In other words, a node that accepts children.</p>
  48. *
  49. * <p><code>siblingNode</code> and
  50. * <code>systemId</code>
  51. * will be set to <code>null</code>.</p>
  52. *
  53. * @param node The DOM node that will contain the result tree.
  54. */
  55. public DOMResult(Node node) {
  56. setNode(node);
  57. setNextSibling(null);
  58. setSystemId(null);
  59. }
  60. /**
  61. * <p>Use a DOM node to create a new output target with the specified System ID.<p>
  62. *
  63. * <p>In practice, the node should be
  64. * a {@link org.w3c.dom.Document} node,
  65. * a {@link org.w3c.dom.DocumentFragment} node, or
  66. * a {@link org.w3c.dom.Element} node.
  67. * In other words, a node that accepts children.</p>
  68. *
  69. * <p><code>siblingNode</code> will be set to <code>null</code>.</p>
  70. *
  71. * @param node The DOM node that will contain the result tree.
  72. * @param systemId The system identifier which may be used in association with this node.
  73. */
  74. public DOMResult(Node node, String systemId) {
  75. setNode(node);
  76. setNextSibling(null);
  77. setSystemId(systemId);
  78. }
  79. /**
  80. * <p>Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before.</p>
  81. *
  82. * <p>In practice, <code>node</code> and <code>nextSibling</code> should be
  83. * a {@link org.w3c.dom.Document} node,
  84. * a {@link org.w3c.dom.DocumentFragment} node, or
  85. * a {@link org.w3c.dom.Element} node.
  86. * In other words, a node that accepts children.</p>
  87. *
  88. * <p>Use <code>nextSibling</code> to specify the child node
  89. * where the result nodes should be inserted before.
  90. * If <code>nextSibling</code> is not a sibling of <code>node</code>,
  91. * then an <code>IllegalArgumentException</code> is thrown.
  92. * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>,
  93. * then an <code>IllegalArgumentException</code> is thrown.
  94. * If <code>nextSibling</code> is <code>null</code>,
  95. * then the behavior is the same as calling {@link #DOMResult(Node node)},
  96. * i.e. append the result nodes as the last child of the specified <code>node</code>.</p>
  97. *
  98. * <p><code>systemId</code> will be set to <code>null</code>.</p>
  99. *
  100. * @param node The DOM node that will contain the result tree.
  101. * @param nextSibling The child node where the result nodes should be inserted before.
  102. *
  103. * @throws IllegalArgumentException If <code>nextSibling</code> is not a sibling of <code>node</code>.
  104. * @throws IllegalArgumentException If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>.
  105. *
  106. * @since 1.5
  107. */
  108. public DOMResult(Node node, Node nextSibling) {
  109. // does the corrent parent/child relationship exist?
  110. if (nextSibling != null) {
  111. // cannot be a sibling of a null node
  112. if (node == null) {
  113. throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
  114. }
  115. // nextSibling contained by node?
  116. if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) {
  117. throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node.");
  118. }
  119. }
  120. setNode(node);
  121. setNextSibling(nextSibling);
  122. setSystemId(null);
  123. }
  124. /**
  125. * <p>Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before and
  126. * the specified System ID.</p>
  127. *
  128. * <p>In practice, <code>node</code> and <code>nextSibling</code> should be
  129. * a {@link org.w3c.dom.Document} node,
  130. * a {@link org.w3c.dom.DocumentFragment} node, or a
  131. * {@link org.w3c.dom.Element} node.
  132. * In other words, a node that accepts children.</p>
  133. *
  134. * <p>Use <code>nextSibling</code> to specify the child node
  135. * where the result nodes should be inserted before.
  136. * If <code>nextSibling</code> is not a sibling of <code>node</code>,
  137. * then an <code>IllegalArgumentException</code> is thrown.
  138. * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>,
  139. * then an <code>IllegalArgumentException</code> is thrown.
  140. * If <code>nextSibling</code> is <code>null</code>,
  141. * then the behavior is the same as calling {@link #DOMResult(Node node, String systemId)},
  142. * i.e. append the result nodes as the last child of the specified node and use the specified System ID.</p>
  143. *
  144. * @param node The DOM node that will contain the result tree.
  145. * @param nextSibling The child node where the result nodes should be inserted before.
  146. * @param systemId The system identifier which may be used in association with this node.
  147. *
  148. * @throws IllegalArgumentException If <code>nextSibling</code> is not a sibling of <code>node</code>.
  149. * @throws IllegalArgumentException If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>.
  150. *
  151. * @since 1.5
  152. */
  153. public DOMResult(Node node, Node nextSibling, String systemId) {
  154. // does the corrent parent/child relationship exist?
  155. if (nextSibling != null) {
  156. // cannot be a sibling of a null node
  157. if (node == null) {
  158. throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
  159. }
  160. // nextSibling contained by node?
  161. if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) {
  162. throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node.");
  163. }
  164. }
  165. setNode(node);
  166. setNextSibling(nextSibling);
  167. setSystemId(systemId);
  168. }
  169. /**
  170. * <p>Set the node that will contain the result DOM tree.<p>
  171. *
  172. * <p>In practice, the node should be
  173. * a {@link org.w3c.dom.Document} node,
  174. * a {@link org.w3c.dom.DocumentFragment} node, or
  175. * a {@link org.w3c.dom.Element} node.
  176. * In other words, a node that accepts children.</p>
  177. *
  178. * <p>An <code>IllegalStateException</code> is thrown if <code>nextSibling</code> is not <code>null</code> and
  179. * <code>node</code> is not a parent of <code>nextSibling</code>.
  180. * An <code>IllegalStateException</code> is thrown if <code>node</code> is <code>null</code> and
  181. * <code>nextSibling</code> is not <code>null</code>.</p>
  182. *
  183. * @param node The node to which the transformation will be appended.
  184. *
  185. * @throws IllegalStateException If <code>nextSibling</code> is not <code>null</code> and
  186. * <code>nextSibling</code> is not a child of <code>node</code>.
  187. * @throws IllegalStateException If <code>node</code> is <code>null</code> and
  188. * <code>nextSibling</code> is not <code>null</code>.
  189. */
  190. public void setNode(Node node) {
  191. // does the corrent parent/child relationship exist?
  192. if (nextSibling != null) {
  193. // cannot be a sibling of a null node
  194. if (node == null) {
  195. throw new IllegalStateException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
  196. }
  197. // nextSibling contained by node?
  198. if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) {
  199. throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node.");
  200. }
  201. }
  202. this.node = node;
  203. }
  204. /**
  205. * <p>Get the node that will contain the result DOM tree.</p>
  206. *
  207. * <p>If no node was set via
  208. * {@link #DOMResult(Node node)},
  209. * {@link #DOMResult(Node node, String systeId)},
  210. * {@link #DOMResult(Node node, Node nextSibling)},
  211. * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or
  212. * {@link #setNode(Node node)},
  213. * then the node will be set by the transformation, and may be obtained from this method once the transformation is complete.
  214. * Calling this method before the transformation will return <code>null</code>.</p>
  215. *
  216. * @return The node to which the transformation will be appended.
  217. */
  218. public Node getNode() {
  219. return node;
  220. }
  221. /**
  222. * <p>Set the child node before which the result nodes will be inserted.</p>
  223. *
  224. * <p>Use <code>nextSibling</code> to specify the child node
  225. * before which the result nodes should be inserted.
  226. * If <code>nextSibling</code> is not a descendant of <code>node</code>,
  227. * then an <code>IllegalArgumentException</code> is thrown.
  228. * If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>,
  229. * then an <code>IllegalStateException</code> is thrown.
  230. * If <code>nextSibling</code> is <code>null</code>,
  231. * then the behavior is the same as calling {@link #DOMResult(Node node)},
  232. * i.e. append the result nodes as the last child of the specified <code>node</code>.</p>
  233. *
  234. * @param nextSibling The child node before which the result nodes will be inserted.
  235. *
  236. * @throws IllegalArgumentException If <code>nextSibling</code> is not a descendant of <code>node</code>.
  237. * @throws IllegalStateException If <code>node</code> is <code>null</code> and <code>nextSibling</code> is not <code>null</code>.
  238. *
  239. * @since 1.5
  240. */
  241. public void setNextSibling(Node nextSibling) {
  242. // does the corrent parent/child relationship exist?
  243. if (nextSibling != null) {
  244. // cannot be a sibling of a null node
  245. if (node == null) {
  246. throw new IllegalStateException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node.");
  247. }
  248. // nextSibling contained by node?
  249. if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) {
  250. throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node.");
  251. }
  252. }
  253. this.nextSibling = nextSibling;
  254. }
  255. /**
  256. * <p>Get the child node before which the result nodes will be inserted.</p>
  257. *
  258. * <p>If no node was set via
  259. * {@link #DOMResult(Node node, Node nextSibling)},
  260. * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or
  261. * {@link #setNextSibling(Node nextSibling)},
  262. * then <code>null</code> will be returned.</p>
  263. *
  264. * @return The child node before which the result nodes will be inserted.
  265. *
  266. * @since 1.5
  267. */
  268. public Node getNextSibling() {
  269. return nextSibling;
  270. }
  271. /**
  272. * <p>Set the systemId that may be used in association with the node.</p>
  273. *
  274. * @param systemId The system identifier as a URI string.
  275. */
  276. public void setSystemId(String systemId) {
  277. this.systemId = systemId;
  278. }
  279. /**
  280. * <p>Get the System Identifier.</p>
  281. *
  282. * <p>If no System ID was set via
  283. * {@link #DOMResult(Node node, String systemId)},
  284. * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or
  285. * {@link #setSystemId(String systemId)},
  286. * then <code>null</code> will be returned.</p>
  287. *
  288. * @return The system identifier.
  289. */
  290. public String getSystemId() {
  291. return systemId;
  292. }
  293. //////////////////////////////////////////////////////////////////////
  294. // Internal state.
  295. //////////////////////////////////////////////////////////////////////
  296. /**
  297. * <p>The node to which the transformation will be appended.</p>
  298. */
  299. private Node node = null;
  300. /**
  301. * <p>The child node before which the result nodes will be inserted.</p>
  302. *
  303. * @since 1.5
  304. */
  305. private Node nextSibling = null;
  306. /**
  307. * <p>The System ID that may be used in association with the node.</p>
  308. */
  309. private String systemId = null;
  310. }