aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java
diff options
context:
space:
mode:
authorDamian Minkov <damencho@jitsi.org>2014-03-14 15:36:01 +0200
committerDamian Minkov <damencho@jitsi.org>2014-03-14 17:02:17 +0200
commitac886ebbed3606140f5ec7806399558a48345c30 (patch)
tree3a2265f2c30dea1b76daab972eab3d18904884eb /src/net/java
parent84fdf4b6a43ce935c8e48cca89f19327693b7e1e (diff)
downloadjitsi-ac886ebbed3606140f5ec7806399558a48345c30.zip
jitsi-ac886ebbed3606140f5ec7806399558a48345c30.tar.gz
jitsi-ac886ebbed3606140f5ec7806399558a48345c30.tar.bz2
Changes the way recent messages are loaded on protocol provider events.
Diffstat (limited to 'src/net/java')
-rw-r--r--src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java33
-rw-r--r--src/net/java/sip/communicator/impl/msghistory/MessageSourceContact.java50
-rw-r--r--src/net/java/sip/communicator/impl/msghistory/MessageSourceService.java712
3 files changed, 606 insertions, 189 deletions
diff --git a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java
index 0c1a827..70e895e 100644
--- a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java
@@ -429,7 +429,7 @@ public class MessageHistoryServiceImpl
}
if(contactToFilter != null
- && !contactToFilter.equals(id.getID()[3]))
+ && !id.getID()[3].startsWith(contactToFilter))
{
continue;
}
@@ -1130,7 +1130,7 @@ public class MessageHistoryServiceImpl
*/
private void loadRecentMessages()
{
- this.messageSourceService = new MessageSourceService();
+ this.messageSourceService = new MessageSourceService(this);
messageSourceServiceReg = bundleContext.registerService(
ContactSourceService.class.getName(),
messageSourceService, null);
@@ -1628,6 +1628,9 @@ public class MessageHistoryServiceImpl
opSetPresence
.addProviderPresenceStatusListener(messageSourceService);
}
+
+ if(messageSourceService != null)
+ messageSourceService.handleProviderAdded(provider);
}
/**
@@ -1690,6 +1693,9 @@ public class MessageHistoryServiceImpl
opSetPresence
.removeProviderPresenceStatusListener(messageSourceService);
}
+
+ if(messageSourceService != null)
+ messageSourceService.handleProviderRemoved(provider);
}
/**
@@ -2745,6 +2751,21 @@ public class MessageHistoryServiceImpl
// start listening for newly register or removed protocol providers
bundleContext.addServiceListener(this);
+ for (ProtocolProviderService pps : getCurrentlyAvailableProviders())
+ {
+ this.handleProviderAdded(pps);
+ }
+ }
+
+ /**
+ * Returns currently registered in osgi ProtocolProviderServices.
+ * @return currently registered in osgi ProtocolProviderServices.
+ */
+ List<ProtocolProviderService> getCurrentlyAvailableProviders()
+ {
+ List<ProtocolProviderService> res
+ = new ArrayList<ProtocolProviderService>();
+
ServiceReference[] protocolProviderRefs = null;
try
{
@@ -2758,7 +2779,7 @@ public class MessageHistoryServiceImpl
// but let's log just in case.
logger.error(
"Error while retrieving service refs", ex);
- return;
+ return res;
}
// in case we found any
@@ -2772,11 +2793,13 @@ public class MessageHistoryServiceImpl
{
ProtocolProviderService provider
= (ProtocolProviderService) bundleContext
- .getService(protocolProviderRefs[i]);
+ .getService(protocolProviderRefs[i]);
- this.handleProviderAdded(provider);
+ res.add(provider);
}
}
+
+ return res;
}
/**
diff --git a/src/net/java/sip/communicator/impl/msghistory/MessageSourceContact.java b/src/net/java/sip/communicator/impl/msghistory/MessageSourceContact.java
index c87ec8f..0a4a87e 100644
--- a/src/net/java/sip/communicator/impl/msghistory/MessageSourceContact.java
+++ b/src/net/java/sip/communicator/impl/msghistory/MessageSourceContact.java
@@ -203,6 +203,34 @@ public class MessageSourceContact
}
/**
+ * Updates fields.
+ * @param msc the object
+ */
+ void update(MessageSourceContact msc)
+ {
+ this.contact = msc.contact;
+
+ this.address = contact.getAddress();
+ this.displayName = contact.getDisplayName();
+ this.ppService = contact.getProtocolProvider();
+ this.image = contact.getImage();
+ this.status = contact.getPresenceStatus();
+ this.messageContent = msc.messageContent;
+ this.timestamp = msc.timestamp;
+
+ updateMessageContent();
+ }
+
+ @Override
+ public String toString()
+ {
+ return "MessageSourceContact{" +
+ "address='" + address + '\'' +
+ ", ppService=" + ppService +
+ '}';
+ }
+
+ /**
* We will the details for this source contact.
* Will skip OperationSetBasicInstantMessaging for chat rooms.
* @param isChatRoom is current source contact a chat room.
@@ -430,4 +458,26 @@ public class MessageSourceContact
return o.getTimestamp()
.compareTo(getTimestamp());
}
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if(this == o) return true;
+ if(o == null || getClass() != o.getClass()) return false;
+
+ MessageSourceContact that = (MessageSourceContact) o;
+
+ if(!address.equals(that.address)) return false;
+ if(!ppService.equals(that.ppService)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = address.hashCode();
+ result = 31 * result + ppService.hashCode();
+ return result;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/msghistory/MessageSourceService.java b/src/net/java/sip/communicator/impl/msghistory/MessageSourceService.java
index bcb01a6..01a5da8 100644
--- a/src/net/java/sip/communicator/impl/msghistory/MessageSourceService.java
+++ b/src/net/java/sip/communicator/impl/msghistory/MessageSourceService.java
@@ -8,6 +8,7 @@ package net.java.sip.communicator.impl.msghistory;
import java.beans.*;
import java.io.*;
+import java.text.*;
import java.util.*;
import java.util.regex.*;
@@ -20,6 +21,8 @@ import net.java.sip.communicator.service.protocol.event.*;
import org.jitsi.util.*;
+import static net.java.sip.communicator.service.history.HistoryService.DATE_FORMAT;
+
/**
* The source contact service. The will show most recent messages.
*
@@ -70,6 +73,12 @@ public class MessageSourceService
= "net.java.sip.communicator.impl.msghistory.contactsrc.IS_SMS_ENABLED";
/**
+ * The number of recent messages to store in the history, but will retrieve
+ * just <tt>numberOfMessages</tt>
+ */
+ private static final int NUMBER_OF_MSGS_IN_HISTORY = 100;
+
+ /**
* Number of messages to show.
*/
private int numberOfMessages = 10;
@@ -78,7 +87,13 @@ public class MessageSourceService
* The structure to save recent messages list.
*/
private static final String[] STRUCTURE_NAMES
- = new String[] { "provider", "contact"};
+ = new String[] { "provider", "contact", "timestamp", "ver"};
+
+ /**
+ * The current version of recent messages. When changed the recent messages
+ * are recreated.
+ */
+ private static final String RECENT_MSGS_VER = "1";
/**
* The structure.
@@ -100,7 +115,13 @@ public class MessageSourceService
/**
* List of recent messages.
*/
- private List<MessageSourceContact> recentMessages = null;
+ private List<MessageSourceContact> recentMessages
+ = new LinkedList<MessageSourceContact>();
+
+ /**
+ * Date of the oldest shown message.
+ */
+ private Date oldestRecentMessage = null;
/**
* The last query created.
@@ -113,10 +134,17 @@ public class MessageSourceService
private boolean isSMSEnabled = false;
/**
+ * Message history service that has created us.
+ */
+ private MessageHistoryServiceImpl messageHistoryService;
+
+ /**
* Constructs MessageSourceService.
*/
- MessageSourceService()
+ MessageSourceService(MessageHistoryServiceImpl messageHistoryService)
{
+ this.messageHistoryService = messageHistoryService;
+
if(MessageHistoryActivator.getConfigurationService()
.getBoolean(IN_HISTORY_PROPERTY , false))
{
@@ -181,184 +209,401 @@ public class MessageSourceService
return recentQuery;
}
- private synchronized List<MessageSourceContact> getRecentMessages()
+ /**
+ * Searches for entries in cached recent messages in history.
+ *
+ * @param provider
+ * @return
+ */
+ private List<MessageSourceContact> getSourceContacts(
+ ProtocolProviderService provider)
{
- if(recentMessages == null)
+ String providerID = provider.getAccountID().getAccountUniqueID();
+ List<String> recentMessagesContactIDs =
+ getRecentContactIDs(providerID,
+ recentMessages.size() < numberOfMessages
+ ? null : oldestRecentMessage );
+
+ List<MessageSourceContact> sourceContactsToAdd
+ = new ArrayList<MessageSourceContact>();
+
+ for(String contactID : recentMessagesContactIDs)
{
- // find locally stored list of recent messages
- // time, provider, contact
- List<MessageSourceContact> cachedRecent
- = getRecentMessagesFromHistory();
+ Collection<EventObject> res =
+ messageHistoryService.findRecentMessagesPerContact(
+ numberOfMessages,
+ providerID,
+ contactID,
+ isSMSEnabled);
- if(cachedRecent != null)
+ for(EventObject obj : res)
{
- recentMessages = cachedRecent;
+ MessageSourceContact msc = new MessageSourceContact(
+ obj, MessageSourceService.this);
+ if(!recentMessages.contains(msc)
+ && !sourceContactsToAdd.contains(msc))
+ sourceContactsToAdd.add(msc);
+ }
+ }
- Collections.sort(recentMessages);
+ return sourceContactsToAdd;
+ }
- return recentMessages;
- }
+ /**
+ * Add the source contacts, newly added will fire new,
+ * for existing fire update and when trimming the list to desired length
+ * fire remove for those that were removed
+ * @param contactsToAdd
+ */
+ private void addNewRecentMessages(List<MessageSourceContact> contactsToAdd)
+ {
+ // now find object to fire new, and object to fire remove
+ // let us find duplicates and fire update
+ List<MessageSourceContact> duplicates
+ = new ArrayList<MessageSourceContact>();
+ for(MessageSourceContact msc : recentMessages)
+ {
+ for(MessageSourceContact mscToAdd : contactsToAdd)
+ {
+ if(mscToAdd.equals(msc))
+ {
+ duplicates.add(msc);
- recentMessages = new LinkedList<MessageSourceContact>();
+ // update currently used instance
+ msc.update(mscToAdd);
- // If missing search and construct it and save it
+ // save update
+ updateRecentMessageToHistory(msc);
+ }
+ }
+ }
- MessageHistoryServiceImpl msgHistoryService =
- MessageHistoryActivator.getMessageHistoryService();
- Collection<EventObject> res = msgHistoryService
- .findRecentMessagesPerContact(
- numberOfMessages, null, null, isSMSEnabled);
+ if(!duplicates.isEmpty())
+ {
+ contactsToAdd.removeAll(duplicates);
- for(EventObject obj : res)
+ Collections.sort(recentMessages);
+
+ if(recentQuery != null)
{
- recentMessages.add(
- new MessageSourceContact(obj, MessageSourceService.this));
+ for(MessageSourceContact msc : duplicates)
+ recentQuery.fireContactChanged(msc);
}
- Collections.sort(recentMessages);
- // save it
- saveRecentMessagesToHistory();
+ return;
+ }
+
+ // now contacts to add has no duplicates, add them all
+ recentMessages.addAll(contactsToAdd);
+
+ Collections.sort(recentMessages);
+
+ if(!recentMessages.isEmpty())
+ oldestRecentMessage
+ = recentMessages.get(recentMessages.size() - 1).getTimestamp();
+
+ // trim
+ List<MessageSourceContact> removedItems = null;
+ if(recentMessages.size() > numberOfMessages)
+ {
+ removedItems = new ArrayList<MessageSourceContact>(
+ recentMessages.subList(numberOfMessages, recentMessages.size()));
+
+ recentMessages.removeAll(removedItems);
}
- return recentMessages;
+ if(recentQuery != null)
+ {
+ // now fire, removed for all that were in the list
+ // and now are removed after trim
+ if(removedItems != null)
+ {
+ for(MessageSourceContact msc : removedItems)
+ {
+ if(!contactsToAdd.contains(msc))
+ recentQuery.fireContactRemoved(msc);
+ }
+ }
+
+ // fire new for all that were added, and not removed after trim
+ for(MessageSourceContact msc : contactsToAdd)
+ {
+ if(removedItems == null
+ || !removedItems.contains(msc))
+ recentQuery.fireContactReceived(msc);
+ }
+ }
}
/**
- * Returns the cached recent messages history.
- * @return
- * @throws IOException
+ * When a provider is added.
+ *
+ * @param provider ProtocolProviderService
*/
- private History getHistory()
- throws IOException
+ void handleProviderAdded(ProtocolProviderService provider)
{
- synchronized(historyID)
+ // lets check if we have cached recent messages for this provider, and
+ // fire events if found and are newer
+
+ synchronized(recentMessages)
{
- HistoryService historyService =
- MessageHistoryActivator.getMessageHistoryService()
- .getHistoryService();
+ List<MessageSourceContact> sourceContactsToAdd
+ = getSourceContacts(provider);
- // if not existing, return to search for initial load
- if (history == null
- && !historyService.isHistoryCreated(historyID))
- return null;
+ if(sourceContactsToAdd.isEmpty())
+ {
+ // maybe there is no cached history for this
+ // let's check
+ // load it not from cache, but do a local search
+ Collection<EventObject> res = messageHistoryService
+ .findRecentMessagesPerContact(
+ numberOfMessages,
+ provider.getAccountID().getAccountUniqueID(),
+ null,
+ isSMSEnabled);
+
+ List<MessageSourceContact> newMsc
+ = new ArrayList<MessageSourceContact>();
+ for(EventObject obj : res)
+ {
+ MessageSourceContact msc = new MessageSourceContact(
+ obj, MessageSourceService.this);
+ if(!recentMessages.contains(msc)
+ && !newMsc.contains(msc))
+ newMsc.add(msc);
+ }
- if(history == null)
+ addNewRecentMessages(newMsc);
+
+ saveRecentMessagesToHistory();
+
+ }
+ else
+ addNewRecentMessages(sourceContactsToAdd);
+ }
+ }
+
+ /**
+ * A provider has been removed.
+ *
+ * @param provider the ProtocolProviderService that has been unregistered.
+ */
+ void handleProviderRemoved(ProtocolProviderService provider)
+ {
+ // lets remove the recent messages for this provider, and update
+ // with recent messages for the available providers
+ synchronized(recentMessages)
+ {
+ if(provider != null)
{
- if (historyService.isHistoryExisting(historyID))
- history = historyService.getHistory(historyID);
+ List<MessageSourceContact> removedItems
+ = new ArrayList<MessageSourceContact>();
+ for(MessageSourceContact msc : recentMessages)
+ {
+ if(msc.getProtocolProviderService().equals(provider))
+ removedItems.add(msc);
+ }
+
+ recentMessages.removeAll(removedItems);
+ if(!recentMessages.isEmpty())
+ oldestRecentMessage
+ = recentMessages.get(recentMessages.size() - 1)
+ .getTimestamp();
else
- history = historyService.createHistory(
- historyID, recordStructure);
+ oldestRecentMessage = null;
+
+ if(recentQuery != null)
+ {
+ for(MessageSourceContact msc : removedItems)
+ {
+ recentQuery.fireContactRemoved(msc);
+ }
+ }
}
- return history;
+ // lets do the same as we enable provider
+ // for all registered providers and finally fire events
+ List<MessageSourceContact> contactsToAdd
+ = new ArrayList<MessageSourceContact>();
+ for (ProtocolProviderService pps
+ : messageHistoryService.getCurrentlyAvailableProviders())
+ {
+ contactsToAdd.addAll(getSourceContacts(pps));
+ }
+
+ addNewRecentMessages(contactsToAdd);
}
}
/**
- * Loads recent messages if saved in history.
+ * Searches for contact ids in history of recent messages.
+ * @param provider
+ * @param after
* @return
*/
- private List<MessageSourceContact> getRecentMessagesFromHistory()
+ List<String> getRecentContactIDs(String provider, Date after)
{
- MessageHistoryServiceImpl msgService
- = MessageHistoryActivator.getMessageHistoryService();
+ List<String> res = new ArrayList<String>();
- // and load it
try
{
History history = getHistory();
- if(history == null)
- return null;
-
- List<MessageSourceContact> res
- = new LinkedList<MessageSourceContact>();
-
- Iterator<HistoryRecord> recs
- = history.getReader().findLast(numberOfMessages);
- while(recs.hasNext())
+ if(history != null)
{
- HistoryRecord hr = recs.next();
+ Iterator<HistoryRecord> recs
+ = history.getReader().findLast(NUMBER_OF_MSGS_IN_HISTORY);
+ SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+ while(recs.hasNext())
+ {
+ HistoryRecord hr = recs.next();
- String provider = null;
- String contact = null;
+ String contact = null;
+ String recordProvider = null;
+ Date timestamp = null;
- for (int i = 0; i < hr.getPropertyNames().length; i++)
- {
- String propName = hr.getPropertyNames()[i];
+ for (int i = 0; i < hr.getPropertyNames().length; i++)
+ {
+ String propName = hr.getPropertyNames()[i];
+
+ if (propName.equals(STRUCTURE_NAMES[0]))
+ recordProvider = hr.getPropertyValues()[i];
+ else if (propName.equals(STRUCTURE_NAMES[1]))
+ contact = hr.getPropertyValues()[i];
+ else if (propName.equals(STRUCTURE_NAMES[2]))
+ {
+ try
+ {
+ timestamp
+ = sdf.parse(hr.getPropertyValues()[i]);
+ }
+ catch (ParseException e)
+ {
+ timestamp =
+ new Date(Long.parseLong(
+ hr.getPropertyValues()[i]));
+ }
+ }
+ }
- if (propName.equals(STRUCTURE_NAMES[0]))
- provider = hr.getPropertyValues()[i];
- else if (propName.equals(STRUCTURE_NAMES[1]))
- contact = hr.getPropertyValues()[i];
- }
+ if(recordProvider == null || contact == null)
+ continue;
- if(provider == null || contact == null)
- return res;
+ if(after != null
+ && timestamp != null
+ && timestamp.before(after))
+ continue;
- for(EventObject ev
- : msgService.findRecentMessagesPerContact(
- numberOfMessages, provider, contact, isSMSEnabled))
- {
- res.add(new MessageSourceContact(ev, this));
+ if(recordProvider.equals(provider))
+ res.add(contact);
}
}
-
- return res;
}
catch(IOException ex)
{
logger.error("cannot create recent_messages history", ex);
- return null;
}
+
+ return res;
}
/**
- * Saves cached list of recent messages in history.
+ * Returns the cached recent messages history.
+ * @return
+ * @throws IOException
*/
- private void saveRecentMessagesToHistory()
+ private History getHistory()
+ throws IOException
{
synchronized(historyID)
{
- HistoryService historyService = MessageHistoryActivator
- .getMessageHistoryService().getHistoryService();
+ HistoryService historyService =
+ MessageHistoryActivator.getMessageHistoryService()
+ .getHistoryService();
- if (historyService.isHistoryExisting(historyID))
+ if(history == null)
{
- // delete it
- try
+ if (historyService.isHistoryExisting(historyID))
+ history = historyService.getHistory(historyID);
+ else
+ history = historyService.createHistory(
+ historyID, recordStructure);
+
+ // lets check the version if not our version, re-create
+ // history (delete it)
+ HistoryReader reader = history.getReader();
+ boolean delete = false;
+ QueryResultSet<HistoryRecord> res = reader.findLast(1);
+ if(res != null && res.hasNext())
{
- historyService.purgeLocallyStoredHistory(historyID);
+ HistoryRecord hr = res.next();
+ if(hr.getPropertyValues().length >= 4)
+ {
+ if(!hr.getPropertyValues()[3].equals(RECENT_MSGS_VER))
+ delete = true;
+ }
+ else
+ delete = true;
}
- catch(IOException ex)
+
+ if(delete)
{
- logger.error("Cannot delete recent_messages history", ex);
- return;
+ // delete it
+ try
+ {
+ historyService.purgeLocallyStoredHistory(historyID);
+
+ history = historyService.createHistory(
+ historyID, recordStructure);
+ }
+ catch(IOException ex)
+ {
+ logger.error(
+ "Cannot delete recent_messages history", ex);
+ }
}
}
+ return history;
+ }
+ }
+
+ /**
+ * Saves cached list of recent messages in history.
+ */
+ private void saveRecentMessagesToHistory()
+ {
+ synchronized(historyID)
+ {
+ if(history == null)
+ {
+ return;
+ }
+
+ HistoryService historyService
+ = messageHistoryService.getHistoryService();
+
+
// and create it
try
{
- history = historyService.createHistory(
- historyID, recordStructure);
-
HistoryWriter writer = history.getWriter();
- List<MessageSourceContact> messages = getRecentMessages();
-
- synchronized(messages)
+ synchronized(recentMessages)
{
- for(MessageSourceContact msc : messages)
+ SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+ for(MessageSourceContact msc : recentMessages)
{
writer.addRecord(
new String[]
{
msc.getProtocolProviderService()
.getAccountID().getAccountUniqueID(),
- msc.getContactAddress()
- });
+ msc.getContactAddress(),
+ sdf.format(msc.getTimestamp()),
+ RECENT_MSGS_VER
+ },
+ NUMBER_OF_MSGS_IN_HISTORY);
}
}
}
@@ -377,11 +622,9 @@ public class MessageSourceService
*/
int getIndex(MessageSourceContact messageSourceContact)
{
- List<MessageSourceContact> messages = getRecentMessages();
-
- synchronized(messages)
+ synchronized(recentMessages)
{
- return messages.indexOf(messageSourceContact);
+ return recentMessages.indexOf(messageSourceContact);
}
}
@@ -412,11 +655,9 @@ public class MessageSourceService
if(recentQuery == null)
return;
- List<MessageSourceContact> messages = getRecentMessages();
-
- synchronized(messages)
+ synchronized(recentMessages)
{
- for(MessageSourceContact msgSC : messages)
+ for(MessageSourceContact msgSC : recentMessages)
{
if(msgSC.getContact() != null
&& msgSC.getContact().equals(evt.getSourceContact()))
@@ -431,62 +672,10 @@ public class MessageSourceService
@Override
public void providerStatusChanged(ProviderPresenceStatusChangeEvent evt)
{
- if(!evt.getNewStatus().isOnline())
+ if(!evt.getNewStatus().isOnline() || evt.getOldStatus().isOnline())
return;
- // now check for chat rooms as we are connected
- MessageHistoryServiceImpl msgHistoryService =
- MessageHistoryActivator.getMessageHistoryService();
- Collection<EventObject> res = msgHistoryService
- .findRecentMessagesPerContact(
- numberOfMessages,
- evt.getProvider().getAccountID().getAccountUniqueID(),
- null,
- isSMSEnabled);
-
- List<String> recentMessagesForProvider = new LinkedList<String>();
- List<MessageSourceContact> messages = getRecentMessages();
- synchronized(messages)
- {
- for(MessageSourceContact msc : messages)
- {
- if(msc.getProtocolProviderService().equals(evt.getProvider()))
- recentMessagesForProvider.add(msc.getContactAddress());
- }
-
- List<MessageSourceContact> newContactSources
- = new LinkedList<MessageSourceContact>();
- for(EventObject obj : res)
- {
- if(obj instanceof ChatRoomMessageDeliveredEvent
- || obj instanceof ChatRoomMessageReceivedEvent)
- {
- MessageSourceContact msc
- = new MessageSourceContact(obj,
- MessageSourceService.this);
-
- if(recentMessagesForProvider
- .contains(msc.getContactAddress()))
- continue;
-
- messages.add(msc);
- newContactSources.add(msc);
-
- }
- }
-
- // sort
- Collections.sort(messages);
-
- // and now fire events to update ui
- if(recentQuery != null)
- {
- for(MessageSourceContact msc : newContactSources)
- {
- recentQuery.addQueryResult(msc);
- }
- }
- }
+ handleProviderAdded(evt.getProvider());
}
@Override
@@ -502,11 +691,9 @@ public class MessageSourceService
MessageSourceContact srcContact = null;
- List<MessageSourceContact> messages = getRecentMessages();
-
- synchronized(messages)
+ synchronized(recentMessages)
{
- for(MessageSourceContact msg : messages)
+ for(MessageSourceContact msg : recentMessages)
{
if(msg.getRoom() != null
&& msg.getRoom().equals(evt.getChatRoom()))
@@ -553,44 +740,58 @@ public class MessageSourceService
String id)
{
// check if provider - contact exist update message content
- List<MessageSourceContact> messages = getRecentMessages();
- synchronized(messages)
+ synchronized(recentMessages)
{
- for(MessageSourceContact msc : messages)
+ MessageSourceContact existingMsc = null;
+ for(MessageSourceContact msc : recentMessages)
{
if(msc.getProtocolProviderService().equals(provider)
&& msc.getContactAddress().equals(id))
{
// update
msc.update(obj);
+ updateRecentMessageToHistory(msc);
- if(recentQuery != null)
- recentQuery.fireContactChanged(msc);
-
- return;
+ existingMsc = msc;
}
}
+ if(existingMsc != null)
+ {
+ Collections.sort(recentMessages);
+ oldestRecentMessage = recentMessages
+ .get(recentMessages.size() - 1).getTimestamp();
+
+ if(recentQuery != null)
+ recentQuery.fireContactChanged(existingMsc);
+
+ return;
+ }
+
// if missing create source contact
// and update recent messages, trim and sort
MessageSourceContact newSourceContact =
new MessageSourceContact(obj, MessageSourceService.this);
- messages.add(newSourceContact);
+ // we have already checked for duplicate
+ recentMessages.add(newSourceContact);
- Collections.sort(messages);
+ Collections.sort(recentMessages);
+ oldestRecentMessage
+ = recentMessages.get(recentMessages.size() - 1).getTimestamp();
// trim
List<MessageSourceContact> removedItems = null;
- if(messages.size() > numberOfMessages)
+ if(recentMessages.size() > numberOfMessages)
{
removedItems = new ArrayList<MessageSourceContact>(
- messages.subList(numberOfMessages, messages.size()));
+ recentMessages.subList(
+ numberOfMessages, recentMessages.size()));
- messages.removeAll(removedItems);
+ recentMessages.removeAll(removedItems);
}
// save
- saveRecentMessagesToHistory();
+ saveRecentMessageToHistory(newSourceContact);
// no query nothing to fire
if(recentQuery == null)
@@ -609,6 +810,150 @@ public class MessageSourceService
}
}
+ /**
+ * Adds recent message in history.
+ */
+ private void saveRecentMessageToHistory(MessageSourceContact msc)
+ {
+ synchronized(historyID)
+ {
+ // and create it
+ try
+ {
+ History history = getHistory();
+
+ HistoryWriter writer = history.getWriter();
+
+ synchronized(recentMessages)
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+ writer.addRecord(
+ new String[]
+ {
+ msc.getProtocolProviderService()
+ .getAccountID().getAccountUniqueID(),
+ msc.getContactAddress(),
+ sdf.format(msc.getTimestamp()),
+ RECENT_MSGS_VER
+ },
+ NUMBER_OF_MSGS_IN_HISTORY);
+ }
+ }
+ catch(IOException ex)
+ {
+ logger.error("cannot create recent_messages history", ex);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Updates recent message in history.
+ */
+ private void updateRecentMessageToHistory(final MessageSourceContact msc)
+ {
+ synchronized(historyID)
+ {
+ // and create it
+ try
+ {
+ History history = getHistory();
+
+ HistoryWriter writer = history.getWriter();
+
+ synchronized(recentMessages)
+ {
+ writer.updateRecord(
+ new HistoryWriter.HistoryRecordUpdater()
+ {
+ HistoryRecord hr;
+
+ @Override
+ public void setHistoryRecord(
+ HistoryRecord historyRecord)
+ {
+ this.hr = historyRecord;
+ }
+
+ @Override
+ public boolean isMatching()
+ {
+ boolean providerFound = false;
+ boolean contactFound = false;
+ for(int i = 0; i < hr.getPropertyNames().length; i++)
+ {
+ String propName = hr.getPropertyNames()[i];
+
+ if(propName.equals(STRUCTURE_NAMES[0]))
+ {
+ if(msc.getProtocolProviderService()
+ .getAccountID().getAccountUniqueID()
+ .equals(hr.getPropertyValues()[i]))
+ {
+ providerFound = true;
+ }
+ }
+ else if(propName.equals(STRUCTURE_NAMES[1]))
+ {
+ if(msc.getContactAddress()
+ .equals(hr.getPropertyValues()[i]))
+ {
+ contactFound = true;
+ }
+ }
+ }
+
+
+ return contactFound && providerFound;
+ }
+
+ @Override
+ public Map<String, String> getUpdateChanges()
+ {
+ HashMap<String, String> map
+ = new HashMap<String, String>();
+ SimpleDateFormat sdf
+ = new SimpleDateFormat(DATE_FORMAT);
+ for(int i = 0;
+ i < hr.getPropertyNames().length;
+ i++)
+ {
+ String propName = hr.getPropertyNames()[i];
+
+ if(propName.equals(STRUCTURE_NAMES[0]))
+ {
+ map.put(
+ propName,
+ msc.getProtocolProviderService()
+ .getAccountID()
+ .getAccountUniqueID());
+ }
+ else if(propName.equals(STRUCTURE_NAMES[1]))
+ {
+ map.put(propName, msc.getContactAddress());
+ }
+ else if(propName.equals(STRUCTURE_NAMES[2]))
+ {
+ map.put(propName,
+ sdf.format(msc.getTimestamp()));
+ }
+ else if(propName.equals(STRUCTURE_NAMES[3]))
+ map.put(propName, RECENT_MSGS_VER);
+ }
+
+ return map;
+ }
+ });
+ }
+ }
+ catch(IOException ex)
+ {
+ logger.error("cannot create recent_messages history", ex);
+ return;
+ }
+ }
+ }
+
@Override
public void messageReceived(MessageReceivedEvent evt)
{
@@ -718,10 +1063,9 @@ public class MessageSourceService
@Override
public void run()
{
- List<MessageSourceContact> messages = getRecentMessages();
- synchronized(messages)
+ synchronized(recentMessages)
{
- for(MessageSourceContact rm : messages)
+ for(MessageSourceContact rm : recentMessages)
{
addQueryResult(rm);
}