Package com.google.code.magja.soap

Source Code of com.google.code.magja.soap.SoapReturnParser

package com.google.code.magja.soap;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMContainer;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.AxisFault;

public class SoapReturnParser {

  private static final String XSD_STRING = ":string";
  private static final String XSD_INTEGER = ":int";
  private static final String XSD_FLOAT = ":float";
  private static final String XSD_BOOLEAN = ":boolean";
  private static final String SOAPXML_MAP = ":Map";
  private static final String SOAPENC_ARRAY = ":Array";
  private static final QName VALUE_NAME = new QName("value");
  private static final QName KEY_NAME = new QName("key");
  private static final QName ITEM_NAME = new QName("item");

  private static final String NAMESPACE_URI_XSI = "http://www.w3.org/2001/XMLSchema-instance";
  private static final String NAMESPACE_URI_XSD = "http://www.w3.org/2001/XMLSchema";
  private static final String NAMESPACE_URI_SOAPXML = "http://xml.apache.org/xml-soap";
  private static final String NAMESPACE_URI_SOAPENC = "http://schemas.xmlsoap.org/soap/encoding/";

  private enum Type {
    StringType, IntegerType, FloatType, BooleanType, ArrayType, MapType
  }

  private OMNamespace xsi;
  private OMNamespace xsd;
  private OMNamespace soapXml;
  private OMNamespace soapEnc;

  @SuppressWarnings("unchecked")
  private void initNamespaces(SOAPEnvelope env) {
    int nsFound = 0;
    for (Iterator<OMNamespace> iNamespaces = env.getAllDeclaredNamespaces(); iNamespaces
        .hasNext();) {
      OMNamespace ns = iNamespaces.next();
      if (this.xsi == null
          && ns.getNamespaceURI().equalsIgnoreCase(NAMESPACE_URI_XSI)) {
        this.xsi = ns;
        nsFound++;
      } else if (this.xsd == null
          && ns.getNamespaceURI().equalsIgnoreCase(NAMESPACE_URI_XSD)) {
        this.xsd = ns;
        nsFound++;
      } else if (this.soapXml == null
          && ns.getNamespaceURI().equalsIgnoreCase(
              NAMESPACE_URI_SOAPXML)) {
        this.soapXml = ns;
        nsFound++;
      } else if (this.soapEnc == null
          && ns.getNamespaceURI().equalsIgnoreCase(
              NAMESPACE_URI_SOAPENC)) {
        this.soapEnc = ns;
        nsFound++;
      }
    }
    if (nsFound != 4) {
      // throw new RuntimeException("insufficient ns?!?");
    }
  }

  public Object parse(OMElement result) throws AxisFault {
    OMContainer parent = result.getParent();
    // find SoapEnvelope in results parents
    while (parent instanceof OMElement && !(parent instanceof SOAPEnvelope)) {
      parent = ((OMElement) parent).getParent();
    }
    if (parent instanceof SOAPEnvelope) {
      initNamespaces((SOAPEnvelope) parent);
    } else {
      throw new AxisFault("no envelope found");
    }

    // Acual Parsing
    Object value = getValue(result);

    // remove found namespaces, for later use of the parser
    // TODO: refactor to ReturnParserFactory
    this.xsd = null;
    this.soapEnc = null;
    this.soapXml = null;
    this.xsi = null;

    return value;
  }

  private Object getValue(OMElement value) {
    switch (getType(value)) {
    case StringType:
      return value.getText();
    case IntegerType:
      return Integer.parseInt(value.getText());
    case FloatType:
      return Double.parseDouble(value.getText());
    case BooleanType:
      return getBoolean(value);
    case ArrayType:
      return getList(value);
    case MapType:
      return getMap(value);
    default:
      throw new RuntimeException("Unsupported type for element: "
          + value.getLocalName());
    }
  }

  /**
   * creates String array of axiom element
   *
   * @param stringArray
   *            (the element supposed to be a string array)
   * @return
   */
  @SuppressWarnings("unchecked")
  private List<Object> getList(OMElement stringArray) {
    List<Object> list = new LinkedList<Object>();
    for (Iterator<OMElement> iElem = stringArray.getChildren(); iElem
        .hasNext();) {
      list.add(getValue(iElem.next()));
    }

    return list;
  }

  @SuppressWarnings("unchecked")
  private Map<String, Object> getMap(OMElement items) {
    Map<String, Object> map = new HashMap<String, Object>();

    for (Iterator<OMElement> iElem = items.getChildrenWithName(ITEM_NAME); iElem
        .hasNext();) {
      OMElement elem = iElem.next();
      String key = elem.getFirstChildWithName(KEY_NAME).getText();
      map.put(key, getValue(elem.getFirstChildWithName(VALUE_NAME)));
    }
    return map;
  }

  /**
   * Based on the type attributes of the element, decides which internal type
   * the element should be mapped to
   *
   * @param elem
   * @return the determined type
   */
  @SuppressWarnings("unchecked")
  private Type getType(OMElement elem) {
    String foundType = "";
    for (Iterator<OMAttribute> iAttr = elem.getAllAttributes(); iAttr
        .hasNext();) {
      OMAttribute test = iAttr.next();
      String localName = test.getLocalName();
      if (localName.equals("type")) {
        if (test.getAttributeValue().equals(
            xsd.getPrefix() + XSD_STRING)) {
          return Type.StringType;
        } else if (test.getAttributeValue().equals(
            xsd.getPrefix() + XSD_INTEGER)) {
          return Type.IntegerType;
        } else if (test.getAttributeValue().equals(
            xsd.getPrefix() + XSD_FLOAT)) {
          return Type.FloatType;
        } else if (test.getAttributeValue().equals(
            xsd.getPrefix() + XSD_BOOLEAN)) {
          return Type.BooleanType;
        } else if (soapXml != null
            && test.getAttributeValue().endsWith(
                soapXml.getPrefix() + SOAPXML_MAP)) {
          return Type.MapType;
        } else if (test.getAttributeValue().endsWith(
            soapEnc.getPrefix() + SOAPENC_ARRAY)) {
          return Type.ArrayType;
        }
        // <value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        // xsi:nil="true" />
      } else if (localName.equals("nil")) {
        if (test.getAttributeValue().equals("true")
            || test.getAttributeValue().equals("false")) {
          return Type.BooleanType;
        }
      }
      foundType = test.getLocalName();
    }
    throw new RuntimeException("Unknown type '" + foundType
        + "' (if empty does not contain type attribute) for tag :"
        + elem.getLocalName());
  }

  // <value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  // xsi:nil="true" />
  private Boolean getBoolean(OMElement items) {
    for (Iterator<OMAttribute> iAttr = items.getAllAttributes(); iAttr
        .hasNext();) {
      OMAttribute test = iAttr.next();
      String localName = test.getLocalName();
      if (localName.equals("nil")) {
        if (test.getAttributeValue().equals("true")) {
          return null;
        } else if (test.getAttributeValue().equals("false")) {
          return false;
        }
      } else {
        return Boolean.parseBoolean(items.getText());
      }
    }
    return false;
  }
}
TOP

Related Classes of com.google.code.magja.soap.SoapReturnParser

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.