From 50bc9f271f334264b4e35502c1dc01e391f401eb Mon Sep 17 00:00:00 2001 From: mightymop Date: Wed, 17 Feb 2021 15:18:19 +0100 Subject: [PATCH] xep333 rebased --- src/i18n/monitoring_i18n.properties | 1 + .../openfire/archive/ArchiveInterceptor.java | 22 +++++- .../openfire/archive/ChatMarker.java | 68 +++++++++++++++++++ .../openfire/archive/ConversationEvent.java | 11 +++ .../openfire/archive/ConversationManager.java | 25 ++++++- .../openfire/archive/ConversationUtils.java | 62 +++++++++++++++-- .../archive/GroupConversationInterceptor.java | 20 +++++- src/web/archiving-settings.jsp | 8 +++ 8 files changed, 206 insertions(+), 11 deletions(-) create mode 100644 src/java/org/jivesoftware/openfire/archive/ChatMarker.java diff --git a/src/i18n/monitoring_i18n.properties b/src/i18n/monitoring_i18n.properties index f924c16e7..0db9f1690 100644 --- a/src/i18n/monitoring_i18n.properties +++ b/src/i18n/monitoring_i18n.properties @@ -91,6 +91,7 @@ archive.settings.cancel = Cancel archive.settings.rebuild = Rebuild Index archive.settings.any = Any archive.settings.one_to_one=Archive one-to-one chats +archive.settings.chatmarker=Archive chatmarkers (XEP-0333) archive.settings.group_chats=Archive group chats archive.settings.group_chats.stanzas=Archive stanzas for group chats archive.settings.certain_rooms=Only archive conversations of the following room names (separated by comma) diff --git a/src/java/org/jivesoftware/openfire/archive/ArchiveInterceptor.java b/src/java/org/jivesoftware/openfire/archive/ArchiveInterceptor.java index bc96035f6..ecc1c4362 100644 --- a/src/java/org/jivesoftware/openfire/archive/ArchiveInterceptor.java +++ b/src/java/org/jivesoftware/openfire/archive/ArchiveInterceptor.java @@ -21,6 +21,7 @@ import org.jivesoftware.openfire.interceptor.PacketInterceptor; import org.jivesoftware.openfire.interceptor.PacketRejectedException; import org.jivesoftware.openfire.session.Session; +import org.jivesoftware.util.JiveGlobals; import org.xmpp.packet.JID; import org.xmpp.packet.Message; import org.xmpp.packet.Packet; @@ -63,7 +64,7 @@ public void interceptPacket(Packet packet, Session session, boolean incoming, bo // Ignore any messages that don't have a body so that we skip events. // Note: XHTML messages should always include a body so we should be ok. It's // possible that we may need special XHTML filtering in the future, however. - if (message.getBody() != null) { + if (message.getBody() != null||(message.getBody()==null&&JiveGlobals.getBooleanProperty("conversation.chatmarkerArchiving", false))) { // Only process messages that are between two users, group chat rooms, or gateways. if (conversationManager.isConversation(message)) { // Process this event in the senior cluster member or local JVM when not in a cluster @@ -74,11 +75,28 @@ public void interceptPacket(Packet packet, Session session, boolean incoming, bo JID sender = message.getFrom(); JID receiver = message.getTo(); ConversationEventsQueue eventsQueue = conversationManager.getConversationEventsQueue(); - eventsQueue.addChatEvent(conversationManager.getConversationKey(sender, receiver), + + if (message.getBody()!=null) + { + eventsQueue.addChatEvent(conversationManager.getConversationKey(sender, receiver), ConversationEvent.chatMessageReceived(sender, receiver, conversationManager.isMessageArchivingEnabled() ? message.getBody() : null, conversationManager.isMessageArchivingEnabled() ? message.toXML() : null, new Date())); + } + else + { + String stanza = message.toXML(); + ChatMarker.TYPE markertype = ChatMarker.searchForXep0333(stanza); + + if (markertype!=ChatMarker.TYPE.NONE) + { + eventsQueue.addChatEvent(conversationManager.getConversationKey(sender, receiver), + ConversationEvent.chatmarkerMessageReceived(sender, receiver,markertype, + conversationManager.isMessageArchivingEnabled() ? message.toXML() : null, + new Date())); + } + } } } } diff --git a/src/java/org/jivesoftware/openfire/archive/ChatMarker.java b/src/java/org/jivesoftware/openfire/archive/ChatMarker.java new file mode 100644 index 000000000..c5440551b --- /dev/null +++ b/src/java/org/jivesoftware/openfire/archive/ChatMarker.java @@ -0,0 +1,68 @@ +package org.jivesoftware.openfire.archive; + +public class ChatMarker { + + public enum TYPE + { + NONE, + MARKABLE, + RECEIVED, + DISPLAYED, + ACKNOWLEGED; + } + + public static TYPE searchForXep0333(String stanza) + { + if (stanza==null) + { + return TYPE.NONE; + } + + int idxmarkable = stanza.indexOf("",idxmarkable); + if (idxEnd==-1) + { + idxEnd = stanza.indexOf("",idxmarkable); + } + return idxEnd!=-1?(stanza.substring(idxmarkable, idxEnd).contains("urn:xmpp:chat-markers:0")?TYPE.MARKABLE:TYPE.NONE):TYPE.NONE; + } + else + if (idxreceived!=-1) + { + int idxEnd = stanza.indexOf("/>",idxreceived); + if (idxEnd==-1) + { + idxEnd = stanza.indexOf("",idxmarkable); + } + return idxEnd!=-1?(stanza.substring(idxreceived, idxEnd).contains("urn:xmpp:chat-markers:0")?TYPE.RECEIVED:TYPE.NONE):TYPE.NONE; + } + else + if (idxdisplayed!=-1) + { + int idxEnd = stanza.indexOf("/>",idxdisplayed); + if (idxEnd==-1) + { + idxEnd = stanza.indexOf("",idxmarkable); + } + return idxEnd!=-1?(stanza.substring(idxdisplayed, idxEnd).contains("urn:xmpp:chat-markers:0")?TYPE.DISPLAYED:TYPE.NONE):TYPE.NONE; + } + else + if (idxacknowled!=-1) + { + int idxEnd = stanza.indexOf("/>",idxacknowled); + if (idxEnd==-1) + { + idxEnd = stanza.indexOf("",idxmarkable); + } + return idxEnd!=-1?(stanza.substring(idxacknowled, idxEnd).contains("urn:xmpp:chat-markers:0")?TYPE.ACKNOWLEGED:TYPE.NONE):TYPE.NONE; + } + else + return TYPE.NONE; + } +} diff --git a/src/java/org/jivesoftware/openfire/archive/ConversationEvent.java b/src/java/org/jivesoftware/openfire/archive/ConversationEvent.java index 9e32d6802..72d40cee0 100644 --- a/src/java/org/jivesoftware/openfire/archive/ConversationEvent.java +++ b/src/java/org/jivesoftware/openfire/archive/ConversationEvent.java @@ -38,6 +38,7 @@ public class ConversationEvent implements Externalizable { private Date date; private String body; private String stanza; + private ChatMarker.TYPE marker; private JID sender; private JID receiver; @@ -147,6 +148,16 @@ public static ConversationEvent chatMessageReceived(JID sender, JID receiver, St event.sender = sender; event.receiver = receiver; event.body = body; + event.date = date; + return event; + } + + public static ConversationEvent chatmarkerMessageReceived(JID sender, JID receiver, ChatMarker.TYPE marker, String stanza, Date date) { + ConversationEvent event = new ConversationEvent(); + event.type = Type.chatMessageReceived; + event.sender = sender; + event.receiver = receiver; + event.marker = marker; event.stanza = stanza; event.date = date; return event; diff --git a/src/java/org/jivesoftware/openfire/archive/ConversationManager.java b/src/java/org/jivesoftware/openfire/archive/ConversationManager.java index 118339908..6f0621fd1 100644 --- a/src/java/org/jivesoftware/openfire/archive/ConversationManager.java +++ b/src/java/org/jivesoftware/openfire/archive/ConversationManager.java @@ -104,6 +104,9 @@ public class ConversationManager implements ComponentEventListener{ */ private boolean roomArchivingEnabled; private boolean roomArchivingStanzasEnabled; + + private boolean chatmarkerArchivingEnabled; + /** * List of room names to archive. When list is empty then all rooms are archived (if roomArchivingEnabled is enabled). */ @@ -143,6 +146,9 @@ public void start() { Log.warn("Metadata archiving must be enabled when message archiving is enabled. Overriding setting."); metadataArchivingEnabled = true; } + + chatmarkerArchivingEnabled = JiveGlobals.getBooleanProperty("conversation.chatmarkerArchiving", false); + roomArchivingEnabled = JiveGlobals.getBooleanProperty("conversation.roomArchiving", false); roomArchivingStanzasEnabled = JiveGlobals.getBooleanProperty("conversation.roomArchivingStanzas", false); roomsArchived = StringUtils.stringToCollection(JiveGlobals.getProperty("conversation.roomsArchived", "")); @@ -269,6 +275,15 @@ public boolean isPartialSample() { InternalComponentManager.getInstance().addListener(this); } + public boolean isChatmarkerArchivingEnabled() { + return chatmarkerArchivingEnabled; + } + + public void setChatmarkerArchivingEnabled(boolean chatmarkerArchivingEnabled) { + this.chatmarkerArchivingEnabled = chatmarkerArchivingEnabled; + JiveGlobals.setProperty("conversation.chatmarkerArchiving", Boolean.toString(chatmarkerArchivingEnabled)); + } + public void stop() { cleanupTask.cancel(); cleanupTask = null; @@ -643,6 +658,9 @@ public void removeConversationListener(ConversationListener listener) { void processMessage(JID sender, JID receiver, String body, String stanza, Date date) { Log.trace("Processing message from date {}...", date ); String conversationKey = getConversationKey(sender, receiver); + + ChatMarker.TYPE chatmarker=ChatMarker.searchForXep0333(stanza); + synchronized (conversationKey.intern()) { Conversation conversation = conversations.get(conversationKey); // Create a new conversation if necessary. @@ -693,7 +711,7 @@ else if ((date.getTime() - conversation.getLastActivity().getTime() > idleTime) conversationArchiver.archive(conversation); } if (messageArchivingEnabled) { - if (body != null) { + if (body != null||(body==null&&chatmarkerArchivingEnabled&&chatmarker!=ChatMarker.TYPE.NONE)) { /* OF-677 - Workaround to prevent null messages being archived */ messageArchiver.archive(new ArchivedMessage(conversation.getConversationID(), sender, receiver, date, body, stanza, false, null) ); } @@ -725,6 +743,9 @@ else if ((date.getTime() - conversation.getLastActivity().getTime() > idleTime) void processRoomMessage(JID roomJID, JID sender, JID receiverIfPM, String nickname, String body, String stanza, Date date) { Log.trace("Processing room {} message from date {}.", roomJID, date ); String conversationKey = getRoomConversationKey(roomJID); + + ChatMarker.TYPE chatmarker=ChatMarker.searchForXep0333(stanza); + synchronized (conversationKey.intern()) { Conversation conversation = conversations.get(conversationKey); // Create a new conversation if necessary. @@ -759,7 +780,7 @@ else if ((date.getTime() - conversation.getLastActivity().getTime() > idleTime) } if (roomArchivingEnabled && (roomsArchived.isEmpty() || roomsArchived.contains(roomJID.getNode()))) { JID jid = new JID(roomJID + "/" + nickname); - if (body != null) { + if (body != null||(body==null&&chatmarkerArchivingEnabled&&chatmarker!=ChatMarker.TYPE.NONE)) { /* OF-677 - Workaround to prevent null messages being archived */ messageArchiver.archive( new ArchivedMessage(conversation.getConversationID(), sender, jid, date, body, roomArchivingStanzasEnabled ? stanza : "", false, receiverIfPM)); } diff --git a/src/java/org/jivesoftware/openfire/archive/ConversationUtils.java b/src/java/org/jivesoftware/openfire/archive/ConversationUtils.java index df95663b5..cac340e12 100644 --- a/src/java/org/jivesoftware/openfire/archive/ConversationUtils.java +++ b/src/java/org/jivesoftware/openfire/archive/ConversationUtils.java @@ -216,10 +216,13 @@ private ByteArrayOutputStream buildPDFContent(Conversation conversation, Map " + to + ": "; + prefix = "[" + time + "] " + from+(body==null?(" ("+message.getToJID().getResource()+")"):"")+ " -> " + to + ": "; } Color color = colorMap.get(message.getFromJID()); if (color == null) { @@ -230,12 +233,35 @@ private ByteArrayOutputStream buildPDFContent(Conversation conversation, Map"); if (!message.isRoomEvent()) { builder.append("").append("[").append(time).append("]").append(""); diff --git a/src/java/org/jivesoftware/openfire/archive/GroupConversationInterceptor.java b/src/java/org/jivesoftware/openfire/archive/GroupConversationInterceptor.java index ad219ee8e..f6605a1bb 100644 --- a/src/java/org/jivesoftware/openfire/archive/GroupConversationInterceptor.java +++ b/src/java/org/jivesoftware/openfire/archive/GroupConversationInterceptor.java @@ -124,9 +124,25 @@ public void messageReceived(JID roomJID, JID user, String nickname, Message mess conversationManager.getRoomsArchived().isEmpty() || conversationManager.getRoomsArchived().contains(roomJID.getNode())); - ConversationEventsQueue eventsQueue = conversationManager.getConversationEventsQueue(); - eventsQueue.addGroupChatEvent(conversationManager.getRoomConversationKey(roomJID), + if (withBody) + { + ConversationEventsQueue eventsQueue = conversationManager.getConversationEventsQueue(); + eventsQueue.addGroupChatEvent(conversationManager.getRoomConversationKey(roomJID), ConversationEvent.roomMessageReceived(roomJID, user, null, nickname, withBody ? message.getBody() : null, message.toXML(), now)); + } + else + { + String stanza = message.toXML(); + ChatMarker.TYPE markertype = ChatMarker.searchForXep0333(stanza); + + if (markertype!=ChatMarker.TYPE.NONE) + { + ConversationEventsQueue eventsQueue = conversationManager.getConversationEventsQueue(); + eventsQueue.addGroupChatEvent(conversationManager.getRoomConversationKey(roomJID), + ConversationEvent.chatmarkerMessageReceived(roomJID, user, markertype,stanza, + new Date())); + } + } } } diff --git a/src/web/archiving-settings.jsp b/src/web/archiving-settings.jsp index 65016e6e5..f3e92faa4 100644 --- a/src/web/archiving-settings.jsp +++ b/src/web/archiving-settings.jsp @@ -181,6 +181,7 @@ boolean updateLogSettings = request.getParameter("updateLogSettings") != null; boolean messageArchiving = conversationManager.isMessageArchivingEnabled(); boolean roomArchiving = conversationManager.isRoomArchivingEnabled(); + boolean chatmarkerArchiving = conversationManager.isChatmarkerArchivingEnabled(); boolean roomArchivingStanzas = conversationManager.isRoomArchivingStanzasEnabled(); int idleTime = ParamUtils.getIntParameter(request, "idleTime", conversationManager.getIdleTime()); int maxTime = ParamUtils.getIntParameter(request, "maxTime", conversationManager.getMaxTime()); @@ -234,6 +235,7 @@ boolean metadataArchiving = request.getParameter("metadataArchiving") != null; messageArchiving = request.getParameter("messageArchiving") != null; roomArchiving = request.getParameter("roomArchiving") != null; + chatmarkerArchiving = request.getParameter("chatmarkerArchiving") != null; roomArchivingStanzas = request.getParameter("roomArchivingStanzas") != null; String roomsArchived = request.getParameter("roomsArchived"); @@ -261,6 +263,7 @@ // If no errors, continue: if (errors.size() == 0) { conversationManager.setMetadataArchivingEnabled(metadataArchiving); + conversationManager.setChatmarkerArchivingEnabled(chatmarkerArchiving); conversationManager.setMessageArchivingEnabled(messageArchiving); conversationManager.setRoomArchivingEnabled(roomArchiving); conversationManager.setRoomArchivingStanzasEnabled(roomArchivingStanzas); @@ -274,6 +277,7 @@ webManager.logEvent("Changed archive settings (monitoring plugin)", "Metadata Archiving Enabled: " + metadataArchiving + ", Message Archiving Enabled: " + messageArchiving + + ", Chatmarker Archiving Enabled: " + chatmarkerArchiving + ", Room Archiving Enabled: " + roomArchiving + ", Room Archiving Stanzas Enabled: " + roomArchivingStanzas + ", RoomsArchived: " + StringUtils.stringToCollection(roomsArchived) @@ -346,6 +350,10 @@ /> + + + + />