From 32e37fba877b4a4be56166fa0d57ed86c07ae4ec Mon Sep 17 00:00:00 2001 From: hristoterezov Date: Fri, 22 Nov 2013 18:59:15 +0200 Subject: [PATCH] Optimizes the chat room contact source. --- .../conference/ConferenceChatManager.java | 65 +------- .../gui/main/contactlist/ContactListPane.java | 7 +- .../ContactListTreeCellRenderer.java | 6 +- .../gui/main/contactlist/TreeContactList.java | 6 +- .../muc/ChatRoomContactSourceService.java | 40 +---- .../impl/muc/ChatRoomListImpl.java | 6 +- .../communicator/impl/muc/ChatRoomQuery.java | 152 +++++++++++++++++- .../communicator/impl/muc/MUCActivator.java | 22 ++- .../communicator/impl/muc/MUCServiceImpl.java | 52 ++++++ .../PhoneNumberContactSource.java | 31 +--- .../communicator/service/muc/MUCService.java | 7 + 11 files changed, 238 insertions(+), 156 deletions(-) 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 9733e601a..1cdab0aa0 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 @@ -45,8 +45,7 @@ public class ConferenceChatManager AdHocChatRoomInvitationRejectionListener, LocalUserChatRoomPresenceListener, LocalUserAdHocChatRoomPresenceListener, - ServiceListener, - ChatRoomList.ChatRoomProviderWrapperListener + ServiceListener { /** * The object used for logging. @@ -76,7 +75,6 @@ public class ConferenceChatManager */ public ConferenceChatManager() { - GuiActivator.getMUCService().addChatRoomProviderWrapperListener(this); // Loads the chat rooms list in a separate thread. new Thread() { @@ -1267,65 +1265,4 @@ public void messageReceived(AdHocChatRoomMessageReceivedEvent evt) public void invitationRejected(AdHocChatRoomInvitationRejectedEvent evt) {} - /** - * Opens a chat window for the chat room. - * - * @param room the chat room. - */ - public void openChatRoom(ChatRoomWrapper room) - { - if (room.getChatRoom() == null) - { - room = GuiActivator.getMUCService().createChatRoom( - room.getChatRoomName(), - room.getParentProvider().getProtocolProvider(), - new ArrayList(),"", false, false, true); - - // leave the chatroom because getChatRoom().isJoined() returns true - // otherwise - if (room.getChatRoom().isJoined()) - room.getChatRoom().leave(); - - } - - String savedNick = - ConfigurationUtils.getChatRoomProperty(room - .getParentProvider().getProtocolProvider(), room - .getChatRoomID(), "userNickName"); - - if (savedNick == null) - { - String[] joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions( - room.getParentProvider().getProtocolProvider(), - room.getChatRoomID()); - String nickName = joinOptions[0]; - if(nickName == null) - return; - - if (!room.getChatRoom().isJoined()) - { - GuiActivator.getMUCService().joinChatRoom(room, nickName, null, - joinOptions[1]); - } - - } - else - { - if (!room.getChatRoom().isJoined()) - GuiActivator.getMUCService().joinChatRoom(room, savedNick, null); - } - - GuiActivator.getUIService().openChatRoomWindow(room); - } - - @Override - public void chatRoomProviderWrapperAdded(ChatRoomProviderWrapper provider) - {} - - @Override - public void chatRoomProviderWrapperRemoved(ChatRoomProviderWrapper provider) - { - for(int i = 0; i < provider.countChatRooms(); i++) - GuiActivator.getUIService().closeChatRoomWindow(provider.getChatRoom(i)); - } } diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java index 82e0f6d80..256b7922e 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java @@ -17,7 +17,6 @@ import net.java.sip.communicator.impl.gui.event.*; import net.java.sip.communicator.impl.gui.main.*; import net.java.sip.communicator.impl.gui.main.chat.*; -import net.java.sip.communicator.impl.gui.main.chat.conference.*; import net.java.sip.communicator.plugin.desktoputil.*; import net.java.sip.communicator.service.contacteventhandler.*; import net.java.sip.communicator.service.contactlist.*; @@ -214,17 +213,13 @@ public void contactClicked(ContactListEvent evt) else if(((SourceContact) descriptor.getDescriptor()) .getContactDetails(OperationSetMultiUserChat.class) != null) { - ConferenceChatManager conferenceChatManager - = GuiActivator.getUIService() - .getConferenceChatManager(); - SourceContact contact = (SourceContact) descriptor.getDescriptor(); ChatRoomWrapper room = GuiActivator.getMUCService() .findChatRoomWrapperFromSourceContact(contact); if(room != null) - conferenceChatManager.openChatRoom(room); + GuiActivator.getMUCService().openChatRoom(room); } } diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java index cd7f40828..6122d2b0d 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java @@ -18,7 +18,6 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.call.*; -import net.java.sip.communicator.impl.gui.main.chat.conference.*; import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.plugin.desktoputil.*; @@ -328,16 +327,13 @@ else if(((SourceContact) contactDescriptor.getDescriptor()) .getContactDetails(OperationSetMultiUserChat.class) != null) { - ConferenceChatManager conferenceChatManager - = GuiActivator.getUIService() - .getConferenceChatManager(); SourceContact contact = (SourceContact) contactDescriptor.getDescriptor(); ChatRoomWrapper room = GuiActivator.getMUCService() .findChatRoomWrapperFromSourceContact(contact); if(room != null) - conferenceChatManager.openChatRoom(room); + GuiActivator.getMUCService().openChatRoom(room); } } } diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java index ac201ec93..0af74a3e9 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java @@ -17,7 +17,6 @@ import javax.swing.tree.*; import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.impl.gui.main.chat.conference.ConferenceChatManager; import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*; import net.java.sip.communicator.impl.gui.main.contactlist.notifsource.*; import net.java.sip.communicator.impl.gui.utils.*; @@ -1575,16 +1574,13 @@ else if(((SourceContact) uiContact.getDescriptor()) .getContactDetails(OperationSetMultiUserChat.class) != null) { - ConferenceChatManager conferenceChatManager - = GuiActivator.getUIService() - .getConferenceChatManager(); SourceContact contact = (SourceContact) uiContact.getDescriptor(); ChatRoomWrapper room = GuiActivator.getMUCService() .findChatRoomWrapperFromSourceContact(contact); if(room != null) - conferenceChatManager.openChatRoom(room); + GuiActivator.getMUCService().openChatRoom(room); } } } diff --git a/src/net/java/sip/communicator/impl/muc/ChatRoomContactSourceService.java b/src/net/java/sip/communicator/impl/muc/ChatRoomContactSourceService.java index 24b0870d8..b1c533559 100644 --- a/src/net/java/sip/communicator/impl/muc/ChatRoomContactSourceService.java +++ b/src/net/java/sip/communicator/impl/muc/ChatRoomContactSourceService.java @@ -5,7 +5,6 @@ */ package net.java.sip.communicator.impl.muc; -import java.util.*; import net.java.sip.communicator.service.contactsource.*; /** @@ -16,13 +15,6 @@ public class ChatRoomContactSourceService implements ContactSourceService { - /** - * The List of ChatRoomQuery instances - * which have been started and haven't stopped yet. - */ - private final List queries - = new LinkedList(); - /** * Returns the type of this contact source. * @@ -68,39 +60,15 @@ public ContactQuery queryContactSource(String queryString, int contactCount) { if (queryString == null) queryString = ""; + ChatRoomQuery contactQuery = new ChatRoomQuery(queryString, this); - synchronized (queries) - { - queries.add(contactQuery); - } - - boolean queryHasStarted = false; - - try - { - contactQuery.start(); - queryHasStarted = true; - } - finally - { - if (!queryHasStarted) - { - synchronized (queries) - { - if (queries.remove(contactQuery)) - queries.notify(); - } - } - } + contactQuery.start(); + + return contactQuery; } - - public synchronized List getQueries() - { - return queries; - } /** * Returns the index of the contact source in the result list. * diff --git a/src/net/java/sip/communicator/impl/muc/ChatRoomListImpl.java b/src/net/java/sip/communicator/impl/muc/ChatRoomListImpl.java index ab57388fb..f90019880 100644 --- a/src/net/java/sip/communicator/impl/muc/ChatRoomListImpl.java +++ b/src/net/java/sip/communicator/impl/muc/ChatRoomListImpl.java @@ -284,7 +284,11 @@ private void removeChatProvider(ChatRoomProviderWrapper chatRoomProvider, } } } - + + for(int i = 0; i < chatRoomProvider.countChatRooms(); i++) + MUCActivator.getUIService().closeChatRoomWindow( + chatRoomProvider.getChatRoom(i)); + fireProviderWrapperRemoved(chatRoomProvider); } diff --git a/src/net/java/sip/communicator/impl/muc/ChatRoomQuery.java b/src/net/java/sip/communicator/impl/muc/ChatRoomQuery.java index 692a3fe13..101cc6fbf 100644 --- a/src/net/java/sip/communicator/impl/muc/ChatRoomQuery.java +++ b/src/net/java/sip/communicator/impl/muc/ChatRoomQuery.java @@ -8,6 +8,8 @@ import java.util.*; import java.util.regex.*; +import org.osgi.framework.*; + import net.java.sip.communicator.service.contactsource.*; import net.java.sip.communicator.service.muc.*; import net.java.sip.communicator.service.muc.ChatRoomList.*; @@ -40,6 +42,18 @@ public class ChatRoomQuery * MUC service. */ private MUCServiceImpl mucService; + + /** + * The number of contact query listeners. + */ + private int contactQueryListenersCount = 0; + + /** + * The protocol provider registration listener. + */ + private ServiceListener protolProviderRegistrationListener = null; + + /** * Creates an instance of ChatRoomQuery by specifying @@ -57,16 +71,32 @@ public ChatRoomQuery(String queryString, Pattern.compile(queryString, Pattern.CASE_INSENSITIVE | Pattern.LITERAL), true); this.queryString = queryString; + + mucService = MUCActivator.getMUCService(); + + } + + /** + * Adds listeners for the query + */ + private void initListeners() + { for(ProtocolProviderService pps : MUCActivator.getChatRoomProviders()) { addQueryToProviderPresenceListeners(pps); } - mucService = MUCActivator.getMUCService(); mucService.addChatRoomListChangeListener(this); mucService.addChatRoomProviderWrapperListener(this); + protolProviderRegistrationListener = new ProtocolProviderRegListener(); + MUCActivator.bundleContext.addServiceListener( + protolProviderRegistrationListener); } + /** + * Adds the query as presence listener to protocol provider service. + * @param pps the protocol provider service. + */ public void addQueryToProviderPresenceListeners(ProtocolProviderService pps) { OperationSetMultiUserChat opSetMUC @@ -77,6 +107,10 @@ public void addQueryToProviderPresenceListeners(ProtocolProviderService pps) } } + /** + * Removes the query from protocol provider service presence listeners. + * @param pps the protocol provider service. + */ public void removeQueryFromProviderPresenceListeners( ProtocolProviderService pps) { @@ -104,6 +138,12 @@ protected void run() setStatus(QUERY_COMPLETED); } + /** + * Handles adding a chat room provider. + * @param provider the provider. + * @param addQueryResult indicates whether we should add the chat room to + * the query results or fire an event without adding it to the results. + */ private void providerAdded(ChatRoomProviderWrapper provider, boolean addQueryResult) { @@ -351,6 +391,11 @@ public void chatRoomProviderWrapperRemoved(ChatRoomProviderWrapper provider) } } + /** + * Returns the index of the contact in the contact results list. + * @param contact the contact. + * @return the index of the contact in the contact results list. + */ public synchronized int indexOf(ChatRoomSourceContact contact) { Iterator it = contactResults.iterator(); @@ -365,4 +410,109 @@ public synchronized int indexOf(ChatRoomSourceContact contact) } return -1; } + + /** + * Clears any listener we used. + */ + private void clearListeners() + { + mucService.removeChatRoomListChangeListener(this); + mucService.removeChatRoomProviderWrapperListener(this); + if(protolProviderRegistrationListener != null) + MUCActivator.bundleContext.removeServiceListener( + protolProviderRegistrationListener); + protolProviderRegistrationListener = null; + for(ProtocolProviderService pps : MUCActivator.getChatRoomProviders()) + { + removeQueryFromProviderPresenceListeners(pps); + } + } + + /** + * Cancels this ContactQuery. + * + * @see ContactQuery#cancel() + */ + public void cancel() + { + clearListeners(); + + super.cancel(); + } + + /** + * If query has status changed to cancel, let's clear listeners. + * @param status {@link ContactQuery#QUERY_CANCELED}, + * {@link ContactQuery#QUERY_COMPLETED} + */ + public void setStatus(int status) + { + if(status == QUERY_CANCELED) + clearListeners(); + + super.setStatus(status); + } + + @Override + public void addContactQueryListener(ContactQueryListener l) + { + super.addContactQueryListener(l); + contactQueryListenersCount++; + if(contactQueryListenersCount == 1) + { + initListeners(); + } + } + @Override + public void removeContactQueryListener(ContactQueryListener l) + { + super.removeContactQueryListener(l); + contactQueryListenersCount--; + if(contactQueryListenersCount == 0) + { + clearListeners(); + } + } + + /** + * Listens for ProtocolProviderService registrations. + */ + private class ProtocolProviderRegListener + implements ServiceListener + { + /** + * Handles service change events. + */ + public void serviceChanged(ServiceEvent event) + { + ServiceReference serviceRef = event.getServiceReference(); + + // if the event is caused by a bundle being stopped, we don't want to + // know + if (serviceRef.getBundle().getState() == Bundle.STOPPING) + { + return; + } + + Object service = MUCActivator.bundleContext.getService(serviceRef); + + // we don't care if the source service is not a protocol provider + if (!(service instanceof ProtocolProviderService)) + { + return; + } + + switch (event.getType()) + { + case ServiceEvent.REGISTERED: + addQueryToProviderPresenceListeners( + (ProtocolProviderService) service); + break; + case ServiceEvent.UNREGISTERING: + removeQueryFromProviderPresenceListeners( + (ProtocolProviderService) service); + break; + } + } + } } \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/muc/MUCActivator.java b/src/net/java/sip/communicator/impl/muc/MUCActivator.java index 37a943bfe..cd75c8cfc 100644 --- a/src/net/java/sip/communicator/impl/muc/MUCActivator.java +++ b/src/net/java/sip/communicator/impl/muc/MUCActivator.java @@ -91,6 +91,12 @@ public class MUCActivator */ private static UIService uiService = null; + /** + * Listens for ProtocolProviderService registrations. + */ + private static ProtocolProviderRegListener protocolProviderRegListener + = null; + /** * Starts this bundle. * @@ -118,6 +124,11 @@ public void start(BundleContext context) throws Exception public void stop(BundleContext context) throws Exception { + if(protocolProviderRegListener != null) + { + bundleContext.removeServiceListener(protocolProviderRegListener); + } + chatRoomProviders.clear(); } /** @@ -240,8 +251,9 @@ public static List getChatRoomProviders() return chatRoomProviders; chatRoomProviders = new LinkedList(); - - bundleContext.addServiceListener(new ProtocolProviderRegListener()); + + protocolProviderRegListener = new ProtocolProviderRegListener(); + bundleContext.addServiceListener(protocolProviderRegListener); ServiceReference[] serRefs = null; try @@ -315,15 +327,9 @@ public void serviceChanged(ServiceEvent event) { case ServiceEvent.REGISTERED: handleProviderAdded((ProtocolProviderService) service); - for(ChatRoomQuery query : getContactSource().getQueries()) - query.addQueryToProviderPresenceListeners( - (ProtocolProviderService) service); break; case ServiceEvent.UNREGISTERING: handleProviderRemoved((ProtocolProviderService) service); - for(ChatRoomQuery query : getContactSource().getQueries()) - query.removeQueryFromProviderPresenceListeners( - (ProtocolProviderService) service); break; } } diff --git a/src/net/java/sip/communicator/impl/muc/MUCServiceImpl.java b/src/net/java/sip/communicator/impl/muc/MUCServiceImpl.java index 5a62c80c7..3a4a429f0 100644 --- a/src/net/java/sip/communicator/impl/muc/MUCServiceImpl.java +++ b/src/net/java/sip/communicator/impl/muc/MUCServiceImpl.java @@ -12,6 +12,7 @@ import net.java.sip.communicator.plugin.desktoputil.*; +import net.java.sip.communicator.plugin.desktoputil.chat.*; import net.java.sip.communicator.service.contactsource.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.muc.*; @@ -967,4 +968,55 @@ public ChatRoomWrapper findChatRoomWrapperFromChatRoom(ChatRoom chatRoom) { return chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom); } + + /** + * Opens a chat window for the chat room. + * + * @param room the chat room. + */ + public void openChatRoom(ChatRoomWrapper room) + { + if (room.getChatRoom() == null) + { + room = createChatRoom( + room.getChatRoomName(), + room.getParentProvider().getProtocolProvider(), + new ArrayList(),"", false, false, true); + + // leave the chatroom because getChatRoom().isJoined() returns true + // otherwise + if (room.getChatRoom().isJoined()) + room.getChatRoom().leave(); + + } + + String savedNick = + ConfigurationUtils.getChatRoomProperty(room + .getParentProvider().getProtocolProvider(), room + .getChatRoomID(), "userNickName"); + + if (savedNick == null) + { + String[] joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions( + room.getParentProvider().getProtocolProvider(), + room.getChatRoomID()); + String nickName = joinOptions[0]; + if(nickName == null) + return; + + if (!room.getChatRoom().isJoined()) + { + joinChatRoom(room, nickName, null, + joinOptions[1]); + } + + } + else + { + if (!room.getChatRoom().isJoined()) + joinChatRoom(room, savedNick, null); + } + + MUCActivator.getUIService().openChatRoomWindow(room); + } } diff --git a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java index a5c662e7c..d8a0de693 100644 --- a/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java +++ b/src/net/java/sip/communicator/plugin/phonenumbercontactsource/PhoneNumberContactSource.java @@ -20,13 +20,6 @@ public class PhoneNumberContactSource implements ContactSourceService { - /** - * The List of PhoneNumberContactQuery instances - * which have been started and haven't stopped yet. - */ - private final List queries - = new LinkedList(); - /** * Returns DEFAULT_TYPE to indicate that this contact source is a default * source. @@ -76,29 +69,7 @@ public ContactQuery queryContactSource( String queryString, PhoneNumberContactQuery contactQuery = new PhoneNumberContactQuery(this, queryString, contactCount); - synchronized (queries) - { - queries.add(contactQuery); - } - - boolean queryHasStarted = false; - - try - { - contactQuery.start(); - queryHasStarted = true; - } - finally - { - if (!queryHasStarted) - { - synchronized (queries) - { - if (queries.remove(contactQuery)) - queries.notify(); - } - } - } + contactQuery.start(); return contactQuery; } diff --git a/src/net/java/sip/communicator/service/muc/MUCService.java b/src/net/java/sip/communicator/service/muc/MUCService.java index c10ab6fa6..175138c19 100644 --- a/src/net/java/sip/communicator/service/muc/MUCService.java +++ b/src/net/java/sip/communicator/service/muc/MUCService.java @@ -298,5 +298,12 @@ public abstract ChatRoomProviderWrapper findServerWrapperFromProvider( */ public abstract ChatRoomWrapper findChatRoomWrapperFromChatRoom( ChatRoom chatRoom); + + /** + * Opens a chat window for the chat room. + * + * @param room the chat room. + */ + public abstract void openChatRoom(ChatRoomWrapper room); }