Package org.springframework.ws.soap.axiom

Source Code of org.springframework.ws.soap.axiom.AxiomHandler

/*
* Copyright 2005-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.ws.soap.axiom;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;

import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMContainer;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;

import org.springframework.util.Assert;
import org.springframework.xml.namespace.QNameUtils;

/**
* Specific SAX {@link ContentHandler} and {@link LexicalHandler} that adds the resulting
* AXIOM OMElement to a specified parent element when {@code endDocument} is called.
* Used for returing {@code SAXResult}s from Axiom elements.
* @author Arjen Poutsma
* @since 1.0.0
*/
class AxiomHandler implements ContentHandler, LexicalHandler {

  private final OMFactory factory;

  private final List<OMContainer> elements = new ArrayList<OMContainer>();

  private final OMContainer container;

  private int charactersType = XMLStreamConstants.CHARACTERS;

  private List<Map<String, String>> namespaceMappings =
      new ArrayList<Map<String, String>>();

  AxiomHandler(OMContainer container, OMFactory factory) {
    Assert.notNull(container, "'container' must not be null");
    Assert.notNull(factory, "'factory' must not be null");
    this.factory = factory;
    this.container = container;
  }

  private OMContainer getParent() {
    if (!elements.isEmpty()) {
      return elements.get(elements.size() - 1);
    }
    else {
      return container;
    }
  }

  @Override
  public void startDocument() throws SAXException {
    removeAllNamespaceMappings();
    newNamespaceMapping();
  }

  @Override
  public void endDocument() throws SAXException {
    removeAllNamespaceMappings();
  }

  @Override
  public void startPrefixMapping(String prefix, String uri) throws SAXException {
    currentNamespaceMapping().put(prefix, uri);
  }

  @Override
  public void endPrefixMapping(String prefix) throws SAXException {
  }

  @Override
  public void startElement(String uri, String localName, String qName,
      Attributes attributes) throws SAXException {
    OMContainer parent = getParent();
    OMNamespace ns = factory.createOMNamespace(uri,
        QNameUtils.toQName(uri, qName).getPrefix());
    OMElement element = factory.createOMElement(localName, ns, parent);

    // declare namespaces
    Map<String, String> namespaceMappings = currentNamespaceMapping();
    for (Map.Entry<String, String> entry : namespaceMappings.entrySet()) {
      String prefix = entry.getKey();
      String namespaceUri = entry.getValue();

      if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) {
        element.declareDefaultNamespace(namespaceUri);
      } else {
        element.declareNamespace(namespaceUri, prefix);
      }
    }
    // declare attributes
    for (int i = 0; i < attributes.getLength(); i++) {
      QName attrName =
          QNameUtils.toQName(attributes.getURI(i), attributes.getQName(i));
      if (!isNamespaceDeclaration(attrName)) {
        OMNamespace namespace =
            factory.createOMNamespace(attrName.getNamespaceURI(),
                attrName.getPrefix());
        OMAttribute attribute =
            factory.createOMAttribute(attrName.getLocalPart(), namespace,
                attributes.getValue(i));
        element.addAttribute(attribute);
      }
    }
    elements.add(element);
    newNamespaceMapping();
  }

  private boolean isNamespaceDeclaration(QName qName) {
    String prefix = qName.getPrefix();
    String localPart = qName.getLocalPart();
    return (XMLConstants.XMLNS_ATTRIBUTE.equals(localPart) && prefix.length() == 0) ||
        (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix) && localPart.length() != 0);
  }

  @Override
  public void endElement(String uri, String localName, String qName)
      throws SAXException {
    elements.remove(elements.size() - 1);
    removeNamespaceMapping();
  }

  @Override
  public void characters(char ch[], int start, int length) throws SAXException {
    String data = new String(ch, start, length);
    OMContainer parent = getParent();
    factory.createOMText(parent, data, charactersType);
  }

  @Override
  public void ignorableWhitespace(char ch[], int start, int length)
      throws SAXException {
    charactersType = XMLStreamConstants.SPACE;
    characters(ch, start, length);
    charactersType = XMLStreamConstants.CHARACTERS;
  }

  @Override
  public void processingInstruction(String target, String data) throws SAXException {
    OMContainer parent = getParent();
    factory.createOMProcessingInstruction(parent, target, data);
  }

  @Override
  public void comment(char ch[], int start, int length) throws SAXException {
    String content = new String(ch, start, length);
    OMContainer parent = getParent();
    factory.createOMComment(parent, content);
  }

  @Override
  public void startCDATA() throws SAXException {
    charactersType = XMLStreamConstants.CDATA;
  }

  @Override
  public void endCDATA() throws SAXException {
    charactersType = XMLStreamConstants.CHARACTERS;
  }

  @Override
  public void startEntity(String name) throws SAXException {
    if (!isPredefinedEntityReference(name)) {
      charactersType = XMLStreamConstants.ENTITY_REFERENCE;
    }
  }

  @Override
  public void endEntity(String name) throws SAXException {
    charactersType = XMLStreamConstants.CHARACTERS;
  }

  private boolean isPredefinedEntityReference(String name) {
    return "lt".equals(name) || "gt".equals(name) || "amp".equals(name) ||
        "quot".equals(name) ||
        "apos".equals(name);
  }

    /*
    * Unsupported
    */

  @Override
  public void setDocumentLocator(Locator locator) {
  }

  @Override
  public void skippedEntity(String name) throws SAXException {
  }

  @Override
  public void startDTD(String name, String publicId, String systemId)
      throws SAXException {
  }

  @Override
  public void endDTD() throws SAXException {
  }

  private Map<String, String> currentNamespaceMapping() {
    return namespaceMappings.get(namespaceMappings.size() - 1);
  }

  private void newNamespaceMapping() {
    namespaceMappings.add(new HashMap<String, String>());
  }

  private void removeNamespaceMapping() {
    namespaceMappings.remove(namespaceMappings.size() - 1);
  }

  private void removeAllNamespaceMappings() {
    namespaceMappings.clear();
  }

}
TOP

Related Classes of org.springframework.ws.soap.axiom.AxiomHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.