diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java index 1cdab0aa0..e10910ea0 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/conference/ConferenceChatManager.java @@ -1,1268 +1,1267 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.gui.main.chat.conference; - -import java.util.*; -import java.util.concurrent.*; - -import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.impl.gui.main.chat.*; -import net.java.sip.communicator.impl.gui.main.chat.history.*; -import net.java.sip.communicator.impl.gui.main.chatroomslist.*; -import net.java.sip.communicator.plugin.desktoputil.*; -import net.java.sip.communicator.plugin.desktoputil.chat.*; -import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.muc.*; -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.event.*; -import net.java.sip.communicator.service.protocol.globalstatus.*; -import net.java.sip.communicator.util.*; - -import org.jdesktop.swingworker.SwingWorker; -import org.osgi.framework.*; - -import javax.swing.*; - -/** - * The ConferenceChatManager is the one that manages both chat room and - * ad-hoc chat rooms invitations. - * - * @author Yana Stamcheva - * @author Lubomir Marinov - * @author Valentin Martinet - * @author Hristo Terezov - */ -public class ConferenceChatManager - implements ChatRoomMessageListener, - ChatRoomInvitationListener, - ChatRoomInvitationRejectionListener, - AdHocChatRoomMessageListener, - AdHocChatRoomInvitationListener, - AdHocChatRoomInvitationRejectionListener, - LocalUserChatRoomPresenceListener, - LocalUserAdHocChatRoomPresenceListener, - ServiceListener -{ - /** - * The object used for logging. - */ - private static final Logger logger - = Logger.getLogger(ConferenceChatManager.class); - - /** - * Maps each history window to a ChatRoomWrapper. - */ - private final Hashtable chatRoomHistory = - new Hashtable(); - - /** - * The list of ad-hoc chat rooms. - */ - private final AdHocChatRoomList adHocChatRoomList = new AdHocChatRoomList(); - - /** - * A list of all AdHocChatRoomListChangeListener-s. - */ - private final Vector - adHoclistChangeListeners = new Vector(); - - /** - * Creates an instance of ConferenceChatManager. - */ - public ConferenceChatManager() - { - // Loads the chat rooms list in a separate thread. - new Thread() - { - @Override - public void run() - { - adHocChatRoomList.loadList(); - } - }.start(); - - GuiActivator.bundleContext.addServiceListener(this); - - } - - /** - * Returns all chat room providers currently contained in the ad-hoc chat - * room list. - * - * @return all chat room providers currently contained in the ad-hoc chat - * room list. - */ - public AdHocChatRoomList getAdHocChatRoomList() - { - return adHocChatRoomList; - } - - /** - * Handles ChatRoomInvitationReceivedEvent-s. - */ - public void invitationReceived(ChatRoomInvitationReceivedEvent evt) - { - InvitationReceivedDialog dialog - = new InvitationReceivedDialog( - this, - evt.getSourceOperationSet(), - evt.getInvitation()); - - dialog.setVisible(true); - } - - public void invitationRejected(ChatRoomInvitationRejectedEvent evt) {} - - /** - * Implements the ChatRoomMessageListener.messageDelivered method. - *
- * Shows the message in the conversation area and clears the write message - * area. - * @param evt the ChatRoomMessageDeliveredEvent that notified us - * that the message was delivered to its destination - */ - public void messageDelivered(ChatRoomMessageDeliveredEvent evt) - { - ChatRoom sourceChatRoom = (ChatRoom) evt.getSource(); - - if (logger.isTraceEnabled()) - logger.trace( - "MESSAGE DELIVERED to chat room: " + sourceChatRoom.getName()); - - ChatPanel chatPanel = GuiActivator.getUIService().getChatWindowManager() - .getMultiChat(sourceChatRoom, false); - - if(chatPanel != null) - { - String messageType; - - switch (evt.getEventType()) - { - case ChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED: - messageType = Chat.OUTGOING_MESSAGE; - break; - case ChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED: - messageType = Chat.ACTION_MESSAGE; - break; - default: - messageType = null; - break; - } - - Message msg = evt.getMessage(); - - chatPanel.addMessage( - sourceChatRoom.getUserNickname(), - null, - evt.getTimestamp(), - messageType, - msg.getContent(), - msg.getContentType(), - msg.getMessageUID(), - null); - } - } - - /** - * Implements the ChatRoomMessageListener.messageReceived method. - *
- * Obtains the corresponding ChatPanel and process the message - * there. - * @param evt the ChatRoomMessageReceivedEvent that notified us - * that a message has been received - */ - public void messageReceived(ChatRoomMessageReceivedEvent evt) - { - ChatRoom sourceChatRoom = evt.getSourceChatRoom(); - ChatRoomMember sourceMember = evt.getSourceChatRoomMember(); - - String messageType = null; - - switch (evt.getEventType()) - { - case ChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED: - messageType = Chat.INCOMING_MESSAGE; - break; - case ChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED: - messageType = Chat.SYSTEM_MESSAGE; - break; - case ChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED: - messageType = Chat.ACTION_MESSAGE; - break; - } - - if (logger.isTraceEnabled()) - logger.trace("MESSAGE RECEIVED from contact: " - + sourceMember.getContactAddress()); - - Message message = evt.getMessage(); - - ChatPanel chatPanel = null; - - ChatWindowManager chatWindowManager - = GuiActivator.getUIService().getChatWindowManager(); - - if(sourceChatRoom.isSystem()) - { - ChatRoomProviderWrapper serverWrapper - = GuiActivator.getMUCService().findServerWrapperFromProvider( - sourceChatRoom.getParentProvider()); - - chatPanel = chatWindowManager.getMultiChat( - serverWrapper.getSystemRoomWrapper(), true); - } - else - { - chatPanel = chatWindowManager.getMultiChat( - sourceChatRoom, true, message.getMessageUID()); - } - - String messageContent = message.getContent(); - - if (evt.isHistoryMessage()) - { - Date timeStamp = chatPanel.getChatConversationPanel() - .getLastIncomingMsgTimestamp(); - Collection c = - chatPanel.getChatSession().getHistoryBeforeDate( - new Date( - timeStamp.equals(new Date(0)) - ? System.currentTimeMillis() - 10000 - : timeStamp.getTime() - ), 20); - if (c.size() > 0) - { - boolean isPresent = false; - for (Object o : c) - { - if (o instanceof ChatRoomMessageDeliveredEvent) - { - ChatRoomMessageDeliveredEvent ev = - (ChatRoomMessageDeliveredEvent) o; - if (evt.getTimestamp() != null - && evt.getTimestamp().equals(ev.getTimestamp())) - { - isPresent = true; - break; - } - } - else if(o instanceof ChatRoomMessageReceivedEvent) - { - ChatRoomMessageReceivedEvent ev = - (ChatRoomMessageReceivedEvent) o; - if (evt.getTimestamp() != null - && evt.getTimestamp().equals(ev.getTimestamp())) - { - isPresent = true; - break; - } - } - } - - if (isPresent) - return; - } - } - - chatPanel.addMessage( - sourceMember.getName(), - null, - evt.getTimestamp(), - messageType, - messageContent, - message.getContentType(), - message.getMessageUID(), - null); - - chatWindowManager.openChat(chatPanel, false); - } - - - /** - * Implements the ChatRoomMessageListener.messageDeliveryFailed - * method. - *
- * In the conversation area shows an error message, explaining the problem. - * @param evt the ChatRoomMessageDeliveryFailedEvent that notified - * us of a delivery failure - */ - public void messageDeliveryFailed(ChatRoomMessageDeliveryFailedEvent evt) - { - ChatRoom sourceChatRoom = evt.getSourceChatRoom(); - - String errorMsg = null; - - /* - * FIXME ChatRoomMessageDeliveryFailedEvent#getSource() is not a Message - * instance at the time of this writing and the attempt "(Message) - * evt.getSource()" seems to be to get the message which failed to be - * delivered. I'm not sure it's - * ChatRoomMessageDeliveryFailedEvent#getMessage() but since it's the - * only message I can get out of ChatRoomMessageDeliveryFailedEvent, I'm - * using it. - */ - Message sourceMessage = evt.getMessage(); - - ChatRoomMember destMember = evt.getDestinationChatRoomMember(); - - if (evt.getErrorCode() - == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED) - { - errorMsg = GuiActivator.getResources().getI18NString( - "service.gui.MSG_DELIVERY_NOT_SUPPORTED", - new String[]{destMember.getName()}); - } - else if (evt.getErrorCode() - == MessageDeliveryFailedEvent.NETWORK_FAILURE) - { - errorMsg = GuiActivator.getResources() - .getI18NString("service.gui.MSG_NOT_DELIVERED"); - } - else if (evt.getErrorCode() - == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED) - { - errorMsg = GuiActivator.getResources().getI18NString( - "service.gui.MSG_SEND_CONNECTION_PROBLEM"); - } - else if (evt.getErrorCode() - == MessageDeliveryFailedEvent.INTERNAL_ERROR) - { - errorMsg = GuiActivator.getResources().getI18NString( - "service.gui.MSG_DELIVERY_INTERNAL_ERROR"); - } - else - { - errorMsg = GuiActivator.getResources().getI18NString( - "service.gui.MSG_DELIVERY_UNKNOWN_ERROR"); - } - - String reason = evt.getReason(); - if (reason != null) - errorMsg += " " + GuiActivator.getResources().getI18NString( - "service.gui.ERROR_WAS", - new String[]{reason}); - - ChatWindowManager chatWindowManager - = GuiActivator.getUIService().getChatWindowManager(); - ChatPanel chatPanel - = chatWindowManager.getMultiChat(sourceChatRoom, true); - - chatPanel.addMessage( - destMember.getName(), - new Date(), - Chat.OUTGOING_MESSAGE, - sourceMessage.getContent(), - sourceMessage.getContentType()); - - chatPanel.addErrorMessage( - destMember.getName(), - errorMsg); - - chatWindowManager.openChat(chatPanel, false); - } - - /** - * Implements the - * LocalUserAdHocChatRoomPresenceListener.localUserPresenceChanged - * method - * - * @param evt the LocalUserAdHocChatRoomPresenceChangeEvent that - * notified us of a presence change - */ - public void localUserAdHocPresenceChanged( - LocalUserAdHocChatRoomPresenceChangeEvent evt) - { - AdHocChatRoom sourceAdHocChatRoom = evt.getAdHocChatRoom(); - AdHocChatRoomWrapper adHocChatRoomWrapper - = adHocChatRoomList - .findChatRoomWrapperFromAdHocChatRoom(sourceAdHocChatRoom); - - String eventType = evt.getEventType(); - - if (LocalUserAdHocChatRoomPresenceChangeEvent - .LOCAL_USER_JOINED.equals(eventType)) - { - if(adHocChatRoomWrapper != null) - { - this.fireAdHocChatRoomListChangedEvent( - adHocChatRoomWrapper, - AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED); - - ChatWindowManager chatWindowManager - = GuiActivator.getUIService().getChatWindowManager(); - ChatPanel chatPanel - = chatWindowManager - .getMultiChat(adHocChatRoomWrapper, true); - - // Check if we have already opened a chat window for this chat - // wrapper and load the real chat room corresponding to the - // wrapper. - if(chatPanel.isShown()) - ((AdHocConferenceChatSession) chatPanel.getChatSession()) - .loadChatRoom(sourceAdHocChatRoom); - else - chatWindowManager.openChat(chatPanel, true); - } - - sourceAdHocChatRoom.addMessageListener(this); - } - else if (evt.getEventType().equals( - LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOIN_FAILED)) - { - new ErrorDialog( - GuiActivator.getUIService().getMainFrame(), - GuiActivator.getResources().getI18NString("service.gui.ERROR"), - GuiActivator.getResources().getI18NString( - "service.gui.FAILED_TO_JOIN_CHAT_ROOM", - new String[]{sourceAdHocChatRoom.getName()}) - + evt.getReason()) - .showDialog(); - } - else if (LocalUserAdHocChatRoomPresenceChangeEvent - .LOCAL_USER_LEFT.equals(eventType) - || LocalUserAdHocChatRoomPresenceChangeEvent - .LOCAL_USER_DROPPED.equals(eventType)) - { - this.closeAdHocChatRoom(adHocChatRoomWrapper); - - // Need to refresh the chat room's list in order to change - // the state of the chat room to offline. - fireAdHocChatRoomListChangedEvent( - adHocChatRoomWrapper, - AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED); - - sourceAdHocChatRoom.removeMessageListener(this); - } - } - - /** - * Implements the - * LocalUserChatRoomPresenceListener.localUserPresenceChanged - * method. - * @param evt the LocalUserChatRoomPresenceChangeEvent that - * notified us - */ - public void localUserPresenceChanged( - final LocalUserChatRoomPresenceChangeEvent evt) - { - if(!SwingUtilities.isEventDispatchThread()) - { - SwingUtilities.invokeLater(new Runnable() - { - @Override - public void run() - { - localUserPresenceChanged(evt); - } - }); - return; - } - - ChatRoom sourceChatRoom = evt.getChatRoom(); - ChatRoomWrapper chatRoomWrapper - = GuiActivator.getMUCService().findChatRoomWrapperFromChatRoom( - sourceChatRoom); - - String eventType = evt.getEventType(); - - if (LocalUserChatRoomPresenceChangeEvent - .LOCAL_USER_JOINED.equals(eventType)) - { - if(chatRoomWrapper != null) - { - GuiActivator.getMUCService().fireChatRoomListChangedEvent( - chatRoomWrapper, - ChatRoomListChangeEvent.CHAT_ROOM_CHANGED); - - ChatWindowManager chatWindowManager - = GuiActivator.getUIService().getChatWindowManager(); - ChatPanel chatPanel - = chatWindowManager.getMultiChat(chatRoomWrapper, true); - - chatPanel.setChatIcon( - chatPanel.getChatSession().getChatStatusIcon()); - - // Check if we have already opened a chat window for this chat - // wrapper and load the real chat room corresponding to the - // wrapper. - if(chatPanel.isShown()) - ((ConferenceChatSession) chatPanel.getChatSession()) - .loadChatRoom(sourceChatRoom); - else - chatWindowManager.openChat(chatPanel, true); - } - - if (sourceChatRoom.isSystem()) - { - ChatRoomProviderWrapper serverWrapper - = GuiActivator.getMUCService() - .findServerWrapperFromProvider( - sourceChatRoom.getParentProvider()); - - serverWrapper.setSystemRoom(sourceChatRoom); - } - - sourceChatRoom.addMessageListener(this); - } - else if (LocalUserChatRoomPresenceChangeEvent - .LOCAL_USER_JOIN_FAILED.equals(eventType)) - { - new ErrorDialog( - GuiActivator.getUIService().getMainFrame(), - GuiActivator.getResources().getI18NString("service.gui.ERROR"), - GuiActivator.getResources().getI18NString( - "service.gui.FAILED_TO_JOIN_CHAT_ROOM", - new String[]{sourceChatRoom.getName()}) + evt.getReason()) - .showDialog(); - } - else if (LocalUserChatRoomPresenceChangeEvent - .LOCAL_USER_LEFT.equals(eventType) - || LocalUserChatRoomPresenceChangeEvent - .LOCAL_USER_KICKED.equals(eventType) - || LocalUserChatRoomPresenceChangeEvent - .LOCAL_USER_DROPPED.equals(eventType)) - { - if(chatRoomWrapper != null) - { - GuiActivator.getUIService() - .closeChatRoomWindow(chatRoomWrapper); - - // Need to refresh the chat room's list in order to change - // the state of the chat room to offline. - - GuiActivator.getMUCService().fireChatRoomListChangedEvent( - chatRoomWrapper, - ChatRoomListChangeEvent.CHAT_ROOM_CHANGED); - } - - sourceChatRoom.removeMessageListener(this); - } - } - - - /** - * Called to accept an incoming invitation. Adds the invitation chat room - * to the list of chat rooms and joins it. - * - * @param invitation the invitation to accept - * @param multiUserChatOpSet the operation set for chat conferencing - * @throws OperationFailedException if the accept fails - */ - public void acceptInvitation( - AdHocChatRoomInvitation invitation, - OperationSetAdHocMultiUserChat multiUserChatOpSet) - throws OperationFailedException - { - AdHocChatRoom chatRoom = invitation.getTargetAdHocChatRoom(); - - chatRoom.join(); - } - - /** - * Rejects the given invitation with the specified reason. - * - * @param multiUserChatAdHocOpSet the operation set to use for rejecting the - * invitation - * @param invitation the invitation to reject - * @param reason the reason for the rejection - */ - public void rejectInvitation( - OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet, - AdHocChatRoomInvitation invitation, - String reason) - { - multiUserChatAdHocOpSet.rejectInvitation(invitation, reason); - } - - /** - * Creates an ad-hoc chat room, by specifying the ad-hoc chat room name, the - * parent protocol provider and eventually, the contacts invited to - * participate in this ad-hoc chat room. - * - * @param protocolProvider the parent protocol provider. - * @param contacts the contacts invited when creating the chat room. - * @param reason the reason for this invitation - * @return the AdHocChatRoomWrapper corresponding to the created - * ad hoc chat room - */ - public AdHocChatRoomWrapper createAdHocChatRoom( - ProtocolProviderService protocolProvider, - Collection contacts, - String reason) - { - AdHocChatRoomWrapper chatRoomWrapper = null; - - OperationSetAdHocMultiUserChat groupChatOpSet - = protocolProvider - .getOperationSet(OperationSetAdHocMultiUserChat.class); - - // If there's no group chat operation set we have nothing to do here. - if (groupChatOpSet == null) - return null; - - AdHocChatRoom chatRoom = null; - - try - { - java.util.List members = new LinkedList(); - - for(String address : contacts) - members.add(address); - - chatRoom = groupChatOpSet.createAdHocChatRoom( - "chatroom-" + new Date().getTime(), members, reason); - } - catch (OperationFailedException ex) - { - new ErrorDialog( - GuiActivator.getUIService().getMainFrame(), - GuiActivator.getResources().getI18NString("service.gui.ERROR"), - GuiActivator.getResources().getI18NString( - "service.gui.CREATE_CHAT_ROOM_ERROR", - new String[]{protocolProvider.getProtocolName()}), - ex) - .showDialog(); - } - catch (OperationNotSupportedException ex) - { - new ErrorDialog( - GuiActivator.getUIService().getMainFrame(), - GuiActivator.getResources().getI18NString("service.gui.ERROR"), - GuiActivator.getResources().getI18NString( - "service.gui.CREATE_CHAT_ROOM_ERROR", - new String[]{protocolProvider.getProtocolName()}), - ex) - .showDialog(); - } - - if(chatRoom != null) - { - AdHocChatRoomProviderWrapper parentProvider - = adHocChatRoomList.findServerWrapperFromProvider( - protocolProvider); - - chatRoomWrapper = new AdHocChatRoomWrapper( - parentProvider, chatRoom); - parentProvider.addAdHocChatRoom(chatRoomWrapper); - adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper); - - fireAdHocChatRoomListChangedEvent( - chatRoomWrapper, - AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED); - } - - return chatRoomWrapper; - } - - /** - * Joins the given ad-hoc chat room - * - * @param chatRoomWrapper - */ - public void joinChatRoom(AdHocChatRoomWrapper chatRoomWrapper) - { - AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom(); - - if(chatRoom == null) - { - new ErrorDialog( - GuiActivator.getUIService().getMainFrame(), - GuiActivator.getResources().getI18NString("service.gui.WARNING"), - GuiActivator.getResources().getI18NString( - "service.gui.CHAT_ROOM_NOT_CONNECTED", - new String[]{chatRoomWrapper.getAdHocChatRoomName()})) - .showDialog(); - - return; - } - - new JoinAdHocChatRoomTask(chatRoomWrapper).execute(); - } - - /** - * Removes the given chat room from the UI. - * - * @param chatRoomWrapper the chat room to remove. - */ - public void removeChatRoom(ChatRoomWrapper chatRoomWrapper) - { - ChatRoom chatRoom = chatRoomWrapper.getChatRoom(); - - if (chatRoom != null) - leaveChatRoom(chatRoomWrapper); - - GuiActivator.getUIService().closeChatRoomWindow(chatRoomWrapper); - - GuiActivator.getMUCService().removeChatRoom(chatRoomWrapper); - - } - - /** - * Joins the given chat room and manages all the exceptions that could - * occur during the join process. - * - * @param chatRoom the chat room to join - */ - public void joinChatRoom(AdHocChatRoom chatRoom) - { - AdHocChatRoomWrapper chatRoomWrapper - = adHocChatRoomList.findChatRoomWrapperFromAdHocChatRoom(chatRoom); - - if(chatRoomWrapper == null) - { - AdHocChatRoomProviderWrapper parentProvider - = adHocChatRoomList.findServerWrapperFromProvider( - chatRoom.getParentProvider()); - - chatRoomWrapper = - new AdHocChatRoomWrapper(parentProvider, chatRoom); - - adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper); - - fireAdHocChatRoomListChangedEvent( - chatRoomWrapper, - AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED); - } - - this.joinChatRoom(chatRoomWrapper); - - ChatWindowManager chatWindowManager - = GuiActivator.getUIService().getChatWindowManager(); - - chatWindowManager - .openChat( - chatWindowManager.getMultiChat(chatRoomWrapper, true), - true); - } - - /** - * Leaves the given ChatRoom. - * - * @param chatRoomWrapper the ChatRoom to leave. - */ - public void leaveChatRoom(ChatRoomWrapper chatRoomWrapper) - { - ChatRoomWrapper leavedRoomWrapped - = GuiActivator.getMUCService().leaveChatRoom(chatRoomWrapper); - if(leavedRoomWrapped != null) - GuiActivator.getUIService().closeChatRoomWindow(leavedRoomWrapped); - } - - /** - * Leaves the given ChatRoom. - * - * @param chatRoomWrapper the ChatRoom to leave. - */ - public void leaveChatRoom(AdHocChatRoomWrapper chatRoomWrapper) - { - AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom(); - - if (chatRoom != null) - { - chatRoom.leave(); - } - else - { - new ErrorDialog( - GuiActivator.getUIService().getMainFrame(), - GuiActivator.getResources().getI18NString("service.gui.WARNING"), - GuiActivator.getResources().getI18NString( - "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED")) - .showDialog(); - } - } - - /** - * Checks if there's an open history window for the given chat room. - * - * @param chatRoomWrapper the chat room wrapper to check for - * @return TRUE if there's an opened history window for the given chat room, - * FALSE otherwise. - */ - public boolean containsHistoryWindowForChatRoom( - ChatRoomWrapper chatRoomWrapper) - { - return chatRoomHistory.containsKey(chatRoomWrapper); - } - - /** - * Returns the history window for the given chat room. - * - * @param chatRoomWrapper the chat room wrapper to search for - * @return the history window for the given chat room - */ - public HistoryWindow getHistoryWindowForChatRoom( - ChatRoomWrapper chatRoomWrapper) - { - return chatRoomHistory.get(chatRoomWrapper); - } - - /** - * Adds a history window for a given chat room in the table of opened - * history windows. - * - * @param chatRoomWrapper the chat room wrapper to add - * @param historyWindow the history window to add - */ - public void addHistoryWindowForChatRoom(ChatRoomWrapper chatRoomWrapper, - HistoryWindow historyWindow) - { - chatRoomHistory.put(chatRoomWrapper, historyWindow); - } - - /** - * Removes the history window for the given chat room. - * - * @param chatRoomWrapper the chat room wrapper to remove the history window - */ - public void removeHistoryWindowForChatRoom(ChatRoomWrapper chatRoomWrapper) - { - chatRoomHistory.remove(chatRoomWrapper); - } - - /** - * Adds the given AdHocChatRoomListChangeListener that will listen - * for all changes of the chat room list data model. - * - * @param l the listener to add. - */ - public void addAdHocChatRoomListChangeListener( - AdHocChatRoomListChangeListener l) - { - synchronized (adHoclistChangeListeners) - { - adHoclistChangeListeners.add(l); - } - } - - /** - * Removes the given AdHocChatRoomListChangeListener. - * - * @param l the listener to remove. - */ - public void removeAdHocChatRoomListChangeListener( - AdHocChatRoomListChangeListener l) - { - synchronized (adHoclistChangeListeners) - { - adHoclistChangeListeners.remove(l); - } - } - - /** - * Notifies all interested listeners that a change in the chat room list - * model has occurred. - * @param adHocChatRoomWrapper the chat room wrapper that identifies the - * chat room - * @param eventID the identifier of the event - */ - private void fireAdHocChatRoomListChangedEvent( - AdHocChatRoomWrapper adHocChatRoomWrapper, - int eventID) - { - AdHocChatRoomListChangeEvent evt - = new AdHocChatRoomListChangeEvent(adHocChatRoomWrapper, eventID); - - for (AdHocChatRoomListChangeListener l : adHoclistChangeListeners) - { - l.contentChanged(evt); - } - } - - - /** - * Closes the chat corresponding to the given ad-hoc chat room wrapper, if - * such exists. - * - * @param chatRoomWrapper the ad-hoc chat room wrapper for which we search a - * chat to close. - */ - private void closeAdHocChatRoom(AdHocChatRoomWrapper chatRoomWrapper) - { - ChatWindowManager chatWindowManager - = GuiActivator.getUIService().getChatWindowManager(); - ChatPanel chatPanel - = chatWindowManager.getMultiChat(chatRoomWrapper, false); - - if (chatPanel != null) - chatWindowManager.closeChat(chatPanel); - } - - /** - * Handles ServiceEvents triggered by adding or removing a - * ProtocolProviderService. Updates the list of available chat rooms and - * chat room servers. - * - * @param event The event to handle. - */ - public void serviceChanged(ServiceEvent event) - { - // if the event is caused by a bundle being stopped, we don't want to - // know - if (event.getServiceReference().getBundle().getState() - == Bundle.STOPPING) - return; - - Object service = GuiActivator.bundleContext.getService(event - .getServiceReference()); - - // we don't care if the source service is not a protocol provider - if (!(service instanceof ProtocolProviderService)) - return; - - ProtocolProviderService protocolProvider - = (ProtocolProviderService) service; - - - Object multiUserChatAdHocOpSet - = protocolProvider - .getOperationSet(OperationSetAdHocMultiUserChat.class); - - if (multiUserChatAdHocOpSet != null) - { - if (event.getType() == ServiceEvent.REGISTERED) - { - adHocChatRoomList.addChatProvider(protocolProvider); - } - else if (event.getType() == ServiceEvent.UNREGISTERING) - { - adHocChatRoomList.removeChatProvider(protocolProvider); - } - } - } - - /** - * Joins an ad-hoc chat room in an asynchronous way. - */ - private static class JoinAdHocChatRoomTask - extends SwingWorker - { - private static final String SUCCESS = "Success"; - - private static final String AUTHENTICATION_FAILED - = "AuthenticationFailed"; - - private static final String REGISTRATION_REQUIRED - = "RegistrationRequired"; - - private static final String PROVIDER_NOT_REGISTERED - = "ProviderNotRegistered"; - - private static final String SUBSCRIPTION_ALREADY_EXISTS - = "SubscriptionAlreadyExists"; - - private static final String UNKNOWN_ERROR - = "UnknownError"; - - private final AdHocChatRoomWrapper adHocChatRoomWrapper; - - JoinAdHocChatRoomTask(AdHocChatRoomWrapper chatRoomWrapper) - { - this.adHocChatRoomWrapper = chatRoomWrapper; - } - - /** - * @override {@link SwingWorker}{@link #doInBackground()} to perform - * all asynchronous tasks. - * @return SUCCESS if success, otherwise the error code - */ - @Override - public String doInBackground() - { - AdHocChatRoom chatRoom = adHocChatRoomWrapper.getAdHocChatRoom(); - - try - { - chatRoom.join(); - - return SUCCESS; - } - catch (OperationFailedException e) - { - if (logger.isTraceEnabled()) - logger.trace("Failed to join ad-hoc chat room: " - + chatRoom.getName(), e); - - switch (e.getErrorCode()) - { - case OperationFailedException.AUTHENTICATION_FAILED: - return AUTHENTICATION_FAILED; - case OperationFailedException.REGISTRATION_REQUIRED: - return REGISTRATION_REQUIRED; - case OperationFailedException.PROVIDER_NOT_REGISTERED: - return PROVIDER_NOT_REGISTERED; - case OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS: - return SUBSCRIPTION_ALREADY_EXISTS; - default: - return UNKNOWN_ERROR; - } - } - } - - /** - * @override {@link SwingWorker}{@link #done()} to perform UI changes - * after the ad-hoc chat room join task has finished. - */ - @Override - protected void done() - { - String returnCode = null; - try - { - returnCode = get(); - } - catch (InterruptedException ignore) - {} - catch (ExecutionException ignore) - {} - - ConfigurationUtils.updateChatRoomStatus( - adHocChatRoomWrapper.getParentProvider().getProtocolProvider(), - adHocChatRoomWrapper.getAdHocChatRoomID(), - GlobalStatusEnum.ONLINE_STATUS); - - String errorMessage = null; - if(PROVIDER_NOT_REGISTERED.equals(returnCode)) - { - errorMessage - = GuiActivator.getResources() - .getI18NString("service.gui.CHAT_ROOM_NOT_CONNECTED", - new String[]{ - adHocChatRoomWrapper.getAdHocChatRoomName()}); - } - else if(SUBSCRIPTION_ALREADY_EXISTS.equals(returnCode)) - { - errorMessage - = GuiActivator.getResources() - .getI18NString("service.gui.CHAT_ROOM_ALREADY_JOINED", - new String[]{ - adHocChatRoomWrapper.getAdHocChatRoomName()}); - } - else - { - errorMessage - = GuiActivator.getResources() - .getI18NString("service.gui.FAILED_TO_JOIN_CHAT_ROOM", - new String[]{ - adHocChatRoomWrapper.getAdHocChatRoomName()}); - } - - if (!SUCCESS.equals(returnCode) - && !AUTHENTICATION_FAILED.equals(returnCode)) - { - new ErrorDialog( - GuiActivator.getUIService().getMainFrame(), - GuiActivator.getResources().getI18NString( - "service.gui.ERROR"), errorMessage).showDialog(); - } - } - } - - - /** - * Indicates that an invitation has been received and opens the invitation - * dialog to notify the user. - * @param evt the AdHocChatRoomInvitationReceivedEvent that - * notified us - */ - public void invitationReceived(AdHocChatRoomInvitationReceivedEvent evt) - { - if (logger.isInfoEnabled()) - logger.info("Invitation received: "+evt.toString()); - OperationSetAdHocMultiUserChat multiUserChatOpSet - = evt.getSourceOperationSet(); - - InvitationReceivedDialog dialog = new InvitationReceivedDialog( - this, multiUserChatOpSet, evt.getInvitation()); - - dialog.setVisible(true); - } - - /** - * Implements the AdHocChatRoomMessageListener.messageDelivered - * method. - *
- * Shows the message in the conversation area and clears the write message - * area. - * @param evt the AdHocChatRoomMessageDeliveredEvent that notified - * us - */ - public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt) - { - AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource(); - - if (logger.isInfoEnabled()) - logger.info("MESSAGE DELIVERED to ad-hoc chat room: " - + sourceChatRoom.getName()); - - ChatPanel chatPanel - = GuiActivator - .getUIService() - .getChatWindowManager() - .getMultiChat(sourceChatRoom, false); - - if(chatPanel != null) - { - String messageType; - switch (evt.getEventType()) - { - case AdHocChatRoomMessageDeliveredEvent - .CONVERSATION_MESSAGE_DELIVERED: - messageType = Chat.OUTGOING_MESSAGE; - break; - case AdHocChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED: - messageType = Chat.ACTION_MESSAGE; - break; - default: - messageType = null; - } - - Message msg = evt.getMessage(); - - chatPanel - .addMessage( - sourceChatRoom - .getParentProvider().getAccountID().getUserID(), - null, - evt.getTimestamp(), - messageType, - msg.getContent(), - msg.getContentType(), - msg.getMessageUID(), - null); - } - else - { - logger.error("chat panel is null, message NOT DELIVERED !"); - } - } - - /** - * Implements AdHocChatRoomMessageListener.messageDeliveryFailed - * method. - *
- * In the conversation area shows an error message, explaining the problem. - * @param evt the AdHocChatRoomMessageDeliveryFailedEvent that - * notified us - */ - public void messageDeliveryFailed( - AdHocChatRoomMessageDeliveryFailedEvent evt) - { - AdHocChatRoom sourceChatRoom = evt.getSourceChatRoom(); - Message sourceMessage = evt.getMessage(); - Contact destParticipant = evt.getDestinationParticipant(); - - String errorMsg = null; - if (evt.getErrorCode() - == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED) - { - errorMsg = GuiActivator.getResources().getI18NString( - "service.gui.MSG_DELIVERY_NOT_SUPPORTED", - new String[]{destParticipant.getDisplayName()}); - } - else if (evt.getErrorCode() - == MessageDeliveryFailedEvent.NETWORK_FAILURE) - { - errorMsg = GuiActivator.getResources() - .getI18NString("service.gui.MSG_NOT_DELIVERED"); - } - else if (evt.getErrorCode() - == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED) - { - errorMsg = GuiActivator.getResources().getI18NString( - "service.gui.MSG_SEND_CONNECTION_PROBLEM"); - } - else if (evt.getErrorCode() - == MessageDeliveryFailedEvent.INTERNAL_ERROR) - { - errorMsg = GuiActivator.getResources().getI18NString( - "service.gui.MSG_DELIVERY_INTERNAL_ERROR"); - } - else - { - errorMsg = GuiActivator.getResources().getI18NString( - "service.gui.MSG_DELIVERY_UNKNOWN_ERROR"); - } - - ChatWindowManager chatWindowManager - = GuiActivator.getUIService().getChatWindowManager(); - ChatPanel chatPanel - = chatWindowManager.getMultiChat(sourceChatRoom, true); - - chatPanel.addMessage( - destParticipant.getDisplayName(), - new Date(), - Chat.OUTGOING_MESSAGE, - sourceMessage.getContent(), - sourceMessage.getContentType()); - - chatPanel.addErrorMessage( - destParticipant.getDisplayName(), - errorMsg); - - chatWindowManager.openChat(chatPanel, false); - } - - /** - * Implements the AdHocChatRoomMessageListener.messageReceived - * method. - *
- * Obtains the corresponding ChatPanel and process the message - * there. - * @param evt the AdHocChatRoomMessageReceivedEvent that notified - * us - */ - public void messageReceived(AdHocChatRoomMessageReceivedEvent evt) - { - AdHocChatRoom sourceChatRoom = evt.getSourceChatRoom(); - Contact sourceParticipant = evt.getSourceChatRoomParticipant(); - - String messageType = null; - - switch (evt.getEventType()) - { - case AdHocChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED: - messageType = Chat.INCOMING_MESSAGE; - break; - case AdHocChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED: - messageType = Chat.SYSTEM_MESSAGE; - break; - case AdHocChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED: - messageType = Chat.ACTION_MESSAGE; - break; - } - - if (logger.isInfoEnabled()) - logger.info("MESSAGE RECEIVED from contact: " - + sourceParticipant.getAddress()); - - Message message = evt.getMessage(); - - ChatWindowManager chatWindowManager - = GuiActivator.getUIService().getChatWindowManager(); - ChatPanel chatPanel - = chatWindowManager - .getMultiChat(sourceChatRoom, true, message.getMessageUID()); - - String messageContent = message.getContent(); - - chatPanel.addMessage( - sourceParticipant.getDisplayName(), - null, - evt.getTimestamp(), - messageType, - messageContent, - message.getContentType(), - message.getMessageUID(), - null); - - chatWindowManager.openChat(chatPanel, false); - } - - public void invitationRejected(AdHocChatRoomInvitationRejectedEvent evt) {} - -} +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.gui.main.chat.conference; + +import java.util.*; +import java.util.concurrent.*; + +import javax.swing.*; + +import net.java.sip.communicator.impl.gui.*; +import net.java.sip.communicator.impl.gui.main.chat.*; +import net.java.sip.communicator.impl.gui.main.chat.history.*; +import net.java.sip.communicator.impl.gui.main.chatroomslist.*; +import net.java.sip.communicator.plugin.desktoputil.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.muc.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.service.protocol.globalstatus.*; +import net.java.sip.communicator.util.*; + +import org.jdesktop.swingworker.SwingWorker; +import org.osgi.framework.*; + +/** + * The ConferenceChatManager is the one that manages both chat room and + * ad-hoc chat rooms invitations. + * + * @author Yana Stamcheva + * @author Lubomir Marinov + * @author Valentin Martinet + * @author Hristo Terezov + */ +public class ConferenceChatManager + implements ChatRoomMessageListener, + ChatRoomInvitationListener, + ChatRoomInvitationRejectionListener, + AdHocChatRoomMessageListener, + AdHocChatRoomInvitationListener, + AdHocChatRoomInvitationRejectionListener, + LocalUserChatRoomPresenceListener, + LocalUserAdHocChatRoomPresenceListener, + ServiceListener +{ + /** + * The object used for logging. + */ + private static final Logger logger + = Logger.getLogger(ConferenceChatManager.class); + + /** + * Maps each history window to a ChatRoomWrapper. + */ + private final Hashtable chatRoomHistory = + new Hashtable(); + + /** + * The list of ad-hoc chat rooms. + */ + private final AdHocChatRoomList adHocChatRoomList = new AdHocChatRoomList(); + + /** + * A list of all AdHocChatRoomListChangeListener-s. + */ + private final Vector + adHoclistChangeListeners = new Vector(); + + /** + * Creates an instance of ConferenceChatManager. + */ + public ConferenceChatManager() + { + // Loads the chat rooms list in a separate thread. + new Thread() + { + @Override + public void run() + { + adHocChatRoomList.loadList(); + } + }.start(); + + GuiActivator.bundleContext.addServiceListener(this); + + } + + /** + * Returns all chat room providers currently contained in the ad-hoc chat + * room list. + * + * @return all chat room providers currently contained in the ad-hoc chat + * room list. + */ + public AdHocChatRoomList getAdHocChatRoomList() + { + return adHocChatRoomList; + } + + /** + * Handles ChatRoomInvitationReceivedEvent-s. + */ + public void invitationReceived(ChatRoomInvitationReceivedEvent evt) + { + InvitationReceivedDialog dialog + = new InvitationReceivedDialog( + this, + evt.getSourceOperationSet(), + evt.getInvitation()); + + dialog.setVisible(true); + } + + public void invitationRejected(ChatRoomInvitationRejectedEvent evt) {} + + /** + * Implements the ChatRoomMessageListener.messageDelivered method. + *
+ * Shows the message in the conversation area and clears the write message + * area. + * @param evt the ChatRoomMessageDeliveredEvent that notified us + * that the message was delivered to its destination + */ + public void messageDelivered(ChatRoomMessageDeliveredEvent evt) + { + ChatRoom sourceChatRoom = (ChatRoom) evt.getSource(); + + if (logger.isTraceEnabled()) + logger.trace( + "MESSAGE DELIVERED to chat room: " + sourceChatRoom.getName()); + + ChatPanel chatPanel = GuiActivator.getUIService().getChatWindowManager() + .getMultiChat(sourceChatRoom, false); + + if(chatPanel != null) + { + String messageType; + + switch (evt.getEventType()) + { + case ChatRoomMessageDeliveredEvent.CONVERSATION_MESSAGE_DELIVERED: + messageType = Chat.OUTGOING_MESSAGE; + break; + case ChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED: + messageType = Chat.ACTION_MESSAGE; + break; + default: + messageType = null; + break; + } + + Message msg = evt.getMessage(); + + chatPanel.addMessage( + sourceChatRoom.getUserNickname(), + null, + evt.getTimestamp(), + messageType, + msg.getContent(), + msg.getContentType(), + msg.getMessageUID(), + null); + } + } + + /** + * Implements the ChatRoomMessageListener.messageReceived method. + *
+ * Obtains the corresponding ChatPanel and process the message + * there. + * @param evt the ChatRoomMessageReceivedEvent that notified us + * that a message has been received + */ + public void messageReceived(ChatRoomMessageReceivedEvent evt) + { + ChatRoom sourceChatRoom = evt.getSourceChatRoom(); + ChatRoomMember sourceMember = evt.getSourceChatRoomMember(); + + String messageType = null; + + switch (evt.getEventType()) + { + case ChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED: + messageType = Chat.INCOMING_MESSAGE; + break; + case ChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED: + messageType = Chat.SYSTEM_MESSAGE; + break; + case ChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED: + messageType = Chat.ACTION_MESSAGE; + break; + } + + if (logger.isTraceEnabled()) + logger.trace("MESSAGE RECEIVED from contact: " + + sourceMember.getContactAddress()); + + Message message = evt.getMessage(); + + ChatPanel chatPanel = null; + + ChatWindowManager chatWindowManager + = GuiActivator.getUIService().getChatWindowManager(); + + if(sourceChatRoom.isSystem()) + { + ChatRoomProviderWrapper serverWrapper + = GuiActivator.getMUCService().findServerWrapperFromProvider( + sourceChatRoom.getParentProvider()); + + chatPanel = chatWindowManager.getMultiChat( + serverWrapper.getSystemRoomWrapper(), true); + } + else + { + chatPanel = chatWindowManager.getMultiChat( + sourceChatRoom, true, message.getMessageUID()); + } + + String messageContent = message.getContent(); + + if (evt.isHistoryMessage()) + { + Date timeStamp = chatPanel.getChatConversationPanel() + .getLastIncomingMsgTimestamp(); + Collection c = + chatPanel.getChatSession().getHistoryBeforeDate( + new Date( + timeStamp.equals(new Date(0)) + ? System.currentTimeMillis() - 10000 + : timeStamp.getTime() + ), 20); + if (c.size() > 0) + { + boolean isPresent = false; + for (Object o : c) + { + if (o instanceof ChatRoomMessageDeliveredEvent) + { + ChatRoomMessageDeliveredEvent ev = + (ChatRoomMessageDeliveredEvent) o; + if (evt.getTimestamp() != null + && evt.getTimestamp().equals(ev.getTimestamp())) + { + isPresent = true; + break; + } + } + else if(o instanceof ChatRoomMessageReceivedEvent) + { + ChatRoomMessageReceivedEvent ev = + (ChatRoomMessageReceivedEvent) o; + if (evt.getTimestamp() != null + && evt.getTimestamp().equals(ev.getTimestamp())) + { + isPresent = true; + break; + } + } + } + + if (isPresent) + return; + } + } + + chatPanel.addMessage( + sourceMember.getName(), + null, + evt.getTimestamp(), + messageType, + messageContent, + message.getContentType(), + message.getMessageUID(), + null); + + chatWindowManager.openChat(chatPanel, false); + } + + + /** + * Implements the ChatRoomMessageListener.messageDeliveryFailed + * method. + *
+ * In the conversation area shows an error message, explaining the problem. + * @param evt the ChatRoomMessageDeliveryFailedEvent that notified + * us of a delivery failure + */ + public void messageDeliveryFailed(ChatRoomMessageDeliveryFailedEvent evt) + { + ChatRoom sourceChatRoom = evt.getSourceChatRoom(); + + String errorMsg = null; + + /* + * FIXME ChatRoomMessageDeliveryFailedEvent#getSource() is not a Message + * instance at the time of this writing and the attempt "(Message) + * evt.getSource()" seems to be to get the message which failed to be + * delivered. I'm not sure it's + * ChatRoomMessageDeliveryFailedEvent#getMessage() but since it's the + * only message I can get out of ChatRoomMessageDeliveryFailedEvent, I'm + * using it. + */ + Message sourceMessage = evt.getMessage(); + + ChatRoomMember destMember = evt.getDestinationChatRoomMember(); + + if (evt.getErrorCode() + == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED) + { + errorMsg = GuiActivator.getResources().getI18NString( + "service.gui.MSG_DELIVERY_NOT_SUPPORTED", + new String[]{destMember.getName()}); + } + else if (evt.getErrorCode() + == MessageDeliveryFailedEvent.NETWORK_FAILURE) + { + errorMsg = GuiActivator.getResources() + .getI18NString("service.gui.MSG_NOT_DELIVERED"); + } + else if (evt.getErrorCode() + == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED) + { + errorMsg = GuiActivator.getResources().getI18NString( + "service.gui.MSG_SEND_CONNECTION_PROBLEM"); + } + else if (evt.getErrorCode() + == MessageDeliveryFailedEvent.INTERNAL_ERROR) + { + errorMsg = GuiActivator.getResources().getI18NString( + "service.gui.MSG_DELIVERY_INTERNAL_ERROR"); + } + else + { + errorMsg = GuiActivator.getResources().getI18NString( + "service.gui.MSG_DELIVERY_UNKNOWN_ERROR"); + } + + String reason = evt.getReason(); + if (reason != null) + errorMsg += " " + GuiActivator.getResources().getI18NString( + "service.gui.ERROR_WAS", + new String[]{reason}); + + ChatWindowManager chatWindowManager + = GuiActivator.getUIService().getChatWindowManager(); + ChatPanel chatPanel + = chatWindowManager.getMultiChat(sourceChatRoom, true); + + chatPanel.addMessage( + destMember.getName(), + new Date(), + Chat.OUTGOING_MESSAGE, + sourceMessage.getContent(), + sourceMessage.getContentType()); + + chatPanel.addErrorMessage( + destMember.getName(), + errorMsg); + + chatWindowManager.openChat(chatPanel, false); + } + + /** + * Implements the + * LocalUserAdHocChatRoomPresenceListener.localUserPresenceChanged + * method + * + * @param evt the LocalUserAdHocChatRoomPresenceChangeEvent that + * notified us of a presence change + */ + public void localUserAdHocPresenceChanged( + LocalUserAdHocChatRoomPresenceChangeEvent evt) + { + AdHocChatRoom sourceAdHocChatRoom = evt.getAdHocChatRoom(); + AdHocChatRoomWrapper adHocChatRoomWrapper + = adHocChatRoomList + .findChatRoomWrapperFromAdHocChatRoom(sourceAdHocChatRoom); + + String eventType = evt.getEventType(); + + if (LocalUserAdHocChatRoomPresenceChangeEvent + .LOCAL_USER_JOINED.equals(eventType)) + { + if(adHocChatRoomWrapper != null) + { + this.fireAdHocChatRoomListChangedEvent( + adHocChatRoomWrapper, + AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED); + + ChatWindowManager chatWindowManager + = GuiActivator.getUIService().getChatWindowManager(); + ChatPanel chatPanel + = chatWindowManager + .getMultiChat(adHocChatRoomWrapper, true); + + // Check if we have already opened a chat window for this chat + // wrapper and load the real chat room corresponding to the + // wrapper. + if(chatPanel.isShown()) + ((AdHocConferenceChatSession) chatPanel.getChatSession()) + .loadChatRoom(sourceAdHocChatRoom); + else + chatWindowManager.openChat(chatPanel, true); + } + + sourceAdHocChatRoom.addMessageListener(this); + } + else if (evt.getEventType().equals( + LocalUserAdHocChatRoomPresenceChangeEvent.LOCAL_USER_JOIN_FAILED)) + { + new ErrorDialog( + GuiActivator.getUIService().getMainFrame(), + GuiActivator.getResources().getI18NString("service.gui.ERROR"), + GuiActivator.getResources().getI18NString( + "service.gui.FAILED_TO_JOIN_CHAT_ROOM", + new String[]{sourceAdHocChatRoom.getName()}) + + evt.getReason()) + .showDialog(); + } + else if (LocalUserAdHocChatRoomPresenceChangeEvent + .LOCAL_USER_LEFT.equals(eventType) + || LocalUserAdHocChatRoomPresenceChangeEvent + .LOCAL_USER_DROPPED.equals(eventType)) + { + this.closeAdHocChatRoom(adHocChatRoomWrapper); + + // Need to refresh the chat room's list in order to change + // the state of the chat room to offline. + fireAdHocChatRoomListChangedEvent( + adHocChatRoomWrapper, + AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_CHANGED); + + sourceAdHocChatRoom.removeMessageListener(this); + } + } + + /** + * Implements the + * LocalUserChatRoomPresenceListener.localUserPresenceChanged + * method. + * @param evt the LocalUserChatRoomPresenceChangeEvent that + * notified us + */ + public void localUserPresenceChanged( + final LocalUserChatRoomPresenceChangeEvent evt) + { + if(!SwingUtilities.isEventDispatchThread()) + { + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + localUserPresenceChanged(evt); + } + }); + return; + } + + ChatRoom sourceChatRoom = evt.getChatRoom(); + ChatRoomWrapper chatRoomWrapper + = GuiActivator.getMUCService().findChatRoomWrapperFromChatRoom( + sourceChatRoom); + + String eventType = evt.getEventType(); + + if (LocalUserChatRoomPresenceChangeEvent + .LOCAL_USER_JOINED.equals(eventType)) + { + if(chatRoomWrapper != null) + { + GuiActivator.getMUCService().fireChatRoomListChangedEvent( + chatRoomWrapper, + ChatRoomListChangeEvent.CHAT_ROOM_CHANGED); + + ChatWindowManager chatWindowManager + = GuiActivator.getUIService().getChatWindowManager(); + ChatPanel chatPanel + = chatWindowManager.getMultiChat(chatRoomWrapper, true); + + chatPanel.setChatIcon( + chatPanel.getChatSession().getChatStatusIcon()); + + // Check if we have already opened a chat window for this chat + // wrapper and load the real chat room corresponding to the + // wrapper. + if(chatPanel.isShown()) + ((ConferenceChatSession) chatPanel.getChatSession()) + .loadChatRoom(sourceChatRoom); + else + chatWindowManager.openChat(chatPanel, true); + } + + if (sourceChatRoom.isSystem()) + { + ChatRoomProviderWrapper serverWrapper + = GuiActivator.getMUCService() + .findServerWrapperFromProvider( + sourceChatRoom.getParentProvider()); + + serverWrapper.setSystemRoom(sourceChatRoom); + } + + sourceChatRoom.addMessageListener(this); + } + else if (LocalUserChatRoomPresenceChangeEvent + .LOCAL_USER_JOIN_FAILED.equals(eventType)) + { + new ErrorDialog( + GuiActivator.getUIService().getMainFrame(), + GuiActivator.getResources().getI18NString("service.gui.ERROR"), + GuiActivator.getResources().getI18NString( + "service.gui.FAILED_TO_JOIN_CHAT_ROOM", + new String[]{sourceChatRoom.getName()}) + evt.getReason()) + .showDialog(); + } + else if (LocalUserChatRoomPresenceChangeEvent + .LOCAL_USER_LEFT.equals(eventType) + || LocalUserChatRoomPresenceChangeEvent + .LOCAL_USER_KICKED.equals(eventType) + || LocalUserChatRoomPresenceChangeEvent + .LOCAL_USER_DROPPED.equals(eventType)) + { + if(chatRoomWrapper != null) + { + GuiActivator.getUIService() + .closeChatRoomWindow(chatRoomWrapper); + + // Need to refresh the chat room's list in order to change + // the state of the chat room to offline. + + GuiActivator.getMUCService().fireChatRoomListChangedEvent( + chatRoomWrapper, + ChatRoomListChangeEvent.CHAT_ROOM_CHANGED); + } + + sourceChatRoom.removeMessageListener(this); + } + } + + + /** + * Called to accept an incoming invitation. Adds the invitation chat room + * to the list of chat rooms and joins it. + * + * @param invitation the invitation to accept + * @param multiUserChatOpSet the operation set for chat conferencing + * @throws OperationFailedException if the accept fails + */ + public void acceptInvitation( + AdHocChatRoomInvitation invitation, + OperationSetAdHocMultiUserChat multiUserChatOpSet) + throws OperationFailedException + { + AdHocChatRoom chatRoom = invitation.getTargetAdHocChatRoom(); + + chatRoom.join(); + } + + /** + * Rejects the given invitation with the specified reason. + * + * @param multiUserChatAdHocOpSet the operation set to use for rejecting the + * invitation + * @param invitation the invitation to reject + * @param reason the reason for the rejection + */ + public void rejectInvitation( + OperationSetAdHocMultiUserChat multiUserChatAdHocOpSet, + AdHocChatRoomInvitation invitation, + String reason) + { + multiUserChatAdHocOpSet.rejectInvitation(invitation, reason); + } + + /** + * Creates an ad-hoc chat room, by specifying the ad-hoc chat room name, the + * parent protocol provider and eventually, the contacts invited to + * participate in this ad-hoc chat room. + * + * @param protocolProvider the parent protocol provider. + * @param contacts the contacts invited when creating the chat room. + * @param reason the reason for this invitation + * @return the AdHocChatRoomWrapper corresponding to the created + * ad hoc chat room + */ + public AdHocChatRoomWrapper createAdHocChatRoom( + ProtocolProviderService protocolProvider, + Collection contacts, + String reason) + { + AdHocChatRoomWrapper chatRoomWrapper = null; + + OperationSetAdHocMultiUserChat groupChatOpSet + = protocolProvider + .getOperationSet(OperationSetAdHocMultiUserChat.class); + + // If there's no group chat operation set we have nothing to do here. + if (groupChatOpSet == null) + return null; + + AdHocChatRoom chatRoom = null; + + try + { + java.util.List members = new LinkedList(); + + for(String address : contacts) + members.add(address); + + chatRoom = groupChatOpSet.createAdHocChatRoom( + "chatroom-" + new Date().getTime(), members, reason); + } + catch (OperationFailedException ex) + { + new ErrorDialog( + GuiActivator.getUIService().getMainFrame(), + GuiActivator.getResources().getI18NString("service.gui.ERROR"), + GuiActivator.getResources().getI18NString( + "service.gui.CREATE_CHAT_ROOM_ERROR", + new String[]{protocolProvider.getProtocolName()}), + ex) + .showDialog(); + } + catch (OperationNotSupportedException ex) + { + new ErrorDialog( + GuiActivator.getUIService().getMainFrame(), + GuiActivator.getResources().getI18NString("service.gui.ERROR"), + GuiActivator.getResources().getI18NString( + "service.gui.CREATE_CHAT_ROOM_ERROR", + new String[]{protocolProvider.getProtocolName()}), + ex) + .showDialog(); + } + + if(chatRoom != null) + { + AdHocChatRoomProviderWrapper parentProvider + = adHocChatRoomList.findServerWrapperFromProvider( + protocolProvider); + + chatRoomWrapper = new AdHocChatRoomWrapper( + parentProvider, chatRoom); + parentProvider.addAdHocChatRoom(chatRoomWrapper); + adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper); + + fireAdHocChatRoomListChangedEvent( + chatRoomWrapper, + AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED); + } + + return chatRoomWrapper; + } + + /** + * Joins the given ad-hoc chat room + * + * @param chatRoomWrapper + */ + public void joinChatRoom(AdHocChatRoomWrapper chatRoomWrapper) + { + AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom(); + + if(chatRoom == null) + { + new ErrorDialog( + GuiActivator.getUIService().getMainFrame(), + GuiActivator.getResources().getI18NString("service.gui.WARNING"), + GuiActivator.getResources().getI18NString( + "service.gui.CHAT_ROOM_NOT_CONNECTED", + new String[]{chatRoomWrapper.getAdHocChatRoomName()})) + .showDialog(); + + return; + } + + new JoinAdHocChatRoomTask(chatRoomWrapper).execute(); + } + + /** + * Removes the given chat room from the UI. + * + * @param chatRoomWrapper the chat room to remove. + */ + public void removeChatRoom(ChatRoomWrapper chatRoomWrapper) + { + ChatRoom chatRoom = chatRoomWrapper.getChatRoom(); + + if (chatRoom != null) + leaveChatRoom(chatRoomWrapper); + + GuiActivator.getUIService().closeChatRoomWindow(chatRoomWrapper); + + GuiActivator.getMUCService().removeChatRoom(chatRoomWrapper); + + } + + /** + * Joins the given chat room and manages all the exceptions that could + * occur during the join process. + * + * @param chatRoom the chat room to join + */ + public void joinChatRoom(AdHocChatRoom chatRoom) + { + AdHocChatRoomWrapper chatRoomWrapper + = adHocChatRoomList.findChatRoomWrapperFromAdHocChatRoom(chatRoom); + + if(chatRoomWrapper == null) + { + AdHocChatRoomProviderWrapper parentProvider + = adHocChatRoomList.findServerWrapperFromProvider( + chatRoom.getParentProvider()); + + chatRoomWrapper = + new AdHocChatRoomWrapper(parentProvider, chatRoom); + + adHocChatRoomList.addAdHocChatRoom(chatRoomWrapper); + + fireAdHocChatRoomListChangedEvent( + chatRoomWrapper, + AdHocChatRoomListChangeEvent.AD_HOC_CHAT_ROOM_ADDED); + } + + this.joinChatRoom(chatRoomWrapper); + + ChatWindowManager chatWindowManager + = GuiActivator.getUIService().getChatWindowManager(); + + chatWindowManager + .openChat( + chatWindowManager.getMultiChat(chatRoomWrapper, true), + true); + } + + /** + * Leaves the given ChatRoom. + * + * @param chatRoomWrapper the ChatRoom to leave. + */ + public void leaveChatRoom(ChatRoomWrapper chatRoomWrapper) + { + ChatRoomWrapper leavedRoomWrapped + = GuiActivator.getMUCService().leaveChatRoom(chatRoomWrapper); + if(leavedRoomWrapped != null) + GuiActivator.getUIService().closeChatRoomWindow(leavedRoomWrapped); + } + + /** + * Leaves the given ChatRoom. + * + * @param chatRoomWrapper the ChatRoom to leave. + */ + public void leaveChatRoom(AdHocChatRoomWrapper chatRoomWrapper) + { + AdHocChatRoom chatRoom = chatRoomWrapper.getAdHocChatRoom(); + + if (chatRoom != null) + { + chatRoom.leave(); + } + else + { + new ErrorDialog( + GuiActivator.getUIService().getMainFrame(), + GuiActivator.getResources().getI18NString("service.gui.WARNING"), + GuiActivator.getResources().getI18NString( + "service.gui.CHAT_ROOM_LEAVE_NOT_CONNECTED")) + .showDialog(); + } + } + + /** + * Checks if there's an open history window for the given chat room. + * + * @param chatRoomWrapper the chat room wrapper to check for + * @return TRUE if there's an opened history window for the given chat room, + * FALSE otherwise. + */ + public boolean containsHistoryWindowForChatRoom( + ChatRoomWrapper chatRoomWrapper) + { + return chatRoomHistory.containsKey(chatRoomWrapper); + } + + /** + * Returns the history window for the given chat room. + * + * @param chatRoomWrapper the chat room wrapper to search for + * @return the history window for the given chat room + */ + public HistoryWindow getHistoryWindowForChatRoom( + ChatRoomWrapper chatRoomWrapper) + { + return chatRoomHistory.get(chatRoomWrapper); + } + + /** + * Adds a history window for a given chat room in the table of opened + * history windows. + * + * @param chatRoomWrapper the chat room wrapper to add + * @param historyWindow the history window to add + */ + public void addHistoryWindowForChatRoom(ChatRoomWrapper chatRoomWrapper, + HistoryWindow historyWindow) + { + chatRoomHistory.put(chatRoomWrapper, historyWindow); + } + + /** + * Removes the history window for the given chat room. + * + * @param chatRoomWrapper the chat room wrapper to remove the history window + */ + public void removeHistoryWindowForChatRoom(ChatRoomWrapper chatRoomWrapper) + { + chatRoomHistory.remove(chatRoomWrapper); + } + + /** + * Adds the given AdHocChatRoomListChangeListener that will listen + * for all changes of the chat room list data model. + * + * @param l the listener to add. + */ + public void addAdHocChatRoomListChangeListener( + AdHocChatRoomListChangeListener l) + { + synchronized (adHoclistChangeListeners) + { + adHoclistChangeListeners.add(l); + } + } + + /** + * Removes the given AdHocChatRoomListChangeListener. + * + * @param l the listener to remove. + */ + public void removeAdHocChatRoomListChangeListener( + AdHocChatRoomListChangeListener l) + { + synchronized (adHoclistChangeListeners) + { + adHoclistChangeListeners.remove(l); + } + } + + /** + * Notifies all interested listeners that a change in the chat room list + * model has occurred. + * @param adHocChatRoomWrapper the chat room wrapper that identifies the + * chat room + * @param eventID the identifier of the event + */ + private void fireAdHocChatRoomListChangedEvent( + AdHocChatRoomWrapper adHocChatRoomWrapper, + int eventID) + { + AdHocChatRoomListChangeEvent evt + = new AdHocChatRoomListChangeEvent(adHocChatRoomWrapper, eventID); + + for (AdHocChatRoomListChangeListener l : adHoclistChangeListeners) + { + l.contentChanged(evt); + } + } + + + /** + * Closes the chat corresponding to the given ad-hoc chat room wrapper, if + * such exists. + * + * @param chatRoomWrapper the ad-hoc chat room wrapper for which we search a + * chat to close. + */ + private void closeAdHocChatRoom(AdHocChatRoomWrapper chatRoomWrapper) + { + ChatWindowManager chatWindowManager + = GuiActivator.getUIService().getChatWindowManager(); + ChatPanel chatPanel + = chatWindowManager.getMultiChat(chatRoomWrapper, false); + + if (chatPanel != null) + chatWindowManager.closeChat(chatPanel); + } + + /** + * Handles ServiceEvents triggered by adding or removing a + * ProtocolProviderService. Updates the list of available chat rooms and + * chat room servers. + * + * @param event The event to handle. + */ + public void serviceChanged(ServiceEvent event) + { + // if the event is caused by a bundle being stopped, we don't want to + // know + if (event.getServiceReference().getBundle().getState() + == Bundle.STOPPING) + return; + + Object service = GuiActivator.bundleContext.getService(event + .getServiceReference()); + + // we don't care if the source service is not a protocol provider + if (!(service instanceof ProtocolProviderService)) + return; + + ProtocolProviderService protocolProvider + = (ProtocolProviderService) service; + + + Object multiUserChatAdHocOpSet + = protocolProvider + .getOperationSet(OperationSetAdHocMultiUserChat.class); + + if (multiUserChatAdHocOpSet != null) + { + if (event.getType() == ServiceEvent.REGISTERED) + { + adHocChatRoomList.addChatProvider(protocolProvider); + } + else if (event.getType() == ServiceEvent.UNREGISTERING) + { + adHocChatRoomList.removeChatProvider(protocolProvider); + } + } + } + + /** + * Joins an ad-hoc chat room in an asynchronous way. + */ + private static class JoinAdHocChatRoomTask + extends SwingWorker + { + private static final String SUCCESS = "Success"; + + private static final String AUTHENTICATION_FAILED + = "AuthenticationFailed"; + + private static final String REGISTRATION_REQUIRED + = "RegistrationRequired"; + + private static final String PROVIDER_NOT_REGISTERED + = "ProviderNotRegistered"; + + private static final String SUBSCRIPTION_ALREADY_EXISTS + = "SubscriptionAlreadyExists"; + + private static final String UNKNOWN_ERROR + = "UnknownError"; + + private final AdHocChatRoomWrapper adHocChatRoomWrapper; + + JoinAdHocChatRoomTask(AdHocChatRoomWrapper chatRoomWrapper) + { + this.adHocChatRoomWrapper = chatRoomWrapper; + } + + /** + * @override {@link SwingWorker}{@link #doInBackground()} to perform + * all asynchronous tasks. + * @return SUCCESS if success, otherwise the error code + */ + @Override + public String doInBackground() + { + AdHocChatRoom chatRoom = adHocChatRoomWrapper.getAdHocChatRoom(); + + try + { + chatRoom.join(); + + return SUCCESS; + } + catch (OperationFailedException e) + { + if (logger.isTraceEnabled()) + logger.trace("Failed to join ad-hoc chat room: " + + chatRoom.getName(), e); + + switch (e.getErrorCode()) + { + case OperationFailedException.AUTHENTICATION_FAILED: + return AUTHENTICATION_FAILED; + case OperationFailedException.REGISTRATION_REQUIRED: + return REGISTRATION_REQUIRED; + case OperationFailedException.PROVIDER_NOT_REGISTERED: + return PROVIDER_NOT_REGISTERED; + case OperationFailedException.SUBSCRIPTION_ALREADY_EXISTS: + return SUBSCRIPTION_ALREADY_EXISTS; + default: + return UNKNOWN_ERROR; + } + } + } + + /** + * @override {@link SwingWorker}{@link #done()} to perform UI changes + * after the ad-hoc chat room join task has finished. + */ + @Override + protected void done() + { + String returnCode = null; + try + { + returnCode = get(); + } + catch (InterruptedException ignore) + {} + catch (ExecutionException ignore) + {} + + ConfigurationUtils.updateChatRoomStatus( + adHocChatRoomWrapper.getParentProvider().getProtocolProvider(), + adHocChatRoomWrapper.getAdHocChatRoomID(), + GlobalStatusEnum.ONLINE_STATUS); + + String errorMessage = null; + if(PROVIDER_NOT_REGISTERED.equals(returnCode)) + { + errorMessage + = GuiActivator.getResources() + .getI18NString("service.gui.CHAT_ROOM_NOT_CONNECTED", + new String[]{ + adHocChatRoomWrapper.getAdHocChatRoomName()}); + } + else if(SUBSCRIPTION_ALREADY_EXISTS.equals(returnCode)) + { + errorMessage + = GuiActivator.getResources() + .getI18NString("service.gui.CHAT_ROOM_ALREADY_JOINED", + new String[]{ + adHocChatRoomWrapper.getAdHocChatRoomName()}); + } + else + { + errorMessage + = GuiActivator.getResources() + .getI18NString("service.gui.FAILED_TO_JOIN_CHAT_ROOM", + new String[]{ + adHocChatRoomWrapper.getAdHocChatRoomName()}); + } + + if (!SUCCESS.equals(returnCode) + && !AUTHENTICATION_FAILED.equals(returnCode)) + { + new ErrorDialog( + GuiActivator.getUIService().getMainFrame(), + GuiActivator.getResources().getI18NString( + "service.gui.ERROR"), errorMessage).showDialog(); + } + } + } + + + /** + * Indicates that an invitation has been received and opens the invitation + * dialog to notify the user. + * @param evt the AdHocChatRoomInvitationReceivedEvent that + * notified us + */ + public void invitationReceived(AdHocChatRoomInvitationReceivedEvent evt) + { + if (logger.isInfoEnabled()) + logger.info("Invitation received: "+evt.toString()); + OperationSetAdHocMultiUserChat multiUserChatOpSet + = evt.getSourceOperationSet(); + + InvitationReceivedDialog dialog = new InvitationReceivedDialog( + this, multiUserChatOpSet, evt.getInvitation()); + + dialog.setVisible(true); + } + + /** + * Implements the AdHocChatRoomMessageListener.messageDelivered + * method. + *
+ * Shows the message in the conversation area and clears the write message + * area. + * @param evt the AdHocChatRoomMessageDeliveredEvent that notified + * us + */ + public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt) + { + AdHocChatRoom sourceChatRoom = (AdHocChatRoom) evt.getSource(); + + if (logger.isInfoEnabled()) + logger.info("MESSAGE DELIVERED to ad-hoc chat room: " + + sourceChatRoom.getName()); + + ChatPanel chatPanel + = GuiActivator + .getUIService() + .getChatWindowManager() + .getMultiChat(sourceChatRoom, false); + + if(chatPanel != null) + { + String messageType; + switch (evt.getEventType()) + { + case AdHocChatRoomMessageDeliveredEvent + .CONVERSATION_MESSAGE_DELIVERED: + messageType = Chat.OUTGOING_MESSAGE; + break; + case AdHocChatRoomMessageDeliveredEvent.ACTION_MESSAGE_DELIVERED: + messageType = Chat.ACTION_MESSAGE; + break; + default: + messageType = null; + } + + Message msg = evt.getMessage(); + + chatPanel + .addMessage( + sourceChatRoom + .getParentProvider().getAccountID().getUserID(), + null, + evt.getTimestamp(), + messageType, + msg.getContent(), + msg.getContentType(), + msg.getMessageUID(), + null); + } + else + { + logger.error("chat panel is null, message NOT DELIVERED !"); + } + } + + /** + * Implements AdHocChatRoomMessageListener.messageDeliveryFailed + * method. + *
+ * In the conversation area shows an error message, explaining the problem. + * @param evt the AdHocChatRoomMessageDeliveryFailedEvent that + * notified us + */ + public void messageDeliveryFailed( + AdHocChatRoomMessageDeliveryFailedEvent evt) + { + AdHocChatRoom sourceChatRoom = evt.getSourceChatRoom(); + Message sourceMessage = evt.getMessage(); + Contact destParticipant = evt.getDestinationParticipant(); + + String errorMsg = null; + if (evt.getErrorCode() + == MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED) + { + errorMsg = GuiActivator.getResources().getI18NString( + "service.gui.MSG_DELIVERY_NOT_SUPPORTED", + new String[]{destParticipant.getDisplayName()}); + } + else if (evt.getErrorCode() + == MessageDeliveryFailedEvent.NETWORK_FAILURE) + { + errorMsg = GuiActivator.getResources() + .getI18NString("service.gui.MSG_NOT_DELIVERED"); + } + else if (evt.getErrorCode() + == MessageDeliveryFailedEvent.PROVIDER_NOT_REGISTERED) + { + errorMsg = GuiActivator.getResources().getI18NString( + "service.gui.MSG_SEND_CONNECTION_PROBLEM"); + } + else if (evt.getErrorCode() + == MessageDeliveryFailedEvent.INTERNAL_ERROR) + { + errorMsg = GuiActivator.getResources().getI18NString( + "service.gui.MSG_DELIVERY_INTERNAL_ERROR"); + } + else + { + errorMsg = GuiActivator.getResources().getI18NString( + "service.gui.MSG_DELIVERY_UNKNOWN_ERROR"); + } + + ChatWindowManager chatWindowManager + = GuiActivator.getUIService().getChatWindowManager(); + ChatPanel chatPanel + = chatWindowManager.getMultiChat(sourceChatRoom, true); + + chatPanel.addMessage( + destParticipant.getDisplayName(), + new Date(), + Chat.OUTGOING_MESSAGE, + sourceMessage.getContent(), + sourceMessage.getContentType()); + + chatPanel.addErrorMessage( + destParticipant.getDisplayName(), + errorMsg); + + chatWindowManager.openChat(chatPanel, false); + } + + /** + * Implements the AdHocChatRoomMessageListener.messageReceived + * method. + *
+ * Obtains the corresponding ChatPanel and process the message + * there. + * @param evt the AdHocChatRoomMessageReceivedEvent that notified + * us + */ + public void messageReceived(AdHocChatRoomMessageReceivedEvent evt) + { + AdHocChatRoom sourceChatRoom = evt.getSourceChatRoom(); + Contact sourceParticipant = evt.getSourceChatRoomParticipant(); + + String messageType = null; + + switch (evt.getEventType()) + { + case AdHocChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED: + messageType = Chat.INCOMING_MESSAGE; + break; + case AdHocChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED: + messageType = Chat.SYSTEM_MESSAGE; + break; + case AdHocChatRoomMessageReceivedEvent.ACTION_MESSAGE_RECEIVED: + messageType = Chat.ACTION_MESSAGE; + break; + } + + if (logger.isInfoEnabled()) + logger.info("MESSAGE RECEIVED from contact: " + + sourceParticipant.getAddress()); + + Message message = evt.getMessage(); + + ChatWindowManager chatWindowManager + = GuiActivator.getUIService().getChatWindowManager(); + ChatPanel chatPanel + = chatWindowManager + .getMultiChat(sourceChatRoom, true, message.getMessageUID()); + + String messageContent = message.getContent(); + + chatPanel.addMessage( + sourceParticipant.getDisplayName(), + null, + evt.getTimestamp(), + messageType, + messageContent, + message.getContentType(), + message.getMessageUID(), + null); + + chatWindowManager.openChat(chatPanel, false); + } + + public void invitationRejected(AdHocChatRoomInvitationRejectedEvent evt) {} + +} diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java index 84b6dd66e..d5dd35a46 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/PresenceFilter.java @@ -1,363 +1,360 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.impl.gui.main.contactlist; - -import java.util.*; - -import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*; -import net.java.sip.communicator.service.contactlist.*; -import net.java.sip.communicator.service.contactsource.*; -import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.gui.event.*; -import net.java.sip.communicator.service.muc.*; -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.util.*; - -/** - * The PresenceFilter is used to filter offline contacts from the - * contact list. - * - * @author Yana Stamcheva - */ -public class PresenceFilter - implements ContactListFilter -{ - /** - * The Logger used by the PresenceFilter class and its - * instances to print debugging information. - */ - private static final Logger logger = Logger.getLogger(PresenceFilter.class); - - /** - * Indicates if this presence filter shows or hides the offline contacts. - */ - private boolean isShowOffline; - - /** - * The initial result count below which we insert all filter results - * directly to the contact list without firing events. - */ - private static final int INITIAL_CONTACT_COUNT = 30; - - /** - * Creates an instance of PresenceFilter. - */ - public PresenceFilter() - { - isShowOffline = ConfigurationUtils.isShowOffline(); - } - - /** - * Applies this filter. This filter is applied over the - * MetaContactListService. - * - * @param filterQuery the query which keeps track of the filtering results - */ - public void applyFilter(FilterQuery filterQuery) - { - // Create the query that will track filtering. - MetaContactQuery query = new MetaContactQuery(); - - // Add this query to the filterQuery. - filterQuery.addContactQuery(query); - - List contactQueryList = new ArrayList(); - Iterator filterSources - = GuiActivator.getContactList().getContactSources( - ContactSourceService.PRESENCE_TYPE).iterator(); - - while (filterSources.hasNext()) - { - final UIContactSource filterSource - = filterSources.next(); - - ContactSourceService sourceService = - filterSource.getContactSourceService(); - - ContactQuery contactQuery = sourceService.queryContactSource(null); - - contactQueryList.add(contactQuery); - - - // Add this query to the filterQuery. - filterQuery.addContactQuery(contactQuery); - } - - // Closes this filter to indicate that we finished adding queries to it. - filterQuery.close(); - - query.addContactQueryListener(GuiActivator.getContactList()); - - - - int resultCount = 0; - addMatching(GuiActivator.getContactListService().getRoot(), - query, - resultCount); - - for(ContactQuery contactQuery : contactQueryList) - { - for(SourceContact contact : contactQuery.getQueryResults()) - { - addSourceContact(contact); - } - contactQuery.addContactQueryListener(GuiActivator.getContactList()); - } - - if (!query.isCanceled()) - query.fireQueryEvent(MetaContactQueryStatusEvent.QUERY_COMPLETED); - else - query.fireQueryEvent(MetaContactQueryStatusEvent.QUERY_CANCELED); - } - - /** - * Indicates if the given uiContact is matching this filter. - * - * @param uiContact the UIContact to check - * @return true if the given uiContact is matching - * this filter, otherwise returns false - */ - public boolean isMatching(UIContact uiContact) - { - Object descriptor = uiContact.getDescriptor(); - if (descriptor instanceof MetaContact) - return isMatching((MetaContact) descriptor); - else if (descriptor instanceof SourceContact) - return isMatching((SourceContact)descriptor); - - return false; - } - - /** - * Indicates if the given uiGroup is matching this filter. - * - * @param uiGroup the UIGroup to check - * @return true if the given uiGroup is matching - * this filter, otherwise returns false - */ - public boolean isMatching(UIGroup uiGroup) - { - Object descriptor = uiGroup.getDescriptor(); - if (descriptor instanceof MetaContactGroup) - return isMatching((MetaContactGroup) descriptor); - - return false; - } - - /** - * Sets the show offline property. - * - * @param isShowOffline indicates if offline contacts are shown - */ - public void setShowOffline(boolean isShowOffline) - { - this.isShowOffline = isShowOffline; - - ConfigurationUtils.setShowOffline(isShowOffline); - } - - /** - * Returns true if offline contacts are shown, otherwise returns - * false. - * - * @return true if offline contacts are shown, otherwise returns - * false - */ - public boolean isShowOffline() - { - return isShowOffline; - } - - /** - * Returns true if offline contacts are shown or if the given - * MetaContact is online, otherwise returns false. - * - * @param metaContact the MetaContact to check - * @return true if the given MetaContact is matching this - * filter - */ - public boolean isMatching(MetaContact metaContact) - { - return isShowOffline || isContactOnline(metaContact); - } - - /** - * Returns true if offline contacts are shown or if the given - * MetaContact is online, otherwise returns false. - * - * @param metaContact the MetaContact to check - * @return true if the given MetaContact is matching this - * filter - */ - public boolean isMatching(SourceContact contact) - { - return isShowOffline || contact.getPresenceStatus().isOnline() || - (contact.getPreferredContactDetail(OperationSetMultiUserChat.class) - != null); - } - - /** - * Returns true if offline contacts are shown or if the given - * MetaContactGroup contains online contacts. - * - * @param metaGroup the MetaContactGroup to check - * @return true if the given MetaContactGroup is matching - * this filter - */ - private boolean isMatching(MetaContactGroup metaGroup) - { - return (isShowOffline || metaGroup.countOnlineChildContacts() > 0 - || MetaContactListSource.isNewGroup(metaGroup)) - ? true - : false; - } - - /** - * Returns true if the given meta contact is online, false - * otherwise. - * - * @param contact the meta contact - * @return true if the given meta contact is online, false - * otherwise - */ - private boolean isContactOnline(MetaContact contact) - { - // If for some reason the default contact is null we return false. - Contact defaultContact = contact.getDefaultContact(); - if(defaultContact == null) - return false; - - // Lays on the fact that the default contact is the most connected. - return defaultContact.getPresenceStatus().getStatus() - >= PresenceStatus.ONLINE_THRESHOLD; - } - - /** - * Adds all contacts contained in the given MetaContactGroup - * matching the current filter and not contained in the contact list. - * - * @param metaGroup the MetaContactGroup, which matching contacts - * to add - * @param query the MetaContactQuery that notifies interested - * listeners of the results of this matching - * @param resultCount the initial result count we would insert directly to - * the contact list without firing events - */ - private void addMatching( MetaContactGroup metaGroup, - MetaContactQuery query, - int resultCount) - { - Iterator childContacts = metaGroup.getChildContacts(); - - while (childContacts.hasNext() && !query.isCanceled()) - { - MetaContact metaContact = childContacts.next(); - - if(isMatching(metaContact)) - { - resultCount++; - if (resultCount <= INITIAL_CONTACT_COUNT) - { - UIGroup uiGroup = null; - if (!MetaContactListSource.isRootGroup(metaGroup)) - { - synchronized (metaGroup) - { - uiGroup = MetaContactListSource - .getUIGroup(metaGroup); - - if (uiGroup == null) - uiGroup = MetaContactListSource - .createUIGroup(metaGroup); - } - } - - if (logger.isDebugEnabled()) - logger.debug("Presence filter contact added: " - + metaContact.getDisplayName()); - - UIContact newUIContact; - synchronized (metaContact) - { - newUIContact = MetaContactListSource - .createUIContact(metaContact); - } - - GuiActivator.getContactList().addContact( - newUIContact, - uiGroup, - true, - true); - - query.setInitialResultCount(resultCount); - } - else - query.fireQueryEvent(metaContact); - } - } - - // If in the meantime the filtering has been stopped we return here. - if (query.isCanceled()) - return; - - Iterator subgroups = metaGroup.getSubgroups(); - while(subgroups.hasNext() && !query.isCanceled()) - { - MetaContactGroup subgroup = subgroups.next(); - - if (isMatching(subgroup)) - { - UIGroup uiGroup; - synchronized(subgroup) - { - uiGroup = MetaContactListSource - .getUIGroup(subgroup); - - if (uiGroup == null) - uiGroup = MetaContactListSource - .createUIGroup(subgroup); - } - - GuiActivator.getContactList().addGroup(uiGroup, true); - - addMatching(subgroup, query, resultCount); - } - } - } - - /** - * Adds the given sourceContact to the contact list. - * @param sourceContact the SourceContact to add - */ - private void addSourceContact(SourceContact sourceContact) - { - ContactSourceService contactSource - = sourceContact.getContactSource(); - - TreeContactList sourceContactList = GuiActivator.getContactList(); - UIContactSource sourceUI - = sourceContactList .getContactSource(contactSource); - - if (sourceUI != null - // ExtendedContactSourceService has already matched the - // SourceContact over the pattern - && (contactSource instanceof ExtendedContactSourceService) - || isMatching(sourceContact)) - { - boolean isSorted = (sourceContact.getIndex() > -1) ? true : false; - - sourceContactList.addContact( - sourceUI.createUIContact(sourceContact), - sourceUI.getUIGroup(), - isSorted, - true); - } - else - sourceUI.removeUIContact(sourceContact); - } -} +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.impl.gui.main.contactlist; + +import java.util.*; + +import net.java.sip.communicator.impl.gui.*; +import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*; +import net.java.sip.communicator.service.contactlist.*; +import net.java.sip.communicator.service.contactsource.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.gui.event.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + +/** + * The PresenceFilter is used to filter offline contacts from the + * contact list. + * + * @author Yana Stamcheva + */ +public class PresenceFilter + implements ContactListFilter +{ + /** + * The Logger used by the PresenceFilter class and its + * instances to print debugging information. + */ + private static final Logger logger = Logger.getLogger(PresenceFilter.class); + + /** + * Indicates if this presence filter shows or hides the offline contacts. + */ + private boolean isShowOffline; + + /** + * The initial result count below which we insert all filter results + * directly to the contact list without firing events. + */ + private static final int INITIAL_CONTACT_COUNT = 30; + + /** + * Creates an instance of PresenceFilter. + */ + public PresenceFilter() + { + isShowOffline = ConfigurationUtils.isShowOffline(); + } + + /** + * Applies this filter. This filter is applied over the + * MetaContactListService. + * + * @param filterQuery the query which keeps track of the filtering results + */ + public void applyFilter(FilterQuery filterQuery) + { + // Create the query that will track filtering. + MetaContactQuery query = new MetaContactQuery(); + + // Add this query to the filterQuery. + filterQuery.addContactQuery(query); + + List contactQueryList = new ArrayList(); + Iterator filterSources + = GuiActivator.getContactList().getContactSources( + ContactSourceService.PRESENCE_TYPE).iterator(); + + while (filterSources.hasNext()) + { + UIContactSource filterSource = filterSources.next(); + ContactSourceService sourceService + = filterSource.getContactSourceService(); + ContactQuery contactQuery = sourceService.queryContactSource(null); + + contactQueryList.add(contactQuery); + + // Add this query to the filterQuery. + filterQuery.addContactQuery(contactQuery); + } + + // Closes this filter to indicate that we finished adding queries to it. + filterQuery.close(); + + query.addContactQueryListener(GuiActivator.getContactList()); + + int resultCount = 0; + addMatching(GuiActivator.getContactListService().getRoot(), + query, + resultCount); + + for(ContactQuery contactQuery : contactQueryList) + { + for(SourceContact contact : contactQuery.getQueryResults()) + { + addSourceContact(contact); + } + contactQuery.addContactQueryListener(GuiActivator.getContactList()); + } + + query.fireQueryEvent( + query.isCanceled() + ? MetaContactQueryStatusEvent.QUERY_CANCELED + : MetaContactQueryStatusEvent.QUERY_COMPLETED); + } + + /** + * Indicates if the given uiContact is matching this filter. + * + * @param uiContact the UIContact to check + * @return true if the given uiContact is matching + * this filter, otherwise returns false + */ + public boolean isMatching(UIContact uiContact) + { + Object descriptor = uiContact.getDescriptor(); + + if (descriptor instanceof MetaContact) + return isMatching((MetaContact) descriptor); + else if (descriptor instanceof SourceContact) + return isMatching((SourceContact)descriptor); + else + return false; + } + + /** + * Indicates if the given uiGroup is matching this filter. + * + * @param uiGroup the UIGroup to check + * @return true if the given uiGroup is matching + * this filter, otherwise returns false + */ + public boolean isMatching(UIGroup uiGroup) + { + Object descriptor = uiGroup.getDescriptor(); + + if (descriptor instanceof MetaContactGroup) + return isMatching((MetaContactGroup) descriptor); + else + return false; + } + + /** + * Sets the show offline property. + * + * @param isShowOffline indicates if offline contacts are shown + */ + public void setShowOffline(boolean isShowOffline) + { + this.isShowOffline = isShowOffline; + + ConfigurationUtils.setShowOffline(isShowOffline); + } + + /** + * Returns true if offline contacts are shown, otherwise returns + * false. + * + * @return true if offline contacts are shown, otherwise returns + * false + */ + public boolean isShowOffline() + { + return isShowOffline; + } + + /** + * Returns true if offline contacts are shown or if the given + * MetaContact is online, otherwise returns false. + * + * @param metaContact the MetaContact to check + * @return true if the given MetaContact is matching this + * filter + */ + public boolean isMatching(MetaContact metaContact) + { + return isShowOffline || isContactOnline(metaContact); + } + + /** + * Returns true if offline contacts are shown or if the given + * MetaContact is online, otherwise returns false. + * + * @param metaContact the MetaContact to check + * @return true if the given MetaContact is matching this + * filter + */ + public boolean isMatching(SourceContact contact) + { + return + isShowOffline + || contact.getPresenceStatus().isOnline() + || (contact.getPreferredContactDetail(OperationSetMultiUserChat.class) + != null); + } + + /** + * Returns true if offline contacts are shown or if the given + * MetaContactGroup contains online contacts. + * + * @param metaGroup the MetaContactGroup to check + * @return true if the given MetaContactGroup is matching + * this filter + */ + private boolean isMatching(MetaContactGroup metaGroup) + { + return + isShowOffline + || (metaGroup.countOnlineChildContacts() > 0) + || MetaContactListSource.isNewGroup(metaGroup); + } + + /** + * Returns true if the given meta contact is online, false + * otherwise. + * + * @param contact the meta contact + * @return true if the given meta contact is online, false + * otherwise + */ + private boolean isContactOnline(MetaContact contact) + { + // If for some reason the default contact is null we return false. + Contact defaultContact = contact.getDefaultContact(); + if(defaultContact == null) + return false; + + // Lays on the fact that the default contact is the most connected. + return defaultContact.getPresenceStatus().getStatus() + >= PresenceStatus.ONLINE_THRESHOLD; + } + + /** + * Adds all contacts contained in the given MetaContactGroup + * matching the current filter and not contained in the contact list. + * + * @param metaGroup the MetaContactGroup, which matching contacts + * to add + * @param query the MetaContactQuery that notifies interested + * listeners of the results of this matching + * @param resultCount the initial result count we would insert directly to + * the contact list without firing events + */ + private void addMatching( MetaContactGroup metaGroup, + MetaContactQuery query, + int resultCount) + { + Iterator childContacts = metaGroup.getChildContacts(); + + while (childContacts.hasNext() && !query.isCanceled()) + { + MetaContact metaContact = childContacts.next(); + + if(isMatching(metaContact)) + { + resultCount++; + if (resultCount <= INITIAL_CONTACT_COUNT) + { + UIGroup uiGroup = null; + if (!MetaContactListSource.isRootGroup(metaGroup)) + { + synchronized (metaGroup) + { + uiGroup = MetaContactListSource + .getUIGroup(metaGroup); + + if (uiGroup == null) + uiGroup = MetaContactListSource + .createUIGroup(metaGroup); + } + } + + if (logger.isDebugEnabled()) + logger.debug("Presence filter contact added: " + + metaContact.getDisplayName()); + + UIContact newUIContact; + synchronized (metaContact) + { + newUIContact = MetaContactListSource + .createUIContact(metaContact); + } + + GuiActivator.getContactList().addContact( + newUIContact, + uiGroup, + true, + true); + + query.setInitialResultCount(resultCount); + } + else + query.fireQueryEvent(metaContact); + } + } + + // If in the meantime the filtering has been stopped we return here. + if (query.isCanceled()) + return; + + Iterator subgroups = metaGroup.getSubgroups(); + while(subgroups.hasNext() && !query.isCanceled()) + { + MetaContactGroup subgroup = subgroups.next(); + + if (isMatching(subgroup)) + { + UIGroup uiGroup; + synchronized(subgroup) + { + uiGroup = MetaContactListSource + .getUIGroup(subgroup); + + if (uiGroup == null) + uiGroup = MetaContactListSource + .createUIGroup(subgroup); + } + + GuiActivator.getContactList().addGroup(uiGroup, true); + + addMatching(subgroup, query, resultCount); + } + } + } + + /** + * Adds the given sourceContact to the contact list. + * @param sourceContact the SourceContact to add + */ + private void addSourceContact(SourceContact sourceContact) + { + ContactSourceService contactSource + = sourceContact.getContactSource(); + + TreeContactList sourceContactList = GuiActivator.getContactList(); + UIContactSource sourceUI + = sourceContactList .getContactSource(contactSource); + + if (sourceUI != null + // ExtendedContactSourceService has already matched the + // SourceContact over the pattern + && (contactSource instanceof ExtendedContactSourceService) + || isMatching(sourceContact)) + { + boolean isSorted = (sourceContact.getIndex() > -1) ? true : false; + + sourceContactList.addContact( + sourceUI.createUIContact(sourceContact), + sourceUI.getUIGroup(), + isSorted, + true); + } + else + sourceUI.removeUIContact(sourceContact); + } +} diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java index d8a0de693..3df220605 100644 --- a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java +++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java @@ -1,85 +1,83 @@ -/* - * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * - * Distributable under LGPL license. - * See terms of license at gnu.org. - */ -package net.java.sip.communicator.plugin.phonenumbercontactsource; - -import java.util.*; - -import net.java.sip.communicator.service.contactsource.*; - -/** - * The PhoneNumberContactSource is a source of phone numbers coming - * from the server stored contact info of all contacts for all protocol - * providers. - * - * @author Yana Stamcheva - */ -public class PhoneNumberContactSource - implements ContactSourceService -{ - /** - * Returns DEFAULT_TYPE to indicate that this contact source is a default - * source. - * - * @return the type of this contact source - */ - public int getType() - { - return DEFAULT_TYPE; - } - - /** - * Returns a user-friendly string that identifies this contact source. - * - * @return the display name of this contact source - */ - public String getDisplayName() - { - return PNContactSourceActivator.getResources().getI18NString( - "plugin.phonenumbercontactsource.DISPLAY_NAME"); - } - - /** - * Queries this contact source for the given queryString. - * - * @param queryString the string to search for - * @return the created query - */ - public ContactQuery queryContactSource(String queryString) - { - return queryContactSource(queryString, -1); - } - - /** - * Queries this contact source for the given queryString. - * - * @param queryString the string to search for - * @param contactCount the maximum count of result contacts - * @return the created query - */ - public ContactQuery queryContactSource( String queryString, - int contactCount) - { - if (queryString == null) - queryString = ""; - - PhoneNumberContactQuery contactQuery - = new PhoneNumberContactQuery(this, queryString, contactCount); - - contactQuery.start(); - return contactQuery; - } - - /** - * Returns the index of the contact source in the result list. - * - * @return the index of the contact source in the result list - */ - public int getIndex() - { - return -1; - } -} +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.phonenumbercontactsource; + +import net.java.sip.communicator.service.contactsource.*; + +/** + * The PhoneNumberContactSource is a source of phone numbers coming + * from the server stored contact info of all contacts for all protocol + * providers. + * + * @author Yana Stamcheva + */ +public class PhoneNumberContactSource + implements ContactSourceService +{ + /** + * Returns DEFAULT_TYPE to indicate that this contact source is a default + * source. + * + * @return the type of this contact source + */ + public int getType() + { + return DEFAULT_TYPE; + } + + /** + * Returns a user-friendly string that identifies this contact source. + * + * @return the display name of this contact source + */ + public String getDisplayName() + { + return PNContactSourceActivator.getResources().getI18NString( + "plugin.phonenumbercontactsource.DISPLAY_NAME"); + } + + /** + * Queries this contact source for the given queryString. + * + * @param queryString the string to search for + * @return the created query + */ + public ContactQuery queryContactSource(String queryString) + { + return queryContactSource(queryString, -1); + } + + /** + * Queries this contact source for the given queryString. + * + * @param queryString the string to search for + * @param contactCount the maximum count of result contacts + * @return the created query + */ + public ContactQuery queryContactSource( String queryString, + int contactCount) + { + if (queryString == null) + queryString = ""; + + PhoneNumberContactQuery contactQuery + = new PhoneNumberContactQuery(this, queryString, contactCount); + + contactQuery.start(); + return contactQuery; + } + + /** + * Returns the index of the contact source in the result list. + * + * @return the index of the contact source in the result list + */ + public int getIndex() + { + return -1; + } +}