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

org.skyscreamer.nevado.jms.message.AbstractMessage Maven / Gradle / Ivy

There is a newer version: 1.3.2
Show newest version
package org.skyscreamer.nevado.jms.message;

import org.skyscreamer.nevado.jms.util.PropertyConvertUtil;
import org.skyscreamer.nevado.jms.util.SerializeUtil;

import javax.jms.*;
import java.io.IOException;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * Generic non-Nevado-specific abstract message.  Designed specific to the generic specification.  Could
 * theoretically be used for other implementations.
 *
 * This abstraction was created to breakout specification-specific logic from Nevado's provider-specific
 * logic.
 *
 * @author Carter Page
 * @see NevadoMessage
 */
public abstract class AbstractMessage implements Message, Serializable {
    public static final String WHITESPACE_CHARS = " \t\r\n";
    public static final String[] RESERVED_PROPERTY_NAMES = { "NULL", "TRUE", "FALSE", "NOT", "AND", "OR", "BETWEEN",
            "LIKE", "IN", "IS", "ESCAPE" };

    private final Map _properties = new HashMap();
    String _messageID;
    private long _timestamp = 0;
    private String _correlationID;
    private Destination _jmsReplyTo;
    private Destination _destination;
    private int _deliveryMode = DEFAULT_DELIVERY_MODE;
    private boolean _redelivered = false;
    private String _type;
    private long _expiration = 0;
    private int _priority = 0;
    private boolean _readOnlyProperties = false;
    private boolean _readOnlyBody = false;

    public String getJMSMessageID() throws JMSException {
        return _messageID;
    }

    public void setJMSMessageID(String messageID) throws JMSException {
        _messageID = messageID;
    }

    public long getJMSTimestamp() throws JMSException {
        return _timestamp;
    }

    public void setJMSTimestamp(long timestamp) throws JMSException {
        _timestamp = timestamp;
    }

