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

1339 lines
71 KiB
Java
Executable File

/*
* BEGIN_HEADER - DO NOT EDIT
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* https://open-jbi-components.dev.java.net/public/CDDLv1.0.html.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* https://open-jbi-components.dev.java.net/public/CDDLv1.0.html.
* If applicable add the following below this CDDL HEADER,
* with the fields enclosed by brackets "[]" replaced with
* your own identifying information: Portions Copyright
* [year] [name of copyright owner]
*/
/*
* @(#)SoapDenormalizer.java
*
* Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
*
* END_HEADER - DO NOT EDIT
*/
package com.sun.jbi.httpsoapbc;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.activation.DataHandler;
import javax.jbi.messaging.Fault;
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.wsdl.extensions.mime.MIMEContent;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.Detail;
import javax.xml.soap.DetailEntry;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import net.java.hulp.measure.Probe;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.sun.jbi.common.util.Base64Utils;
import com.sun.jbi.httpsoapbc.util.DebugLog;
import com.sun.jbi.httpsoapbc.util.WSDLUtilities;
import com.sun.jbi.httpsoapbc.util.Util;
import com.sun.jbi.internationalization.Messages;
import com.sun.jbi.nms.wsdl11wrapper.HelperFactory;
import com.sun.jbi.nms.wsdl11wrapper.WrapperParser;
import com.sun.jbi.nms.wsdl11wrapper.WrapperProcessingException;
import com.sun.jbi.nms.wsdl11wrapper.util.WrapperUtil;
/**
*
*/
public class Soap11Denormalizer implements SoapDenormalizer {
private static Messages mMessages = Messages.getMessages(Soap11Denormalizer.class);
private static Logger mLog = Messages.getLogger(Soap11Denormalizer.class);
protected SOAPFactory mSoapFactory;
protected SOAPFactory mSoap12Factory;
protected boolean mIsHeaderCopyEnabled = true;
// measurements
protected Probe mMeasurement = null;
protected static Map<String,String> mStandardNamespaceURIs = new HashMap<String,String> ();
static {
mStandardNamespaceURIs.put ("http://schemas.xmlsoap.org/soap/envelope", "http://schemas.xmlsoap.org/soap/envelope");
mStandardNamespaceURIs.put ("http://www.w3.org/2003/05/soap-envelope", "http://www.w3.org/2003/05/soap-envelope");
mStandardNamespaceURIs.put ("http://www.w3.org/1999/XMLSchema", "http://www.w3.org/1999/XMLSchema");
mStandardNamespaceURIs.put ("http://www.w3.org/1999/XMLSchema-instance", "http://www.w3.org/1999/XMLSchema-instance");
mStandardNamespaceURIs.put ("http://www.w3.org/2001/XMLSchema", "http://www.w3.org/2001/XMLSchema");
mStandardNamespaceURIs.put ("http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/2001/XMLSchema-instance");
mStandardNamespaceURIs.put ("http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper", "http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper");
};
/** Creates a new instance */
public Soap11Denormalizer() {
try {
mSoapFactory = SOAPFactory.newInstance();
mSoap12Factory=SOAPFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
} catch (Exception e) {
mLog.log(Level.SEVERE, e.getMessage(), e);
}
}
/* (non-Javadoc)
* @see com.sun.jbi.httpsoapbc.SoapDenormalizerI#denormalize(javax.jbi.messaging.NormalizedMessage, javax.jbi.messaging.MessageExchange, com.sun.jbi.httpsoapbc.OperationMetaData, javax.xml.soap.MessageFactory, boolean)
*/
public SOAPMessage denormalize(NormalizedMessage normalizedMessage, MessageExchange exchange, OperationMetaData meta, MessageFactory messageFactory,
boolean inMsg) throws MessagingException {
try {
if (mLog.isLoggable(Level.FINE)) {
DebugLog.debugLog(mLog, Level.FINE, "Normalized message to denormalize", normalizedMessage.getContent());
}
String topic = "normalize" + (inMsg? "Request" : "Reply");
mMeasurement = Probe.fine(getClass(), topic);
Node node = Util.messageAsDom(normalizedMessage);
Document normalDoc = null;
Element normalRoot = null;
if (node != null) {
if (node instanceof Document) {
normalDoc = (Document) node;
} else {
normalDoc = ((Element) node).getOwnerDocument();
}
normalRoot = normalDoc.getDocumentElement();
} else {
throw new WrapperProcessingException(mMessages.getString("HTTPBC-E00795.Not_wrapped_wsdl_11"));
}
// Get "global" namespace(s) from JBI message root element
Map jbiMessageNSs = WrapperUtil.extractNamespaceDeclarations(normalRoot);
if (mLog.isLoggable(Level.FINE)) {
DebugLog.debugLog(mLog, Level.FINE, "JBI message namespaces", jbiMessageNSs);
}
//TODO this needs to be re-factored
SOAPMessage outSoapMessage = null;
if (meta.isSoap12()) {
MessageFactory msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
outSoapMessage=msgFactory.createMessage();
} else {
outSoapMessage = messageFactory.createMessage();
}
// TODO: for inbound respond with same as incoming
//TODO: outbound make configurable (?)
WrapperParser wrapperParser = HelperFactory.createParser();
if (Fault.class.isInstance(normalizedMessage)) {
wrapperParser.parse(normalDoc, meta.getFullDefinition());
if (!wrapperParser.isMessageWrapped()) {
throw new WrapperProcessingException(mMessages.getString("HTTPBC-E00795.Not_wrapped_wsdl_11"));
}
processSoapFault(normalizedMessage, normalRoot, outSoapMessage, meta, inMsg, wrapperParser);
} else {
Message msgDef = null;
if (inMsg) {
msgDef = meta.getInputMessage();
} else {
msgDef = meta.getOutputMessage();
}
wrapperParser.parse(normalDoc, msgDef);
if (!wrapperParser.isMessageWrapped()) {
throw new WrapperProcessingException(mMessages.getString("HTTPBC-E00795.Not_wrapped_wsdl_11"));
}
processSoapHeader(exchange, outSoapMessage, meta, inMsg, wrapperParser, jbiMessageNSs);
processSoapBody(outSoapMessage, meta, inMsg, wrapperParser, jbiMessageNSs, normalizedMessage);
processSoapAttachment(outSoapMessage, meta, inMsg, wrapperParser, normalizedMessage);
}
if (mLog.isLoggable(Level.FINE)) {
DebugLog.debugLog(mLog, Level.FINE, "Denormalized SOAP envelope", outSoapMessage.getSOAPPart().getEnvelope());
}
return outSoapMessage;
} catch (FactoryConfigurationError fce) {
String msg = mMessages.getString("HTTPBC-E00776.Failed_create_soap_normalizer");
mLog.log(Level.SEVERE, msg, fce);
throw new IllegalStateException(msg);
} catch (TransformerException tex) {
String msg = mMessages.getString("Unable to obtain normalized message as DOM");
throw new MessagingException(msg, tex);
} catch (WrapperProcessingException ex) {
String msg = mMessages.getString("HTTPBC-E00799.Denormalize_fail");
throw new MessagingException(msg, ex);
} catch (Exception ex) {
String msg = mMessages.getString("HTTPBC-E00799.Denormalize_fail");
throw new MessagingException(msg, ex);
} finally {
if (mMeasurement != null) {
mMeasurement.end();
}
}
}
protected void copyNode(Node src, Node dest) {
NodeList nl = src.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
n = dest.getOwnerDocument().importNode(n, true);
dest.appendChild(n);
}
// NamedNodeMap attrs = src.getAttributes();
// NamedNodeMap destAttrs = dest.getAttributes();
// if (attrs != null) {
// for (int i = 0; i < attrs.getLength(); i++) {
// Node attr = attrs.item(i);
// Node n = dest.getOwnerDocument().importNode(attr, true);
// if (destAttrs != null) {
// destAttrs.setNamedItemNS(n);
// }
// }
// }
}
protected void processSoapFault(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.soap.SOAPHeader headerDef = (javax.wsdl.extensions.soap.SOAPHeader) headerList.get(i);
List soapHeaderFaults = headerDef.getSOAPHeaderFaults();
if (soapHeaderFaults != null && soapHeaderFaults.size() > 0) {
for (int hfCount = 0; hfCount < soapHeaderFaults.size(); hfCount++) {
javax.wsdl.extensions.soap.SOAPHeaderFault hf = (javax.wsdl.extensions.soap.SOAPHeaderFault) 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() + ":" + "Client"; // 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 = mSoapFactory.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);
final String faultCode = outSoapMessage.getSOAPPart().getEnvelope().getPrefix() + ":" +
((faultCodeProp != null) ? faultCodeProp :"Client"); // 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 = mSoapFactory.createName(tagName, "", "");
DetailEntry de = detail.addDetailEntry(name);
de.addTextNode(detailnode.getNodeValue());
//detail.addTextNode(detailnode.getNodeValue());
} else {
Name name = mSoapFactory.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() + ":" + "Server"; // NOI18N
fault.setFaultCode(faultCode);
fault.setFaultString(""); // NOI18N
if (tagName != null) {
Detail detail = fault.addDetail();
Name name = mSoapFactory.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 = mSoapFactory.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());
}
}
protected void addFaultDetailNodeAttrributes(SOAPMessage outSoapMessage, Node detailnode, DetailEntry de) throws SOAPException {
NamedNodeMap attrMap = detailnode.getAttributes();
if (attrMap != null) {
for (int x = 0; x < attrMap.getLength(); x++) {
Node n = attrMap.item(x);
n = outSoapMessage.getSOAPBody().getOwnerDocument().importNode(n, true);
Attr attr = (Attr)n;
if(attr.getLocalName() == null){
de.setAttributeNode(attr);
}else{
de.setAttributeNodeNS(attr);
}
}
}
}
protected void processSoapHeader(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 = mSoapFactory.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
extractSOAPHeadersProperty(soapHeader,outNormalMsg); // propagate custom headers to the response envelope.
}
}
}
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.soap.SOAPHeader headerDef = (javax.wsdl.extensions.soap.SOAPHeader) 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 = mSoapFactory.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);
}
}
protected void processRpcBody(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.soap.SOAPBody soapBody = null;
if (inMsg) {
soapBody = meta.getInputSoapBody();
} else {
soapBody = meta.getOutputSoapBody();
}
// 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");
}
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);
copyNameSpaces(wrapper, jbiMessageNSs);
// 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 = new HashMap(); // we don't want to copy the NS defined on the jbi:message to each part
// if (jbiMessageNSs != null) {
// partElemNSs = new HashMap(jbiMessageNSs);
// } else {
// partElemNSs = new HashMap();
// }
Map attrMap = 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);
}
Map attrs = WrapperUtil.extractAttributeDeclarations(jbiWrappedPart);
if (attrs != null) {
if (mLog.isLoggable(Level.FINE)) {
DebugLog.debugLog(mLog, Level.FINE, "JBI part '" + part.getName() + "' attributes", attrs);
}
attrMap.putAll(attrs);
}
}
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 = new HashMap();
// if (jbiMessageNSs != null) {
// partElemNSs = new HashMap(jbiMessageNSs);
// } else {
// partElemNSs = new HashMap();
// }
Map attrMap = 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);
}
Map attrs = WrapperUtil.extractAttributeDeclarations(jbiWrappedPart);
if (attrs != null) {
if (mLog.isLoggable(Level.FINE)) {
DebugLog.debugLog(mLog, Level.FINE, "JBI part '" + part.getName() + "' attributes", attrs);
}
attrMap.putAll(attrs);
}
}
copyNameSpaces (partElem, partElemNSs);
copyAttributes(partElem, attrMap);
} 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());
}
}
protected void processDocBody(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.soap.SOAPBody soapBody = null;
if (inMsg) {
soapBody = meta.getInputSoapBody();
} else {
soapBody = meta.getOutputSoapBody();
}
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());
//Element partElem = bodyElement.getOwnerDocument().createElementNS("", 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());
}
}
protected void processSoapBody(SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser, Map jbiMessageNSs, NormalizedMessage normalizedMessage)
throws MessagingException, SOAPException, WrapperProcessingException, Exception {
if (meta.isDocumentMode()) {
processDocBody(outSoapMessage, meta, inMsg, wrapperParser, jbiMessageNSs, normalizedMessage);
} else {
processRpcBody(outSoapMessage, meta, inMsg, wrapperParser, jbiMessageNSs, normalizedMessage);
}
}
protected void processSoapAttachment(SOAPMessage outSoapMessage, OperationMetaData meta, boolean inMsg, WrapperParser wrapperParser,
NormalizedMessage normalizedMessage) throws MessagingException, WrapperProcessingException {
Map mimeParts = null;
Message message = null;
if (inMsg) {
mimeParts = meta.getInputSOAPMimeContents();
message = meta.getInputMessage();
} else {
mimeParts = meta.getOutputSOAPMimeContents();
message = meta.getOutputMessage();
}
//MimeHeaders mimeHeaders = soapMessage.getMimeHeaders();
Iterator mimeContents = mimeParts.values().iterator();
while (mimeContents.hasNext()) {
MIMEContent mimeContent = (MIMEContent) mimeContents.next();
String mimePart = mimeContent.getPart();
String mimeType = mimeContent.getType();
if (wrapperParser.hasPart(mimePart)) {
// it is document literal mode with types
if (mLog.isLoggable(Level.FINE)) {
mLog.log(Level.FINE, "Found a JBI part \"" + mimePart + "\" that matches the mime part defined in the WSDL");
}
NodeList unwrappedList = wrapperParser.getPartNodes(mimePart);
if (unwrappedList != null) {
Node unwrapped = (Node) unwrappedList.item(0);
String contentId = null;
DataHandler dataHandler = null;
/** Let's see if unwrapped node is an xop:Include node or not.
* If it is, then it contains a reference to an attachment (javax.activation.DataHandler)
* if it is not, we need to create a javax.activation.DataHandler object.
* In both cases, we will add a SOAP attachment with the DataHandler object
*/
if (WrapperUtil.isNodeXopInclude(unwrapped)) {
contentId = WrapperUtil.getXopContentId(unwrapped);
// get the DataHandler object with the content ID specified on the xop:Include node
dataHandler = normalizedMessage.getAttachment(contentId);
// add as SOAP attachment
AttachmentPart soapAttachment = outSoapMessage.createAttachmentPart();
soapAttachment.setContentId(encodeContentId(mimePart, contentId));
soapAttachment.setMimeHeader("Content-Type", mimeType);
soapAttachment.setDataHandler(dataHandler);
outSoapMessage.addAttachmentPart(soapAttachment);
} else {
if (message != null) { // really, it cannot be null if we reach here. But it doesn't hurt to be safe...
Part messagePart = message.getPart(mimePart);
if (messagePart != null) { // found the corresponding message part
/** There are 3 possibilities here:
* 1. message part is defined as an element. Will need to serialize into an XML infoset
* 2. message part is defined as a type. Will ignore the message part type and favor the mime content type
* 3. message part is defined as an element, the corresponding mime part must be suitable for an XML infoset.
*/
Node partNode = (Node)unwrappedList.item(0);
if (messagePart.getElementName() != null) { // dealing with an element definition
// TODO: check if the content type is suitable for XML infoset
AttachmentPart soapAttachment = outSoapMessage.createAttachmentPart();
soapAttachment.setContentId(encodeContentId(mimePart, contentId));
soapAttachment.setMimeHeader("Content-Type", mimeType);
soapAttachment.setContent(new DOMSource(partNode), mimeType);
outSoapMessage.addAttachmentPart(soapAttachment);
} else if (messagePart.getTypeName() != null) { // dealing with a type definition
// our support is limited to base64 encoded binary data for now
QName partType = messagePart.getTypeName();
AttachmentPart soapAttachment = null;
try {
soapAttachment = outSoapMessage.createAttachmentPart();
soapAttachment.setContentId(encodeContentId(mimePart, contentId));
soapAttachment.setMimeHeader("Content-Type", mimeType);
if ((SCHEMA_XSD_URI_2001.equals(partType.getNamespaceURI()) ||
SCHEMA_XSD_URI_1999.equals(partType.getNamespaceURI())) &&
"base64Binary".equals(partType.getLocalPart())) {
// decode the base64 encoded binary data and set attachment content
byte[] bytes = Base64Utils.base64DecodeToByte(partNode.getNodeValue());
soapAttachment.setRawContent(new ByteArrayInputStream(bytes), mimeType);
} else {
soapAttachment.setRawContent(new ByteArrayInputStream(partNode.getNodeValue().getBytes()), mimeType);
}
if (soapAttachment != null) {
outSoapMessage.addAttachmentPart(soapAttachment);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
throw new RuntimeException(mMessages.getString("HTTPBC-E00783.Part_not_element_nor_type", mimePart));
}
}
}
}
} else {
// TODO: double check the AP spec to make sure that it is required
if (mLog.isLoggable(Level.WARNING)) {
mLog.log(Level.WARNING, "HTTPBC-W00701.Message_has_no_match_for_part", mimePart);
}
}
}
}
}
protected void copyNameSpaces (Element elem, Map namespaces) {
if (elem == null || namespaces == null) return;
Set keys = namespaces.keySet();
for (Iterator iter = keys.iterator(); iter.hasNext();) {
String prefix = (String) iter.next();
String nsURI = (String) namespaces.get(prefix);
String normalizedURI = nsURI.trim();
normalizedURI = normalizedURI.endsWith("/")?new StringBuffer(normalizedURI).deleteCharAt(normalizedURI.length()-1).toString():normalizedURI;
if (mStandardNamespaceURIs.containsKey(normalizedURI)) {
// We also want to remove the standard namespace from the element if the element already
// has this namespace as an attribute
if (elem.hasAttribute(prefix)) {
elem.removeAttribute(prefix);
}
continue;
} else {
// try brute force method to cover all basis...
boolean foundMatching = false;
for (Iterator<String> ii = this.mStandardNamespaceURIs.keySet().iterator(); ii.hasNext();) {
String standardURI = ii.next();
if (nsURI.contains(standardURI) || standardURI.contains(nsURI)) {
foundMatching = true;
// We also want to remove the standard namespace from the element if the element already
// has this namespace as an attribute
if (elem.hasAttribute(prefix)) {
elem.removeAttribute(prefix);
}
break;
}
}
// if not a standard URI and also not already defined on the element, add it
if (!foundMatching && elem.lookupPrefix(nsURI) == null) {
elem.setAttributeNS("http://www.w3.org/2000/xmlns/",
(prefix.startsWith("xmlns:")) ? prefix : "xmlns:"+ prefix,
nsURI);
}
}
}
}
protected void copyAttributes(Element elem, Map attrMap) {
if (elem == null || attrMap == null) return;
Set keys = attrMap.keySet();
for (Iterator iter = keys.iterator(); iter.hasNext();) {
String name = (String) iter.next();
String prefix = (name.indexOf(":") > 0 )? name.substring(0, name.indexOf(":")) : null;
Attr attrNode = (Attr) attrMap.get(name);
if (prefix != null) {
elem.setAttributeNS(attrNode.getNamespaceURI(), name, attrNode.getValue());
} else {
elem.setAttribute(name, attrNode.getValue());
}
}
}
protected void extractSOAPHeadersProperty(SOAPHeader soapHeader, NormalizedMessage normalMsg)
throws SOAPException {
Map propertyMap = (Map<String, DocumentFragment>)normalMsg.getProperty(NormalizedMessageProperties.SOAP_HEADER_PROPERTY);
if (propertyMap != null) {
Iterator iter = propertyMap.values().iterator();
while (iter.hasNext()) {
DocumentFragment frag = (DocumentFragment) iter.next();
// copy all the child nodes in the documentFragment
NodeList children = frag.getChildNodes();
for (int ii = 0; ii < children.getLength(); ii++) {
Element aHeader = (Element) frag.getChildNodes().item(ii);
String nsuri = aHeader.getNamespaceURI();
String localname = aHeader.getLocalName();
QName name = (nsuri == null) ? new QName("", localname): new QName(nsuri, localname);
SOAPHeaderElement headerElem = soapHeader.addHeaderElement(name);
copyNode(aHeader, headerElem);
}
}
}
}
protected String encodeContentId(String part, String attachmentCid) {
String contentId = UUID.randomUUID() + "@" + XOP_CONTENT_ID_SUFFIX;
if (attachmentCid != null &&
!"".equals(attachmentCid) &&
attachmentCid.startsWith("cid:")) {
try {
URI uri = new URI(attachmentCid.substring(4)); // remove the "cid:" prefix
contentId = uri.toURL().getHost();
} catch (MalformedURLException e) {
try {
contentId = URLEncoder.encode(attachmentCid, "UTF-8");
} catch (UnsupportedEncodingException e1) {
// don't use the content ID from the JBI attachment
contentId = UUID.randomUUID() + "@" + XOP_CONTENT_ID_SUFFIX;
}
} catch (URISyntaxException e) {
contentId = UUID.randomUUID() + "@" + XOP_CONTENT_ID_SUFFIX;
}
}
return part + "=" + contentId;
}
protected Node processNodesAsAttachment(QName typeQName, Node unwrapped, NormalizedMessage normalizedMessage, SOAPBody soapBodyElement) throws Exception {
Node partNode = null;
String contentId = WrapperUtil.getXopContentId(unwrapped);
DataHandler dataHandler = normalizedMessage.getAttachment(contentId);
InputStream is = dataHandler.getInputStream();
// special treatment for binary data
if (WSDLUtilities.isBuiltInType(typeQName)) {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] bytes = new byte[128];
int len;
while((len = is.read(bytes)) != -1){
bout.write(bytes, 0, len);
}
//resetting the inputstream
is.reset();
// special treatment for base64 encoded binary data
if ((SCHEMA_XSD_URI_2001.equals(typeQName.getNamespaceURI()) ||
SCHEMA_XSD_URI_1999.equals(typeQName.getNamespaceURI())) &&
"base64Binary".equals(typeQName.getLocalPart())) {
// decode the base64 encoded binary data and set attachment content
partNode = soapBodyElement.getOwnerDocument().createTextNode(Base64Utils.byteToBase64String(bout.toByteArray()));
} else {
partNode = soapBodyElement.getOwnerDocument().createTextNode(new String(bout.toByteArray()));
}
} else {
// we are dealing with xml node here
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document elementDoc = docBuilder.parse(is);
partNode = elementDoc.getDocumentElement();
}
return partNode;
}
}