All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.camel.component.jms.JmsMessageHelper Maven / Gradle / Ivy

There is a newer version: 4.8.1
Show 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.camel.component.jms;

import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import jakarta.jms.DeliveryMode;
import jakarta.jms.Destination;
import jakarta.jms.JMSException;
import jakarta.jms.Message;
import jakarta.jms.Queue;
import jakarta.jms.Topic;

import org.apache.camel.Exchange;
import org.apache.camel.support.ExchangeHelper;
import org.apache.camel.trait.message.MessageTrait;
import org.apache.camel.trait.message.RedeliveryTraitPayload;
import org.apache.camel.util.ObjectHelper;

import static org.apache.camel.component.jms.JmsConfiguration.QUEUE_PREFIX;
import static org.apache.camel.component.jms.JmsConfiguration.TEMP_QUEUE_PREFIX;
import static org.apache.camel.component.jms.JmsConfiguration.TEMP_TOPIC_PREFIX;
import static org.apache.camel.component.jms.JmsConfiguration.TOPIC_PREFIX;
import static org.apache.camel.util.StringHelper.removeStartingCharacters;

/**
 * Utility class for {@link jakarta.jms.Message}.
 */
public final class JmsMessageHelper {

    private JmsMessageHelper() {
    }

    /**
     * Removes the property from the JMS message.
     *
     * @param  jmsMessage   the JMS message
     * @param  name         name of the property to remove
     * @return              the old value of the property or null if not exists
     * @throws JMSException can be thrown
     */
    public static Object removeJmsProperty(Message jmsMessage, String name) throws JMSException {
        // check if the property exists
        if (!jmsMessage.propertyExists(name)) {
            return null;
        }

        Object answer = null;

        // store the properties we want to keep in a temporary map
        // as the JMS API is a bit strict as we are not allowed to
        // clear a single property, but must clear them all and redo
        // the properties
        Map map = new LinkedHashMap<>();
        Enumeration en = jmsMessage.getPropertyNames();
        while (en.hasMoreElements()) {
            String key = (String) en.nextElement();
            if (name.equals(key)) {
                answer = key;
            } else {
                map.put(key, getProperty(jmsMessage, key));
            }
        }

        // redo the properties to keep
        jmsMessage.clearProperties();
        for (Entry entry : map.entrySet()) {
            jmsMessage.setObjectProperty(entry.getKey(), entry.getValue());
        }

        return answer;
    }

