916 lines
37 KiB
Java
Executable File
916 lines
37 KiB
Java
Executable File
package com.sun.jbi.httpsoapbc;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import javax.jbi.messaging.MessageExchange;
|
|
import javax.jbi.messaging.MessagingException;
|
|
import javax.jbi.messaging.NormalizedMessage;
|
|
import javax.wsdl.Message;
|
|
import javax.wsdl.Part;
|
|
import javax.xml.namespace.QName;
|
|
import javax.xml.soap.Detail;
|
|
import javax.xml.soap.DetailEntry;
|
|
import javax.xml.soap.Name;
|
|
import javax.xml.soap.SOAPBody;
|
|
import javax.xml.soap.SOAPException;
|
|
import javax.xml.soap.SOAPFault;
|
|
import javax.xml.soap.SOAPHeader;
|
|
import javax.xml.soap.SOAPHeaderElement;
|
|
import javax.xml.soap.SOAPMessage;
|
|
|
|
import net.java.hulp.measure.Probe;
|
|
|
|
import org.w3c.dom.Attr;
|
|
import org.w3c.dom.Element;
|
|
import org.w3c.dom.Node;
|
|
import org.w3c.dom.NodeList;
|
|
|
|
import com.sun.jbi.httpsoapbc.util.DebugLog;
|
|
import com.sun.jbi.internationalization.Messages;
|
|
import com.sun.jbi.nms.wsdl11wrapper.WrapperParser;
|
|
import com.sun.jbi.nms.wsdl11wrapper.WrapperProcessingException;
|
|
import com.sun.jbi.nms.wsdl11wrapper.util.WrapperUtil;
|
|
|
|
public class Soap12Denormalizer extends Soap11Denormalizer {
|
|
|
|
private static Messages mMessages = Messages.getMessages(Soap12Denormalizer.class);
|
|
private static Logger mLog = Messages.getLogger(Soap12Denormalizer.class);
|
|
|
|
@Override
|
|
protected void processSoapFault(NormalizedMessage nm, Element normalRoot, SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser) throws MessagingException,
|
|
SOAPException, WrapperProcessingException {
|
|
// TODO Auto-generated method stub
|
|
processSoap12Fault(nm, normalRoot, outSoapMessage, meta, inMsg, wrapperParser);
|
|
}
|
|
|
|
@Override
|
|
protected void processSoapHeader(MessageExchange exchange, SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser, Map jbiMessageNSs)
|
|
throws MessagingException, SOAPException, WrapperProcessingException {
|
|
// TODO Auto-generated method stub
|
|
processSoap12Header(exchange, outSoapMessage, meta, inMsg, wrapperParser, jbiMessageNSs);
|
|
}
|
|
|
|
private void processSoap12Header(MessageExchange exchange, SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser, Map jbiMessageNSs)
|
|
throws MessagingException, SOAPException, WrapperProcessingException {
|
|
List headerList = null;
|
|
if (inMsg) {
|
|
headerList = meta.getInputSoapHeaders();
|
|
} else {
|
|
headerList = meta.getOutputSoapHeaders();
|
|
}
|
|
|
|
// TODO: this is just a work-around for testing
|
|
if (outSoapMessage.getSOAPHeader() == null) {
|
|
outSoapMessage.getSOAPPart().getEnvelope().addHeader();
|
|
}
|
|
|
|
SOAPHeader soapHeader = outSoapMessage.getSOAPHeader();
|
|
|
|
// Handle custom reliability protocol.
|
|
// If a message ID is present on the "in" message message exchange
|
|
// properties, populate a header with it
|
|
// By always looking in the "in" message, it will result in the header
|
|
// getting added to replies in request/reply scenarios as well
|
|
NormalizedMessage inNormalMsg = exchange.getMessage(IN_MSG);
|
|
if (inNormalMsg != null) {
|
|
String messageID = (String) inNormalMsg.getProperty(SoapNormalizer.CUSTOM_RELIABILITY_MESSAGE_ID_PROPERTY);
|
|
if (messageID != null) {
|
|
Name msgIDHeaderName = mSoap12Factory.createName(SoapNormalizer.CUSTOM_RELIABILITY_HEADER_LOCAL_NAME, null, SoapNormalizer.CUSTOM_RELIABILITY_HEADER_NAMESPACE_URI);
|
|
SOAPHeaderElement headerElem = soapHeader.addHeaderElement(msgIDHeaderName);
|
|
headerElem.setTextContent(messageID);
|
|
}
|
|
}
|
|
// End handling of custom reliability protocol
|
|
|
|
// Create header elements for every SOAP header stored in the normalized
|
|
// message
|
|
if (mIsHeaderCopyEnabled) {
|
|
if (inMsg) { // inbound
|
|
extractSOAPHeadersProperty(soapHeader, inNormalMsg);
|
|
} else {
|
|
NormalizedMessage outNormalMsg = exchange.getMessage(OUT_MSG);
|
|
if (outNormalMsg != null) { // got a "regular" response
|
|
// propagate custom headers to the response envelope
|
|
extractSOAPHeadersProperty(soapHeader, outNormalMsg);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((headerList == null || headerList.size() < 1) && inNormalMsg.getProperty(SoapNormalizer.CUSTOM_RELIABILITY_MESSAGE_ID_PROPERTY) == null) {
|
|
// there is nothing to be done here because no headers are defined
|
|
return;
|
|
}
|
|
|
|
// assumes the message where the header part is defined is the same
|
|
// as the in/out message of the operation.
|
|
// @todo consider the case where header is not a part in the in/out
|
|
// message
|
|
Message wsMessage = null;
|
|
if (inMsg) {
|
|
wsMessage = meta.getInputMessage();
|
|
} else {
|
|
wsMessage = meta.getOutputMessage();
|
|
}
|
|
|
|
// for each one of the declared headers, see if we can find the
|
|
// corresponding part
|
|
// in the normalized message
|
|
for (int i = 0; i < headerList.size(); i++) {
|
|
javax.wsdl.extensions.soap12.SOAP12Header headerDef = (javax.wsdl.extensions.soap12.SOAP12Header) headerList.get(i);
|
|
String partName = headerDef.getPart();
|
|
|
|
if (wrapperParser.hasPart(partName)) {
|
|
// look up the part in the msg
|
|
Part wsdlPart = wsMessage.getPart(partName);
|
|
|
|
if (wsdlPart == null) {
|
|
String msg = mMessages.getString("HTTPBC-W00714.Unsupported_feature_part_in_header_not_in_message", new Object[] { partName, wsMessage.getQName() });
|
|
throw new IllegalStateException(msg);
|
|
}
|
|
QName partElemQName = wsdlPart.getElementName();
|
|
if (partElemQName == null) {
|
|
String msg = mMessages.getString("HTTPBC-W00715.Unsupported_feature_part_in_header_not_element", new Object[] { partName, wsMessage.getQName() });
|
|
mLog.log(Level.WARNING, msg);
|
|
}
|
|
Name name = mSoap12Factory.createName(partElemQName.getLocalPart(), partElemQName.getPrefix(), partElemQName.getNamespaceURI());
|
|
SOAPHeaderElement headerElem = soapHeader.addHeaderElement(name);
|
|
// it is document literal mode with elements
|
|
// after we have the part node, it should contain one child with
|
|
// the element QName
|
|
|
|
Node e2 = null;
|
|
// remove the JBI wrapper and check that it contains the
|
|
// expected element
|
|
NodeList unwrappedList = wrapperParser.getPartNodes(partName);
|
|
if (unwrappedList != null) {
|
|
for (int j = 0; j < unwrappedList.getLength(); j++) {
|
|
Node unwrapped = (Node) unwrappedList.item(j);
|
|
if (unwrapped.getLocalName() != null && unwrapped.getLocalName().equals(partElemQName.getLocalPart())) {
|
|
e2 = unwrapped;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (e2 != null) {
|
|
copyNode(e2, headerElem);
|
|
|
|
// Per namespace mapping rules, collect all relevant
|
|
// namespaces from
|
|
// the JBI part wrapper element and copy these
|
|
// namespaces to the soap message part element
|
|
Map partElemNSs;
|
|
if (jbiMessageNSs != null) {
|
|
partElemNSs = new HashMap(jbiMessageNSs);
|
|
} else {
|
|
partElemNSs = new HashMap();
|
|
}
|
|
Element jbiWrappedPart = wrapperParser.getWrappedPart(partName);
|
|
if (jbiWrappedPart != null) {
|
|
Map jbiWrappedPartNSs = WrapperUtil.extractNamespaceDeclarations(jbiWrappedPart);
|
|
if (jbiWrappedPartNSs != null) {
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "JBI part '" + partName + "' namespaces", jbiWrappedPartNSs);
|
|
}
|
|
partElemNSs.putAll(jbiWrappedPartNSs);
|
|
}
|
|
}
|
|
copyNameSpaces(headerElem, partElemNSs);
|
|
} else {
|
|
String err = mMessages.getString("HTTPBC-W00703.Part_non_element_type_not_supported", new Object[] { partElemQName.getLocalPart(),
|
|
wsMessage.getQName().toString() });
|
|
throw new IllegalArgumentException(err);
|
|
}
|
|
}
|
|
} else {
|
|
String msg = mMessages.getString("HTTPBC-W00701.Message_has_no_match_for_part", partName);
|
|
mLog.warning(msg);
|
|
}
|
|
}
|
|
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "Denormalized SOAP header", soapHeader);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void processSoapBody(SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser, Map jbiMessageNSs, NormalizedMessage normalizedMessage)
|
|
throws MessagingException, SOAPException, WrapperProcessingException, Exception {
|
|
// TODO Auto-generated method stub
|
|
processSoap12Body(outSoapMessage, meta, inMsg, wrapperParser, jbiMessageNSs, normalizedMessage);
|
|
}
|
|
|
|
private void processSoap12Body(SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser, Map jbiMessageNSs, NormalizedMessage normalizedMessage)
|
|
throws MessagingException, SOAPException, WrapperProcessingException, Exception {
|
|
if (meta.isDocumentMode()) {
|
|
processDoc12Body(outSoapMessage, meta, inMsg, wrapperParser, jbiMessageNSs, normalizedMessage);
|
|
} else {
|
|
processRpc12Body(outSoapMessage, meta, inMsg, wrapperParser, jbiMessageNSs, normalizedMessage);
|
|
}
|
|
}
|
|
|
|
private void processDoc12Body(SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser, Map jbiMessageNSs, NormalizedMessage normalizedMessage)
|
|
throws MessagingException, SOAPException, WrapperProcessingException, Exception {
|
|
|
|
SOAPBody bodyElement = outSoapMessage.getSOAPBody();
|
|
// based on the part name, look up the element/type QName in the
|
|
// WSDLMessage
|
|
Message msg = null;
|
|
if (inMsg) {
|
|
msg = meta.getInputMessage();
|
|
} else {
|
|
msg = meta.getOutputMessage();
|
|
}
|
|
|
|
// look up the part used as soap body from the operation meta-data.
|
|
javax.wsdl.extensions.soap12.SOAP12Body soapBody = null;
|
|
if (inMsg) {
|
|
soapBody = meta.getInputSoap12Body();
|
|
} else {
|
|
soapBody = meta.getOutputSoap12Body();
|
|
}
|
|
|
|
List bodyParts = soapBody.getParts();
|
|
Iterator bodyIterator = null;
|
|
if (bodyParts != null && bodyParts.size() > 0) {
|
|
// since soap body binding specifies parts, we use only the parts
|
|
// that are in the binding
|
|
bodyIterator = bodyParts.iterator();
|
|
} else {
|
|
bodyIterator = msg.getOrderedParts(null).iterator();
|
|
}
|
|
while (bodyIterator != null && bodyIterator.hasNext()) {
|
|
Part part = null;
|
|
Object value = bodyIterator.next();
|
|
String partName;
|
|
if (value instanceof String) {
|
|
String bodyPart = partName = (String) value;
|
|
part = msg.getPart(bodyPart);
|
|
} else {
|
|
part = (Part) value;
|
|
partName = (part == null ? null : part.toString());
|
|
}
|
|
|
|
if (msg == null) {
|
|
// assert failed
|
|
throw new IllegalStateException("Unexpected state, input WSDLMessage is not defined, however we are attempting to invoke the operation with non-empty input");
|
|
}
|
|
|
|
if (part == null) {
|
|
// assert failed
|
|
String err = mMessages.getString("HTTPBC-W00703.Part_non_element_type_not_supported", new Object[] { partName, msg.getQName().toString() });
|
|
throw new IllegalStateException(err);
|
|
}
|
|
QName typeQName = part.getTypeName();
|
|
QName elemQName = part.getElementName();
|
|
if (typeQName != null) {
|
|
// means its a type
|
|
// see if the part name can be found in the normalized message
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
mLog.log(Level.FINEST, "Looking for part " + part.getName() + " in normalized message");
|
|
}
|
|
|
|
if (wrapperParser.hasPart(part.getName())) {
|
|
// it is document literal mode with types
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
mLog.log(Level.FINEST, "Creating SOAP node in document-literal mode with types");
|
|
}
|
|
// Add a part element, remove the JBI wrapper and add
|
|
// content to part element
|
|
Element srcPart = wrapperParser.getWrappedPart(part.getName());
|
|
Element partElem = bodyElement.getOwnerDocument().createElement(part.getName());
|
|
copyNode(srcPart, partElem);
|
|
bodyElement.appendChild(partElem);
|
|
|
|
// Per namespace mapping rules, collect all relevant
|
|
// namespaces from
|
|
// the JBI part wrapper element and copy these namespaces to
|
|
// the soap message part element
|
|
Map partElemNSs;
|
|
if (jbiMessageNSs != null) {
|
|
partElemNSs = new HashMap(jbiMessageNSs);
|
|
} else {
|
|
partElemNSs = new HashMap();
|
|
}
|
|
if (srcPart != null) {
|
|
Map jbiWrappedPartNSs = WrapperUtil.extractNamespaceDeclarations(srcPart);
|
|
if (jbiWrappedPartNSs != null) {
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "JBI part '" + part.getName() + "' namespaces", jbiWrappedPartNSs);
|
|
}
|
|
partElemNSs.putAll(jbiWrappedPartNSs);
|
|
}
|
|
}
|
|
copyNameSpaces(partElem, partElemNSs);
|
|
} else {
|
|
mLog.log(Level.WARNING, "HTTPBC-W00701.Message_has_no_match_for_part", part.getName());
|
|
}
|
|
} else if (elemQName != null) {
|
|
// it is of element type
|
|
// see if the part name can be found in the normalized message
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
mLog.log(Level.FINEST, "Looking for part " + part.getName() + " in normalized message");
|
|
}
|
|
|
|
if (wrapperParser.hasPart(part.getName())) {
|
|
// it is document literal mode with elements
|
|
// after we have the part node, it should contain one child
|
|
// with the element QName
|
|
|
|
Node e2 = null;
|
|
// remove the JBI wrapper and check that it contains the
|
|
// expected element
|
|
NodeList unwrappedList = wrapperParser.getPartNodes(part.getName());
|
|
if (unwrappedList != null) {
|
|
Probe m = Probe.fine(getClass(), "findDocumentElement");
|
|
for (int i = 0; i < unwrappedList.getLength(); i++) {
|
|
Node unwrapped = (Node) unwrappedList.item(i);
|
|
if (WrapperUtil.isNodeXopInclude(unwrapped)) {
|
|
e2 = processNodesAsAttachment(elemQName, unwrapped, normalizedMessage, bodyElement);
|
|
} else if (elemQName.getLocalPart().equals(unwrapped.getLocalName())) {
|
|
e2 = unwrapped;
|
|
}
|
|
|
|
if (e2 != null) {
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
mLog.log(Level.FINEST, "Creating SOAP message for document-literal mode with elements");
|
|
}
|
|
Node n = bodyElement.getOwnerDocument().importNode(e2, true);
|
|
bodyElement.appendChild(n);
|
|
if (n instanceof Element) {
|
|
// Per namespace mapping rules, collect all
|
|
// relevant namespaces from
|
|
// the JBI part wrapper element and copy
|
|
// these namespaces to the soap message part
|
|
// element
|
|
Map partElemNSs;
|
|
if (jbiMessageNSs != null) {
|
|
partElemNSs = new HashMap(jbiMessageNSs);
|
|
} else {
|
|
partElemNSs = new HashMap();
|
|
}
|
|
Element jbiWrappedPart = wrapperParser.getWrappedPart(part.getName());
|
|
if (jbiWrappedPart != null) {
|
|
Map jbiWrappedPartNSs = WrapperUtil.extractNamespaceDeclarations(jbiWrappedPart);
|
|
if (jbiWrappedPartNSs != null) {
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "JBI part '" + part.getName() + "' namespaces", jbiWrappedPartNSs);
|
|
}
|
|
partElemNSs.putAll(jbiWrappedPartNSs);
|
|
}
|
|
}
|
|
copyNameSpaces((Element) n, partElemNSs);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (m != null) {
|
|
m.end();
|
|
}
|
|
}
|
|
|
|
if (e2 == null) {
|
|
String err = mMessages.getString("HTTPBC-W00703.Part_non_element_type_not_supported", new Object[] { elemQName.getLocalPart(), msg.getQName().toString() });
|
|
throw new IllegalArgumentException(err);
|
|
}
|
|
} else {
|
|
mLog.log(Level.WARNING, "HTTPBC-W00701.Message_has_no_match_for_part", part.getName());
|
|
}
|
|
} else {
|
|
// both are null? unexpected
|
|
throw new IllegalArgumentException(mMessages.getString("HTTPBC-E00783.Part_not_element_nor_type", part.getName()));
|
|
}
|
|
} // end while
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
DebugLog.debugLog(mLog, Level.FINEST, "Document - Denormalized SOAP Body", outSoapMessage.getSOAPBody());
|
|
}
|
|
}
|
|
|
|
private void processRpc12Body(SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser, Map jbiMessageNSs, NormalizedMessage normalizedMessage)
|
|
throws MessagingException, SOAPException, WrapperProcessingException, Exception {
|
|
SOAPBody bodyElement = outSoapMessage.getSOAPBody();
|
|
// based on the part name, look up the element/type QName in the
|
|
// WSDLMessage
|
|
Message msg = null;
|
|
if (inMsg) {
|
|
msg = meta.getInputMessage();
|
|
} else {
|
|
msg = meta.getOutputMessage();
|
|
}
|
|
|
|
// look up the part used as soap body from the operation meta-data.
|
|
javax.wsdl.extensions.soap12.SOAP12Body soapBody = null;
|
|
if (inMsg) {
|
|
soapBody = meta.getInputSoap12Body();
|
|
} else {
|
|
soapBody = meta.getOutputSoap12Body();
|
|
}
|
|
|
|
// set the encodingStyle attribute on the soap:body
|
|
// although this is optional per SOAP specification, it needs to be set for certain webservice providers, e.g. Apache Axis
|
|
if("encoded".equalsIgnoreCase(soapBody.getUse())) {
|
|
bodyElement.setEncodingStyle(SOAP_RPC_ENCODING_STYLE);
|
|
}
|
|
|
|
List bodyParts = soapBody.getParts();
|
|
Iterator bodyIterator = null;
|
|
|
|
if (bodyParts != null && bodyParts.size() > 0) {
|
|
// since soap body binding specifies parts, we use only the parts
|
|
// that are in the binding
|
|
bodyIterator = bodyParts.iterator();
|
|
} else {
|
|
if (msg == null) {
|
|
// assert failed
|
|
throw new IllegalStateException("Unexpected state, input WSDLMessage is not defined, however we are attempting to invoke the operation with non-empty input");
|
|
}
|
|
// Since no parts are defined, just add the operation wrapper
|
|
// element in the soap body and return
|
|
List msgParts = msg.getOrderedParts(null);
|
|
if (msgParts != null && msgParts.size() > 0) {
|
|
bodyIterator = msgParts.iterator();
|
|
} else {
|
|
// Since no parts are defined, just add the operation wrapper
|
|
// element in soap body and return
|
|
Element wrapper;
|
|
String wrapperName = meta.getOperationName();
|
|
String wrapperNS = soapBody.getNamespaceURI();
|
|
if (wrapperNS != null && wrapperNS.length() > 0) {
|
|
// Add prefix to for body namespace
|
|
wrapperName = "m:" + wrapperName; // NOI18N
|
|
}
|
|
if (!inMsg) {
|
|
wrapperName += RPC_RESPONSE_SUFFIX;
|
|
}
|
|
wrapper = bodyElement.getOwnerDocument().createElementNS(wrapperNS, wrapperName);
|
|
bodyElement.appendChild(wrapper);
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "RPC - Denormalized SOAP body", bodyElement.getOwnerDocument());
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
while (bodyIterator != null && bodyIterator.hasNext()) {
|
|
Part part = null;
|
|
int nsCount = 0;
|
|
Object value = bodyIterator.next();
|
|
String partName;
|
|
if (value instanceof String) {
|
|
if (msg == null) {
|
|
// assert failed
|
|
throw new IllegalStateException("Unexpected state, input WSDLMessage is not defined, however we are attempting to invoke the operation with non-empty input");
|
|
}
|
|
String bodyPart = partName = (String) value;
|
|
part = msg.getPart(bodyPart);
|
|
} else {
|
|
part = (Part) value;
|
|
partName = (part == null ? null : part.toString());
|
|
}
|
|
|
|
if (part == null) {
|
|
// assert failed
|
|
String err = mMessages.getString("HTTPBC-E00702.Message_part_bad_reference", new Object[] { partName, msg.getQName().toString() });
|
|
throw new IllegalStateException(err);
|
|
}
|
|
QName typeQName = part.getTypeName();
|
|
QName elemQName = part.getElementName();
|
|
if (typeQName != null) {
|
|
// means its a type
|
|
// see if the part name can be found in the normalized message
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
mLog.log(Level.FINEST, "Looking for part " + part.getName() + " in normalized message");
|
|
}
|
|
|
|
if (wrapperParser.hasPart(part.getName())) {
|
|
// it is rpc literal mode with types
|
|
// create a new operation node and append the part node to
|
|
// it.
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
mLog.log(Level.FINEST, "Creating SOAP node in rpc-literal mode with types");
|
|
}
|
|
|
|
Map<String, Attr> attrMap=null;
|
|
Element wrapper;
|
|
// Element bodyElementRoot =
|
|
// bodyElement.getOwnerDocument().getDocumentElement();
|
|
Element bodyElementRoot = (Element) bodyElement.getFirstChild();
|
|
if (bodyElementRoot == null) {
|
|
String wrapperName = meta.getOperationName();
|
|
String wrapperNS = soapBody.getNamespaceURI();
|
|
if (wrapperNS != null && wrapperNS.length() > 0) {
|
|
// Add prefix to for body namespace
|
|
wrapperName = "m:" + wrapperName; // NOI18N
|
|
}
|
|
if (!inMsg) {
|
|
wrapperName += RPC_RESPONSE_SUFFIX;
|
|
}
|
|
wrapper = bodyElement.getOwnerDocument().createElementNS(wrapperNS, wrapperName);
|
|
bodyElement.appendChild(wrapper);
|
|
} else {
|
|
wrapper = bodyElementRoot;
|
|
}
|
|
bodyElement.getOwnerDocument().importNode(wrapper, true);
|
|
bodyElement.appendChild(wrapper);
|
|
// Add a part element, remove the JBI wrapper and add
|
|
// content to part element
|
|
Element partElem = bodyElement.getOwnerDocument().createElement(part.getName());
|
|
// handle rpc/encoded case by adding xsi:type for all
|
|
// elements
|
|
if ("encoded".equalsIgnoreCase(soapBody.getUse())) {
|
|
// check if the namespace exists in the envelope, if not
|
|
// add it.
|
|
String namespace = outSoapMessage.getSOAPPart().getEnvelope().lookupNamespaceURI(part.getTypeName().getNamespaceURI());
|
|
String prefix = meta.getFullDefinition().getPrefix(part.getTypeName().getNamespaceURI());
|
|
if ((prefix == null) || (prefix.equals(""))) {
|
|
if (namespace == null) {
|
|
outSoapMessage.getSOAPPart().getEnvelope().setAttribute("xmlns:ns" + nsCount++, part.getTypeName().getNamespaceURI());
|
|
part.getTypeName().getNamespaceURI();
|
|
}
|
|
partElem.setAttributeNS(SCHEMA_XSI_URI_2001, "xsi:type", part.getTypeName().getLocalPart());
|
|
} else {
|
|
if (namespace == null) {
|
|
outSoapMessage.getSOAPPart().getEnvelope().setAttribute("xmlns:" + meta.getFullDefinition().getPrefix(part.getTypeName().getNamespaceURI()),
|
|
part.getTypeName().getNamespaceURI());
|
|
}
|
|
partElem.setAttributeNS(SCHEMA_XSI_URI_2001, "xsi:type", prefix + ":" + part.getTypeName().getLocalPart());
|
|
}
|
|
|
|
}
|
|
wrapper.appendChild(partElem);
|
|
NodeList unwrappedList = wrapperParser.getPartNodes(part.getName());
|
|
if (unwrappedList != null) {
|
|
for (int i = 0; i < unwrappedList.getLength(); i++) {
|
|
Node unwrapped = (Node) unwrappedList.item(i);
|
|
if (WrapperUtil.isNodeXopInclude(unwrapped)) {
|
|
Node n = processNodesAsAttachment(typeQName, unwrapped, normalizedMessage, bodyElement);
|
|
partElem.appendChild(n);
|
|
} else {
|
|
Node n = bodyElement.getOwnerDocument().importNode(unwrapped, true);
|
|
partElem.appendChild(n);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Per namespace mapping rules, collect all relevant
|
|
// namespaces from
|
|
// the JBI part wrapper element and copy these namespaces to
|
|
// the soap message part element
|
|
Map partElemNSs;
|
|
if (jbiMessageNSs != null) {
|
|
partElemNSs = new HashMap(jbiMessageNSs);
|
|
} else {
|
|
partElemNSs = new HashMap();
|
|
}
|
|
Element jbiWrappedPart = wrapperParser.getWrappedPart(part.getName());
|
|
if (jbiWrappedPart != null) {
|
|
Map jbiWrappedPartNSs = WrapperUtil.extractNamespaceDeclarations(jbiWrappedPart);
|
|
if (jbiWrappedPartNSs != null) {
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "JBI part '" + part.getName() + "' namespaces", jbiWrappedPartNSs);
|
|
}
|
|
partElemNSs.putAll(jbiWrappedPartNSs);
|
|
}
|
|
attrMap = WrapperUtil.extractAttributeDeclarations(jbiWrappedPart);
|
|
if (attrMap != null) {
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "JBI part '" + part.getName() + "' attributes", attrMap);
|
|
}
|
|
|
|
}
|
|
}
|
|
copyNameSpaces(partElem, partElemNSs);
|
|
copyAttributes(partElem, attrMap);
|
|
} else {
|
|
mLog.log(Level.WARNING, "HTTPBC-W00701.Message_has_no_match_for_part", part.getName());
|
|
}
|
|
} else if (elemQName != null) {
|
|
// it is of element type
|
|
// see if the part name can be found in the normalized message
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
mLog.log(Level.FINEST, "Looking for part " + part.getName() + " in normalized message");
|
|
}
|
|
|
|
if (wrapperParser.hasPart(part.getName())) {
|
|
// it is rpc literal mode with elements
|
|
// look for the operation node wrapper, create a new one if
|
|
// necessary
|
|
// and append the part node to it.
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
mLog.log(Level.FINEST, "Creating SOAP node for rpc-literal mode with elements");
|
|
}
|
|
Element wrapper;
|
|
// Element bodyElementRoot =
|
|
// bodyElement.getOwnerDocument().getDocumentElement();
|
|
Element bodyElementRoot = (Element) bodyElement.getFirstChild();
|
|
if (bodyElementRoot == null) {
|
|
String wrapperName = meta.getOperationName();
|
|
String wrapperNS = soapBody.getNamespaceURI();
|
|
if (wrapperNS != null && wrapperNS.length() > 0) {
|
|
// Add prefix to for body namespace
|
|
wrapperName = "m:" + wrapperName; // NOI18N
|
|
}
|
|
if (!inMsg) {
|
|
wrapperName += RPC_RESPONSE_SUFFIX;
|
|
}
|
|
wrapper = bodyElement.getOwnerDocument().createElementNS(wrapperNS, wrapperName);
|
|
bodyElement.appendChild(wrapper);
|
|
} else {
|
|
wrapper = bodyElementRoot;
|
|
}
|
|
|
|
// @TODO: is this correct? Should rpc/literal with element
|
|
// have the part name in there???
|
|
// ...WSDL spec seems to say it should have part name
|
|
// (without differentiating type/element parts)
|
|
// Add a part element, remove the JBI wrapper and add
|
|
// content to part element
|
|
Element partElem = bodyElement.getOwnerDocument().createElement(part.getName());
|
|
// handle rpc/encoded case by adding xsi:type for all
|
|
// elements
|
|
if ("encoded".equalsIgnoreCase(soapBody.getUse())) {
|
|
// check if the namespace exists in the envelope, if not
|
|
// add it.
|
|
String namespace = outSoapMessage.getSOAPPart().getEnvelope().lookupNamespaceURI(part.getElementName().getNamespaceURI());
|
|
String prefix = meta.getFullDefinition().getPrefix(part.getElementName().getNamespaceURI());
|
|
if ((prefix == null) || (prefix.equals(""))) {
|
|
if (namespace == null) {
|
|
outSoapMessage.getSOAPPart().getEnvelope().setAttribute("xmlns:ns" + nsCount++, part.getElementName().getNamespaceURI());
|
|
}
|
|
partElem.setAttributeNS(SCHEMA_XSI_URI_2001, "xsi:type", part.getElementName().getLocalPart());
|
|
} else {
|
|
if (namespace == null) {
|
|
outSoapMessage.getSOAPPart().getEnvelope().setAttribute("xmlns:" + meta.getFullDefinition().getPrefix(part.getElementName().getNamespaceURI()),
|
|
part.getElementName().getNamespaceURI());
|
|
|
|
}
|
|
partElem.setAttributeNS(SCHEMA_XSI_URI_2001, "xsi:type", prefix + ":" + part.getElementName().getLocalPart());
|
|
}
|
|
|
|
}
|
|
wrapper.appendChild(partElem);
|
|
NodeList unwrappedList = wrapperParser.getPartNodes(part.getName());
|
|
if (unwrappedList != null) {
|
|
for (int i = 0; i < unwrappedList.getLength(); i++) {
|
|
Node unwrapped = (Node) unwrappedList.item(i);
|
|
// the part node may be an xop:Include element
|
|
// we need to handle it if that's the case
|
|
if (WrapperUtil.isNodeXopInclude(unwrapped)) {
|
|
Node n = processNodesAsAttachment(elemQName, unwrapped, normalizedMessage, bodyElement);
|
|
bodyElement.getOwnerDocument().importNode(n, true);
|
|
partElem.appendChild(n);
|
|
} else {
|
|
Node n = bodyElement.getOwnerDocument().importNode(unwrapped, true);
|
|
partElem.appendChild(n);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Per namespace mapping rules, collect all relevant
|
|
// namespaces from
|
|
// the JBI part wrapper element and copy these namespaces to
|
|
// the soap message part element
|
|
Map partElemNSs;
|
|
if (jbiMessageNSs != null) {
|
|
partElemNSs = new HashMap(jbiMessageNSs);
|
|
} else {
|
|
partElemNSs = new HashMap();
|
|
}
|
|
Element jbiWrappedPart = wrapperParser.getWrappedPart(part.getName());
|
|
if (jbiWrappedPart != null) {
|
|
Map jbiWrappedPartNSs = WrapperUtil.extractNamespaceDeclarations(jbiWrappedPart);
|
|
if (jbiWrappedPartNSs != null) {
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "JBI part '" + part.getName() + "' namespaces", jbiWrappedPartNSs);
|
|
}
|
|
partElemNSs.putAll(jbiWrappedPartNSs);
|
|
}
|
|
}
|
|
copyNameSpaces(partElem, partElemNSs);
|
|
} else {
|
|
mLog.log(Level.WARNING, "HTTPBC-W00701.Message_has_no_match_for_part", part.getName());
|
|
}
|
|
} else {
|
|
// both are null? unexpected
|
|
mLog.log(Level.SEVERE, "HTTPBC-E00783.Part_not_element_nor_type", part.getName());
|
|
}
|
|
}// end while
|
|
if (mLog.isLoggable(Level.FINEST)) {
|
|
DebugLog.debugLog(mLog, Level.FINEST, "RPC - Denormalized SOAP body", bodyElement.getOwnerDocument());
|
|
}
|
|
|
|
}
|
|
|
|
private void processSoap12Fault(NormalizedMessage nm, Element normalRoot, SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser) throws MessagingException,
|
|
SOAPException, WrapperProcessingException {
|
|
String tagName = null;
|
|
if (wrapperParser.isMessageWrapped()) {
|
|
// todo find a better way to map normalized fault to SOAP fault,
|
|
// perhaps by name
|
|
tagName = wrapperParser.getMessageType().getLocalPart();
|
|
|
|
// Process header faults
|
|
|
|
List headerList = null;
|
|
// header faults are defined in the corresponding "originating"
|
|
// header definition
|
|
if (inMsg) {
|
|
headerList = meta.getInputSoapHeaders();
|
|
} else {
|
|
headerList = meta.getOutputSoapHeaders();
|
|
}
|
|
|
|
if (headerList != null && headerList.size() > 0) {
|
|
|
|
SOAPHeader soapHeader = outSoapMessage.getSOAPHeader();
|
|
|
|
// for each one of the declared headers, see if we can find the
|
|
// corresponding part
|
|
// in the normalized message
|
|
for (int i = 0; i < headerList.size(); i++) {
|
|
javax.wsdl.extensions.soap12.SOAP12Header headerDef = (javax.wsdl.extensions.soap12.SOAP12Header) headerList.get(i);
|
|
|
|
List soapHeaderFaults = headerDef.getSOAP12HeaderFaults();
|
|
if (soapHeaderFaults != null && soapHeaderFaults.size() > 0) {
|
|
for (int hfCount = 0; hfCount < soapHeaderFaults.size(); hfCount++) {
|
|
javax.wsdl.extensions.soap12.SOAP12HeaderFault hf = (javax.wsdl.extensions.soap12.SOAP12HeaderFault) soapHeaderFaults.get(hfCount);
|
|
QName hfMsgName = hf.getMessage();
|
|
String hfPartName = hf.getPart();
|
|
|
|
if (wrapperParser.hasPart(hfPartName)) {
|
|
|
|
// Add the fault in the soap body (w/o detail as
|
|
// it is a headerfault)
|
|
SOAPFault fault = outSoapMessage.getSOAPBody().addFault();
|
|
String faultCode = outSoapMessage.getSOAPPart().getEnvelope().getPrefix() + ":" + (inMsg ? "Sender" : "Receiver"); // NOI18N
|
|
fault.setFaultCode(faultCode);
|
|
fault.setFaultString("headerfault");
|
|
|
|
// For header fault, add the 'details' in the
|
|
// header
|
|
Message wsMessage = meta.getFullDefinition().getMessage(hfMsgName);
|
|
|
|
if (wsMessage == null) {
|
|
mLog.log(Level.WARNING, "HTTPBC-W00704.Headerfault_bad_message_reference", hfMsgName);
|
|
} else {
|
|
|
|
// look up the part in the msg
|
|
Part wsdlPart = wsMessage.getPart(hfPartName);
|
|
|
|
if (wsdlPart == null) {
|
|
mLog.log(Level.WARNING, "HTTPBC-W00702.Headerfault_bad_message_part_reference", new Object[] { hfMsgName, hfPartName });
|
|
} else {
|
|
QName partElemQName = wsdlPart.getElementName();
|
|
if (partElemQName == null) {
|
|
String msg = mMessages
|
|
.getString("HTTPBC-W00703.Part_non_element_type_not_supported", new Object[] { hfPartName, wsMessage.getQName() });
|
|
throw new IllegalStateException(msg);
|
|
}
|
|
Name name = mSoap12Factory.createName(partElemQName.getLocalPart(), partElemQName.getPrefix(), partElemQName.getNamespaceURI());
|
|
SOAPHeaderElement headerElem = soapHeader.addHeaderElement(name);
|
|
|
|
boolean found = false;
|
|
NodeList unwrappedList = wrapperParser.getPartNodes(hfPartName);
|
|
for (int j = 0; j < unwrappedList.getLength(); j++) {
|
|
Node unwrapped = (Node) unwrappedList.item(j);
|
|
if (unwrapped.getLocalName() != null && unwrapped.getLocalName().equals(partElemQName.getLocalPart())) {
|
|
copyNode(unwrapped, headerElem);
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
String msg = mMessages.getString("HTTPBC-W00705.Message_missing_element", new Object[] { hfPartName, partElemQName.getLocalPart() });
|
|
throw new IllegalStateException(msg);
|
|
}
|
|
}
|
|
}
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "Denormalized SOAP headerfault", outSoapMessage.getSOAPPart());
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Process Faults
|
|
|
|
Map definedFaults = meta.getFaults();
|
|
if (definedFaults != null && definedFaults.size() > 0) {
|
|
// faults defined
|
|
Iterator iter = definedFaults.values().iterator();
|
|
while (iter.hasNext()) {
|
|
javax.wsdl.Fault f = (javax.wsdl.Fault) iter.next();
|
|
Message msg = f.getMessage();
|
|
QName faultMsgName = msg.getQName();
|
|
|
|
if (tagName.equals(faultMsgName.getLocalPart())) {
|
|
// found the msg that defines this fault
|
|
// create soap fault
|
|
SOAPFault fault = outSoapMessage.getSOAPBody().addFault();
|
|
final String faultCodeProp = (String)nm.getProperty(NormalizedMessageProperties.SOAP_FAULTCODE_PROPERTY);
|
|
|
|
// Sorry for this "WAT?!"
|
|
final String faultCode = outSoapMessage.getSOAPPart().getEnvelope().getPrefix() + ":" +
|
|
((faultCodeProp != null) ? faultCodeProp :
|
|
(inMsg ? "Sender" : "Receiver")); // NOI18N
|
|
fault.setFaultCode(faultCode);
|
|
|
|
final String faultActorProp = (String)nm.getProperty(NormalizedMessageProperties.SOAP_FAULTACTOR_PROPERTY);
|
|
if (faultActorProp != null)
|
|
fault.setFaultActor(faultActorProp);
|
|
|
|
final String faultStringProp = (String)nm.getProperty(NormalizedMessageProperties.SOAP_FAULTSTRING_PROPERTY);
|
|
final String faultName = (faultStringProp != null) ? faultStringProp : f.getName();
|
|
fault.setFaultString(faultName);
|
|
Detail detail = fault.addDetail();
|
|
|
|
// extract part from normalized message
|
|
List l = msg.getOrderedParts(null);
|
|
for (int i = 0; l != null && i < l.size(); i++) {
|
|
Part p = (Part) l.get(i);
|
|
tagName = p.getName();
|
|
|
|
String partName = tagName;
|
|
if (wrapperParser.hasPart(partName)) {
|
|
NodeList detailList = wrapperParser.getPartNodes(partName);
|
|
for (int j = 0; j < detailList.getLength(); j++) {
|
|
Node detailnode = (Node) detailList.item(j);
|
|
if (detailnode.getNodeType() == Node.TEXT_NODE) {
|
|
// Wrap the text node using the part
|
|
// name. This is the
|
|
// way we're doing it when we have
|
|
// document style with
|
|
// parts that have type attributes.
|
|
Name name = mSoap12Factory.createName(tagName, "", "");
|
|
DetailEntry de = detail.addDetailEntry(name);
|
|
de.addTextNode(detailnode.getNodeValue());
|
|
// detail.addTextNode(detailnode.getNodeValue());
|
|
} else {
|
|
Name name = mSoap12Factory.createName(detailnode.getLocalName(), "", detailnode.getNamespaceURI()); // NOI18N
|
|
DetailEntry de = detail.addDetailEntry(name);
|
|
NodeList nl = detailnode.getChildNodes();
|
|
for (int k = 0; k < nl.getLength(); k++) {
|
|
Node n2 = nl.item(k);
|
|
n2 = outSoapMessage.getSOAPBody().getOwnerDocument().importNode(n2, true);
|
|
de.appendChild(n2);
|
|
}
|
|
addFaultDetailNodeAttrributes(outSoapMessage, detailnode, de);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "Denormalized SOAP fault", outSoapMessage.getSOAPPart());
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
String msg = mMessages.getString("HTTPBC-W00706.Fault_not_for_operation", meta.getOperationName());
|
|
mLog.log(Level.WARNING, msg);
|
|
} else {
|
|
// no fault was defined for this operation
|
|
String msg = mMessages.getString("HTTPBC-W00707.Operation_no_faults", meta.getOperationName());
|
|
mLog.log(Level.WARNING, msg);
|
|
}
|
|
}
|
|
|
|
// unknown fault, we simply create a SERVER fault and set the normalized
|
|
// message in the fault detail
|
|
SOAPFault fault = outSoapMessage.getSOAPBody().addFault();
|
|
// Ensure we use QName to set the fault code in the envelope name space
|
|
String faultCode = outSoapMessage.getSOAPPart().getEnvelope().getPrefix() + ":" + "Receiver"; // NOI18N
|
|
fault.setFaultCode(faultCode);
|
|
fault.setFaultString(""); // NOI18N
|
|
|
|
if (tagName != null) {
|
|
Detail detail = fault.addDetail();
|
|
Name name = mSoap12Factory.createName(tagName);
|
|
DetailEntry de = detail.addDetailEntry(name);
|
|
// maybe we want to consider not copying from the root of normalized
|
|
// doc, should
|
|
// revisit this later
|
|
if (normalRoot != null) {
|
|
copyNode(normalRoot, de);
|
|
}
|
|
} else if (normalRoot != null) {
|
|
Detail detail = fault.addDetail();
|
|
Name name = mSoap12Factory.createName(normalRoot.getLocalName());
|
|
DetailEntry de = detail.addDetailEntry(name);
|
|
copyNode(normalRoot, de);
|
|
}
|
|
|
|
if (mLog.isLoggable(Level.FINE)) {
|
|
DebugLog.debugLog(mLog, Level.FINE, "Denormalized SOAP fault", outSoapMessage.getSOAPPart());
|
|
}
|
|
}
|
|
|
|
}
|