refactored muc item parsing to also parse muc status messages

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/MucOptions.java            | 12 
src/main/java/eu/siacs/conversations/parser/AbstractParser.java          | 23 
src/main/java/eu/siacs/conversations/parser/MessageParser.java           | 16 
src/main/java/eu/siacs/conversations/parser/PresenceParser.java          |  2 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 18 
5 files changed, 44 insertions(+), 27 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/MucOptions.java 🔗

@@ -274,6 +274,10 @@ public class MucOptions {
 		public String toString() {
 			return "[fulljid:"+String.valueOf(fullJid)+",realjid:"+String.valueOf(realJid)+",affiliation"+affiliation.toString()+"]";
 		}
+
+		public boolean realJidMatchesAccount() {
+			return realJid != null && realJid.equals(options.account.getJid().toBareJid());
+		}
 	}
 
 	private Account account;
@@ -589,14 +593,6 @@ public class MucOptions {
 		return this.conversation;
 	}
 
-	public void putMember(Jid fullJid, Jid realJid, String affiliation, String role) {
-		User user = new User(this, fullJid);
-		user.setRealJid(realJid);
-		user.setAffiliation(affiliation);
-		user.setRole(role);
-		addUser(user);
-	}
-
 	public List<Jid> getMembers() {
 		ArrayList<Jid> members = new ArrayList<>();
 		for(User user : users) {

src/main/java/eu/siacs/conversations/parser/AbstractParser.java 🔗

@@ -8,8 +8,11 @@ import java.util.Locale;
 
 import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Contact;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.services.XmppConnectionService;
 import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xmpp.jid.InvalidJidException;
 import eu.siacs.conversations.xmpp.jid.Jid;
 import eu.siacs.conversations.xmpp.stanzas.AbstractStanza;
 
@@ -66,4 +69,24 @@ public abstract class AbstractParser {
 		}
 		return item.findChildContent("data", "urn:xmpp:avatar:data");
 	}
+
+	public static MucOptions.User parseItem(Conversation conference, Element item) {
+		final String local = conference.getJid().getLocalpart();
+		final String domain = conference.getJid().getDomainpart();
+		String affiliation = item.getAttribute("affiliation");
+		String role = item.getAttribute("role");
+		String nick = item.getAttribute("nick");
+		Jid fullJid;
+		try {
+			fullJid = nick != null ? Jid.fromParts(local, domain, nick) : null;
+		} catch (InvalidJidException e) {
+			fullJid = null;
+		}
+		Jid realJid = item.getAttributeAsJid("jid");
+		MucOptions.User user = new MucOptions.User(conference.getMucOptions(), fullJid);
+		user.setRealJid(realJid);
+		user.setAffiliation(affiliation);
+		user.setRole(role);
+		return user;
+	}
 }

src/main/java/eu/siacs/conversations/parser/MessageParser.java 🔗

@@ -533,8 +533,8 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 				}
 			}
 		} else if (!packet.hasChild("body")){ //no body
+			Conversation conversation = mXmppConnectionService.find(account, from.toBareJid());
 			if (isTypeGroupChat) {
-				Conversation conversation = mXmppConnectionService.find(account, from.toBareJid());
 				if (packet.hasChild("subject")) {
 					if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
 						conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0);
@@ -550,14 +550,24 @@ public class MessageParser extends AbstractParser implements OnMessagePacketRece
 						return;
 					}
 				}
-
-				if (conversation != null && isMucStatusMessage) {
+			}
+			if (conversation != null && mucUserElement != null && from.isBareJid()) {
+				if (mucUserElement.hasChild("status")) {
 					for (Element child : mucUserElement.getChildren()) {
 						if (child.getName().equals("status")
 								&& MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED.equals(child.getAttribute("code"))) {
 							mXmppConnectionService.fetchConferenceConfiguration(conversation);
 						}
 					}
+				} else if (mucUserElement.hasChild("item")) {
+					for(Element child : mucUserElement.getChildren()) {
+						if ("item".equals(child.getName())) {
+							MucOptions.User user = AbstractParser.parseItem(conversation,child);
+							if (!user.realJidMatchesAccount()) {
+								conversation.getMucOptions().addUser(user);
+							}
+						}
+					}
 				}
 			}
 		}

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -83,6 +83,7 @@ import eu.siacs.conversations.generator.IqGenerator;
 import eu.siacs.conversations.generator.MessageGenerator;
 import eu.siacs.conversations.generator.PresenceGenerator;
 import eu.siacs.conversations.http.HttpConnectionManager;
+import eu.siacs.conversations.parser.AbstractParser;
 import eu.siacs.conversations.parser.IqParser;
 import eu.siacs.conversations.parser.MessageParser;
 import eu.siacs.conversations.parser.PresenceParser;
@@ -1902,22 +1903,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 
 				Element query = packet.query("http://jabber.org/protocol/muc#admin");
 				if (packet.getType() == IqPacket.TYPE.RESULT && query != null) {
-					final String local = conversation.getJid().getLocalpart();
-					final String domain = conversation.getJid().getDomainpart();
 					for(Element child : query.getChildren()) {
 						if ("item".equals(child.getName())) {
-							String affiliation = child.getAttribute("affiliation");
-							String role = child.getAttribute("role");
-							String nick = child.getAttribute("nick");
-							Jid fullJid;
-							try {
-								fullJid = nick != null ? Jid.fromParts(local, domain, nick) : null;
-							} catch (InvalidJidException e) {
-								fullJid = null;
-							}
-							Jid realJid = child.getAttributeAsJid("jid");
-							if (realJid != null && !realJid.equals(account.getJid().toBareJid())) {
-								conversation.getMucOptions().putMember(fullJid, realJid, affiliation, role);
+							MucOptions.User user = AbstractParser.parseItem(conversation,child);
+							if (!user.realJidMatchesAccount()) {
+								conversation.getMucOptions().addUser(user);
 							}
 						}
 					}