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 + -
显示快捷键?