Fix for inserting large number of query results for server chat room

listing.

Previously chat rooms were inserted one by one into the result and
listeners were informed for each of the chat rooms immediately after it
was inserted, and on top of that we reorder after each insertion. All in
all this caused very unpredictable results.

The modification massively inserts the whole result set and then fires a
listener event for each of the added chat rooms.
fix-message-formatting
Danny van Heumen 11 years ago
parent 5e5bdf5c59
commit 8ca39e0afb

@ -107,18 +107,26 @@ protected void run()
* @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)
private void providerAdded(final ChatRoomProviderWrapper provider,
final boolean addQueryResult)
{
List<String> chatRoomNames
= MUCActivator.getMUCService().getExistingChatRooms(provider);
if(chatRoomNames == null)
final ProtocolProviderService pps = provider.getProtocolProvider();
List<String> chatRoomNames =
MUCActivator.getMUCService().getExistingChatRooms(provider);
if (chatRoomNames == null)
{
return;
for(String chatRoomName : chatRoomNames)
}
// Already create all the BaseChatRoomSourceContact instances since all
// the data is already available.
final Set<BaseChatRoomSourceContact> chatRooms =
new HashSet<BaseChatRoomSourceContact>(chatRoomNames.size());
for (final String name : chatRoomNames)
{
addChatRoom( provider.getProtocolProvider(), chatRoomName,
chatRoomName, addQueryResult);
chatRooms.add(new BaseChatRoomSourceContact(name, name, this, pps));
}
addChatRooms(pps, chatRooms, addQueryResult);
}
@ -159,6 +167,55 @@ private void addChatRoom(ProtocolProviderService pps,
}
}
/**
* Adds found results to the query results.
*
* @param pps the protocol provider associated with the found chat room.
* @param chatRooms The set of chat rooms based on
* BaseChatRoomSourceContact. This is the full set and it will be
* filtered according to demands of the queryString.
* @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 addChatRooms(final ProtocolProviderService pps,
final Set<BaseChatRoomSourceContact> chatRooms,
final boolean addQueryResult)
{
BaseChatRoomSourceContact room;
Iterator<BaseChatRoomSourceContact> iterator = chatRooms.iterator();
while (iterator.hasNext())
{
room = iterator.next();
// Notice the NOT operator at the start ...
if (!((queryString == null || (room.getChatRoomName().contains(
queryString) || room.getChatRoomID().contains(queryString)))
&& isMatching(room.getChatRoomID(), pps)))
{
iterator.remove();
}
}
synchronized (contactResults)
{
contactResults.addAll(chatRooms);
}
if (addQueryResult)
{
addQueryResults(chatRooms);
}
else
{
// TODO Need something to fire one event for multiple contacts.
for (SourceContact contact : chatRooms)
{
fireContactReceived(contact, false);
}
}
}
@Override
public void chatRoomProviderWrapperAdded(ChatRoomProviderWrapper provider)
{
@ -273,4 +330,4 @@ public int indexOf(BaseChatRoomSourceContact contact)
}
return -1;
}
}
}

@ -116,7 +116,7 @@ protected boolean addQueryResult(SourceContact sourceContact,
return changed;
}
/**
* Adds a specific <tt>SourceContact</tt> to the list of
* <tt>SourceContact</tt>s to be returned by this <tt>ContactQuery</tt> in
@ -141,6 +141,39 @@ protected boolean addQueryResult(SourceContact sourceContact)
return changed;
}
/**
* Adds a set of <tt>SourceContact</tt> instances to the list of
* <tt>SourceContact</tt>s to be returned by this <tt>ContactQuery</tt> in
* response to {@link #getQueryResults()}.
*
* @param sourceContacts the set of <tt>SourceContact</tt> to be added to
* the <tt>queryResults</tt> of this <tt>ContactQuery</tt>
* @return <tt>true</tt> if the <tt>queryResults</tt> of this
* <tt>ContactQuery</tt> has changed in response to the call
*/
protected boolean addQueryResults(
final Set<? extends SourceContact> sourceContacts)
{
final boolean changed;
synchronized (queryResults)
{
changed = queryResults.addAll(sourceContacts);
}
if (changed)
{
// TODO Need something to fire one event for multiple contacts.
for (SourceContact contact : sourceContacts)
{
fireContactReceived(contact, false);
}
}
return changed;
}
/**
* Gets the {@link #query} of this <tt>AsyncContactQuery</tt> as a
* <tt>String</tt> which represents a phone number (if possible).

Loading…
Cancel
Save