aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java
diff options
context:
space:
mode:
authorDamian Minkov <damencho@jitsi.org>2014-11-18 11:11:20 +0200
committerDamian Minkov <damencho@jitsi.org>2014-11-18 11:29:13 +0200
commitd47cbb28e3613a0b1c59e408e0fa15d74c8053fb (patch)
treec2b8deb7083fd6a4f6612e2eb173a5543a066ee6 /src/net/java
parent12d551f7a15b1aeb9aafe6449c9911a8f82bd97e (diff)
downloadjitsi-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/net/java')
-rw-r--r--src/net/java/sip/communicator/impl/history/HistoryWriterImpl.java203
-rw-r--r--src/net/java/sip/communicator/impl/msghistory/MessageHistoryServiceImpl.java53
-rw-r--r--src/net/java/sip/communicator/service/history/HistoryWriter.java15
-rw-r--r--src/net/java/sip/communicator/service/msghistory/MessageHistoryAdvancedService.java39
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);
+}