diff options
author | Damian Minkov <damencho@jitsi.org> | 2014-11-18 11:11:20 +0200 |
---|---|---|
committer | Damian Minkov <damencho@jitsi.org> | 2014-11-18 11:29:13 +0200 |
commit | d47cbb28e3613a0b1c59e408e0fa15d74c8053fb (patch) | |
tree | c2b8deb7083fd6a4f6612e2eb173a5543a066ee6 /src | |
parent | 12d551f7a15b1aeb9aafe6449c9911a8f82bd97e (diff) | |
download | jitsi-d47cbb28e3613a0b1c59e408e0fa15d74c8053fb.zip jitsi-d47cbb28e3613a0b1c59e408e0fa15d74c8053fb.tar.gz jitsi-d47cbb28e3613a0b1c59e408e0fa15d74c8053fb.tar.bz2 |
Adds advanced msg history service, to allow plugins to insert messages into the history, and tests for the implementation.
Diffstat (limited to 'src')
4 files changed, 262 insertions, 48 deletions
diff --git a/src/net/java/sip/communicator/impl/history/HistoryWriterImpl.java b/src/net/java/sip/communicator/impl/history/HistoryWriterImpl.java index 882b435..2b6c045 100644 --- a/src/net/java/sip/communicator/impl/history/HistoryWriterImpl.java +++ b/src/net/java/sip/communicator/impl/history/HistoryWriterImpl.java @@ -145,54 +145,8 @@ public class HistoryWriterImpl removeFirstRecord(root); } - Element elem = this.currentDoc.createElement("record"); - SimpleDateFormat sdf - = new SimpleDateFormat(DATE_FORMAT); - elem.setAttribute("timestamp", sdf.format(date)); - - for (int i = 0; i < propertyNames.length; i++) - { - String propertyName = propertyNames[i]; - - if(propertyName.endsWith(CDATA_SUFFIX)) - { - if (propertyValues[i] != null) - { - propertyName = - propertyName.replaceFirst(CDATA_SUFFIX, ""); - - Element propertyElement = this.currentDoc - .createElement(propertyName); - - Text value = this.currentDoc - .createCDATASection( - XmlEscapers.xmlContentEscaper().escape( - propertyValues[i].replaceAll("\0", " ") - )); - propertyElement.appendChild(value); - - elem.appendChild(propertyElement); - } - } - else - { - if (propertyValues[i] != null) - { - Element propertyElement = this.currentDoc - .createElement(propertyName); - - Text value = this.currentDoc - .createTextNode( - XmlEscapers.xmlContentEscaper().escape( - propertyValues[i].replaceAll("\0", " ") - )); - propertyElement.appendChild(value); - - elem.appendChild(propertyElement); - } - } - } - + Element elem = createRecord( + this.currentDoc, propertyNames, propertyValues, date); root.appendChild(elem); this.currentDocElements++; } @@ -209,6 +163,66 @@ public class HistoryWriterImpl } /** + * Creates an element. + * @param doc the parent of the element. + * @param propertyNames property names for the element + * @param propertyValues values for the properties + * @param date the of creation of the record + * @return the newly created element. + */ + private Element createRecord(Document doc, + String[] propertyNames, + String[] propertyValues, + Date date) + { + Element elem = doc.createElement("record"); + SimpleDateFormat sdf + = new SimpleDateFormat(DATE_FORMAT); + elem.setAttribute("timestamp", sdf.format(date)); + + for (int i = 0; i < propertyNames.length; i++) + { + String propertyName = propertyNames[i]; + + if(propertyName.endsWith(CDATA_SUFFIX)) + { + if (propertyValues[i] != null) + { + propertyName = + propertyName.replaceFirst(CDATA_SUFFIX, ""); + + Element propertyElement = doc.createElement(propertyName); + + Text value = doc.createCDATASection( + XmlEscapers.xmlContentEscaper().escape( + propertyValues[i].replaceAll("\0", " ") + )); + propertyElement.appendChild(value); + + elem.appendChild(propertyElement); + } + } + else + { + if (propertyValues[i] != null) + { + Element propertyElement = doc.createElement(propertyName); + + Text value = doc.createTextNode( + XmlEscapers.xmlContentEscaper().escape( + propertyValues[i].replaceAll("\0", " ") + )); + propertyElement.appendChild(value); + + elem.appendChild(propertyElement); + } + } + } + + return elem; + } + + /** * Finds the oldest node by timestamp in current root and deletes it. * @param root where to search for records */ @@ -252,6 +266,99 @@ public class HistoryWriterImpl root.removeChild(oldestNode); } + /** + * Stores the passed propertyValues complying with the + * historyRecordStructure. + * + * @param propertyValues + * The values of the record. + * @param timestamp + * The timestamp of the record. + * + * @throws IOException + */ + public void insertRecord( + String[] propertyValues, Date timestamp, String timestampProperty) + throws IOException + { + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); + Iterator<String> fileIterator + = HistoryReaderImpl.filterFilesByDate( + this.historyImpl.getFileList(), timestamp, null) + .iterator(); + String filename = null; + while (fileIterator.hasNext()) + { + filename = fileIterator.next(); + + Document doc = this.historyImpl.getDocumentForFile(filename); + + if(doc == null) + continue; + + NodeList nodes = doc.getElementsByTagName("record"); + + boolean changed = false; + + Node node; + for (int i = 0; i < nodes.getLength(); i++) + { + node = nodes.item(i); + + Element idNode = XMLUtils.findChild( + (Element)node, timestampProperty); + if(idNode == null) + continue; + + Node nestedNode = idNode.getFirstChild(); + if(nestedNode == null) + continue; + + // Get nested TEXT node's value + String nodeValue = nestedNode.getNodeValue(); + + Date nodeTimeStamp; + try + { + nodeTimeStamp = sdf.parse(nodeValue); + } + catch (ParseException e) + { + nodeTimeStamp = new Date(Long.parseLong(nodeValue)); + } + + if(nodeTimeStamp.before(timestamp)) + continue; + + Element newElem = createRecord( + doc, structPropertyNames, propertyValues, timestamp); + + doc.getFirstChild().insertBefore(newElem, node); + + changed = true; + break; + } + + if(changed) + { + // write changes + synchronized (this.docWriteLock) + { + this.historyImpl.writeFile(filename, doc); + } + + // this prevents that the current writer, which holds + // instance for the last document he is editing will not + // override our last changes to the document + if(filename.equals(this.currentFile)) + { + this.currentDoc = doc; + } + + break; + } + } + } /** * If no file is currently loaded loads the last opened file. If it does not diff --git a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java index 5ff97c3..cd3872f 100644 --- a/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java +++ b/src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java @@ -43,6 +43,7 @@ import org.osgi.framework.*; */ public class MessageHistoryServiceImpl implements MessageHistoryService, + MessageHistoryAdvancedService, MessageListener, ChatRoomMessageListener, AdHocChatRoomMessageListener, @@ -1485,6 +1486,58 @@ public class MessageHistoryServiceImpl } } + /** + * Inserts message to the history. Allows to update the laready saved + * history. + * @param direction String direction of the message in or out. + * @param source The source Contact + * @param destination The destination Contact + * @param message Message message to be written + * @param messageTimestamp Date this is the timestamp when was message + * received that came from the protocol provider + * @param isSmsSubtype whether message to write is an sms + */ + public void insertMessage( + String direction, + Contact source, + Contact destination, + Message message, + Date messageTimestamp, + boolean isSmsSubtype) + { + try + { + MetaContact metaContact = MessageHistoryActivator + .getContactListService().findMetaContactByContact(destination); + if(metaContact != null + && !isHistoryLoggingEnabled( + metaContact.getMetaUID())) + { + // logging is switched off for this particular contact + return; + } + + History history = this.getHistory(source, destination); + + HistoryWriter historyWriter = history.getWriter(); + SimpleDateFormat sdf + = new SimpleDateFormat(HistoryService.DATE_FORMAT); + historyWriter.insertRecord(new String[]{direction, + message.getContent(), message.getContentType(), + message.getEncoding(), message.getMessageUID(), + message.getSubject(), sdf.format(messageTimestamp), + isSmsSubtype ? MSG_SUBTYPE_SMS : null}, + messageTimestamp, + STRUCTURE_NAMES[6]); + // this date is when the history record to be written + // as we are inserting + + } catch (IOException e) + { + logger.error("Could not add message to history", e); + } + } + // ////////////////////////////////////////////////////////////////////////// /** diff --git a/src/net/java/sip/communicator/service/history/HistoryWriter.java b/src/net/java/sip/communicator/service/history/HistoryWriter.java index 3d952b3..413b300 100644 --- a/src/net/java/sip/communicator/service/history/HistoryWriter.java +++ b/src/net/java/sip/communicator/service/history/HistoryWriter.java @@ -70,6 +70,21 @@ public interface HistoryWriter throws IOException; /** + * Stores the passed propertyValues complying with the + * historyRecordStructure. + * + * @param propertyValues + * The values of the record. + * @param timestamp + * The timestamp of the record. + * + * @throws IOException + */ + public void insertRecord( + String[] propertyValues, Date timestamp, String timestampProperty) + throws IOException; + + /** * Updates a record by searching for record with idProperty which have idValue * and updating/creating the property with newValue. * diff --git a/src/net/java/sip/communicator/service/msghistory/MessageHistoryAdvancedService.java b/src/net/java/sip/communicator/service/msghistory/MessageHistoryAdvancedService.java new file mode 100644 index 0000000..53786cb --- /dev/null +++ b/src/net/java/sip/communicator/service/msghistory/MessageHistoryAdvancedService.java @@ -0,0 +1,39 @@ +/* + * 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.service.msghistory; + +import net.java.sip.communicator.service.protocol.*; + +import java.util.*; + +/** + * Adds advanced operation to the message service like inserting/editing + * messages. Can be used to insert messages when synchronizing history with + * external source. + * @author Damian Minkov + */ +public interface MessageHistoryAdvancedService +{ + /** + * Inserts message to the history. Allows to update the already saved + * history. + * @param direction String direction of the message in or out. + * @param source The source Contact + * @param destination The destination Contact + * @param message Message message to be written + * @param messageTimestamp Date this is the timestamp when was message + * received that came from the protocol provider + * @param isSmsSubtype whether message to write is an sms + */ + public void insertMessage( + String direction, + Contact source, + Contact destination, + Message message, + Date messageTimestamp, + boolean isSmsSubtype); +} |