content: /*
   *  This file is part of AndroidIDE.
   *
   *  AndroidIDE is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation, either version 3 of the License, or
   *  (at your option) any later version.
   *
   *  AndroidIDE is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *   along with AndroidIDE.  If not, see <https://www.gnu.org/licenses/>.
   */
  
  /*
   * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Oracle in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
  package jaxp.sun.org.apache.xalan.internal.xsltc.trax;
  
  import java.io.IOException;
  
  import org.xml.sax.Attributes;
  import org.xml.sax.ContentHandler;
  import org.xml.sax.DTDHandler;
  import org.xml.sax.EntityResolver;
  import org.xml.sax.ErrorHandler;
  import org.xml.sax.InputSource;
  import org.xml.sax.Locator;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXNotRecognizedException;
  import org.xml.sax.SAXNotSupportedException;
  import org.xml.sax.XMLReader;
  import org.xml.sax.ext.LexicalHandler;
  import org.xml.sax.ext.Locator2;
  import org.xml.sax.helpers.AttributesImpl;
  import jaxp.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl;
  
  
  
  import jaxp.xml.namespace.QName;
  import jaxp.xml.stream.XMLStreamReader;
  import jaxp.xml.stream.XMLStreamConstants;
  import jaxp.xml.stream.XMLStreamException;
  
  
  /**
   * @author Padmaja Vedula
   * @author Sunitha Reddy
   */
  public class StAXStream2SAX implements XMLReader, Locator {
  
      //private final static String EMPTYSTRING = "";
      //private static final String XMLNS_PREFIX = "xmlns";
  
      // StAX Stream source
      private final XMLStreamReader staxStreamReader;
  
      //private Node _dom = null;
      private ContentHandler _sax = null;
      private LexicalHandler _lex = null;
      private SAXImpl _saxImpl = null;
      //private Hashtable _nsPrefixes = new Hashtable();
  
      public StAXStream2SAX(XMLStreamReader staxSrc) {
              staxStreamReader = staxSrc;
      }
  
      public ContentHandler getContentHandler() {
          return _sax;
      }
  
      public void setContentHandler(ContentHandler handler) throws
          NullPointerException
      {
          _sax = handler;
          if (handler instanceof LexicalHandler) {
              _lex = (LexicalHandler) handler;
          }
  
          if (handler instanceof SAXImpl) {
              _saxImpl = (SAXImpl)handler;
          }
      }
  
  
      public void parse(InputSource unused) throws IOException, SAXException {
          try {
              bridge();
          } catch (XMLStreamException e) {
              throw new SAXException(e);
          }
      }
  
  
      //Main Work Starts Here.
      public void parse() throws IOException, SAXException, XMLStreamException {
          bridge();
      }
  
  
     /**
       * This class is only used internally so this method should never
       * be called.
       */
      public void parse(String sysId) throws IOException, SAXException {
          throw new IOException("This method is not yet implemented.");
      }
  
  
     public void bridge() throws XMLStreamException {
  
          try {
              // remembers the nest level of elements to know when we are done.
              int depth=0;
  
              // skip over START_DOCUMENT
              int event = staxStreamReader.getEventType();
              if (event == XMLStreamConstants.START_DOCUMENT) {
                  event = staxStreamReader.next();
              }
  
              // If not a START_ELEMENT (e.g., a DTD), skip to next tag
              if (event != XMLStreamConstants.START_ELEMENT) {
                  event = staxStreamReader.nextTag();
                  // An error if a START_ELEMENT isn't found now
                  if (event != XMLStreamConstants.START_ELEMENT) {
                      throw new IllegalStateException("The current event is " +
                              "not START_ELEMENT\n but" + event);
                  }
              }
  
              handleStartDocument();
  
              do {
                  // These are all of the events listed in the javadoc for
                  // XMLEvent.
                  // The spec only really describes 11 of them.
                  switch (event) {
                      case XMLStreamConstants.START_ELEMENT :
                          depth++;
                          handleStartElement();
                          break;
                      case XMLStreamConstants.END_ELEMENT :
                          handleEndElement();
                          depth--;
                          break;
                      case XMLStreamConstants.CHARACTERS :
                          handleCharacters();
                          break;
                      case XMLStreamConstants.ENTITY_REFERENCE :
                          handleEntityReference();
                          break;
                      case XMLStreamConstants.PROCESSING_INSTRUCTION :
                          handlePI();
                          break;
                      case XMLStreamConstants.COMMENT :
                          handleComment();
                          break;
                      case XMLStreamConstants.DTD :
                          handleDTD();
                          break;
                      case XMLStreamConstants.ATTRIBUTE :
                          handleAttribute();
                          break;
                      case XMLStreamConstants.NAMESPACE :
                          handleNamespace();
                          break;
                      case XMLStreamConstants.CDATA :
                          handleCDATA();
                          break;
                      case XMLStreamConstants.ENTITY_DECLARATION :
                          handleEntityDecl();
                          break;
                      case XMLStreamConstants.NOTATION_DECLARATION :
                          handleNotationDecl();
                          break;
                      case XMLStreamConstants.SPACE :
                          handleSpace();
                          break;
                      default :
                          throw new InternalError("processing event: " + event);
                  }
  
                  event=staxStreamReader.next();
              } while (depth!=0);
  
              handleEndDocument();
          } catch (SAXException e) {
              throw new XMLStreamException(e);
          }
      }
  
      private void handleEndDocument() throws SAXException {
          _sax.endDocument();
      }
  
      private void handleStartDocument() throws SAXException {
          _sax.setDocumentLocator(new Locator2() {
              public int getColumnNumber() {
                  return staxStreamReader.getLocation().getColumnNumber();
              }
              public int getLineNumber() {
                  return staxStreamReader.getLocation().getLineNumber();
              }
              public String getPublicId() {
                  return staxStreamReader.getLocation().getPublicId();
              }
              public String getSystemId() {
                  return staxStreamReader.getLocation().getSystemId();
              }
              public String getXMLVersion() {
                  return staxStreamReader.getVersion();
              }
              public String getEncoding() {
                  return staxStreamReader.getEncoding();
              }
           });
          _sax.startDocument();
      }
  
      private void handlePI() throws XMLStreamException {
          try {
              _sax.processingInstruction(
                  staxStreamReader.getPITarget(),
                  staxStreamReader.getPIData());
          } catch (SAXException e) {
              throw new XMLStreamException(e);
          }
      }
  
      private void handleCharacters() throws XMLStreamException {
  
          // workaround for bugid 5046319 - switch over to commented section
          // below when it is fixed.
          int textLength = staxStreamReader.getTextLength();
          char[] chars = new char[textLength];
  
          staxStreamReader.getTextCharacters(0, chars, 0, textLength);
  
          try {
              _sax.characters(chars, 0, chars.length);
          } catch (SAXException e) {
              throw new XMLStreamException(e);
          }
  
  
  //        int start = 0;
  //        int len;
  //        do {
  //            len = staxStreamReader.getTextCharacters(start, buf, 0, buf.length);
  //            start += len;
  //            try {
  //                _sax.characters(buf, 0, len);
  //            } catch (SAXException e) {
  //                throw new XMLStreamException(e);
  //            }
  //        } while (len == buf.length);
      }
  
      private void handleEndElement() throws XMLStreamException {
          QName qName = staxStreamReader.getName();
  
          try {
              //construct prefix:localName from qName
              String qname = "";
              if (qName.getPrefix() != null && qName.getPrefix().trim().length() != 0){
                  qname = qName.getPrefix() + ":";
              }
              qname += qName.getLocalPart();
  
              // fire endElement
              _sax.endElement(
                  qName.getNamespaceURI(),
                  qName.getLocalPart(),
                  qname);
  
              // end namespace bindings
              int nsCount = staxStreamReader.getNamespaceCount();
              for (int i = nsCount - 1; i >= 0; i--) {
                  String prefix = staxStreamReader.getNamespacePrefix(i);
                  if (prefix == null) { // true for default namespace
                      prefix = "";
                  }
                  _sax.endPrefixMapping(prefix);
              }
          } catch (SAXException e) {
              throw new XMLStreamException(e);
          }
      }
  
      private void handleStartElement() throws XMLStreamException {
  
          try {
              // start namespace bindings
              int nsCount = staxStreamReader.getNamespaceCount();
              for (int i = 0; i < nsCount; i++) {
                  String prefix = staxStreamReader.getNamespacePrefix(i);
                  if (prefix == null) { // true for default namespace
                      prefix = "";
                  }
                  _sax.startPrefixMapping(
                      prefix,
                      staxStreamReader.getNamespaceURI(i));
              }
  
              // fire startElement
              QName qName = staxStreamReader.getName();
              String prefix = qName.getPrefix();
              String rawname;
              if(prefix==null || prefix.length()==0)
                  rawname = qName.getLocalPart();
              else
                  rawname = prefix + ':' + qName.getLocalPart();
              Attributes attrs = getAttributes();
              _sax.startElement(
                  qName.getNamespaceURI(),
                  qName.getLocalPart(),
                  rawname,
                  attrs);
          } catch (SAXException e) {
              throw new XMLStreamException(e);
          }
      }
  
      /**
       * Get the attributes associated with the given START_ELEMENT or ATTRIBUTE
       * StAXevent.
       *
       * @return the StAX attributes converted to an org.xml.sax.Attributes
       */
      private Attributes getAttributes() {
          AttributesImpl attrs = new AttributesImpl();
  
          int eventType = staxStreamReader.getEventType();
          if (eventType != XMLStreamConstants.ATTRIBUTE
              && eventType != XMLStreamConstants.START_ELEMENT) {
              throw new InternalError(
                  "getAttributes() attempting to process: " + eventType);
          }
  
          // in SAX, namespace declarations are not part of attributes by default.
          // (there's a property to control that, but as far as we are concerned
          // we don't use it.) So don't add xmlns:* to attributes.
  
          // gather non-namespace attrs
          for (int i = 0; i < staxStreamReader.getAttributeCount(); i++) {
              String uri = staxStreamReader.getAttributeNamespace(i);
              if(uri==null)   uri="";
              String localName = staxStreamReader.getAttributeLocalName(i);
              String prefix = staxStreamReader.getAttributePrefix(i);
              String qName;
              if(prefix==null || prefix.length()==0)
                  qName = localName;
              else
                  qName = prefix + ':' + localName;
              String type = staxStreamReader.getAttributeType(i);
              String value = staxStreamReader.getAttributeValue(i);
  
              attrs.addAttribute(uri, localName, qName, type, value);
          }
  
          return attrs;
      }
  
      private void handleNamespace() {
          // no-op ???
          // namespace events don't normally occur outside of a startElement
          // or endElement
      }
  
      private void handleAttribute() {
          // no-op ???
          // attribute events don't normally occur outside of a startElement
          // or endElement
      }
  
      private void handleDTD() {
          // no-op ???
          // it seems like we need to pass this info along, but how?
      }
  
      private void handleComment() {
          // no-op ???
      }
  
      private void handleEntityReference() {
          // no-op ???
      }
  
      private void handleSpace() {
          // no-op ???
          // this event is listed in the javadoc, but not in the spec.
      }
  
      private void handleNotationDecl() {
          // no-op ???
          // this event is listed in the javadoc, but not in the spec.
      }
  
      private void handleEntityDecl() {
          // no-op ???
          // this event is listed in the javadoc, but not in the spec.
      }
  
      private void handleCDATA() {
          // no-op ???
          // this event is listed in the javadoc, but not in the spec.
      }
  
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public DTDHandler getDTDHandler() {
          return null;
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public ErrorHandler getErrorHandler() {
          return null;
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public boolean getFeature(String name) throws SAXNotRecognizedException,
          SAXNotSupportedException
      {
          return false;
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public void setFeature(String name, boolean value) throws
          SAXNotRecognizedException, SAXNotSupportedException
      {
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public void setDTDHandler(DTDHandler handler) throws NullPointerException {
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public void setEntityResolver(EntityResolver resolver) throws
          NullPointerException
      {
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public EntityResolver getEntityResolver() {
          return null;
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public void setErrorHandler(ErrorHandler handler) throws
          NullPointerException
      {
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public void setProperty(String name, Object value) throws
          SAXNotRecognizedException, SAXNotSupportedException {
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public Object getProperty(String name) throws SAXNotRecognizedException,
          SAXNotSupportedException
      {
          return null;
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public int getColumnNumber() {
          return 0;
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public int getLineNumber() {
          return 0;
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public String getPublicId() {
          return null;
      }
  
      /**
       * This class is only used internally so this method should never
       * be called.
       */
      public String getSystemId() {
          return null;
      }
  
  }
  