/*
* MicroJIAC - A Lightweight Agent Framework
* This file is part of MicroJIAC ActiveMQ-Broker.
*
* Copyright (c) 2007-2012 DAI-Labor, Technische Universität Berlin
*
* This library includes software developed at DAI-Labor, Technische
* Universität Berlin (http://www.dai-labor.de)
*
* This library is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* $Id$
*/
package de.jiac.micro.ext.jms;
import java.util.HashMap;
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import org.slf4j.Logger;
import com.github.libxjava.lang.IClassLoader;
import de.jiac.micro.agent.memory.IFact;
import de.jiac.micro.agent.memory.IShortTermMemory;
import de.jiac.micro.core.io.IAddress;
/**
* @author Marcel Patzlaff
* @version $Revision:$
*/
final class JMSReceiver implements MessageListener {
private final Logger _logger;
private final ContentTransformer _transformer;
private final Session _session;
private IShortTermMemory _stm;
private HashMap _consumers;
public JMSReceiver(Connection connection, IClassLoader classLoader, Logger log, IShortTermMemory stm)
throws JMSException {
_session= connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
_transformer= new ContentTransformer(classLoader);
_stm= stm;
_logger= log;
_consumers= new HashMap();
}
public synchronized void register(IAddress address) {
// first check if we already have a listener like that
String key= address.toString();
if (_consumers.containsKey(key)) {
_logger.warn("JMS: there is already a listener for '" + key + "' registered");
return;
}
// then create a listener if needed and map it with the others.
final MessageConsumer consumer= createConsumer((JMSAddress) address);
if (consumer != null) {
_consumers.put(key, consumer);
}
}
public synchronized void unregister(IAddress address) {
final String key= address.toString();
final MessageConsumer consumer= (MessageConsumer) _consumers.remove(key);
if (consumer != null) {
destroyConsumer(consumer);
}
_logger.debug("JMS: unregistered for address '" + address + "'");
}
public void onMessage(Message message) {
try {
/*
* By default JMS only delivers a message once per session. So it
* doesn't matter for which selector we received it, we won't get it
* through another consumer!
*/
if (message instanceof BytesMessage) {
IFact fact= _transformer.unpack((BytesMessage) message);
_stm.notice(fact);
} else {
_logger.warn("JMS: unsupported message type: " + message.getClass());
}
} catch (Exception e) {
_logger.error("JMS: error while receiving message", e);
}
}
private MessageConsumer createConsumer(JMSAddress address) {
MessageConsumer consumer= null;
try {
final String add= address.getAddressName();
final Destination dest;
if (address.getType() == IAddress.MULTICAST) {
dest= _session.createTopic(add);
} else {
dest= _session.createQueue(add);
}
consumer= _session.createConsumer(dest);
consumer.setMessageListener(this);
} catch (JMSException e) {
_logger.error("JMS: could not initialise consumer", e);
destroyConsumer(consumer);
consumer= null;
}
return consumer;
}
private void destroyConsumer(MessageConsumer consumer) {
if (consumer != null) {
try {
consumer.close();
} catch (JMSException e) {
_logger.warn("JMS: could not destroy consumer", e);
}
}
}
}