blob: 540a028d53dba71cc724cf396056f367ae3ac422 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ode.jbi.msgmap;
import java.util.Collection;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
import javax.wsdl.Fault;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Part;
import javax.xml.namespace.QName;
import javax.xml.transform.dom.DOMSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.apache.ode.utils.DOMUtils;
/**
* Mapper to handle messages that are single-part docliteral (WSDL2.0 style).
*/
public class DocLitMapper extends BaseXmlMapper implements Mapper {
public Recognized isRecognized(NormalizedMessage nmsMsg, Operation op) {
Message in = op.getInput() == null ? null : op.getInput().getMessage();
Message out = op.getOutput() == null ? null : op.getOutput().getMessage();
// First we check if the signature of the operation makes this mapper
// a possibility.
if (!checkMessageDef(in) || !checkMessageDef(out))
return Recognized.FALSE;
// Ok, if it is possible, then we have to check the content of the
// input message to see if it matches doc lit style, if the input
// message is empty, then we have an ambiguous match
if (in == null)
return Recognized.UNSURE;
Part inpart = (Part) in.getParts().values().iterator().next();
assert inpart != null;
assert inpart.getElementName() != null;
Element msg;
try {
msg = parse(nmsMsg.getContent());
} catch (MessageTranslationException e) {
__log.debug("Failed to parse NMS message: " + nmsMsg, e);
return Recognized.FALSE;
}
QName elName = DOMUtils.getElementQName(msg);
// If the message element matches the single part element, then
// we are using doc-lit style messaging.
return inpart.getElementName().equals(elName) ? Recognized.TRUE : Recognized.FALSE;
}
public void toNMS(NormalizedMessage nmsMsg,
org.apache.ode.bpel.iapi.Message odeMsg, Message msgdef, QName fault)
throws MessagingException, MessageTranslationException {
// If this is an unkown fault, just return an empty element
// built with the fault name
if (msgdef == null && fault != null) {
Document doc = newDocument();
Element content = doc.createElementNS(fault.getNamespaceURI(), fault.getLocalPart());
doc.appendChild(content);
nmsMsg.setContent(new DOMSource(doc));
return;
}
// For empty messages there is nothing to do.
if (msgdef == null || msgdef.getParts().size() == 0)
return;
// The assertions assume isRecognized was called!
assert msgdef.getParts().size() == 1 : "multi part!";
Part partdef = (Part) msgdef.getParts().values().iterator().next();
assert partdef.getElementName() != null : "non-element part!";
if (odeMsg.getMessage() == null) {
String errmsg = "Unknown fault: " + odeMsg.getType();
__log.debug(errmsg);
throw new MessageTranslationException(errmsg);
}
Element part = DOMUtils.findChildByName(odeMsg.getMessage(),new QName(null, partdef.getName()));
if (part == null) {
String errmsg = "ODE message did not contain expected part: " + partdef.getName();
__log.debug(errmsg);
throw new MessageTranslationException(errmsg);
}
Element content = DOMUtils.findChildByName(part, partdef.getElementName());
if (content == null) {
String errmsg = "ODE message did not contain element " + partdef.getElementName() + " in part: " + partdef.getName();
__log.debug(errmsg);
throw new MessageTranslationException(errmsg);
}
nmsMsg.setContent(new DOMSource(content));
}
public void toODE(org.apache.ode.bpel.iapi.Message odeMsg,
NormalizedMessage nmsMsg, Message msgdef)
throws MessageTranslationException {
// The assertions assume isRecognized was called!
assert msgdef.getParts().size() == 1 : "multi part!";
Part partdef = (Part) msgdef.getParts().values().iterator().next();
assert partdef.getElementName() != null : "non-element part!";
Element el = parse(nmsMsg.getContent());
if (!DOMUtils.getElementQName(el).equals(partdef.getElementName())) {
String errmsg = "NMS message did not contain element " + partdef.getElementName();
__log.debug(errmsg);
throw new MessageTranslationException(errmsg);
}
Document doc = newDocument();
Element msgel = doc.createElement("message");
doc.appendChild(msgel);
Element pel = doc.createElement(partdef.getName());
msgel.appendChild(pel);
pel.appendChild(doc.importNode(el,true));
odeMsg.setMessage(msgel);
}
public Fault toFaultType(javax.jbi.messaging.Fault jbiFlt, Collection<Fault> faults) throws MessageTranslationException {
Element el = parse(jbiFlt.getContent());
QName elQname = new QName(el.getNamespaceURI(),el.getLocalName());
for (Fault f : faults) {
if (f.getMessage() == null || f.getMessage().getParts().size() != 1)
continue;
javax.wsdl.Part pdef = (Part) f.getMessage().getParts().values().iterator().next();
if (pdef.getElementName() == null)
continue;
if (pdef.getElementName().equals(elQname))
return f;
}
return null;
}
/**
* Check if a message definition is compatible with doc-lit mapping. For
* WSDL1.1 this means that the message definition needs to have exactly one
* element part.
*
* @param msg
* message definition to check
* @return true if compatible, false otherwise
*/
private boolean checkMessageDef(Message msg) {
// Null messages are acceptable.
if (msg == null)
return true;
// If we are non-empty, we need to have exactly one part.
if (msg.getParts().size() != 1)
return false;
// The single part must also be an "element" typed part.
if (((Part) msg.getParts().values().iterator().next()).getElementName() == null)
return false;
return true;
}
}