package er.imadaptor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import er.extensions.concurrency.ERXAsyncQueue;
public class InstantMessengerConnection {
private InstantMessageQueue _messageQueue;
private IInstantMessenger _instantMessenger;
private InstantMessengerWatchDog _watchDog;
private Map<String, Conversation> _conversations;
protected InstantMessengerConnection() {
_conversations = new HashMap<>();
_messageQueue = new InstantMessageQueue();
_messageQueue.start();
}
public InstantMessengerConnection(String screenName, String password, IInstantMessengerFactory factory) {
this();
_instantMessenger = factory.createInstantMessenger(screenName, password);
}
public InstantMessengerConnection(IInstantMessenger instantMessenger) {
this();
_instantMessenger = instantMessenger;
}
public void setWatchDog(String screenName, String password, IInstantMessengerFactory watchdogFactory) {
if (_watchDog != null) {
_watchDog.stop();
}
IInstantMessenger watchdogInstantMessenger = watchdogFactory.createInstantMessenger(screenName, password);
setWatchDog(watchdogInstantMessenger);
}
public void setWatchDog(IInstantMessenger instantMessenger) {
if (_watchDog != null) {
_watchDog.stop();
}
_watchDog = new InstantMessengerWatchDog(_instantMessenger, instantMessenger);
}
public IInstantMessenger instantMessenger() {
return _instantMessenger;
}
public InstantMessengerWatchDog watchDog() {
return _watchDog;
}
public List<Conversation> conversations() {
List<Conversation> conversations = new LinkedList<>(_conversations.values());
return conversations;
}
public Conversation conversationForBuddyNamed(String buddyName, long conversationTimeout) {
Conversation conversation;
synchronized (_conversations) {
conversation = _conversations.get(buddyName);
System.out.println("InstantMessengerConnection.conversationForBuddyNamed: conversation = " + conversation);
if (conversation == null || conversation.isExpired(conversationTimeout)) {
System.out.println("InstantMessengerConnection.conversationForBuddyNamed: ... created a new one");
conversation = new Conversation();
conversation.setScreenName(_instantMessenger.getScreenName());
conversation.setBuddyName(buddyName);
_conversations.put(buddyName, conversation);
}
else {
conversation.ping();
}
}
return conversation;
}
public void removeExpiredConversations(long conversationTimeout) {
synchronized (_conversations) {
Iterator conversationsIter = _conversations.entrySet().iterator();
while (conversationsIter.hasNext()) {
Map.Entry entry = (Map.Entry) conversationsIter.next();
Conversation conversation = (Conversation) entry.getValue();
if (conversation.isExpired(conversationTimeout)) {
conversationExpired(conversation);
conversationsIter.remove();
}
}
}
}
protected void conversationExpired(Conversation conversation) {
// DO NOTHING
}
public void sendMessage(String buddyName, String message, boolean block) throws MessageException {
if (block) {
_instantMessenger.sendMessage(buddyName, message, true);
}
else {
_messageQueue.enqueue(new Message(buddyName, message));
}
}
public void connect(IMessageListener messageListener) {
_instantMessenger.addMessageListener(messageListener);
try {
_instantMessenger.connect();
}
catch (Throwable e) {
InstantMessengerAdaptor.log.debug("Failed to connect to provider.", e);
}
if (_watchDog != null) {
_watchDog.start();
}
}
public void disconnect() {
if (_instantMessenger != null) {
_instantMessenger.disconnect();
}
if (_watchDog != null) {
_watchDog.stop();
}
}
protected static class Message {
private String _contents;
private String _buddyName;
public Message(String buddyName, String contents) {
_buddyName = buddyName;
_contents = contents;
}
public String contents() {
return _contents;
}
public String buddyName() {
return _buddyName;
}
}
protected class InstantMessageQueue extends ERXAsyncQueue<Message> {
@Override
public void process(Message message) {
try {
IInstantMessenger instantMessenger = instantMessenger();
instantMessenger.sendMessage(message.buddyName(), message.contents(), true);
}
catch (MessageException e) {
InstantMessengerAdaptor.log.error(e);
}
}
}
}