    /**
     * Tests whether a given property with the name exists
     *
     * @param  jmsMessage   the JMS message
     * @param  name         name of the property to test if exists
     * @return              true if the property exists, false if not.
     * @throws JMSException can be thrown
     */
    public static boolean hasProperty(Message jmsMessage, String name) throws JMSException {
        Enumeration en = jmsMessage.getPropertyNames();
        while (en.hasMoreElements()) {
            String key = (String) en.nextElement();
            if (name.equals(key)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Gets a JMS property
     *
     * @param  jmsMessage   the JMS message
     * @param  name         name of the property to get
     * @return              the property value, or null if does not exist
     * @throws JMSException can be thrown
     */
    public static Object getProperty(Message jmsMessage, String name) throws JMSException {
        Object value = jmsMessage.getObjectProperty(name);
        if (value == null) {
            value = jmsMessage.getStringProperty(name);
        }
        return value;
    }

    /**
     * Gets a JMS property in a safe way
     *
     * @param  jmsMessage the JMS message
     * @param  name       name of the property to get
     * @return            the property value, or null if does not exist or failure to get the value
     */
    public static Long getSafeLongProperty(Message jmsMessage, String name) {
        try {
            return jmsMessage.getLongProperty(name);
        } catch (Exception e) {
            // ignore
        }
        return null;
    }

    /**
     * Sets the property on the given JMS message.
     *
     * @param  jmsMessage   the JMS message
     * @param  name         name of the property to set
     * @param  value        the value
     * @throws JMSException can be thrown
     */
    public static void setProperty(Message jmsMessage, String name, Object value) throws JMSException {
        if (value == null) {
            return;
        }
        if (value instanceof Byte) {
            jmsMessage.setByteProperty(name, (Byte) value);
        } else if (value instanceof Boolean) {
            jmsMessage.setBooleanProperty(name, (Boolean) value);
        } else if (value instanceof Double) {
            jmsMessage.setDoubleProperty(name, (Double) value);
        } else if (value instanceof Float) {
            jmsMessage.setFloatProperty(name, (Float) value);
        } else if (value instanceof Integer) {
            jmsMessage.setIntProperty(name, (Integer) value);
        } else if (value instanceof Long) {
            jmsMessage.setLongProperty(name, (Long) value);
        } else if (value instanceof Short) {
            jmsMessage.setShortProperty(name, (Short) value);
        } else if (value instanceof String) {
            jmsMessage.setStringProperty(name, (String) value);
        } else {
            // fallback to Object
            jmsMessage.setObjectProperty(name, value);
        }
    }

    /**
     * Sets the correlation id on the JMS message.
     * 

* Will ignore exception thrown * * @param message the JMS message * @param correlationId the correlation id */ public static void setCorrelationId(Message message, String correlationId) { try { message.setJMSCorrelationID(correlationId); } catch (JMSException e) { // ignore } } /** * Whether the destination name has either queue or temp queue prefix. * * @param destination the destination * @return true if queue or temp-queue prefix, false otherwise */ public static boolean isQueuePrefix(String destination) { if (ObjectHelper.isEmpty(destination)) { return false; } return destination.startsWith(QUEUE_PREFIX) || destination.startsWith(TEMP_QUEUE_PREFIX); } /** * Whether the destination name has either topic or temp topic prefix. * * @param destination the destination * @return true if topic or temp-topic prefix, false otherwise */ public static boolean isTopicPrefix(String destination) { if (ObjectHelper.isEmpty(destination)) { return false; } return destination.startsWith(TOPIC_PREFIX) || destination.startsWith(TEMP_TOPIC_PREFIX); } /** * Normalizes the destination name. *

* This ensures the destination name is correct, and we do not create queues as queue://queue:foo, which * was intended as queue://foo. * * @param destination the destination * @return the normalized destination */ public static String normalizeDestinationName(String destination) { // do not include prefix which is the current behavior when using this method. return normalizeDestinationName(destination, false); } /** * Normalizes the destination name. *

* This ensures the destination name is correct, and we do not create queues as queue://queue:foo, which * was intended as queue://foo. * * @param destination the destination * @param includePrefix whether to include queue://, or topic:// prefix in the normalized * destination name * @return the normalized destination */ public static String normalizeDestinationName(String destination, boolean includePrefix) { if (ObjectHelper.isEmpty(destination)) { return destination; } if (destination.startsWith(QUEUE_PREFIX)) { String s = removeStartingCharacters(destination.substring(QUEUE_PREFIX.length()), '/'); if (includePrefix) { s = QUEUE_PREFIX + "//" + s; } return s; } else if (destination.startsWith(TEMP_QUEUE_PREFIX)) { String s = removeStartingCharacters(destination.substring(TEMP_QUEUE_PREFIX.length()), '/'); if (includePrefix) { s = TEMP_QUEUE_PREFIX + "//" + s; } return s; } else if (destination.startsWith(TOPIC_PREFIX)) { String s = removeStartingCharacters(destination.substring(TOPIC_PREFIX.length()), '/'); if (includePrefix) { s = TOPIC_PREFIX + "//" + s; } return s; } else if (destination.startsWith(TEMP_TOPIC_PREFIX)) { String s = removeStartingCharacters(destination.substring(TEMP_TOPIC_PREFIX.length()), '/'); if (includePrefix) { s = TEMP_TOPIC_PREFIX + "//" + s; } return s; } else { return destination; } } /** * Sets the JMSReplyTo on the message. * * @param message the message * @param replyTo the reply to destination */ public static void setJMSReplyTo(Message message, Destination replyTo) { try { message.setJMSReplyTo(replyTo); } catch (Exception e) { // ignore due OracleAQ does not support accessing JMSReplyTo } } /** * Gets the JMSReplyTo from the message. * * @param message the message * @return the reply to, can be null */ public static Destination getJMSReplyTo(Message message) { try { return message.getJMSReplyTo(); } catch (Exception e) { // ignore due OracleAQ does not support accessing JMSReplyTo } return null; } /** * Gets the JMSType from the message. * * @param message the message * @return the type, can be null */ public static String getJMSType(Message message) { try { return message.getJMSType(); } catch (Exception e) { // ignore due OracleAQ does not support accessing JMSType } return null; } /** * Gets the String Properties from the message. * * @param message the message * @return the type, can be null */ public static String getStringProperty(Message message, String propertyName) { try { return message.getStringProperty(propertyName); } catch (Exception e) { // ignore due some broker client does not support accessing StringProperty } return null; } /** * Gets the JMSRedelivered from the message. * * @param message the message * @return true if redelivered, false if not, null if not able to determine */ public static Boolean getJMSRedelivered(Message message) { try { return message.getJMSRedelivered(); } catch (Exception e) { // ignore if JMS broker do not support this } return null; } /** * For a given message, evaluates what is the redelivery state for it and gives the appropriate {@link MessageTrait} * for that redelivery state * * @param message the message to evalute * @return The appropriate MessageTrait for the redelivery state (one of MessageTrait.UNDEFINED_REDELIVERY, * MessageTrait.IS_REDELIVERY or MessageTrait.NON_REDELIVERY). */ public static RedeliveryTraitPayload evalRedeliveryMessageTrait(Message message) { final Boolean redelivered = JmsMessageHelper.getJMSRedelivered(message); if (redelivered == null) { return RedeliveryTraitPayload.UNDEFINED_REDELIVERY; } if (Boolean.TRUE.equals(redelivered)) { return RedeliveryTraitPayload.IS_REDELIVERY; } return RedeliveryTraitPayload.NON_REDELIVERY; } /** * Gets the JMSMessageID from the message. * * @param message the message * @return the JMSMessageID, or null if not able to get */ public static String getJMSMessageID(Message message) { try { return message.getJMSMessageID(); } catch (Exception e) { // ignore if JMS broker do not support this } return null; } /** * Gets the JMSDestination from the message. * * @param message the message * @return the JMSDestination, or null if not able to get */ public static Destination getJMSDestination(Message message) { try { return message.getJMSDestination(); } catch (Exception e) { // ignore if JMS broker do not support this } return null; } /** * Sets the JMSDeliveryMode on the message. * * @param exchange the exchange * @param message the message * @param deliveryMode the delivery mode, either as a String or integer * @throws jakarta.jms.JMSException is thrown if error setting the delivery mode */ public static void setJMSDeliveryMode(Exchange exchange, Message message, Object deliveryMode) throws JMSException { Integer mode = null; if (deliveryMode instanceof String) { String s = (String) deliveryMode; if ("PERSISTENT".equalsIgnoreCase(s)) { mode = DeliveryMode.PERSISTENT; } else if ("NON_PERSISTENT".equalsIgnoreCase(s)) { mode = DeliveryMode.NON_PERSISTENT; } else { // it may be a number in the String so try that Integer value = ExchangeHelper.convertToType(exchange, Integer.class, deliveryMode); if (value != null) { mode = value; } else { throw new IllegalArgumentException("Unknown delivery mode with value: " + deliveryMode); } } } else { // fallback and try to convert to a number Integer value = ExchangeHelper.convertToType(exchange, Integer.class, deliveryMode); if (value != null) { mode = value; } } if (mode != null) { message.setJMSDeliveryMode(mode); message.setIntProperty(JmsConstants.JMS_DELIVERY_MODE, mode); } } /** * Gets the JMSCorrelationIDAsBytes from the message. * * @param message the message * @return the JMSCorrelationIDAsBytes, or null if not able to get */ public static byte[] getJMSCorrelationIDAsBytes(Message message) { try { byte[] bytes = message.getJMSCorrelationIDAsBytes(); boolean isNull = true; if (bytes != null) { for (byte b : bytes) { if (b != 0) { isNull = false; break; } } } return isNull ? null : bytes; } catch (Exception e) { // ignore if JMS broker do not support this } return null; } /** * Gets the JMSCorrelationID from the message. * * @param message the message * @return the JMSCorrelationID, or null if not able to get */ public static String getJMSCorrelationID(Message message) { try { return message.getJMSCorrelationID(); } catch (Exception e) { // ignore if JMS broker do not support this } return null; } /** * Gets the queue or topic name. * * @param destination the JMS destination * @return the name, or null if not possible to get the name */ public static String getDestinationName(Destination destination) { try { if (destination instanceof Queue q) { return q.getQueueName(); } else if (destination instanceof Topic t) { return t.getTopicName(); } } catch (JMSException e) { // ignore } return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy