/*
* 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.io.IOException;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import org.slf4j.Logger;
import com.github.libxjava.lang.IClassLoader;
import de.jiac.micro.agent.IActuator;
import de.jiac.micro.agent.ISensor;
import de.jiac.micro.agent.handle.ICommunicationHandle;
import de.jiac.micro.agent.memory.IShortTermMemory;
import de.jiac.micro.core.IAgent;
import de.jiac.micro.core.IHandle;
import de.jiac.micro.core.ILifecycleAware;
import de.jiac.micro.core.io.IAddress;
import de.jiac.micro.core.io.IMessage;
import de.jiac.micro.core.io.IMulticastAddress;
import de.jiac.micro.core.io.IUnicastAddress;
import de.jiac.micro.core.scope.AgentScope;
import de.jiac.micro.internal.io.Message;
/**
* @author Marcel Patzlaff
* @version $Revision:$
*/
public final class JMSCommunicationElement implements ISensor, IActuator, ILifecycleAware, ICommunicationHandle {
private IShortTermMemory _stm;
private ConnectionFactory _connectionFactory;
private Connection _connection;
private Logger _logger;
private JMSSender _sender;
private JMSReceiver _receiver;
private IUnicastAddress _localAddress;
public void setShortTermMemory(IShortTermMemory stm) {
_stm= stm;
}
public IHandle getHandle() {
return this;
}
public void cleanup() {
_sender= null;
_receiver= null;
if(_connection != null) {
try {
_connection.close();
} catch (JMSException e) {
_logger.warn("JMS: could not close connection", e);
}
_connection= null;
}
_connectionFactory= null;
_localAddress= null;
_logger= null;
}
public void initialise() {
IAgent agent= AgentScope.getAgentReference();
IClassLoader classLoader= (IClassLoader) agent.getHandle(IClassLoader.class);
_logger= agent.getLogger("JMS");
_connectionFactory= (JMSLocalConnectionFactory) agent.getHandle(JMSLocalConnectionFactory.class);
if(_connectionFactory == null) {
_logger.error("JMS: node has no local JMS broker");
// TODO: build local factory?
}
if(_connectionFactory != null) {
try {
_connection= _connectionFactory.createConnection();
} catch (JMSException e) {
_logger.error("JMS: could not create connection", e);
}
}
if(_connection != null) {
try {
_receiver= new JMSReceiver(_connection, classLoader, _logger, _stm);
} catch (JMSException e) {
_logger.error("JMS: could not create receiver", e);
_receiver= null;
}
try {
_sender= new JMSSender(_connection, classLoader, _logger);
} catch (JMSException e) {
_logger.error("JMS: could not create sender", e);
_sender= null;
}
}
_localAddress= new JMSAddress(IAddress.UNICAST, "agent" + System.currentTimeMillis() + "h" + System.identityHashCode(AgentScope.getAgentReference()));
}
public void start() {
if(_connection != null) {
try {
_connection.start();
} catch (JMSException e) {
_logger.error("JMS: could not start connection", e);
}
}
try {
changeRegistration(_localAddress, false);
} catch (IOException e) {
_logger.error("JMS: could not register unicast address '" + _localAddress + "'", e);
}
}
public void stop() {
try {
changeRegistration(_localAddress, true);
} catch (IOException e) {
_logger.error("JMS: could not unregister unicast address '" + _localAddress + "'", e);
}
if(_connection != null) {
try {
_connection.stop();
} catch (JMSException e) {
_logger.error("JMS: could not stop connection", e);
}
}
}
public IMessage createMessage() {
return new Message();
}
public IAddress getAddressForString(String addressStr) {
return JMSAddress.getAddressForString(addressStr);
}
public IUnicastAddress[] getLocalAddresses() {
return new IUnicastAddress[] {_localAddress};
}
public IMulticastAddress getMulticastAddressForName(String groupName) {
return new JMSAddress(IAddress.MULTICAST, groupName);
}
public void joinGroup(IMulticastAddress address) throws IOException {
changeRegistration(address, false);
}
public void leaveGroup(IMulticastAddress address) throws IOException {
changeRegistration(address, true);
}
public void sendMessage(IAddress address, IMessage message) throws IOException {
if(_sender == null) {
throw new IOException("sender is not available");
}
try {
message.setHeader(IMessage.DefaultHeader.SOURCE_ADDRESS, _localAddress.toString());
message.setHeader(IMessage.DefaultHeader.TARGET_ADDRESS, address.toString());
_sender.send(message, address);
} catch (Exception e) {
e.printStackTrace();
}
}
private void changeRegistration(IAddress address, boolean unregister) throws IOException {
if(_receiver == null) {
throw new IOException("receiver is not available");
}
if(unregister) {
_receiver.unregister(address);
} else {
_receiver.register(address);
}
}
}