Uploaded image for project: 'Spring Web Services'
  1. Spring Web Services
  2. SWS-265

AbstractStaxXmlReader should support the required standard SAX features (namespace, namespace-prefixes...)

    Details

    • Type: New Feature
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.0.3
    • Fix Version/s: 1.5 M2
    • Component/s: XML
    • Labels:
      None
    • Environment:
      Java 5 (build 1.5.0_13-b05-241) with Saxon 6.5.5 / 9.0.0.2 & Axiom 1.2.5

      Description

      XSLT processors (Saxon & Xalan) expect the SAX XMLReader provided by SAXSource implementations such as AbstractStaxXmlReader to support at least the required standard SAX features.
      AbstractStaxXmlReader (through its superclass AbstractXmlReader) throws a SAXNotRecognizedException when trying to read or set any feature.
      This prevents using Saxon as XSLT processor when using the Axiom stack.

      The following patch add support for reading and setting (to their default value only) most SAX default features, making Saxon accept the Axiom StAXSource :

      — ../spring-ws-1.0.3/modules/xml/src/main/java/org/springframework/xml/stream/AbstractStaxXmlReader.java 2007-12-21 16:26:18.000000000 +0100
      +++ AbstractStaxXmlReader.java 2008-01-08 16:10:17.000000000 +0100
      @@ -16,6 +16,9 @@

      package org.springframework.xml.stream;

      +import java.util.Map;
      +import java.util.HashMap;
      +
      import javax.xml.stream.Location;
      import javax.xml.stream.XMLStreamException;

      @@ -24,6 +27,9 @@
      import org.xml.sax.Locator;
      import org.xml.sax.SAXException;
      import org.xml.sax.SAXParseException;
      +import org.xml.sax.SAXNotRecognizedException;
      +import org.xml.sax.SAXNotSupportedException;
      +import org.xml.sax.ext.LexicalHandler;

      import org.springframework.xml.sax.AbstractXmlReader;

      @@ -39,6 +45,40 @@
      */
      public abstract class AbstractStaxXmlReader extends AbstractXmlReader {

      + private final static String[][] DEFAULT_FEATURES = {
      +

      { "http://xml.org/sax/features/validation", "false" }

      ,
      +

      { "http://xml.org/sax/features/namespaces", "true" }

      ,
      +

      { "http://xml.org/sax/features/namespace-prefixes", "false" }

      ,
      +
      +

      { "http://xml.org/sax/features/external-general-entities", "true" }

      ,
      +

      { "http://xml.org/sax/features/external-parameter-entities", "true" }

      ,
      +

      { "http://xml.org/sax/features/lexical-handler/parameter-entities", "false" }

      ,
      +
      +

      { "http://xml.org/sax/features/resolve-dtd-uris", "true" }

      ,
      +

      { "http://xml.org/sax/features/string-interning", "false" }

      ,
      +

      { "http://xml.org/sax/features/unicode-normalization-checking", "false" }

      ,
      +
      +

      { "http://xml.org/sax/features/use-attributes2", "false" }

      ,
      +

      { "http://xml.org/sax/features/use-locator2", "false" }

      ,
      +

      { "http://xml.org/sax/features/use-entity-resolver2", "false" }

      ,
      +

      { "http://xml.org/sax/features/xmlns-uris", "false" }

      ,
      +

      { "http://xml.org/sax/features/xml-1.1", "false" }

      + };
      +
      + private final static Object[][] DEFAULT_PROPERTIES = {
      +

      { "http://xml.org/sax/properties/lexical-handler", null }

      ,
      +

      { "http://xml.org/sax/properties/document-xml-version", "1.0" }

      + };
      +
      + private final Map saxFeatures = new HashMap();
      + private final Map saxProps = new HashMap();
      +
      + public AbstractStaxXmlReader()
      +

      { + this.initSaxFeatures(); + this.initSaxProperties(); + }

      +
      /**

      • Parses the StAX XML reader passed at construction-time.
      • <p/>
        @@ -97,6 +137,102 @@
        /** Template-method that parses the StAX reader passed at construction-time. */
        protected abstract void parseInternal() throws SAXException, XMLStreamException;

      +
      + public void setLexicalHandler(LexicalHandler lexicalHandler)
      + {
      + super.setLexicalHandler(lexicalHandler);
      +
      + try
      +

      { + this.internalSetProperty( + "http://xml.org/sax/properties/lexical-handler", + lexicalHandler); + }

      + catch (SAXException e)

      { /* Ignore... */ }

      + }
      +
      + public boolean getFeature(String name)
      + throws SAXNotRecognizedException, SAXNotSupportedException
      + {
      + if (this.saxFeatures.containsKey(name))
      +

      { + return ((Boolean)(this.saxFeatures.get(name))).booleanValue(); + }

      + else
      +

      { + // Chaning feature values is not supported. + throw new SAXNotRecognizedException(name); + }

      + }
      +
      + public void setFeature(String name, boolean value)
      + throws SAXNotRecognizedException, SAXNotSupportedException
      + {
      + if (value != this.getFeature(name)) // Takes care of unsupp. features
      +

      { + throw new SAXNotSupportedException(name); + }

      + }
      +
      + public Object getProperty(String name)
      + throws SAXNotRecognizedException, SAXNotSupportedException
      + {
      + if (this.saxProps.containsKey(name))
      +

      { + return this.saxProps.get(name); + }

      + else
      +

      { + throw new SAXNotRecognizedException(name); + }

      + }
      +
      + public void setProperty(String name, Object value)
      + throws SAXNotRecognizedException, SAXNotSupportedException
      + {
      + if (("http://xml.org/sax/properties/lexical-handler".equals(name)) &&
      + (value instanceof LexicalHandler))
      +

      { + this.setLexicalHandler((LexicalHandler)value); + }

      + else
      +

      { + this.internalSetProperty(name, value); + }

      + }
      +
      +
      + private void initSaxFeatures()
      + {
      + for (int i=0; i<DEFAULT_FEATURES.length; i++)
      +

      { + this.saxFeatures.put(DEFAULT_FEATURES[i][0], + Boolean.valueOf(DEFAULT_FEATURES[i][1])); + }

      + }
      +
      + private void initSaxProperties()
      + {
      + for (int i=0; i<DEFAULT_PROPERTIES.length; i++)
      +

      { + this.saxProps.put(DEFAULT_PROPERTIES[i][0], + DEFAULT_PROPERTIES[i][1]); + }

      + }
      +
      + public void internalSetProperty(String name, Object value)
      + throws SAXNotRecognizedException, SAXNotSupportedException
      + {
      + Object oldValue = this.getProperty(name);
      + // Takes care of unsupported properties
      + if (((value == null) && (oldValue != null)) ||
      + ((value != null) && (value.equals(oldValue) == false)))
      +

      { + // Chaning property values is not supported. + throw new SAXNotSupportedException(name); + }

      + }
      +
      /**

      • Implementation of the <code>Locator</code> interface that is based on a StAX <code>Location</code>.
        *

        Attachments

          Activity

            People

            • Assignee:
              arjen.poutsma Arjen Poutsma
              Reporter:
              lbihanic Laurent Bihanic
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: