Author: ngn
Date: Sun Sep 13 21:33:58 2009
New Revision: 814388

URL: http://svn.apache.org/viewvc?rev=814388&view=rev
Log:
Implement retrieving discussion history based on "seconds" or "since" 
attributes (VYSPER-109)

Modified:
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistory.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessage.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/Delay.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/History.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistoryTestCase.java
    
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessageTestCase.java

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistory.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistory.java?rev=814388&r1=814387&r2=814388&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistory.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistory.java
 Sun Sep 13 21:33:58 2009
@@ -20,8 +20,10 @@
 package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
 
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Collections;
 import java.util.List;
+import java.util.TimeZone;
 
 import org.apache.vysper.xmpp.modules.extension.xep0045_muc.stanzas.History;
 import org.apache.vysper.xmpp.stanza.Stanza;
@@ -42,8 +44,12 @@
     private List<DiscussionMessage> items = new ArrayList<DiscussionMessage>();
     
     public void append(Stanza stanza, Occupant sender) {
+        append(stanza, sender, 
Calendar.getInstance(TimeZone.getTimeZone("UTC")));
+    }
+    
+    public void append(Stanza stanza, Occupant sender, Calendar timestamp) {
         synchronized (items) {
-            DiscussionMessage discMsg = new DiscussionMessage(stanza, sender);
+            DiscussionMessage discMsg = new DiscussionMessage(stanza, sender, 
timestamp);
             
             if(discMsg.hasSubject() && !discMsg.hasBody()) {
                 subjectMessage = discMsg;
@@ -66,52 +72,71 @@
     
     public List<Stanza> createStanzas(Occupant receiver, boolean includeJid, 
             History history) {
-        
-        int maxstanzas = history != null && history.getMaxStanzas() != null ? 
history.getMaxStanzas() : -1;
-        int maxchars = history != null && history.getMaxChars() != null ? 
history.getMaxChars() : -1;
-        int seconds = history != null && history.getSeconds() != null ? 
history.getSeconds() : -1;
-        
-        List<Stanza> stanzas = new ArrayList<Stanza>();
-        
-        if(maxchars == 0 || maxstanzas == 0 || seconds == 0) {
-            // quick return for no-stanza requests
-        } else {
-            int counter = 0;
-            int totalChars = 0;
+        synchronized (items) {
             
-            List<DiscussionMessage> itemsWithSubject = new 
ArrayList<DiscussionMessage>(items);
-            // add subject if one is provided
-            if(subjectMessage != null) {
-                itemsWithSubject.add(subjectMessage);
-            }
+            int maxstanzas = history != null && history.getMaxStanzas() != 
null ? history.getMaxStanzas() : -1;
+            int maxchars = history != null && history.getMaxChars() != null ? 
history.getMaxChars() : -1;
+            int seconds = history != null && history.getSeconds() != null ? 
history.getSeconds() : -1;
             
+            List<Stanza> stanzas = new ArrayList<Stanza>();
             
-            // now add all messages, as long as the predicated are fulfilled
-            // first, do this in reverse order so that older messages are 
filtered out
-            for(int i = itemsWithSubject.size() - 1; i > -1; i--) {
-                DiscussionMessage item = itemsWithSubject.get(i);
-                Stanza stanza = item.createStanza(receiver, includeJid); 
-                counter++;
-
-                // only count chars if needed
-                if(maxchars != -1) {
-                    totalChars += new Renderer(stanza).getComplete().length();
+            if(maxchars == 0 || maxstanzas == 0 || seconds == 0) {
+                // quick return for no-stanza requests
+            } else {
+                int counter = 0;
+                int totalChars = 0;
+                
+                List<DiscussionMessage> itemsWithSubject = new 
ArrayList<DiscussionMessage>(items);
+                // add subject if one is provided
+                if(subjectMessage != null) {
+                    itemsWithSubject.add(subjectMessage);
+                }
+    
+                // the timestamp at which "seconds" start filtering from 
+                long secondsLimit = -1;
+                if(seconds != -1) {
+                    Calendar cal = 
Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+                    cal.add(Calendar.SECOND, -seconds);
+                    secondsLimit = cal.getTimeInMillis();
+                }
+                
+                // now add all messages, as long as the predicated are 
fulfilled
+                // first, do this in reverse order so that older messages are 
filtered out
+                for(int i = itemsWithSubject.size() - 1; i > -1; i--) {
+                    DiscussionMessage item = itemsWithSubject.get(i);
+                    Stanza stanza = item.createStanza(receiver, includeJid); 
+                    counter++;
+    
+                    if(secondsLimit != -1 && secondsLimit > 
item.getTimestamp().getTimeInMillis()) {
+                        // too old, break
+                        break;
+                    }
                     
-                    if(totalChars > maxchars) {
+                    if(history != null && history.getSince() != null && 
history.getSince().after(item.getTimestamp())) {
+                        // too old, break
+                        break;
+                    }
+                    
+                    // only count chars if needed
+                    if(maxchars != -1) {
+                        totalChars += new 
Renderer(stanza).getComplete().length();
+                        
+                        if(totalChars > maxchars) {
+                            break;
+                        }
+                    }
+                    
+                    // checks after this line will include the last stanza
+                    stanzas.add(stanza);
+                    if(maxstanzas != -1 && counter == maxstanzas) {
+                        // max number of stanzas reached, return
                         break;
                     }
-                }
-                
-                // checks after this line will include the last stanza
-                stanzas.add(stanza);
-                if(maxstanzas != -1 && counter == maxstanzas) {
-                    // max number of stanzas reached, return
-                    break;
                 }
             }
+            // reverse list so that the oldest message is first
+            Collections.reverse(stanzas);
+            return stanzas;
         }
-        // reverse list so that the oldest message is first
-        Collections.reverse(stanzas);
-        return stanzas;
     }
 }

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessage.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessage.java?rev=814388&r1=814387&r2=814388&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessage.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessage.java
 Sun Sep 13 21:33:58 2009
@@ -19,7 +19,8 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
 
-import java.util.Date;
+import java.util.Calendar;
+import java.util.TimeZone;
 
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.addressing.EntityImpl;
@@ -31,21 +32,21 @@
 
     private Stanza message;
     private String fromNick;
-    private Date timestamp;
+    private Calendar timestamp;
     
     public DiscussionMessage(Stanza stanza, Occupant from) {
-        this(stanza, from, new Date());
+        this(stanza, from, Calendar.getInstance(TimeZone.getTimeZone("UTC")));
     }
 
-    public DiscussionMessage(Stanza stanza, Occupant from, Date date) {
+    public DiscussionMessage(Stanza stanza, Occupant from, Calendar timestamp) 
{
         this.message = stanza;
         this.fromNick = from.getName();
         
-        this.timestamp = (Date) date.clone();
+        this.timestamp = (Calendar) timestamp.clone();
     }
     
-    public Date getTimestamp() {
-        return timestamp;
+    public Calendar getTimestamp() {
+        return (Calendar) timestamp.clone();
     }
 
     public String getNick() {

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/Delay.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/Delay.java?rev=814388&r1=814387&r2=814388&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/Delay.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/Delay.java
 Sun Sep 13 21:33:58 2009
@@ -20,7 +20,7 @@
 package org.apache.vysper.xmpp.modules.extension.xep0045_muc.stanzas;
 
 import java.util.Arrays;
-import java.util.Date;
+import java.util.Calendar;
 import java.util.List;
 
 import org.apache.vysper.xmpp.addressing.Entity;
@@ -33,11 +33,11 @@
 
 public class Delay extends XMLElement {
 
-    public Delay(Entity from, Date timestamp) {
+    public Delay(Entity from, Calendar timestamp) {
         super("delay", null, Arrays.asList(
             new NamespaceAttribute(NamespaceURIs.URN_XMPP_DELAY),
             new Attribute("from", from.getFullQualifiedName()),
-            new Attribute("stamp", 
DateTimeProfile.getInstance().getDateTimeInUTC(timestamp))
+            new Attribute("stamp", 
DateTimeProfile.getInstance().getDateTimeInUTC(timestamp.getTime()))
             ), (List<XMLFragment>)null);
     }
 

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/History.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/History.java?rev=814388&r1=814387&r2=814388&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/History.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/stanzas/History.java
 Sun Sep 13 21:33:58 2009
@@ -20,6 +20,7 @@
 package org.apache.vysper.xmpp.modules.extension.xep0045_muc.stanzas;
 
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 
@@ -33,8 +34,6 @@
 
 public class History extends XMLElement {
 
-    
-    
     private static final String ELEMENT_HISTORY = "history";
     private static final String ATTRIBUTE_SINCE = "since";
     private static final String ATTRIBUTE_SECONDS = "seconds";
@@ -63,16 +62,16 @@
         super(ELEMENT_HISTORY, null, elm.getAttributes(), 
(List<XMLFragment>)null);
     }
     
-    public History(Integer maxstanzas, Integer maxchars, Integer seconds, Date 
since) {
+    public History(Integer maxstanzas, Integer maxchars, Integer seconds, 
Calendar since) {
         super(ELEMENT_HISTORY, null, createAttributes(maxstanzas, maxchars, 
seconds, since), (List<XMLFragment>)null);
     }
 
-    private static List<Attribute> createAttributes(Integer maxstanzas, 
Integer maxchars, Integer seconds, Date since) {
+    private static List<Attribute> createAttributes(Integer maxstanzas, 
Integer maxchars, Integer seconds, Calendar since) {
         List<Attribute> attributes = new ArrayList<Attribute>();
         if(maxstanzas != null) attributes.add(new 
Attribute(ATTRIBUTE_MAXSTANZAS, maxstanzas.toString()));
         if(maxchars != null) attributes.add(new Attribute(ATTRIBUTE_MAXCHARS, 
maxchars.toString()));
         if(seconds != null) attributes.add(new Attribute(ATTRIBUTE_SECONDS, 
seconds.toString()));
-        if(since != null) attributes.add(new Attribute(ATTRIBUTE_SINCE, 
DateTimeProfile.getInstance().getDateTimeInUTC(since)));
+        if(since != null) attributes.add(new Attribute(ATTRIBUTE_SINCE, 
DateTimeProfile.getInstance().getDateTimeInUTC(since.getTime())));
         return attributes;
     }
     
@@ -97,7 +96,14 @@
         return getAttributeIntValue(ATTRIBUTE_SECONDS);
     }
 
-    // TODO implement
-//    public Integer getSince() {
-//    }
+    public Calendar getSince() {
+        String value = getAttributeValue(ATTRIBUTE_SINCE);
+        if(value != null) {
+            // TODO handle IllegalArgumentException
+            Calendar timestamp = 
DateTimeProfile.getInstance().fromDateTime(value);
+            return timestamp;
+        } else {
+            return null;
+        }
+    }
 }

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistoryTestCase.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistoryTestCase.java?rev=814388&r1=814387&r2=814388&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistoryTestCase.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistoryTestCase.java
 Sun Sep 13 21:33:58 2009
@@ -19,7 +19,9 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
 
+import java.util.Calendar;
 import java.util.List;
+import java.util.TimeZone;
 
 import junit.framework.TestCase;
 
@@ -31,7 +33,6 @@
 import org.apache.vysper.xmpp.stanza.MessageStanzaType;
 import org.apache.vysper.xmpp.stanza.Stanza;
 import org.apache.vysper.xmpp.stanza.StanzaBuilder;
-import org.apache.vysper.xmpp.xmlfragment.Renderer;
 
 /**
  * 
@@ -52,15 +53,22 @@
     private DiscussionHistory history;
 
     
+    private Calendar createTimestamp(int minutesAgo) {
+        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+        cal.add(Calendar.MINUTE, -minutesAgo);
+        return cal;
+    }
+    
     @Override
     protected void setUp() throws Exception {
         history = new DiscussionHistory();
         
         // add some messages to the history, one more than is handled
-        for(int i = 0; i<DiscussionHistory.DEFAULT_HISTORY_SIZE + 1; i++) {
+        int maxStanzas = DiscussionHistory.DEFAULT_HISTORY_SIZE + 1;
+        for(int i = 0; i<maxStanzas; i++) {
             history.append(
-                    StanzaBuilder.createMessageStanza(FROM, ROOM_JID, 
MessageStanzaType.GROUPCHAT, null, BODY).getFinalStanza(),
-                    FROM_OCCUPANT);
+                    StanzaBuilder.createMessageStanza(FROM, ROOM_JID, 
MessageStanzaType.GROUPCHAT, null, BODY + i).getFinalStanza(),
+                    FROM_OCCUPANT, createTimestamp(maxStanzas - i));
         }
         
         // add a subject message
@@ -107,18 +115,32 @@
         assertStanzas(stanzas, 0);
     }
 
+    public void test150SecondsStanzas() throws Exception {
+        List<Stanza> stanzas = history.createStanzas(RECEIVER_OCCUPANT, true, 
new History(null, null, 150, null));
+        
+        // 2 stanzas + subject should fit in 150 seconds
+        assertStanzas(stanzas, 3);
+    }
+
+    
+    public void testSince5minutesStanzas() throws Exception {
+        List<Stanza> stanzas = history.createStanzas(RECEIVER_OCCUPANT, true, 
new History(null, null, null, createTimestamp(5)));
+        
+        // 2 stanzas + subject should fit in 150 seconds
+        assertStanzas(stanzas, 6);
+    }
+
     
     private void assertStanzas(List<Stanza> stanzas, int expectedSize) throws 
Exception {
         assertEquals(expectedSize, stanzas.size());
 
         if(expectedSize > 0) {
-            
-            for(int i = 1; i<expectedSize - 1; i++) {
+            for(int i = 0; i<expectedSize - 1; i++) {
                 Stanza stanza = stanzas.get(i);
-                assertStanza(stanza, BODY, null);
+                assertStanza(stanza, BODY + 
(DiscussionHistory.DEFAULT_HISTORY_SIZE - expectedSize + 2 + i), null);
             }
 
-            // first check subject message
+            // then check subject message
             assertStanza(stanzas.get(expectedSize - 1), null, SUBJECT);
         }
     }

Modified: 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessageTestCase.java
URL: 
http://svn.apache.org/viewvc/mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessageTestCase.java?rev=814388&r1=814387&r2=814388&view=diff
==============================================================================
--- 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessageTestCase.java
 (original)
+++ 
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessageTestCase.java
 Sun Sep 13 21:33:58 2009
@@ -19,7 +19,9 @@
  */
 package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
 
+import java.util.Calendar;
 import java.util.Date;
+import java.util.TimeZone;
 
 import junit.framework.TestCase;
 
@@ -42,7 +44,7 @@
     private static final String NICK = "nick";
     private static final String BODY = "Body";
     private static final String SUBJECT = "Subject";
-    private static final Date TIMESTAMP = new Date();
+    private static final Calendar TIMESTAMP = 
Calendar.getInstance(TimeZone.getTimeZone("UTC"));
 
     
     private static final Entity FROM = 
TestUtil.parseUnchecked("[email protected]/res");
@@ -88,7 +90,7 @@
         
         XMLElement delayElm = outStanza.getInnerElements().get(1);
         assertEquals(FROM.getFullQualifiedName(), 
delayElm.getAttributeValue("from"));
-        
assertEquals(DateTimeProfile.getInstance().getDateTimeInUTC(TIMESTAMP), 
delayElm.getAttributeValue("stamp"));
+        
assertEquals(DateTimeProfile.getInstance().getDateTimeInUTC(TIMESTAMP.getTime()),
 delayElm.getAttributeValue("stamp"));
         
     }
 }


Reply via email to