org.apache.qpid.jms.message.JmsMessageTransformation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of qpid-jms-client Show documentation
Show all versions of qpid-jms-client Show documentation
The core JMS Client implementation
/*
* 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.qpid.jms.message;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Enumeration;
import jakarta.jms.BytesMessage;
import jakarta.jms.Destination;
import jakarta.jms.JMSException;
import jakarta.jms.MapMessage;
import jakarta.jms.Message;
import jakarta.jms.MessageEOFException;
import jakarta.jms.ObjectMessage;
import jakarta.jms.Queue;
import jakarta.jms.StreamMessage;
import jakarta.jms.TemporaryQueue;
import jakarta.jms.TemporaryTopic;
import jakarta.jms.TextMessage;
import jakarta.jms.Topic;
import org.apache.qpid.jms.JmsConnection;
import org.apache.qpid.jms.JmsDestination;
import org.apache.qpid.jms.JmsQueue;
import org.apache.qpid.jms.JmsTemporaryQueue;
import org.apache.qpid.jms.JmsTemporaryTopic;
import org.apache.qpid.jms.JmsTopic;
/**
* A helper class for converting normal JMS interfaces into the QpidJMS specific
* versions.
*/
public final class JmsMessageTransformation {
private static JmsUnresolvedDestinationTransformer unresolvedDestinationHandler =
new JmsDefaultUnresolvedDestinationTransformer();
/**
* Creates a an available JMS message from another provider.
*
* @param connection
* The Connection instance that is requesting the transformation.
* @param destination
* Destination to be converted into Jms's implementation.
*
* @return JmsDestination - Jms's implementation of the destination.
*
* @throws JMSException if an error occurs during the transformation.
*/
public static JmsDestination transformDestination(JmsConnection connection, Destination destination) throws JMSException {
JmsDestination result = null;
if (destination != null) {
if (destination instanceof JmsDestination) {
result = (JmsDestination) destination;
} else if (destination instanceof Queue && destination instanceof Topic) {
String queueName = ((Queue) destination).getQueueName();
String topicName = ((Topic) destination).getTopicName();
if (queueName != null && topicName == null) {
result = new JmsQueue(queueName);
} else if (queueName == null && topicName != null) {
result = new JmsTopic(topicName);
} else {
result = unresolvedDestinationHandler.transform(destination);
}
} else {
if (destination instanceof TemporaryQueue) {
result = new JmsTemporaryQueue(((TemporaryQueue) destination).getQueueName());
} else if (destination instanceof TemporaryTopic) {
result = new JmsTemporaryTopic(((TemporaryTopic) destination).getTopicName());
} else if (destination instanceof Queue) {
result = new JmsQueue(((Queue) destination).getQueueName());
} else if (destination instanceof Topic) {
result = new JmsTopic(((Topic) destination).getTopicName());
} else {
result = unresolvedDestinationHandler.transform(destination);
}
}
}
return result;
}
/**
* Creates a new JmsMessage object and populates it using the details of
* the given Message.
*
* @param connection
* The JmsConnection where this transformation is being initiated.
* @param message
* Message to be converted into the clients implementation.
*
* @return JmsMessage
* The client's implementation object for the incoming message.
*
* @throws JMSException if an error occurs during the transform.
*/
public static JmsMessage transformMessage(JmsConnection connection, Message message) throws JMSException {
JmsMessage jmsMessage = null;
JmsMessageFactory factory = connection.getMessageFactory();
if (message instanceof BytesMessage) {
BytesMessage bytesMsg = (BytesMessage) message;
bytesMsg.reset();
JmsBytesMessage msg = factory.createBytesMessage();
try {
for (;;) {
// Reads a byte from the message stream until the stream is empty
msg.writeByte(bytesMsg.readByte());
}
} catch (MessageEOFException e) {
// Indicates all the bytes have been read from the source.
}
jmsMessage = msg;
} else if (message instanceof MapMessage) {
MapMessage mapMsg = (MapMessage) message;
JmsMapMessage msg = factory.createMapMessage();
Enumeration> iter = mapMsg.getMapNames();
while (iter.hasMoreElements()) {
String name = iter.nextElement().toString();
msg.setObject(name, mapMsg.getObject(name));
}
jmsMessage = msg;
} else if (message instanceof ObjectMessage) {
ObjectMessage objMsg = (ObjectMessage) message;
JmsObjectMessage msg = factory.createObjectMessage();
msg.setObject(objMsg.getObject());
jmsMessage = msg;
} else if (message instanceof StreamMessage) {
StreamMessage streamMessage = (StreamMessage) message;
streamMessage.reset();
JmsStreamMessage msg = factory.createStreamMessage();
Object obj = null;
try {
while ((obj = streamMessage.readObject()) != null) {
msg.writeObject(obj);
}
} catch (MessageEOFException e) {
// Indicates all the stream values have been read from the source.
}
jmsMessage = msg;
} else if (message instanceof TextMessage) {
TextMessage textMsg = (TextMessage) message;
JmsTextMessage msg = factory.createTextMessage();
msg.setText(textMsg.getText());
jmsMessage = msg;
} else {
jmsMessage = factory.createMessage();
}
copyProperties(connection, message, jmsMessage);
return jmsMessage;
}
/**
* Copies the standard JMS and user defined properties from the given source
* message to the specified target message. The copy can only handle the JMS
* specific message properties and known JMS Headers, any headers that are
* specific to the foreign message may be lost if not returned directly via
* the propertyNames
method.
*
* @param connection
* The Connection instance that is requesting the transformation.
* @param source
* the message to take the properties from
* @param target
* the message to add the properties to
*
* @throws JMSException if an error occurs during the copy of message properties.
*/
public static void copyProperties(JmsConnection connection, Message source, JmsMessage target) throws JMSException {
target.setJMSMessageID(source.getJMSMessageID());
target.setJMSCorrelationID(source.getJMSCorrelationID());
target.setJMSReplyTo(transformDestination(connection, source.getJMSReplyTo()));
target.setJMSDestination(transformDestination(connection, source.getJMSDestination()));
target.setJMSDeliveryMode(source.getJMSDeliveryMode());
target.setJMSDeliveryTime(getForeignMessageDeliveryTime(source));
target.setJMSRedelivered(source.getJMSRedelivered());
target.setJMSType(source.getJMSType());
target.setJMSExpiration(source.getJMSExpiration());
target.setJMSPriority(source.getJMSPriority());
target.setJMSTimestamp(source.getJMSTimestamp());
Enumeration> propertyNames = source.getPropertyNames();
while (propertyNames.hasMoreElements()) {
String name = propertyNames.nextElement().toString();
Object obj = source.getObjectProperty(name);
target.setObjectProperty(name, obj);
}
}
public static void setUnresolvedDestinationHandler(JmsUnresolvedDestinationTransformer handler) {
unresolvedDestinationHandler = handler;
}
public static JmsUnresolvedDestinationTransformer getUnresolvedDestinationTransformer() {
if (unresolvedDestinationHandler == null) {
unresolvedDestinationHandler = new JmsDefaultUnresolvedDestinationTransformer();
}
return unresolvedDestinationHandler;
}
private static long getForeignMessageDeliveryTime(Message foreignMessage) throws JMSException {
// Verify if the getJMSDeliveryTime method exists, i.e the foreign provider isn't only JMS 1.1.
Method deliveryTimeMethod = null;
try {
Class> clazz = foreignMessage.getClass();
Method method = clazz.getMethod("getJMSDeliveryTime", (Class[]) null);
if (!Modifier.isAbstract(method.getModifiers())) {
deliveryTimeMethod = method;
}
} catch (NoSuchMethodException e) {
// Assume its a JMS 1.1 Message, we will return 0.
}
if (deliveryTimeMethod != null) {
// Method exists, isn't abstract, so use it.
return foreignMessage.getJMSDeliveryTime();
}
return 0;
}
}