org.apache.servicemix.jms.DefaultJmsMarshaler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of servicemix-jms Show documentation
Show all versions of servicemix-jms Show documentation
JBI compliant JMS binding component for reading and writing JMS messages using queues and topics.
The newest version!
/*
* 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.servicemix.jms;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import javax.jms.BytesMessage;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.xml.transform.Source;
import org.apache.servicemix.jbi.jaxp.SourceTransformer;
import org.apache.servicemix.soap.SoapFault;
import org.apache.servicemix.soap.SoapHelper;
import org.apache.servicemix.soap.marshalers.SoapMessage;
import org.apache.servicemix.soap.marshalers.SoapWriter;
/**
* Encapsulates the conversion to and from JMS messages
*/
public class DefaultJmsMarshaler implements JmsMarshaler {
public static final String CONTENT_TYPE = "MimeContentType";
public static final String DONE_JMS_PROPERTY = "JBIDone";
public static final String FAULT_JMS_PROPERTY = "JBIFault";
public static final String ERROR_JMS_PROPERTY = "JBIError";
private JmsEndpoint endpoint;
public DefaultJmsMarshaler(JmsEndpoint endpoint) {
this.endpoint = endpoint;
}
/**
* Converts an {@link Exception} into an JMS message. This method will be
* invoked when the {@link javax.jbi.messaging.MessageExchange} contains an error.
*
* @param e
* Exception to convert
* @param session
* JMS session used to create JMS messages
* @return JMS message
* @see javax.jbi.messaging.MessageExchange#getError()
*/
public Message toJMS(Exception e, Session session) throws Exception {
return session.createObjectMessage(e);
}
/**
* Template method to allow custom functionality. Custom JmsMarshallers
* should override this method.
*
* @param message Source message
* @param session JMS session used to create JMS messages
* @return JMS version of the specified source SOAP message
* @throws Exception if an IO error occurs
* @throws javax.jms.JMSException if a JMS error occurs
*/
protected Message toJMS(SoapMessage message, Session session) throws Exception {
SoapHelper soapHelper = new SoapHelper(endpoint);
// turn SOAP message into byte array/string
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SoapWriter writer = soapHelper.getSoapMarshaler().createWriter(message);
writer.write(baos);
// create text message
TextMessage msg = session.createTextMessage();
msg.setText(baos.toString(SourceTransformer.getDefaultCharset()));
// overwrite whatever content-type was passed on to us with the one
// the SoapWriter constructed
msg.setStringProperty(CONTENT_TYPE, writer.getContentType());
return msg;
}
/**
* Converts a SOAP message to a JMS message, including any message headers.
*
* @param message
* message to convert
* @param headers
* protocol headers present in the NormalizedMessage
* @param session
* JMS session used to create JMS messages
* @throws Exception if something bad happens
* @return JMS message
*/
public Message toJMS(SoapMessage message, Map headers, Session session) throws Exception {
// create message
Message msg = toJMS(message, session);
// add protocol headers to message
if (headers != null) {
for (Iterator it = headers.keySet().iterator(); it.hasNext();) {
String name = (String) it.next();
Object value = headers.get(name);
if (shouldIncludeHeader(name, value)) {
msg.setObjectProperty(name, value);
}
}
}
if (message.getFault() != null) {
msg.setBooleanProperty(FAULT_JMS_PROPERTY, true);
}
return msg;
}
/**
* Template method to allow custom functionality. Custom JmsMarshalers
* should override this method.
*
* @param message
* Message to be turned into XML/SOAP
* @return Stream containing either the whole SOAP envelope or just the
* payload of the body.
* @throws Exception
* if JMS message is an ObjectMessage containing an Exception
* (the containing exception is thrown.)
* @throws javax.jms.JMSException
* if a JMS problem occurs
* @throws UnsupportedOperationException
* if the JMS message is an ObjectMessage which contains
* something other than an Exception
* @throws IllegalArgumentException
* if the message is anything other than a TextMessage or
* BytesMessage
*/
protected InputStream toXmlInputStream(Message message) throws Exception {
InputStream is = null;
if (message instanceof ObjectMessage) {
Object o = ((ObjectMessage) message).getObject();
if (o instanceof Exception) {
throw (Exception) o;
} else {
throw new UnsupportedOperationException("Can not handle objects of type " + o.getClass().getName());
}
} else if (message instanceof TextMessage) {
is = new ByteArrayInputStream(((TextMessage) message).getText().getBytes());
} else if (message instanceof BytesMessage) {
int length = (int) ((BytesMessage) message).getBodyLength();
byte[] bytes = new byte[length];
((BytesMessage) message).readBytes(bytes);
is = new ByteArrayInputStream(bytes);
} else {
throw new IllegalArgumentException("JMS message should be a text or bytes message");
}
return is;
}
/**
* Converts a JMS message into a SOAP message
*
* @param message
* JMS message to convert
* @return SOAP representation of the specified JMS message
* @throws Exception
* if an IO exception occurs
*/
public SoapMessage toSOAP(Message message) throws Exception {
SoapHelper soapHelper = new SoapHelper(endpoint);
InputStream is = toXmlInputStream(message);
String contentType = message.getStringProperty(CONTENT_TYPE);
SoapMessage soap = soapHelper.getSoapMarshaler().createReader().read(is, contentType);
if (message.getBooleanProperty(FAULT_JMS_PROPERTY)) {
Source src = soap.getSource();
soap.setSource(null);
soap.setFault(new SoapFault(SoapFault.SENDER, null, null, null, src));
}
return soap;
}
private boolean shouldIncludeHeader(String name, Object value) {
return (value instanceof String || value instanceof Number || value instanceof Date)
&& (!endpoint.isNeedJavaIdentifiers() || isJavaIdentifier(name));
}
private static boolean isJavaIdentifier(String s) {
int n = s.length();
if (n == 0) {
return false;
}
if (!Character.isJavaIdentifierStart(s.charAt(0))) {
return false;
}
for (int i = 1; i < n; i++) {
if (!Character.isJavaIdentifierPart(s.charAt(i))) {
return false;
}
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy