/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.transport.jms; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; import javax.jms.Message; import org.springframework.jms.core.JmsTemplate; import com.opengamma.transport.ByteArraySource; import com.opengamma.util.ArgumentChecker; /** * A byte array source for JMS. * <p> * The {@code receiveTimeout} property on the supplied {@link JmsTemplate} * is completely ignored, being changed dynamically by this class. * The whole class is synchronized to ensure that the last message batch is maintained * properly, and use of the underlying {@link JmsTemplate} is handled properly. */ public class JmsByteArraySource implements ByteArraySource { /** * The underlying JMS template. */ private final JmsTemplate _jmsTemplate; /** * The last message batch. */ private final List<Message> _lastMessageBatch = Collections.synchronizedList(new ArrayList<Message>()); /** * Creates an instance wrapping a JMS template. * * @param jmsTemplate the JMS template, not null */ public JmsByteArraySource(final JmsTemplate jmsTemplate) { ArgumentChecker.notNull(jmsTemplate, "jmsTemplate"); _jmsTemplate = jmsTemplate; } //------------------------------------------------------------------------- /** * Gets the underlying JMS template. * * @return the underlying JMS template, not null */ public JmsTemplate getJmsTemplate() { return _jmsTemplate; } /** * Gets a copy of the last message batch. * * @return the last batch, not null */ public List<Message> getLastMessageBatch() { synchronized (_lastMessageBatch) { // need to sync as following line uses iterator return new ArrayList<Message>(_lastMessageBatch); } } //------------------------------------------------------------------------- @Override public synchronized List<byte[]> batchReceive(final long maxWaitInMilliseconds) { getJmsTemplate().setReceiveTimeout(maxWaitInMilliseconds); Message message = getJmsTemplate().receive(); if (message == null) { return Collections.emptyList(); } _lastMessageBatch.clear(); final List<byte[]> byteBatch = new LinkedList<byte[]>(); getJmsTemplate().setReceiveTimeout(JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT); while (message != null) { _lastMessageBatch.add(message); byte[] bytes = JmsByteArrayHelper.extractBytes(message); byteBatch.add(bytes); message = getJmsTemplate().receive(); } return byteBatch; } @Override public synchronized List<byte[]> batchReceiveNoWait() { return batchReceive(JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT); } @Override public synchronized byte[] receive(final long maxWaitInMilliseconds) { getJmsTemplate().setReceiveTimeout(maxWaitInMilliseconds); final Message message = getJmsTemplate().receive(); byte[] bytes = JmsByteArrayHelper.extractBytes(message); _lastMessageBatch.clear(); _lastMessageBatch.add(message); return bytes; } @Override public synchronized byte[] receiveNoWait() { return receive(JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT); } }