Package org.springframework.amqp.rabbit.support

Source Code of org.springframework.amqp.rabbit.support.DefaultMessagePropertiesConverter

/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed 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.springframework.amqp.rabbit.support;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.amqp.AmqpUnsupportedEncodingException;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.util.CollectionUtils;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.LongString;

/**
* Default implementation of the {@link MessagePropertiesConverter} strategy.
*
* @author Mark Fisher
* @author Gary Russell
* @author Soeren Unruh
* @since 1.0
*/
public class DefaultMessagePropertiesConverter implements MessagePropertiesConverter {

  public MessageProperties toMessageProperties(final BasicProperties source, final Envelope envelope,
      final String charset) {
    MessageProperties target = new MessageProperties();
    Map<String, Object> headers = source.getHeaders();
    if (!CollectionUtils.isEmpty(headers)) {
      for (Map.Entry<String, Object> entry : headers.entrySet()) {
        target.setHeader(entry.getKey(), convertLongStringIfNecessary(entry.getValue(), charset));
      }
    }
    target.setTimestamp(source.getTimestamp());
    target.setMessageId(source.getMessageId());
    target.setUserId(source.getUserId());
    target.setAppId(source.getAppId());
    target.setClusterId(source.getClusterId());
    target.setType(source.getType());
    Integer deliverMode = source.getDeliveryMode();
    if (deliverMode != null) {
      target.setDeliveryMode(MessageDeliveryMode.fromInt(deliverMode));
    }
    target.setExpiration(source.getExpiration());
    target.setPriority(source.getPriority());
    target.setContentType(source.getContentType());
    target.setContentEncoding(source.getContentEncoding());
    String correlationId = source.getCorrelationId();
    if (correlationId != null) {
      try {
        target.setCorrelationId(source.getCorrelationId().getBytes(charset));
      } catch (UnsupportedEncodingException ex) {
        throw new AmqpUnsupportedEncodingException(ex);
      }
    }
    String replyTo = source.getReplyTo();
    if (replyTo != null) {
      target.setReplyTo(replyTo);
    }
    if (envelope != null) {
      target.setReceivedExchange(envelope.getExchange());
      target.setReceivedRoutingKey(envelope.getRoutingKey());
      target.setRedelivered(envelope.isRedeliver());
      target.setDeliveryTag(envelope.getDeliveryTag());
    }
    return target;
  }

  public BasicProperties fromMessageProperties(final MessageProperties source, final String charset) {
    BasicProperties.Builder target = new BasicProperties.Builder();
    target.headers(this.convertHeadersIfNecessary(source.getHeaders()));
    target.timestamp(source.getTimestamp());
    target.messageId(source.getMessageId());
    target.userId(source.getUserId());
    target.appId(source.getAppId());
    target.clusterId(source.getClusterId());
    target.type(source.getType());
    MessageDeliveryMode deliveryMode = source.getDeliveryMode();
    if (deliveryMode != null) {
      target.deliveryMode(MessageDeliveryMode.toInt(deliveryMode));
    }
    target.expiration(source.getExpiration());
    target.priority(source.getPriority());
    target.contentType(source.getContentType());
    target.contentEncoding(source.getContentEncoding());
    byte[] correlationId = source.getCorrelationId();
    if (correlationId != null && correlationId.length > 0) {
      try {
        target.correlationId(new String(correlationId, charset));
      } catch (UnsupportedEncodingException ex) {
        throw new AmqpUnsupportedEncodingException(ex);
      }
    }
    String replyTo = source.getReplyTo();
    if (replyTo != null) {
      target.replyTo(replyTo);
    }
    return target.build();
  }

  private Map<String, Object> convertHeadersIfNecessary(Map<String, Object> headers) {
    if (CollectionUtils.isEmpty(headers)) {
      return Collections.<String, Object> emptyMap();
    }
    Map<String, Object> writableHeaders = new HashMap<String, Object>();
    for (Map.Entry<String, Object> entry : headers.entrySet()) {
      writableHeaders.put(entry.getKey(), this.convertHeaderValueIfNecessary(entry.getValue()));
    }
    return writableHeaders;
  }

  /**
   * Converts a header value to a String if the value type is unsupported by AMQP, also handling values
   * nested inside Lists or Maps.
   * <p> {@code null} values are passed through, although Rabbit client will throw an IllegalArgumentException.
   */
  private Object convertHeaderValueIfNecessary(Object value) {
    boolean valid = (value instanceof String) || (value instanceof byte[]) || (value instanceof Boolean)
        || (value instanceof LongString) || (value instanceof Integer) || (value instanceof Long)
        || (value instanceof Float) || (value instanceof Double) || (value instanceof BigDecimal)
        || (value instanceof Short) || (value instanceof Byte) || (value instanceof Date)
        || (value instanceof List) || (value instanceof Map);
    if (!valid && value != null) {
      value = value.toString();
    }
    else if (value instanceof List<?>) {
      List<Object> writableList = new ArrayList<Object>(((List<?>) value).size());
      for (Object listValue : (List<?>) value) {
        writableList.add(convertHeaderValueIfNecessary(listValue));
      }
      value = writableList;
    }
    else if (value instanceof Map<?, ?>) {
      @SuppressWarnings("unchecked")
      Map<String, Object> originalMap = (Map<String, Object>) value;
      Map<String, Object> writableMap = new HashMap<String, Object>(originalMap.size());
      for (Map.Entry<String, Object> entry : originalMap.entrySet()) {
        writableMap.put(entry.getKey(), this.convertHeaderValueIfNecessary(entry.getValue()));
      }
      value = writableMap;
    }
    return value;
  }

  /**
   * Converts a LongString value to either a String or DataInputStream based on a length-driven threshold. If the
   * length is 1024 bytes or less, a String will be returned, otherwise a DataInputStream is returned.
   */
  private Object convertLongString(LongString longString, String charset) {
    try {
      if (longString.length() <= 1024) {
        return new String(longString.getBytes(), charset);
      } else {
        return longString.getStream();
      }
    } catch (Exception e) {
      throw RabbitExceptionTranslator.convertRabbitAccessException(e);
    }
  }

  /**
   * Converts a LongString value using {@link #convertLongString(LongString, String)}, also handling values
   * nested in Lists or Maps.
   */
  private Object convertLongStringIfNecessary(Object value, String charset) {
    if (value instanceof LongString) {
      value = convertLongString((LongString) value, charset);
    }
    else if (value instanceof List<?>) {
      List<Object> convertedList = new ArrayList<Object>(((List<?>) value).size());
      for (Object listValue : (List<?>) value) {
        convertedList.add(this.convertLongStringIfNecessary(listValue, charset));
      }
      value = convertedList;
    }
    else if (value instanceof Map<?, ?>) {
      @SuppressWarnings("unchecked")
      Map<String, Object> originalMap = (Map<String, Object>) value;
      Map<String, Object> convertedMap = new HashMap<String, Object>();
      for (Map.Entry<String, Object> entry : originalMap.entrySet()) {
        convertedMap.put(entry.getKey(), this.convertLongStringIfNecessary(entry.getValue(), charset));
      }
      value = convertedMap;
    }
    return value;
  }

}
TOP

Related Classes of org.springframework.amqp.rabbit.support.DefaultMessagePropertiesConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.