package org.jentrata.ebms.internal.messaging;
import org.apache.camel.Body;
import org.apache.camel.Headers;
import org.jentrata.ebms.EbmsConstants;
import org.jentrata.ebms.MessageType;
import javax.xml.soap.SOAPConstants;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Determines ebxml message types and versions and set header attributes accordingly
*
* @author aaronwalker
*/
public class MessageDetector {
private Pattern messageIdRegex = Pattern.compile("<(.*?)MessageId>(.*?)</(.*?)MessageId>", Pattern.DOTALL | Pattern.MULTILINE);
private Pattern refToMessageIdRegex = Pattern.compile("<(.*?)RefToMessageId>(.*?)</(.*?)RefToMessageId>", Pattern.DOTALL | Pattern.MULTILINE);
/**
* Partially reads the input message and determines what type of message this is
*
* (right now this it pretty dumb the goal for this would to replace this with some sort of message codec)
*
* @param input - the message input stream
* @param headers- the message headers that we will add the additional headers to contain the message version details
* @throws IOException
*/
public void parse(@Body InputStream input, @Headers Map<String, Object> headers) throws IOException {
try {
byte [] msgData = new byte[20480];
int count = input.read(msgData);
if(count > 0) {
String msg = new String(msgData); //should be able to use a header to determine encoding
//First determine if the message is a SOAP 1.1 or 1.2 message by default we will assume 1.1
String soapVersion = msg.contains(EbmsConstants.SOAP_1_2_NAMESPACE) ? SOAPConstants.SOAP_1_2_PROTOCOL : SOAPConstants.SOAP_1_1_PROTOCOL;
headers.put(EbmsConstants.SOAP_VERSION,soapVersion);
//next determine what version of ebms message is it, by default assume ebms V2
String ebmsVersion = msg.contains(EbmsConstants.EBXML_V3_NAMESPACE) ? EbmsConstants.EBMS_V3 : EbmsConstants.EBMS_V2;
headers.put(EbmsConstants.EBMS_VERSION,ebmsVersion);
headers.put(EbmsConstants.MESSAGE_ID, getMessageId(msg));
headers.put(EbmsConstants.REF_TO_MESSAGE_ID, getRefMessageId(msg));
headers.put(EbmsConstants.MESSAGE_TYPE, getMessageType(msg).name());
}
} finally {
input.reset();
}
}
private String getRefMessageId(String msg) {
Matcher matcher = refToMessageIdRegex.matcher(msg);
if(matcher.find()) {
return matcher.group(2);
} else {
return null;
}
}
private String getMessageId(String msg) {
Matcher matcher = messageIdRegex.matcher(msg);
if(matcher.find()) {
return matcher.group(2);
} else {
return UUID.randomUUID().toString();
}
}
private MessageType getMessageType(String msg) {
MessageType msgType = MessageType.UNKNOWN;
if(msg.contains("UserMessage") && msg.contains("SignalMessage")) {
msgType = MessageType.SIGNAL_MESSAGE_WITH_USER_MESSAGE;
} else if(msg.contains("UserMessage")) {
msgType = MessageType.USER_MESSAGE;
} else if(msg.contains("SignalMessage")) {
if(msg.contains("Error")) {
msgType = MessageType.SIGNAL_MESSAGE_ERROR;
} else {
msgType = MessageType.SIGNAL_MESSAGE;
}
}
return msgType;
}
}