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