soapformatter.java

来自「ejb3 java session bean」· Java 代码 · 共 708 行 · 第 1/2 页

JAVA
708
字号
/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as * published by JBoss Inc.; either version 1.0 of the License, or * (at your option) any later version. * * This software 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. */package org.jbpm.bpel.integration.soap;import java.net.URI;import java.net.URISyntaxException;import java.util.Iterator;import java.util.List;import java.util.Map;import javax.wsdl.Binding;import javax.wsdl.BindingFault;import javax.wsdl.BindingOperation;import javax.wsdl.Fault;import javax.wsdl.Message;import javax.wsdl.Operation;import javax.wsdl.Part;import javax.wsdl.extensions.soap.SOAPBinding;import javax.wsdl.extensions.soap.SOAPBody;import javax.wsdl.extensions.soap.SOAPFault;import javax.wsdl.extensions.soap.SOAPOperation;import javax.xml.namespace.QName;import javax.xml.soap.Name;import javax.xml.soap.SOAPElement;import javax.xml.soap.SOAPEnvelope;import javax.xml.soap.SOAPException;import javax.xml.soap.SOAPMessage;import org.w3c.dom.Element;import com.ibm.wsdl.extensions.soap.SOAPConstants;import org.jbpm.bpel.wsdl.xml.WsdlUtil;import org.jbpm.bpel.xml.BpelConstants;import org.jbpm.bpel.xml.util.DatatypeUtil;import org.jbpm.bpel.xml.util.XmlUtil;/** * @author Alejandro Guizar * @version $Revision: 1.8 $ $Date: 2008/01/30 07:18:22 $ */public class SoapFormatter {  private final Binding binding;  private final FaultFormat faultFormat;  public SoapFormatter(final Binding binding) {    this(binding, FaultFormat.DEFAULT);  }  public SoapFormatter(final Binding binding, final FaultFormat faultFormat) {    SOAPBinding soapBinding = (SOAPBinding) WsdlUtil.getExtension(        binding.getExtensibilityElements(), SOAPConstants.Q_ELEM_SOAP_BINDING);    // exclude non-soap bindings    if (soapBinding == null)      throw new IllegalArgumentException("non-soap binding not supported: " + binding);    // exclude non-http transport protocols    String transport = soapBinding.getTransportURI();    if (!SoapBindConstants.HTTP_TRANSPORT_URI.equals(transport))      throw new IllegalArgumentException("non-http transport not supported: " + transport);    // exclude null fault formats    if (faultFormat == null)      throw new IllegalArgumentException("fault format must not be null");    this.binding = binding;    this.faultFormat = faultFormat;  }  public Binding getBinding() {    return binding;  }  public FaultFormat getFaultFormat() {    return faultFormat;  }  public void writeMessage(String operation, SOAPMessage soapMessage, Map parts,      MessageDirection direction) throws SOAPException {    // obtain operation binding details    BindingOperation bindOperation = binding.getBindingOperation(operation, null, null);    SOAPOperation soapOperation = (SOAPOperation) WsdlUtil.getExtension(        bindOperation.getExtensibilityElements(), SOAPConstants.Q_ELEM_SOAP_OPERATION);    // set the value of the SOAPAction HTTP header    String action = soapOperation.getSoapActionURI();    if (action != null) {      /*       * BP 1.2 R1109: The value of the SOAPAction HTTP header field in a HTTP request MESSAGE MUST       * be a quoted string       */      action = '"' + action + '"';    }    else {      // BP 1.2 section 3.6.3: A WSDL Description that has:      // <soapbind:operation />      // results in a SOAPAction HTTP header field as follows:      // SOAPAction: ""      action = "\"\"";    }    soapMessage.getSOAPPart().setMimeHeader(SoapBindConstants.SOAP_ACTION_HEADER, action);    // determine whether operation is rpc-oriented or document-oriented    String style = determineOperationStyle(soapOperation);    // write env:Body    if (SoapBindConstants.RPC_STYLE.equals(style))      writeRpcBody(bindOperation, direction, soapMessage.getSOAPBody(), parts);    else      writeDocumentBody(bindOperation, direction, soapMessage.getSOAPBody(), parts);  }  private String determineOperationStyle(SOAPOperation soapOperation) {    /*     * BP 1.2 section 4.4: A "document-literal operation" is a wsdl:operation child element of     * wsdl:binding whose soapbind:body descendent elements specifies the use attribute with the     * value "literal" and, either:     *      * 1. The style attribute with the value "document" is specified on the child soapbind:operation     * element;     */    String style = soapOperation.getStyle();    if (style == null) {      /*       * or 2. The style attribute is not present on the child soapbind:operation element, and the       * soapbind:binding element in the enclosing wsdl:binding specifies the style attribute with       * the value "document";       */      SOAPBinding soapBinding = (SOAPBinding) WsdlUtil.getExtension(          getBinding().getExtensibilityElements(), SOAPConstants.Q_ELEM_SOAP_BINDING);      style = soapBinding.getStyle();      if (style == null) {        /*         * or 3. The style attribute is not present on both the child soapbind:operation element and         * the soapbind:binding element in the enclosing wsdl:binding.         */        style = SoapBindConstants.DOCUMENT_STYLE;      }    }    return style;  }  protected void writeRpcBody(BindingOperation bindOperation, MessageDirection direction,      javax.xml.soap.SOAPBody body, Map parts) throws SOAPException {    // obtain soapbind:body element    SOAPBody soapBindBody = direction.getBodyDescription(bindOperation);    /*     * BP 1.2 R2706: A wsdl:binding MUST use the value of "literal" for the use attribute in all     * soapbind:body elements     */    if (!SoapBindConstants.LITERAL_USE.equals(soapBindBody.getUse())) {      throw new SOAPException("binding must use value 'literal' for attribute "          + "'use' in all soapbind:body elements: "          + binding);    }    /*     * BP 1.2 R2717: An rpc-literal binding MUST have the namespace attribute specified, the value     * of which MUST be an absolute URI, on contained soapbind:body elements     */    String operationNamespace = soapBindBody.getNamespaceURI();    if (operationNamespace == null) {      throw new SOAPException("rpc binding must have the namespace attribute "          + "specified on contained soapbind:body elements: "          + binding);    }    try {      if (!new URI(operationNamespace).isAbsolute()) {        throw new SOAPException("rpc binding must have the namespace attribute specified, "            + "the value of which must be an absolute URI"            + binding);      }    }    catch (URISyntaxException e) {      throw new SOAPException("rpc binding must have the namespace attribute specified, "          + "the value of which must be an absolute URI"          + binding, e);    }    // create operation element    Operation operation = bindOperation.getOperation();    SOAPEnvelope envelope = (SOAPEnvelope) body.getParentElement();    Name operationQName = envelope.createName(direction.getRpcWrapperLocalName(operation),        "operationNS", operationNamespace);    SOAPElement operationElem = body.addBodyElement(operationQName);    List partNames = direction.getRpcBodyPartNames(soapBindBody, operation);    List wsdlParts = getWsdlParts(partNames, direction.getMessageDefinition(operation));    // fill in part values    for (int i = 0, n = parts.size(); i < n; i++) {      Part wsdlPart = (Part) wsdlParts.get(i);      /*       * BP 1.2 R2203: An rpc-literal binding MUST refer, in its soapbind:body element(s), only to       * wsdl:part element(s) that have been defined using the type attribute       */      if (wsdlPart.getTypeName() == null) {        throw new SOAPException("rpc binding must refer, in its soapbind:body "            + "elements, only to wsdl:part elements defined using the type attribute: "            + binding);      }      // copy part to accessor inside operation wrapper      Element part = (Element) parts.get(wsdlPart.getName());      SoapUtil.copyChildElement(operationElem, part);    }  }  protected void writeDocumentBody(BindingOperation bindOperation, MessageDirection direction,      javax.xml.soap.SOAPBody body, Map parts) throws SOAPException {    // obtain soapbind:body element    SOAPBody soapBindBody = direction.getBodyDescription(bindOperation);    /*     * BP 1.2 R2706: A wsdl:binding MUST use the value of "literal" for the use attribute in all     * soapbind:body elements     */    if (!SoapBindConstants.LITERAL_USE.equals(soapBindBody.getUse())) {      throw new SOAPException("binding must use value 'literal' for the use "          + "attribute in all soapbind:body elements: "          + binding);    }    /*     * BP 1.2 R2716: A document-literal binding MUST NOT have the namespace attribute specified on     * contained soapbind:body elements     */    if (soapBindBody.getNamespaceURI() != null) {      throw new SOAPException("document binding must not have the namespace "          + "attribute specified on contained soapbind:body elements: "          + binding);    }    List partNames = soapBindBody.getParts();    Message message = direction.getMessageDefinition(bindOperation.getOperation());    if (partNames == null) {      /*       * BP 1.2 R2210: If a document-literal binding does not specify the parts attribute on a       * soapbind:body element, the corresponding abstract wsdl:message MUST define zero or one       * wsdl:parts       */      if (message.getParts().size() > 1) {        throw new SOAPException("if a document binding does not specify "            + "attribute 'parts' on a soapbind:body element, the corresponding "            + "wsdl:message must define zero or one wsdl:parts: "            + binding);      }    }    else if (partNames.size() > 1) {      /*       * BP 1.2 R2201: A document-literal binding MUST, in each of its soapbind:body element(s),       * have at most one part listed in the parts attribute, if the parts attribute is specified       */      throw new SOAPException("document binding must, in its soapbind:body "          + "elements, have at most one part listed in attribute 'parts': "          + binding);    }    /*     * BP 1.2 section 4.4.1: For document-literal bindings, the Profile requires that at most one     * part be serialized into the soap:Body element.     */    List wsdlParts = getWsdlParts(partNames, message);    assert wsdlParts.size() <= 1 : wsdlParts.size();    // fill in single part value    if (wsdlParts.size() == 1) {      Part wsdlPart = (Part) wsdlParts.get(0);      /*       * BP 1.2 R2204: A document-literal binding MUST refer, in each of its soapbind:body       * element(s), only to wsdl:part element(s) that have been defined using the element       * attribute.       */      QName elementName = wsdlPart.getElementName();      if (elementName == null) {        throw new SOAPException("document binding must refer, in its "            + "soapbind:body elements, only to wsdl:part elements defined "            + "using attribute 'element': "            + binding);      }      /*       * BP 1.2 R2712: A document binding MUST be serialized as an ENVELOPE with a soap:Body whose       * child element is an instance of the global element declaration referenced by the       * corresponding wsdl:message part       */      Element part = (Element) parts.get(wsdlPart.getName());      if (!XmlUtil.nodeNameEquals(part, elementName)) {        throw new SOAPException("document binding must be serialized as an "            + "envelope with a soap:Body whose child element is an instance "            + "of the element declaration referenced by the corresponding "            + "wsdl:message part: "            + binding);      }      // copy part to element inside env:Body      SoapUtil.copyChildElement(body, part);    }  }  private static List getWsdlParts(List partNames, Message message) {    /*     * WSDL 1.1 section 3.5: If the parts attribute is omitted, then all parts defined by the     * message are assumed to be included in the SOAP Body portion     *      * BP 1.2 R2214: In a rpc-literal description where the value of the parts attribute of     * soapbind:body is an empty string, the corresponding ENVELOPE MUST have no part accessor     * elements     *      * Message.getOrderedParts() implements section 3.5 and R2214 as follows. If partNames is null,     * then return all wsdl:part elements. Otherwise, if partNames is empty, then return zero     * wsdl:part elements.     */    return message.getOrderedParts(partNames);  }  public void readMessage(String operation, SOAPMessage message, Map parts,      MessageDirection direction) throws SOAPException {    // obtain operation binding details    BindingOperation bindOperation = binding.getBindingOperation(operation, null, null);    SOAPOperation soapOperation = (SOAPOperation) WsdlUtil.getExtension(        bindOperation.getExtensibilityElements(), SOAPConstants.Q_ELEM_SOAP_OPERATION);    // determine operation style    String style = soapOperation.getStyle();    if (style == null) {      // fall back to value specified in wsdlsoap:binding      SOAPBinding soapBinding = (SOAPBinding) WsdlUtil.getExtension(          binding.getExtensibilityElements(), SOAPConstants.Q_ELEM_SOAP_BINDING);      style = soapBinding.getStyle();      if (style == null) {        // wsdlsoap:binding does not specify any style, assume 'document'        style = SoapBindConstants.DOCUMENT_STYLE;      }    }    // read env:Body    if (SoapBindConstants.DOCUMENT_STYLE.equals(style))      readDocumentBody(bindOperation, message.getSOAPBody(), parts, direction);    else      readRpcBody(bindOperation, message.getSOAPBody(), parts, direction);  }  protected void readRpcBody(BindingOperation bindOperation, javax.xml.soap.SOAPBody body,      Map parts, MessageDirection direction) throws SOAPException {    // obtain soapbind:body element    SOAPBody soapBindBody = direction.getBodyDescription(bindOperation);    /*     * BP 1.2 R2706: A wsdl:binding MUST use the value of "literal" for the use attribute in all     * soapbind:body elements

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?