/**
* $Revision: $
* $Date: $
*
* Copyright (C) 2006 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Lesser Public License (LGPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.spark;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.MessageEventNotificationListener;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.spark.ui.ChatContainer;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.ChatRoomListener;
import org.jivesoftware.spark.ui.ChatRoomNotFoundException;
import org.jivesoftware.spark.ui.ContactItem;
import org.jivesoftware.spark.ui.ContactItemHandler;
import org.jivesoftware.spark.ui.ContactList;
import org.jivesoftware.spark.ui.MessageFilter;
import org.jivesoftware.spark.ui.conferences.RoomInvitationListener;
import org.jivesoftware.spark.ui.rooms.ChatRoomImpl;
import org.jivesoftware.spark.ui.rooms.GroupChatRoom;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;
import javax.swing.Icon;
import javax.swing.SwingUtilities;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* Handles the Chat Management of each individual Workspace. The ChatManager is responsible
* for creation and removal of chat rooms, transcripts, and transfers and room invitations.
*/
public class ChatManager implements MessageEventNotificationListener {
private List messageFilters = new ArrayList();
private List invitationListeners = new ArrayList();
private final ChatContainer chatContainer;
private String conferenceService;
private List contactItemHandlers = new ArrayList();
private Set customList = new HashSet();
private static ChatManager singleton;
private static final Object LOCK = new Object();
/**
* Returns the singleton instance of ChatManager,
* creating it if necessary.
*
*
* @return the singleton instance of ChatManager
*/
public static ChatManager getInstance() {
// Synchronize on LOCK to ensure that we don't end up creating
// two singletons.
synchronized (LOCK) {
if (null == singleton) {
ChatManager controller = new ChatManager();
singleton = controller;
return controller;
}
}
return singleton;
}
/**
* Create a new instance of ChatManager.
*/
private ChatManager() {
chatContainer = new ChatContainer();
// Add a Message Handler
SparkManager.getMessageEventManager().addMessageEventNotificationListener(this);
SparkManager.getConnection().addPacketListener(new PacketListener() {
public void processPacket(final Packet packet) {
try {
if (customList.contains(StringUtils.parseBareAddress(packet.getFrom()))) {
cancelledNotification(packet.getFrom(), "");
}
}
catch (Exception e) {
Log.error(e);
}
}
}, new PacketTypeFilter(Message.class));
}
/**
* Used to listen for rooms opening, closing or being
* activated( already opened, but tabbed to )
*
* @param listener the ChatRoomListener to add
*/
public void addChatRoomListener(ChatRoomListener listener) {
getChatContainer().addChatRoomListener(listener);
}
/**
* Simplace facade for chatroom. Removes a listener
*
* @param listener the ChatRoomListener to remove
*/
public void removeChatRoomListener(ChatRoomListener listener) {
getChatContainer().removeChatRoomListener(listener);
}
/**
* Removes the personal 1 to 1 chat from the ChatFrame.
*
* @param chatRoom the ChatRoom to remove.
*/
public void removeChat(ChatRoom chatRoom) {
chatContainer.closeTab(chatRoom);
}
/**
* Returns all ChatRooms currently active.
*
* @return all ChatRooms.
*/
public ChatContainer getChatContainer() {
return chatContainer;
}
/**
* Returns the MultiUserChat associated with the specified roomname.
*
* @param roomName the name of the chat room.
* @return the MultiUserChat found for that room.
*/
public GroupChatRoom getGroupChat(String roomName) throws ChatNotFoundException {
Iterator iter = getChatContainer().getAllChatRooms();
while (iter.hasNext()) {
ChatRoom chatRoom = (ChatRoom)iter.next();
if (chatRoom instanceof GroupChatRoom) {
GroupChatRoom groupChat = (GroupChatRoom)chatRoom;
if (groupChat.getRoomname().equals(roomName)) {
return groupChat;
}
}
}
throw new ChatNotFoundException("Could not locate Group Chat Room - " + roomName);
}
/**
* Creates and/or opens a chat room with the specified user.
*
* @param userJID the jid of the user to chat with.
* @param nickname the nickname to use for the user.
*/
public ChatRoom createChatRoom(String userJID, String nickname, String title) {
ChatRoom chatRoom = null;
try {
chatRoom = getChatContainer().getChatRoom(userJID);
}
catch (ChatRoomNotFoundException e) {
chatRoom = new ChatRoomImpl(userJID, nickname, title);
getChatContainer().addChatRoom(chatRoom);
}
return chatRoom;
}
/**
* Returns the ChatRoom for the giving jid. If the ChatRoom is not found,
* a new ChatRoom will be created.
*
* @param jid the jid of the user to chat with.
* @return the ChatRoom.
*/
public ChatRoom getChatRoom(String jid) {
ChatRoom chatRoom = null;
try {
chatRoom = getChatContainer().getChatRoom(jid);
}
catch (ChatRoomNotFoundException e) {
ContactList contactList = SparkManager.getWorkspace().getContactList();
ContactItem item = contactList.getContactItemByJID(jid);
if (item != null) {
String nickname = item.getNickname();
chatRoom = new ChatRoomImpl(jid, nickname, nickname);
}
else {
chatRoom = new ChatRoomImpl(jid, jid, jid);
}
getChatContainer().addChatRoom(chatRoom);
}
return chatRoom;
}
/**
* Creates a new public Conference Room.
*
* @param roomName the name of the room.
* @param serviceName the service name to use (ex.conference.jivesoftware.com)
* @return the new ChatRoom created. If an error occured, null will be returned.
*/
public ChatRoom createConferenceRoom(String roomName, String serviceName) {
final MultiUserChat chatRoom = new MultiUserChat(SparkManager.getConnection(), roomName + "@" + serviceName);
final GroupChatRoom room = new GroupChatRoom(chatRoom);
try {
LocalPreferences pref = SettingsManager.getLocalPreferences();
chatRoom.create(pref.getNickname());
// Send an empty room configuration form which indicates that we want
// an instant room
chatRoom.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));
}
catch (XMPPException e1) {
Log.error("Unable to send conference room chat configuration form.", e1);
return null;
}
getChatContainer().addChatRoom(room);
return room;
}
/**
* Adds a new MessageFilter.
*
* @param filter the MessageFilter.
*/
public void addMessageFilter(MessageFilter filter) {
messageFilters.add(filter);
}
/**
* Removes a MessageFilter.
*
* @param filter the MessageFilter.
*/
public void removeMessageFilter(MessageFilter filter) {
messageFilters.remove(filter);
}
/**
* Returns a Collection of MessageFilters registered to Spark.
*
* @return the Collection of MessageFilters.
*/
public Collection getMessageFilters() {
return messageFilters;
}
public void filterIncomingMessage(ChatRoom room, Message message) {
// Fire Message Filters
final ChatManager chatManager = SparkManager.getChatManager();
Iterator filters = chatManager.getMessageFilters().iterator();
while (filters.hasNext()) {
((MessageFilter)filters.next()).filterIncoming(room, message);
}
}
public void filterOutgoingMessage(ChatRoom room, Message message) {
// Fire Message Filters
final ChatManager chatManager = SparkManager.getChatManager();
Iterator filters = chatManager.getMessageFilters().iterator();
while (filters.hasNext()) {
((MessageFilter)filters.next()).filterOutgoing(room, message);
}
}
public void addInvitationListener(RoomInvitationListener listener) {
invitationListeners.add(listener);
}
public void removeInvitationListener(RoomInvitationListener listener) {
invitationListeners.remove(listener);
}
public Collection getInvitationListeners() {
return invitationListeners;
}
public String getDefaultConferenceService() {
if (conferenceService == null) {
try {
Collection col = MultiUserChat.getServiceNames(SparkManager.getConnection());
if (col.size() > 0) {
conferenceService = (String)col.iterator().next();
}
}
catch (XMPPException e) {
Log.error(e);
}
}
return conferenceService;
}
public void addContactItemHandler(ContactItemHandler handler) {
contactItemHandlers.add(handler);
}
public void removeContactItemHandler(ContactItemHandler handler) {
contactItemHandlers.remove(handler);
}
public boolean fireContactItemPresenceChanged(ContactItem item, Presence presence) {
for (ContactItemHandler handler : contactItemHandlers) {
if (handler.handlePresence(item, presence)) {
return true;
}
}
return false;
}
public boolean fireContactItemDoubleClicked(ContactItem item) {
for (ContactItemHandler handler : contactItemHandlers) {
if (handler.handleDoubleClick(item)) {
return true;
}
}
return false;
}
public Icon getPresenceIconForContactHandler(Presence presence) {
for (ContactItemHandler handler : contactItemHandlers) {
Icon icon = handler.useIcon(presence);
if (icon != null) {
return icon;
}
}
return null;
}
// Implemenation of MessageEventListener
public void deliveredNotification(String from, String packetID) {
}
public void displayedNotification(String from, String packetID) {
}
public void composingNotification(final String from, String packetID) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final ContactList contactList = SparkManager.getWorkspace().getContactList();
ChatRoom chatRoom = null;
try {
chatRoom = getChatContainer().getChatRoom(StringUtils.parseBareAddress(from));
if (chatRoom != null && chatRoom instanceof ChatRoomImpl) {
((ChatRoomImpl)chatRoom).showTyping(true);
}
}
catch (ChatRoomNotFoundException e) {
}
contactList.setIconFor(from, SparkRes.getImageIcon(SparkRes.SMALL_MESSAGE_EDIT_IMAGE));
customList.add(StringUtils.parseBareAddress(from));
}
});
}
public void offlineNotification(String from, String packetID) {
}
public void cancelledNotification(final String from, String packetID) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ContactList contactList = SparkManager.getWorkspace().getContactList();
ChatRoom chatRoom = null;
try {
chatRoom = getChatContainer().getChatRoom(StringUtils.parseBareAddress(from));
if (chatRoom != null && chatRoom instanceof ChatRoomImpl) {
((ChatRoomImpl)chatRoom).showTyping(false);
}
}
catch (ChatRoomNotFoundException e) {
}
contactList.useDefaults(from);
customList.remove(StringUtils.parseBareAddress(from));
}
});
}
}