Save This Page
Home » openjdk-7 » com.sun.org.apache.xalan » internal » xsltc » trax » [javadoc | source]
    1   /*
    2    * reserved comment block
    3    * DO NOT REMOVE OR ALTER!
    4    */
    5   /*
    6    * Copyright 2001-2004 The Apache Software Foundation.
    7    *
    8    * Licensed under the Apache License, Version 2.0 (the "License");
    9    * you may not use this file except in compliance with the License.
   10    * You may obtain a copy of the License at
   11    *
   12    *     http://www.apache.org/licenses/LICENSE-2.0
   13    *
   14    * Unless required by applicable law or agreed to in writing, software
   15    * distributed under the License is distributed on an "AS IS" BASIS,
   16    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   17    * See the License for the specific language governing permissions and
   18    * limitations under the License.
   19    */
   20   /*
   21    * $Id: SAX2DOM.java,v 1.7 2006/01/26 07:01:40 jeffsuttor Exp $
   22    */
   23   
   24   
   25   package com.sun.org.apache.xalan.internal.xsltc.trax;
   26   
   27   import java.util.Stack;
   28   import java.util.Vector;
   29   
   30   import javax.xml.parsers.DocumentBuilderFactory;
   31   import javax.xml.parsers.ParserConfigurationException;
   32   
   33   import com.sun.org.apache.xalan.internal.xsltc.runtime.Constants;
   34   
   35   import org.w3c.dom.Comment;
   36   import org.w3c.dom.Document;
   37   import org.w3c.dom.Element;
   38   import org.w3c.dom.Node;
   39   import org.w3c.dom.Text;
   40   import org.w3c.dom.ProcessingInstruction;
   41   import org.xml.sax.Attributes;
   42   import org.xml.sax.ContentHandler;
   43   import org.xml.sax.Locator;
   44   import org.xml.sax.SAXException;
   45   import org.xml.sax.ext.LexicalHandler;
   46   import org.xml.sax.ext.Locator2;
   47   
   48   /**
   49    * @author G. Todd Miller
   50    * @author Sunitha Reddy
   51    */
   52   public class SAX2DOM implements ContentHandler, LexicalHandler, Constants {
   53   
   54       private Node _root = null;
   55       private Document _document = null;
   56       private Node _nextSibling = null;
   57       private Stack _nodeStk = new Stack();
   58       private Vector _namespaceDecls = null;
   59       private Node _lastSibling = null;
   60       private Locator locator = null;
   61       private boolean needToSetDocumentInfo = true;
   62   
   63       /**
   64        * JAXP document builder factory. Create a single instance and use
   65        * synchronization because the Javadoc is not explicit about
   66        * thread safety.
   67        */
   68       static final DocumentBuilderFactory _factory =
   69               DocumentBuilderFactory.newInstance();
   70   
   71       public SAX2DOM() throws ParserConfigurationException {
   72           synchronized (SAX2DOM.class) {
   73             _document = _factory.newDocumentBuilder().newDocument();
   74           }
   75           _root = _document;
   76       }
   77   
   78       public SAX2DOM(Node root, Node nextSibling) throws ParserConfigurationException {
   79           _root = root;
   80           if (root instanceof Document) {
   81             _document = (Document)root;
   82           }
   83           else if (root != null) {
   84             _document = root.getOwnerDocument();
   85           }
   86           else {
   87             synchronized (SAX2DOM.class) {
   88                 _document = _factory.newDocumentBuilder().newDocument();
   89             }
   90             _root = _document;
   91           }
   92   
   93           _nextSibling = nextSibling;
   94       }
   95   
   96       public SAX2DOM(Node root) throws ParserConfigurationException {
   97           this(root, null);
   98       }
   99   
  100       public Node getDOM() {
  101           return _root;
  102       }
  103   
  104       public void characters(char[] ch, int start, int length) {
  105           // Ignore text nodes of length 0
  106           if (length == 0) {
  107               return;
  108           }
  109   
  110           final Node last = (Node)_nodeStk.peek();
  111   
  112           // No text nodes can be children of root (DOM006 exception)
  113           if (last != _document) {
  114               final String text = new String(ch, start, length);
  115               if( _lastSibling != null && _lastSibling.getNodeType() == Node.TEXT_NODE ){
  116                     ((Text)_lastSibling).appendData(text);
  117               }
  118               else if (last == _root && _nextSibling != null) {
  119                   _lastSibling = last.insertBefore(_document.createTextNode(text), _nextSibling);
  120               }
  121               else {
  122                   _lastSibling = last.appendChild(_document.createTextNode(text));
  123               }
  124           }
  125       }
  126   
  127       public void startDocument() {
  128           _nodeStk.push(_root);
  129       }
  130   
  131       public void endDocument() {
  132           _nodeStk.pop();
  133       }
  134   
  135       private void setDocumentInfo() {
  136           //try to set document version
  137           if (locator == null) return;
  138           try{
  139               _document.setXmlVersion(((Locator2)locator).getXMLVersion());
  140           }catch(ClassCastException e){}
  141   
  142       }
  143   
  144       public void startElement(String namespace, String localName, String qName,
  145           Attributes attrs)
  146       {
  147   
  148           if (needToSetDocumentInfo) {
  149               setDocumentInfo();
  150               needToSetDocumentInfo = false;
  151           }
  152   
  153           final Element tmp = (Element)_document.createElementNS(namespace, qName);
  154   
  155           // Add namespace declarations first
  156           if (_namespaceDecls != null) {
  157               final int nDecls = _namespaceDecls.size();
  158               for (int i = 0; i < nDecls; i++) {
  159                   final String prefix = (String) _namespaceDecls.elementAt(i++);
  160   
  161                   if (prefix == null || prefix.equals(EMPTYSTRING)) {
  162                       tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX,
  163                           (String) _namespaceDecls.elementAt(i));
  164                   }
  165                   else {
  166                       tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix,
  167                           (String) _namespaceDecls.elementAt(i));
  168                   }
  169               }
  170               _namespaceDecls.clear();
  171           }
  172   
  173           // Add attributes to element
  174   /*      final int nattrs = attrs.getLength();
  175           for (int i = 0; i < nattrs; i++) {
  176               if (attrs.getLocalName(i) == null) {
  177                   tmp.setAttribute(attrs.getQName(i), attrs.getValue(i));
  178               }
  179               else {
  180                   tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i),
  181                       attrs.getValue(i));
  182               }
  183           } */
  184   
  185   
  186           // Add attributes to element
  187           final int nattrs = attrs.getLength();
  188           for (int i = 0; i < nattrs; i++) {
  189               // checking if Namespace processing is being done
  190               String attQName = attrs.getQName(i);
  191               String attURI = attrs.getURI(i);
  192               if (attrs.getLocalName(i).equals("")) {
  193                   tmp.setAttribute(attQName, attrs.getValue(i));
  194                   if (attrs.getType(i).equals("ID")) {
  195                       tmp.setIdAttribute(attQName, true);
  196                   }
  197               } else {
  198                   tmp.setAttributeNS(attURI, attQName, attrs.getValue(i));
  199                   if (attrs.getType(i).equals("ID")) {
  200                       tmp.setIdAttributeNS(attURI, attrs.getLocalName(i), true);
  201                   }
  202               }
  203           }
  204   
  205   
  206           // Append this new node onto current stack node
  207           Node last = (Node)_nodeStk.peek();
  208   
  209           // If the SAX2DOM is created with a non-null next sibling node,
  210           // insert the result nodes before the next sibling under the root.
  211           if (last == _root && _nextSibling != null)
  212               last.insertBefore(tmp, _nextSibling);
  213           else
  214               last.appendChild(tmp);
  215   
  216           // Push this node onto stack
  217           _nodeStk.push(tmp);
  218           _lastSibling = null;
  219       }
  220   
  221       public void endElement(String namespace, String localName, String qName) {
  222           _nodeStk.pop();
  223           _lastSibling = null;
  224       }
  225   
  226       public void startPrefixMapping(String prefix, String uri) {
  227           if (_namespaceDecls == null) {
  228               _namespaceDecls = new Vector(2);
  229           }
  230           _namespaceDecls.addElement(prefix);
  231           _namespaceDecls.addElement(uri);
  232       }
  233   
  234       public void endPrefixMapping(String prefix) {
  235           // do nothing
  236       }
  237   
  238       /**
  239        * This class is only used internally so this method should never
  240        * be called.
  241        */
  242       public void ignorableWhitespace(char[] ch, int start, int length) {
  243       }
  244   
  245       /**
  246        * adds processing instruction node to DOM.
  247        */
  248       public void processingInstruction(String target, String data) {
  249           final Node last = (Node)_nodeStk.peek();
  250           ProcessingInstruction pi = _document.createProcessingInstruction(
  251                   target, data);
  252           if (pi != null){
  253             if (last == _root && _nextSibling != null)
  254                 last.insertBefore(pi, _nextSibling);
  255             else
  256                 last.appendChild(pi);
  257   
  258             _lastSibling = pi;
  259           }
  260       }
  261   
  262       /**
  263        * This class is only used internally so this method should never
  264        * be called.
  265        */
  266       public void setDocumentLocator(Locator locator) {
  267           this.locator = locator;
  268       }
  269   
  270       /**
  271        * This class is only used internally so this method should never
  272        * be called.
  273        */
  274       public void skippedEntity(String name) {
  275       }
  276   
  277   
  278       /**
  279        * Lexical Handler method to create comment node in DOM tree.
  280        */
  281       public void comment(char[] ch, int start, int length) {
  282           final Node last = (Node)_nodeStk.peek();
  283           Comment comment = _document.createComment(new String(ch,start,length));
  284           if (comment != null){
  285             if (last == _root && _nextSibling != null)
  286                 last.insertBefore(comment, _nextSibling);
  287             else
  288                 last.appendChild(comment);
  289   
  290             _lastSibling = comment;
  291           }
  292       }
  293   
  294       // Lexical Handler methods- not implemented
  295       public void startCDATA() { }
  296       public void endCDATA() { }
  297       public void startEntity(java.lang.String name) { }
  298       public void endDTD() { }
  299       public void endEntity(String name) { }
  300       public void startDTD(String name, String publicId, String systemId)
  301           throws SAXException {}
  302   }

Save This Page
Home » openjdk-7 » com.sun.org.apache.xalan » internal » xsltc » trax » [javadoc | source]