    public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
        try {
            return _correlationID != null ? _correlationID.getBytes("UTF-8") : null;
        } catch (UnsupportedEncodingException e) {
            throw new JMSException(e.getMessage());
        }
    }

    public void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException {
        try {
            _correlationID = correlationID != null ? new String(correlationID, "UTF-8") : null;
        } catch (UnsupportedEncodingException e) {
            throw new JMSException(e.getMessage());
        }
    }

    public void setJMSCorrelationID(String correlationID) throws JMSException {
        _correlationID = correlationID;
    }

    public String getJMSCorrelationID() throws JMSException {
        return _correlationID;
    }

    public Destination getJMSReplyTo() throws JMSException {
        return _jmsReplyTo;
    }

    public void setJMSReplyTo(Destination jmsReplyTo) throws JMSException {
        _jmsReplyTo = jmsReplyTo;
    }

    public Destination getJMSDestination() throws JMSException {
        return _destination;
    }

    public void setJMSDestination(Destination destination) throws JMSException {
        _destination = destination;
    }

    public int getJMSDeliveryMode() throws JMSException {
        return _deliveryMode;
    }

    public void setJMSDeliveryMode(int deliveryMode) throws JMSException {
        _deliveryMode = deliveryMode;
    }

    public boolean getJMSRedelivered() throws JMSException {
        return _redelivered;
    }

    public void setJMSRedelivered(boolean redelivered) throws JMSException {
        _redelivered = redelivered;
    }

    public String getJMSType() throws JMSException {
        return _type;
    }

    public void setJMSType(String type) throws JMSException {
        _type = type;
    }

    public long getJMSExpiration() throws JMSException {
        return _expiration;
    }

    public void setJMSExpiration(long expiration) throws JMSException {
        _expiration = expiration;
    }

    public int getJMSPriority() throws JMSException {
        return _priority;
    }

    public void setJMSPriority(int priority) throws JMSException {
        if (priority < 0 || priority > 9) {
            throw new IllegalArgumentException("Priority must be a number between 0-9.  Given: " + priority);
        }
        _priority = priority;
    }

    public void clearProperties() throws JMSException {
        _properties.clear();
        _readOnlyProperties = false;
    }

    public abstract void internalClearBody() throws JMSException;

    public void clearBody() throws JMSException {
        internalClearBody();
        _readOnlyBody = false;
    }

    public boolean propertyExists(String propertyName) throws JMSException {
        return _properties.containsKey(propertyName);
    }

    public boolean getBooleanProperty(String name) throws JMSException {
        return PropertyConvertUtil.convertToBoolean("property " + name, getObjectProperty(name));
    }

    public byte getByteProperty(String name) throws JMSException {
        return PropertyConvertUtil.convertToByte("property " + name, getObjectProperty(name));
    }

    public short getShortProperty(String name) throws JMSException {
        return PropertyConvertUtil.convertToShort("property " + name, getObjectProperty(name));
    }

    public int getIntProperty(String name) throws JMSException {
        return PropertyConvertUtil.convertToInt("property " + name, getObjectProperty(name));
    }

    public long getLongProperty(String name) throws JMSException {
        return PropertyConvertUtil.convertToLong("property " + name, getObjectProperty(name));
    }

    public float getFloatProperty(String name) throws JMSException {
        return PropertyConvertUtil.convertToFloat("property " + name, getObjectProperty(name));
    }

    public double getDoubleProperty(String name) throws JMSException {
        return PropertyConvertUtil.convertToDouble("property " + name, getObjectProperty(name));
    }

    public String getStringProperty(String name) throws JMSException {
        return PropertyConvertUtil.convertToString("property " + name, getObjectProperty(name));
    }

    public Object getObjectProperty(String name) throws JMSException {
        if (name == null) {
            throw new NullPointerException("Property name cannot be null");
        }
        return _properties.get(name);
    }

    public Enumeration getPropertyNames() throws JMSException {
        return new Vector(_properties.keySet()).elements();
    }

    public void setBooleanProperty(String name, boolean value) throws JMSException {
        setObjectProperty(name, value);
    }

    public void setByteProperty(String name, byte value) throws JMSException {
        setObjectProperty(name, value);
    }

    public void setShortProperty(String name, short value) throws JMSException {
        setObjectProperty(name, value);
    }

    public void setIntProperty(String name, int value) throws JMSException {
        setObjectProperty(name, value);
    }

    public void setLongProperty(String name, long value) throws JMSException {
        setObjectProperty(name, value);
    }

    public void setFloatProperty(String name, float value) throws JMSException {
        setObjectProperty(name, value);
    }

    public void setDoubleProperty(String name, double value) throws JMSException {
        setObjectProperty(name, value);
    }

    public void setStringProperty(String name, String value) throws JMSException {
        setObjectProperty(name, value);
    }

    public void setObjectProperty(String name, Object value) throws JMSException {
        checkReadOnlyProperties();
        checkValidPropertyName(name);
        internalSetObjectProperty(name, value);
        // TODO - Food for thought: ActiveMQMessage uses the idea of property setter to enforce the data type for defined properties.  May be overkill.
    }

    protected void internalSetObjectProperty(String name, Object value) throws JMSException {
        if (name == null || name.trim().equals("")) {
            throw new IllegalArgumentException("Property name cannot be empty or null");
        }
        PropertyConvertUtil.checkValidObject(value);
        _properties.put(name, value);
    }
            
    public abstract void acknowledge() throws JMSException;

    private void checkReadOnlyProperties() throws MessageNotWriteableException {
        if (_readOnlyProperties) {
            throw new MessageNotWriteableException("Message properties are read-only");
        }
    }

    protected void checkReadOnlyBody() throws MessageNotWriteableException {
        if (_readOnlyBody) {
            throw new MessageNotWriteableException("Message body is read-only");
        }
    }

    // This is only used by StreamMessage, where readOnly and writeOnly are mutually exclusive.
    protected void checkWriteOnlyBody() throws MessageNotReadableException {
        if (!_readOnlyBody) {
            throw new MessageNotReadableException("Message body is write-only");
        }
    }

    private void checkValidPropertyName(String name)
    {
        if (name == null || name.trim().length() == 0)
        {
            throw new IllegalArgumentException("Property name cannot be empty");
        }
        if (!Character.isJavaIdentifierStart(name.charAt(0)))
        {
            throw new IllegalArgumentException("Invalid first character: " + name.charAt(0));
        }
        if (Arrays.asList(RESERVED_PROPERTY_NAMES).contains(name))
        {
            throw new IllegalArgumentException("Property name cannot be reserved word '" + name + "'");
        }
        if (name.startsWith(NevadoProperty.PROVIDER_PREFIX))
        {
            throw new IllegalArgumentException("Property name cannot start with provider-reserved prefix of "
                    + NevadoProperty.PROVIDER_PREFIX);
        }
        for(char c : WHITESPACE_CHARS.toCharArray())
        {
            if (name.indexOf(c) > -1) {
                throw new IllegalArgumentException("Property name cannot contain whitespace: '" + name + "'");
            }
        }
    }

    public void onSend() {
        _readOnlyProperties = true;
        _readOnlyBody = true;
    }

    public T copyOf() throws JMSException {
        try {
            byte[] data = SerializeUtil.serialize(this);
            return (T)SerializeUtil.deserialize(data);
        }
        catch(IOException e) {
            throw new JMSException("Unable to make copy of messsage: " + e.getMessage());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy