Author: ngn
Date: Tue Sep 8 20:27:30 2009
New Revision: 812677
URL: http://svn.apache.org/viewvc?rev=812677&view=rev
Log:
Implement discussion history (still lacking support for "seconds" and "since"
in the history element) (VYSPER-109)
Added:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Delay.java
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/model/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
Removed:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/AbstractServerInfoDiscoTestCase.java
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/MUCServerInfoDiscoTestCase.java
Modified:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/ServerMain.java
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCMessageHandler.java
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandlerEnterRoomTestCase.java
Modified:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/ServerMain.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/ServerMain.java?rev=812677&r1=812676&r2=812677&view=diff
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/ServerMain.java
(original)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/ServerMain.java
Tue Sep 8 20:27:30 2009
@@ -68,7 +68,7 @@
//server.addEndpoint(new StanzaSessionFactory());
server.setStorageProviderRegistry(providerRegistry);
- server.setTLSCertificateInfo(new
File("src/main/resources/bogus_mina_tls.cert"), "boguspw");
+ server.setTLSCertificateInfo(new
File("src/main/config/bogus_mina_tls.cert"), "boguspw");
try {
server.start();
@@ -83,8 +83,6 @@
server.addModule(new XmppPingModule());
server.addModule(new PrivateDataModule());
- Conference conference = new Conference("Test conference");
- server.addModule(new MUCModule("chat.vysper.org", conference));
-
+ server.addModule(new MUCModule());
}
}
Modified:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCMessageHandler.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/handler/MUCMessageHandler.java?rev=812677&r1=812676&r2=812677&view=diff
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCMessageHandler.java
(original)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCMessageHandler.java
Tue Sep 8 20:27:30 2009
@@ -116,7 +116,11 @@
relayStanza(occupent.getJid(),
StanzaBuilder.createClone(stanza, true,
replaceAttributes).getFinalStanza(),
serverRuntimeContext);
+
}
+
+ // add to discussion history
+ room.getHistory().append(stanza, sendingOccupant);
} else {
return createMessageErrorStanza(room.getJID(), from,
stanza.getID(), StanzaErrorType.MODIFY, StanzaErrorCondition.FORBIDDEN, stanza);
}
Modified:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.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/handler/MUCPresenceHandler.java?rev=812677&r1=812676&r2=812677&view=diff
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java
(original)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java
Tue Sep 8 20:27:30 2009
@@ -31,6 +31,8 @@
import org.apache.vysper.xmpp.modules.core.base.handler.DefaultPresenceHandler;
import
org.apache.vysper.xmpp.modules.extension.xep0045_muc.handler.Status.StatusCode;
import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Conference;
+import
org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.DiscussionHistory;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.History;
import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Occupant;
import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Role;
import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Room;
@@ -203,6 +205,11 @@
sendNewOccupantPresenceToExisting(newOccupant, occupant, room,
serverRuntimeContext);
}
+ // send discussion history to user
+ boolean includeJid = room.isRoomType(RoomType.NonAnonymous);
+ List<Stanza> history =
room.getHistory().createStanzas(newOccupant, includeJid,
History.fromStanza(stanza));
+ relayStanzas(newOccupantJid, history, serverRuntimeContext);
+
logger.debug("{} successfully entered room {}", newOccupantJid,
roomJid);
}
return null;
@@ -401,6 +408,12 @@
relayStanza(existingOccupant.getJid(), builder.getFinalStanza(),
serverRuntimeContext);
}
+
+ protected void relayStanzas(Entity receiver, List<Stanza> stanzas,
ServerRuntimeContext serverRuntimeContext) {
+ for(Stanza stanza : stanzas) {
+ relayStanza(receiver, stanza, serverRuntimeContext);
+ }
+ }
protected void relayStanza(Entity receiver, Stanza stanza,
ServerRuntimeContext serverRuntimeContext) {
try {
Added:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/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/model/Delay.java?rev=812677&view=auto
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Delay.java
(added)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Delay.java
Tue Sep 8 20:27:30 2009
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.datetime.DateTimeProfile;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.xmlfragment.Attribute;
+import org.apache.vysper.xmpp.xmlfragment.NamespaceAttribute;
+import org.apache.vysper.xmpp.xmlfragment.XMLElement;
+import org.apache.vysper.xmpp.xmlfragment.XMLFragment;
+
+public class Delay extends XMLElement {
+
+ public Delay(Entity from, Date timestamp) {
+ super("delay", null, Arrays.asList(
+ new NamespaceAttribute(NamespaceURIs.URN_XMPP_DELAY),
+ new Attribute("from", from.getFullQualifiedName()),
+ new Attribute("stamp",
DateTimeProfile.getInstance().getDateTimeInUTC(timestamp))
+ ), (List<XMLFragment>)null);
+ }
+
+
+}
Added:
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=812677&view=auto
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistory.java
(added)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistory.java
Tue Sep 8 20:27:30 2009
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.xmlfragment.Renderer;
+
+
+/**
+ * The discussion history for a room
+ *
+ * @author The Apache MINA Project ([email protected])
+ */
+public class DiscussionHistory {
+
+ public static final int DEFAULT_HISTORY_SIZE = 20;
+
+ private int maxItems = DEFAULT_HISTORY_SIZE;
+ private DiscussionMessage subjectMessage;
+ private List<DiscussionMessage> items = new ArrayList<DiscussionMessage>();
+
+ public void append(Stanza stanza, Occupant sender) {
+ synchronized (items) {
+ DiscussionMessage discMsg = new DiscussionMessage(stanza, sender);
+
+ if(discMsg.hasSubject() && !discMsg.hasBody()) {
+ subjectMessage = discMsg;
+ } else {
+ items.add(discMsg);
+ }
+
+ // check if size is over limits
+ if(getSize() > maxItems) {
+ items.remove(0);
+ }
+ }
+ }
+
+ private int getSize() {
+ int size = items.size();
+ if(subjectMessage != null) size++;
+ return size;
+ }
+
+ 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;
+
+ List<DiscussionMessage> itemsWithSubject = new
ArrayList<DiscussionMessage>(items);
+ // add subject if one is provided
+ if(subjectMessage != null) {
+ itemsWithSubject.add(subjectMessage);
+ }
+
+
+ // 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(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;
+ }
+ }
+ }
+ // reverse list so that the oldest message is first
+ Collections.reverse(stanzas);
+ return stanzas;
+ }
+}
Added:
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=812677&view=auto
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessage.java
(added)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessage.java
Tue Sep 8 20:27:30 2009
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
+
+import java.util.Date;
+
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.stanza.StanzaBuilder;
+
+public class DiscussionMessage {
+
+ private Stanza message;
+ private String fromNick;
+ private Date timestamp;
+
+ public DiscussionMessage(Stanza stanza, Occupant from) {
+ this(stanza, from, new Date());
+ }
+
+ public DiscussionMessage(Stanza stanza, Occupant from, Date date) {
+ this.message = stanza;
+ this.fromNick = from.getName();
+
+ this.timestamp = (Date) date.clone();
+ }
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public String getNick() {
+ return fromNick;
+ }
+
+ public Stanza createStanza(Occupant receiver, boolean includeJid) {
+
+// <message
+// from='[email protected]/secondwitch'
+// to='[email protected]/broom'
+// type='groupchat'>
+// <body>Thrice and once the hedge-pig whined.</body>
+// <delay xmlns='urn:xmpp:delay'
+// from='[email protected]/laptop'
+// stamp='2002-10-13T23:58:43Z'/>
+// </message>
+
+ Entity roomJid = message.getTo();
+ StanzaBuilder builder = StanzaBuilder.createForward(message, new
EntityImpl(roomJid, fromNick), receiver.getJid());
+
+ Entity delayFrom;
+ if(includeJid) {
+ delayFrom = message.getFrom();
+ } else {
+ delayFrom = new EntityImpl(roomJid, fromNick);
+ }
+ Delay delay = new Delay(delayFrom, timestamp);
+ builder.addPreparedElement(delay);
+
+ return builder.getFinalStanza();
+ }
+
+ public boolean hasSubject() {
+ return !message.getInnerElementsNamed("subject").isEmpty();
+ }
+
+ public boolean hasBody() {
+ return !message.getInnerElementsNamed("body").isEmpty();
+ }
+
+}
Added:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/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/model/History.java?rev=812677&view=auto
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/History.java
(added)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/History.java
Tue Sep 8 20:27:30 2009
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.vysper.xmpp.datetime.DateTimeProfile;
+import org.apache.vysper.xmpp.protocol.NamespaceURIs;
+import org.apache.vysper.xmpp.stanza.Stanza;
+import org.apache.vysper.xmpp.xmlfragment.Attribute;
+import org.apache.vysper.xmpp.xmlfragment.XMLElement;
+import org.apache.vysper.xmpp.xmlfragment.XMLFragment;
+import org.apache.vysper.xmpp.xmlfragment.XMLSemanticError;
+
+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";
+ private static final String ATTRIBUTE_MAXCHARS = "maxchars";
+ private static final String ATTRIBUTE_MAXSTANZAS = "maxstanzas";
+
+ public static History fromStanza(Stanza stanza) {
+ // history is in a x element in the MUC namespace
+ try {
+ XMLElement xElm = stanza.getSingleInnerElementsNamed("x",
NamespaceURIs.XEP0045_MUC);
+ if(xElm != null) {
+ XMLElement historyElm =
xElm.getSingleInnerElementsNamed("history");
+ if(historyElm != null) {
+ return new History(historyElm);
+ }
+ }
+
+ // history element not found
+ return null;
+ } catch (XMLSemanticError e) {
+ throw new IllegalArgumentException("Invalid stanza", e);
+ }
+ }
+
+ public History(XMLElement elm) {
+ super(ELEMENT_HISTORY, null, elm.getAttributes(),
(List<XMLFragment>)null);
+ }
+
+ public History(Integer maxstanzas, Integer maxchars, Integer seconds, Date
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) {
+ 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)));
+ return attributes;
+ }
+
+ private Integer getAttributeIntValue(String name) {
+ String value = getAttributeValue(name);
+ if(value != null && value.trim().length() > 0) {
+ return Integer.valueOf(value);
+ } else {
+ return null;
+ }
+ }
+
+ public Integer getMaxStanzas() {
+ return getAttributeIntValue(ATTRIBUTE_MAXSTANZAS);
+ }
+
+ public Integer getMaxChars() {
+ return getAttributeIntValue(ATTRIBUTE_MAXCHARS);
+ }
+
+ public Integer getSeconds() {
+ return getAttributeIntValue(ATTRIBUTE_SECONDS);
+ }
+
+ // TODO implement
+// public Integer getSince() {
+// }
+}
Modified:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.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/Room.java?rev=812677&r1=812676&r2=812677&view=diff
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
(original)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
Tue Sep 8 20:27:30 2009
@@ -54,6 +54,7 @@
private Entity jid;
private String name;
private String password;
+ private DiscussionHistory history = new DiscussionHistory();
// keep in a map to allow for quick access
private Map<Entity, Occupant> occupants = new ConcurrentHashMap<Entity,
Occupant>();
@@ -188,4 +189,8 @@
this.password = password;
}
+ public DiscussionHistory getHistory() {
+ return history;
+ }
+
}
Modified:
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandlerEnterRoomTestCase.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/handler/MUCPresenceHandlerEnterRoomTestCase.java?rev=812677&r1=812676&r2=812677&view=diff
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandlerEnterRoomTestCase.java
(original)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandlerEnterRoomTestCase.java
Tue Sep 8 20:27:30 2009
@@ -4,7 +4,10 @@
import java.util.List;
import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Affiliation;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.History;
import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Occupant;
+import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Role;
import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Room;
import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.RoomType;
import org.apache.vysper.xmpp.protocol.NamespaceURIs;
@@ -13,6 +16,8 @@
import org.apache.vysper.xmpp.protocol.StanzaHandler;
import org.apache.vysper.xmpp.server.SessionContext;
import org.apache.vysper.xmpp.server.TestSessionContext;
+import org.apache.vysper.xmpp.stanza.MessageStanza;
+import org.apache.vysper.xmpp.stanza.MessageStanzaType;
import org.apache.vysper.xmpp.stanza.PresenceStanza;
import org.apache.vysper.xmpp.stanza.Stanza;
import org.apache.vysper.xmpp.stanza.StanzaBuilder;
@@ -26,10 +31,10 @@
public class MUCPresenceHandlerEnterRoomTestCase extends
AbstractMUCHandlerTestCase {
private Stanza enterRoom(Entity occupantJid, Entity roomJid) throws
ProtocolException {
- return enterRoom(occupantJid, roomJid, null);
+ return enterRoom(occupantJid, roomJid, null, null);
}
- private Stanza enterRoom(Entity occupantJid, Entity roomJid, String
password) throws ProtocolException {
+ private Stanza enterRoom(Entity occupantJid, Entity roomJid, String
password, History history) throws ProtocolException {
SessionContext userSessionContext;
if(occupantJid.equals(OCCUPANT1_JID)) {
userSessionContext = sessionContext;
@@ -42,6 +47,9 @@
if(password != null) {
stanzaBuilder.startInnerElement("password").addText(password).endInnerElement();
}
+ if(history != null) {
+ stanzaBuilder.addPreparedElement(history);
+ }
stanzaBuilder.endInnerElement();
Stanza presenceStanza = stanzaBuilder.getFinalStanza();
@@ -115,7 +123,7 @@
room.setPassword("secret");
// no error should be returned
- assertNull(enterRoom(OCCUPANT1_JID, ROOM2_JID_WITH_NICK, "secret"));
+ assertNull(enterRoom(OCCUPANT1_JID, ROOM2_JID_WITH_NICK, "secret",
null));
assertEquals(1, room.getOccupants().size());
}
@@ -183,4 +191,41 @@
assertEquals("110", statusElements.get(1).getAttributeValue("code"));
}
+
+ public void testDiscussionHistory() throws Exception {
+ // add some messages
+ Room room = conference.findOrCreateRoom(ROOM1_JID, "Room 1");
+
room.getHistory().append(StanzaBuilder.createMessageStanza(OCCUPANT2_JID,
ROOM1_JID, MessageStanzaType.GROUPCHAT, null, "Body").getFinalStanza(),
+ new Occupant(OCCUPANT2_JID, "nick2", Affiliation.None,
Role.Participant));
+
room.getHistory().append(StanzaBuilder.createMessageStanza(OCCUPANT2_JID,
ROOM1_JID, MessageStanzaType.GROUPCHAT, null, "Body2").getFinalStanza(),
+ new Occupant(OCCUPANT2_JID, "nick2", Affiliation.None,
Role.Participant));
+
room.getHistory().append(StanzaBuilder.createMessageStanza(OCCUPANT2_JID,
ROOM1_JID, MessageStanzaType.GROUPCHAT, null, "Body3").getFinalStanza(),
+ new Occupant(OCCUPANT2_JID, "nick2", Affiliation.None,
Role.Participant));
+
+ // now, let user 1 enter room
+ enterRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK, null, new History(2,
null, null, null));
+
+ Stanza stanza = occupant1Queue.getNext();
+ // first stanza should be room presence
+ assertNotNull(stanza);
+ assertEquals("presence", stanza.getName());
+
+ stanza = occupant1Queue.getNext();
+ // here we get the message history
+ assertNotNull(stanza);
+ assertEquals("message", stanza.getName());
+ MessageStanza msgStanza = (MessageStanza)
MessageStanza.getWrapper(stanza);
+ assertEquals("Body2", msgStanza.getBody(null));
+
+ stanza = occupant1Queue.getNext();
+ // first stanza should be room presence
+ assertNotNull(stanza);
+ assertEquals("message", stanza.getName());
+ msgStanza = (MessageStanza) MessageStanza.getWrapper(stanza);
+ assertEquals("Body3", msgStanza.getBody(null));
+
+ // we only requested two messages
+ assertNull(occupant1Queue.getNext());
+}
+
}
Added:
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=812677&view=auto
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistoryTestCase.java
(added)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionHistoryTestCase.java
Tue Sep 8 20:27:30 2009
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.vysper.TestUtil;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.stanza.MessageStanza;
+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;
+
+/**
+ *
+ * @author The Apache MINA Project ([email protected])
+ */
+public class DiscussionHistoryTestCase extends TestCase {
+
+ private static final String NICK = "nick";
+ private static final String BODY = "Body";
+ private static final String SUBJECT = "Subject";
+
+ private static final Entity FROM =
TestUtil.parseUnchecked("[email protected]/res");
+ private static final Entity RECEIVER =
TestUtil.parseUnchecked("[email protected]/res");
+ private static final Entity ROOM_JID =
TestUtil.parseUnchecked("[email protected]");
+
+ private static final Occupant FROM_OCCUPANT = new Occupant(FROM, NICK,
Affiliation.None, Role.Visitor);
+ private static final Occupant RECEIVER_OCCUPANT = new Occupant(RECEIVER,
"nick2", Affiliation.None, Role.Visitor);
+ private DiscussionHistory history;
+
+
+ @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++) {
+ history.append(
+ StanzaBuilder.createMessageStanza(FROM, ROOM_JID,
MessageStanzaType.GROUPCHAT, null, BODY).getFinalStanza(),
+ FROM_OCCUPANT);
+ }
+
+ // add a subject message
+ history.append(
+ StanzaBuilder.createMessageStanza(FROM, ROOM_JID,
MessageStanzaType.GROUPCHAT, null, null).
+
startInnerElement("subject").addText(SUBJECT).endInnerElement().getFinalStanza(),
+ FROM_OCCUPANT);
+ }
+
+ public void testGetAllStanzas() throws Exception {
+ List<Stanza> stanzas = history.createStanzas(RECEIVER_OCCUPANT, true,
new History(null, null, null, null));
+
+ assertStanzas(stanzas, DiscussionHistory.DEFAULT_HISTORY_SIZE);
+ }
+
+ public void testGetAllStanzasNullHistory() throws Exception {
+ List<Stanza> stanzas = history.createStanzas(RECEIVER_OCCUPANT, true,
null);
+
+ assertStanzas(stanzas, DiscussionHistory.DEFAULT_HISTORY_SIZE);
+ }
+
+
+ public void testThreeStanzas() throws Exception {
+ List<Stanza> stanzas = history.createStanzas(RECEIVER_OCCUPANT, true,
new History(3, null, null, null));
+ assertStanzas(stanzas, 3);
+ }
+
+ public void testZeroStanzas() throws Exception {
+ List<Stanza> stanzas = history.createStanzas(RECEIVER_OCCUPANT, true,
new History(0, null, null, null));
+
+ assertStanzas(stanzas, 0);
+ }
+
+ public void test500CharStanzas() throws Exception {
+ List<Stanza> stanzas = history.createStanzas(RECEIVER_OCCUPANT, true,
new History(null, 500, null, null));
+
+ // 2 stanzas should fit in 500 chars
+ assertStanzas(stanzas, 2);
+ }
+
+ public void test0CharStanzas() throws Exception {
+ List<Stanza> stanzas = history.createStanzas(RECEIVER_OCCUPANT, true,
new History(null, 0, null, null));
+
+ assertStanzas(stanzas, 0);
+ }
+
+
+ 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++) {
+ Stanza stanza = stanzas.get(i);
+ assertStanza(stanza, BODY, null);
+ }
+
+ // first check subject message
+ assertStanza(stanzas.get(expectedSize - 1), null, SUBJECT);
+ }
+ }
+
+ private void assertStanza(Stanza stanza, String expectedBody, String
expectedSubject) throws Exception {
+ assertNotNull(stanza);
+ MessageStanza msgStanza = (MessageStanza)
MessageStanza.getWrapper(stanza);
+
+ assertEquals(new EntityImpl(ROOM_JID, NICK), msgStanza.getFrom());
+ assertEquals(RECEIVER, msgStanza.getTo());
+ assertEquals("groupchat", msgStanza.getType());
+ assertEquals(expectedBody, msgStanza.getBody(null));
+ assertEquals(expectedSubject, msgStanza.getSubject(null));
+ assertEquals(1, msgStanza.getInnerElementsNamed("delay").size());
+ }
+}
Added:
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=812677&view=auto
==============================================================================
---
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessageTestCase.java
(added)
+++
mina/sandbox/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/DiscussionMessageTestCase.java
Tue Sep 8 20:27:30 2009
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.vysper.xmpp.modules.extension.xep0045_muc.model;
+
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+import org.apache.vysper.TestUtil;
+import org.apache.vysper.xmpp.addressing.Entity;
+import org.apache.vysper.xmpp.addressing.EntityImpl;
+import org.apache.vysper.xmpp.datetime.DateTimeProfile;
+import org.apache.vysper.xmpp.stanza.MessageStanza;
+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.XMLElement;
+
+/**
+ *
+ * @author The Apache MINA Project ([email protected])
+ */
+public class DiscussionMessageTestCase extends TestCase {
+
+ 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 Entity FROM =
TestUtil.parseUnchecked("[email protected]/res");
+ private static final Entity ROOM_JID =
TestUtil.parseUnchecked("[email protected]");
+
+ private static final Occupant FROM_OCCUPANT = new Occupant(FROM, NICK,
Affiliation.None, Role.Visitor);
+
+ public void testSubjectMessage() {
+ StanzaBuilder builder = StanzaBuilder.createMessageStanza(FROM,
ROOM_JID, null, null);
+
builder.startInnerElement("subject").addText(SUBJECT).endInnerElement();
+
+ DiscussionMessage item = new
DiscussionMessage(builder.getFinalStanza(), FROM_OCCUPANT, TIMESTAMP);
+ assertEquals(NICK, item.getNick());
+ assertEquals(TIMESTAMP, item.getTimestamp());
+ assertFalse(item.hasBody());
+ assertTrue(item.hasSubject());
+ }
+
+
+ public void testBodyMessage() {
+ StanzaBuilder builder = StanzaBuilder.createMessageStanza(FROM,
ROOM_JID, null, BODY);
+
+ DiscussionMessage item = new
DiscussionMessage(builder.getFinalStanza(), FROM_OCCUPANT, TIMESTAMP);
+ assertEquals(NICK, item.getNick());
+ assertEquals(TIMESTAMP, item.getTimestamp());
+ assertTrue(item.hasBody());
+ assertFalse(item.hasSubject());
+ }
+
+ public void testCreateStanza() throws Exception {
+ StanzaBuilder builder = StanzaBuilder.createMessageStanza(FROM,
ROOM_JID, MessageStanzaType.GROUPCHAT, null, BODY);
+ Stanza inStanza = builder.getFinalStanza();
+ DiscussionMessage item = new DiscussionMessage(inStanza,
FROM_OCCUPANT, TIMESTAMP);
+
+ Entity to = TestUtil.parseUnchecked("[email protected]/res");
+ Occupant toOccupant = new Occupant(to, "nick 2", Affiliation.None,
Role.Visitor);
+ MessageStanza outStanza = (MessageStanza)
MessageStanza.getWrapper(item.createStanza(toOccupant, true));
+
+ assertEquals(to, outStanza.getTo());
+ assertEquals(new EntityImpl(ROOM_JID, NICK), outStanza.getFrom());
+ assertEquals("groupchat", outStanza.getType());
+ assertEquals(BODY, outStanza.getBody(null));
+
+ XMLElement delayElm = outStanza.getInnerElements().get(1);
+ assertEquals(FROM.getFullQualifiedName(),
delayElm.getAttributeValue("from"));
+
assertEquals(DateTimeProfile.getInstance().getDateTimeInUTC(TIMESTAMP),
delayElm.getAttributeValue("stamp"));
+
+ }
+}