1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * $Id: DOM2Helper.java,v 1.5 2004/02/17 04:21:14 minchau Exp $
  18. */
  19. package com.sun.org.apache.xml.internal.utils;
  20. import java.io.IOException;
  21. import javax.xml.parsers.DocumentBuilder;
  22. import javax.xml.parsers.DocumentBuilderFactory;
  23. import javax.xml.parsers.ParserConfigurationException;
  24. import javax.xml.transform.TransformerException;
  25. import org.w3c.dom.Attr;
  26. import org.w3c.dom.Document;
  27. import org.w3c.dom.Element;
  28. import org.w3c.dom.Node;
  29. import org.xml.sax.InputSource;
  30. /**
  31. * @deprecated Since the introduction of the DTM, this class will be removed.
  32. * This class provides a DOM level 2 "helper", which provides services currently
  33. * not provided be the DOM standard.
  34. */
  35. public class DOM2Helper extends DOMHelper
  36. {
  37. /**
  38. * Construct an instance.
  39. */
  40. public DOM2Helper(){}
  41. /**
  42. * Check node to see if it was created by a DOM implementation
  43. * that this helper is intended to support. This is currently
  44. * disabled, and assumes all nodes are acceptable rather than checking
  45. * that they implement com.sun.org.apache.xerces.internal.dom.NodeImpl.
  46. *
  47. * @param node The node to be tested.
  48. *
  49. * @throws TransformerException if the node is not one which this
  50. * DOM2Helper can support. If we return without throwing the exception,
  51. * the node is compatable.
  52. * @xsl.usage internal
  53. */
  54. public void checkNode(Node node) throws TransformerException
  55. {
  56. // if(!(node instanceof com.sun.org.apache.xerces.internal.dom.NodeImpl))
  57. // throw new TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_XERCES_CANNOT_HANDLE_NODES, new Object[]{((Object)node).getClass()})); //"DOM2Helper can not handle nodes of type"
  58. //+((Object)node).getClass());
  59. }
  60. /**
  61. * Returns true if the DOM implementation handled by this helper
  62. * supports the SAX ContentHandler interface.
  63. *
  64. * @return true (since Xerces does).
  65. */
  66. public boolean supportsSAX()
  67. {
  68. return true;
  69. }
  70. /** Field m_doc: Document Node for the document this helper is currently
  71. * accessing or building
  72. * @see #setDocument
  73. * @see #getDocument
  74. * */
  75. private Document m_doc;
  76. /**
  77. * Specify which document this helper is currently operating on.
  78. *
  79. * @param doc The DOM Document node for this document.
  80. * @see #getDocument
  81. */
  82. public void setDocument(Document doc)
  83. {
  84. m_doc = doc;
  85. }
  86. /**
  87. * Query which document this helper is currently operating on.
  88. *
  89. * @return The DOM Document node for this document.
  90. * @see #setDocument
  91. */
  92. public Document getDocument()
  93. {
  94. return m_doc;
  95. }
  96. /**
  97. * Parse an XML document.
  98. *
  99. * <p>Right now the Xerces DOMParser class is used. This needs
  100. * fixing, either via jaxp, or via some other, standard method.</p>
  101. *
  102. * <p>The application can use this method to instruct the SAX parser
  103. * to begin parsing an XML document from any valid input
  104. * source (a character stream, a byte stream, or a URI).</p>
  105. *
  106. * <p>Applications may not invoke this method while a parse is in
  107. * progress (they should create a new Parser instead for each
  108. * additional XML document). Once a parse is complete, an
  109. * application may reuse the same Parser object, possibly with a
  110. * different input source.</p>
  111. *
  112. * @param source The input source for the top-level of the
  113. * XML document.
  114. *
  115. * @throws TransformerException if any checked exception is thrown.
  116. * @xsl.usage internal
  117. */
  118. public void parse(InputSource source) throws TransformerException
  119. {
  120. try
  121. {
  122. // I guess I should use JAXP factory here... when it's legal.
  123. // com.sun.org.apache.xerces.internal.parsers.DOMParser parser
  124. // = new com.sun.org.apache.xerces.internal.parsers.DOMParser();
  125. DocumentBuilderFactory builderFactory =
  126. DocumentBuilderFactory.newInstance();
  127. builderFactory.setNamespaceAware(true);
  128. builderFactory.setValidating(true);
  129. DocumentBuilder parser = builderFactory.newDocumentBuilder();
  130. /*
  131. // domParser.setFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes", getShouldExpandEntityRefs()? false : true);
  132. if(m_useDOM2getNamespaceURI)
  133. {
  134. parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", true);
  135. parser.setFeature("http://xml.org/sax/features/namespaces", true);
  136. }
  137. else
  138. {
  139. parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false);
  140. }
  141. parser.setFeature("http://apache.org/xml/features/allow-java-encodings", true);
  142. */
  143. parser.setErrorHandler(
  144. new com.sun.org.apache.xml.internal.utils.DefaultErrorHandler());
  145. // if(null != m_entityResolver)
  146. // {
  147. // System.out.println("Setting the entity resolver.");
  148. // parser.setEntityResolver(m_entityResolver);
  149. // }
  150. setDocument(parser.parse(source));
  151. }
  152. catch (org.xml.sax.SAXException se)
  153. {
  154. throw new TransformerException(se);
  155. }
  156. catch (ParserConfigurationException pce)
  157. {
  158. throw new TransformerException(pce);
  159. }
  160. catch (IOException ioe)
  161. {
  162. throw new TransformerException(ioe);
  163. }
  164. // setDocument(((com.sun.org.apache.xerces.internal.parsers.DOMParser)parser).getDocument());
  165. }
  166. /**
  167. * Given an XML ID, return the element. This requires assistance from the
  168. * DOM and parser, and is meaningful only in the context of a DTD
  169. * or schema which declares attributes as being of type ID. This
  170. * information may or may not be available in all parsers, may or
  171. * may not be available for specific documents, and may or may not
  172. * be available when validation is not turned on.
  173. *
  174. * @param id The ID to search for, as a String.
  175. * @param doc The document to search within, as a DOM Document node.
  176. * @return DOM Element node with an attribute of type ID whose value
  177. * uniquely matches the requested id string, or null if there isn't
  178. * such an element or if the DOM can't answer the question for other
  179. * reasons.
  180. */
  181. public Element getElementByID(String id, Document doc)
  182. {
  183. return doc.getElementById(id);
  184. }
  185. /**
  186. * Figure out whether node2 should be considered as being later
  187. * in the document than node1, in Document Order as defined
  188. * by the XPath model. This may not agree with the ordering defined
  189. * by other XML applications.
  190. * <p>
  191. * There are some cases where ordering isn't defined, and neither are
  192. * the results of this function -- though we'll generally return true.
  193. * <p>
  194. * TODO: Make sure this does the right thing with attribute nodes!!!
  195. *
  196. * @param node1 DOM Node to perform position comparison on.
  197. * @param node2 DOM Node to perform position comparison on .
  198. *
  199. * @return false if node2 comes before node1, otherwise return true.
  200. * You can think of this as
  201. * <code>(node1.documentOrderPosition <= node2.documentOrderPosition)</code>.
  202. */
  203. public static boolean isNodeAfter(Node node1, Node node2)
  204. {
  205. // Assume first that the nodes are DTM nodes, since discovering node
  206. // order is massivly faster for the DTM.
  207. if(node1 instanceof DOMOrder && node2 instanceof DOMOrder)
  208. {
  209. int index1 = ((DOMOrder) node1).getUid();
  210. int index2 = ((DOMOrder) node2).getUid();
  211. return index1 <= index2;
  212. }
  213. else
  214. {
  215. // isNodeAfter will return true if node is after countedNode
  216. // in document order. The base isNodeAfter is sloooow (relatively).
  217. return DOMHelper.isNodeAfter(node1, node2);
  218. }
  219. }
  220. /**
  221. * Get the XPath-model parent of a node. This version takes advantage
  222. * of the DOM Level 2 Attr.ownerElement() method; the base version we
  223. * would otherwise inherit is prepared to fall back on exhaustively
  224. * walking the document to find an Attr's parent.
  225. *
  226. * @param node Node to be examined
  227. *
  228. * @return the DOM parent of the input node, if there is one, or the
  229. * ownerElement if the input node is an Attr, or null if the node is
  230. * a Document, a DocumentFragment, or an orphan.
  231. */
  232. public static Node getParentOfNode(Node node)
  233. {
  234. Node parent=node.getParentNode();
  235. if(parent==null && (Node.ATTRIBUTE_NODE == node.getNodeType()) )
  236. parent=((Attr) node).getOwnerElement();
  237. return parent;
  238. }
  239. /**
  240. * Returns the local name of the given node, as defined by the
  241. * XML Namespaces specification. This is prepared to handle documents
  242. * built using DOM Level 1 methods by falling back upon explicitly
  243. * parsing the node name.
  244. *
  245. * @param n Node to be examined
  246. *
  247. * @return String containing the local name, or null if the node
  248. * was not assigned a Namespace.
  249. */
  250. public String getLocalNameOfNode(Node n)
  251. {
  252. String name = n.getLocalName();
  253. return (null == name) ? super.getLocalNameOfNode(n) : name;
  254. }
  255. /**
  256. * Returns the Namespace Name (Namespace URI) for the given node.
  257. * In a Level 2 DOM, you can ask the node itself. Note, however, that
  258. * doing so conflicts with our decision in getLocalNameOfNode not
  259. * to trust the that the DOM was indeed created using the Level 2
  260. * methods. If Level 1 methods were used, these two functions will
  261. * disagree with each other.
  262. * <p>
  263. * TODO: Reconcile with getLocalNameOfNode.
  264. *
  265. * @param n Node to be examined
  266. *
  267. * @return String containing the Namespace URI bound to this DOM node
  268. * at the time the Node was created.
  269. */
  270. public String getNamespaceOfNode(Node n)
  271. {
  272. return n.getNamespaceURI();
  273. }
  274. /** Field m_useDOM2getNamespaceURI is a compile-time flag which
  275. * gates some of the parser options used to build a DOM -- but
  276. * that code is commented out at this time and nobody else
  277. * references it, so I've commented this out as well. */
  278. //private boolean m_useDOM2getNamespaceURI = false;
  279. }