All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mule.service.soap.xml.stax.StaxSource Maven / Gradle / Ivy

/*
 * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */
package org.mule.service.soap.xml.stax;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

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.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;

import javanet.staxutils.StAXReaderToContentHandler;
import javanet.staxutils.StAXSource;
import javanet.staxutils.helpers.XMLFilterImplEx;

/**
 * A StaxSource which gives us access to the underlying XMLStreamReader if we are StaxCapable down the line.
 * 
 * @since 1.0, Copied from the removed XML module.
 */
public class StaxSource extends StAXSource {

  private XMLStreamReader reader;

  // StAX to SAX converter that will read from StAX and produce SAX
  // this object will be wrapped by the XMLReader exposed to the client
  protected final StAXReaderToContentHandler handler;

  // SAX allows ContentHandler to be changed during the parsing,
  // but JAXB doesn't. So this repeater will sit between those
  // two components.
  protected XMLFilterImplEx repeater = new XMLFilterImplEx();

  protected final XMLReader pseudoParser = new PseudoReader();

  public StaxSource(XMLStreamReader reader) {
    super(reader);

    this.reader = reader;

    this.handler = new XMLStreamReaderToContentHandler(reader, repeater);

    super.setXMLReader(pseudoParser);
    // pass a dummy InputSource. We don't care
    super.setInputSource(new InputSource());
  }

  public XMLStreamReader getXMLStreamReader() {
    return reader;
  }

  private final class PseudoReader implements XMLReader {

    // we will store this value but never use it by ourselves.
    private EntityResolver entityResolver;
    private DTDHandler dtdHandler;
    private ErrorHandler errorHandler;

    @Override
    public boolean getFeature(String name) throws SAXNotRecognizedException {
      if ("http://xml.org/sax/features/namespaces".equals(name)) {
        return true;
      } else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) {
        return repeater.getNamespacePrefixes();
      } else if ("http://xml.org/sax/features/external-general-entities".equals(name)) {
        return true;
      } else if ("http://xml.org/sax/features/external-parameter-entities".equals(name)) {
        return true;
      }

      throw new SAXNotRecognizedException(name);
    }

    @Override
    public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
      if ("http://xml.org/sax/features/namespaces".equals(name)) {
        // Presently we only support namespaces==true. [Issue 9]
        if (!value) {
          throw new SAXNotSupportedException(name);
        }
      } else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) {
        repeater.setNamespacePrefixes(value);
      } else if ("http://xml.org/sax/features/external-general-entities".equals(name)) {
        // Pass over, XOM likes to get this feature
      } else if ("http://xml.org/sax/features/external-parameter-entities".equals(name)) {
        // Pass over, XOM likes to get this feature
      } else if ("http://xml.org/sax/features/validation".equals(name)) {
        // Don't really make sense when using Stax
      } else {
        throw new SAXNotRecognizedException(name);
      }
    }

    @Override
    public Object getProperty(String name) throws SAXNotRecognizedException {
      if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
        return repeater.getLexicalHandler();
      }

      throw new SAXNotRecognizedException(name);
    }

    @Override
    public void setProperty(String name, Object value) throws SAXNotRecognizedException {
      if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
        repeater.setLexicalHandler((LexicalHandler) value);
      } else {
        throw new SAXNotRecognizedException(name);
      }
    }

    @Override
    public void setEntityResolver(EntityResolver resolver) {
      this.entityResolver = resolver;
    }

    @Override
    public EntityResolver getEntityResolver() {
      return entityResolver;
    }

    @Override
    public void setDTDHandler(DTDHandler handler) {
      this.dtdHandler = handler;
    }

    @Override
    public DTDHandler getDTDHandler() {
      return dtdHandler;
    }

    @Override
    public void setContentHandler(ContentHandler handler) {
      repeater.setContentHandler(handler);
    }

    @Override
    public ContentHandler getContentHandler() {
      return repeater.getContentHandler();
    }

    @Override
    public void setErrorHandler(ErrorHandler handler) {
      this.errorHandler = handler;
    }

    @Override
    public ErrorHandler getErrorHandler() {
      return errorHandler;
    }

    @Override
    public void parse(InputSource input) throws SAXException {
      parse();
    }

    @Override
    public void parse(String systemId) throws SAXException {
      parse();
    }

    public void parse() throws SAXException {
      // parses from a StAX reader and generates SAX events which
      // go through the repeater and are forwarded to the appropriate
      // component
      try {
        handler.bridge();
      } catch (XMLStreamException e) {
        // determine location
        int lineNumber = -1;
        int columnNumber = -1;
        if (e.getLocation() != null) {
          lineNumber = e.getLocation().getLineNumber();
          columnNumber = e.getLocation().getColumnNumber();
        }

        // wrap it in a SAXException
        SAXParseException se = new SAXParseException(e.getMessage(), null, null, lineNumber, columnNumber, e);

        // if the consumer sets an error handler, it is our responsibility
        // to notify it.
        if (errorHandler != null)
          errorHandler.fatalError(se);

        // this is a fatal error. Even if the error handler
        // returns, we will abort anyway.
        throw se;
      } finally {
        try {
          reader.close();
        } catch (XMLStreamException e) {
          throw new SAXException(e);
        }
      }
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy