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