openesb-components/ojc-core/httpsoapbc/httpsoapbcimpl/src/main/java/com/sun/jbi/httpsoapbc/Soap12Denormalizer.java

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());
}
}
}