From 3dd1365a5a025d90b60c117c2d6844e40dad12f9 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 7 Jan 2015 19:35:11 +0100 Subject: [PATCH] Improve Privacy List code notably add a cache for the active and default privacy list to avoid IQ get/response round-trips. Also add a few methods to PrivacyListManager to get the privacy list names. The already existing methods always returned the whole list together with the name, which caused two round-trips. Simplified some code. Properly escape Privacy XML. --- .../smack/AbstractXMPPConnection.java | 21 +++ .../jivesoftware/smack/XMPPConnection.java | 9 + .../smack/filter/IQResultReplyFilter.java | 41 +++++ .../smackx/privacy/PrivacyList.java | 4 + .../smackx/privacy/PrivacyListManager.java | 158 ++++++++++++++++-- .../privacy/filter/SetActiveListFilter.java | 38 +++++ .../privacy/filter/SetDefaultListFilter.java | 38 +++++ .../smackx/privacy/packet/Privacy.java | 8 +- 8 files changed, 299 insertions(+), 18 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/filter/IQResultReplyFilter.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/filter/SetActiveListFilter.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/filter/SetDefaultListFilter.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index 10515ff7c..677994b65 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -1371,6 +1371,27 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { sendStanzaWithResponseCallback(iqRequest, replyFilter, callback, exceptionCallback, timeout); } + @Override + public void addOneTimeSyncCallback(final PacketListener callback, final PacketFilter packetFilter) { + final PacketListener packetListener = new PacketListener() { + @Override + public void processPacket(Packet packet) throws NotConnectedException { + try { + callback.processPacket(packet); + } finally { + removeSyncPacketListener(this); + } + } + }; + addSyncPacketListener(packetListener, packetFilter); + removeCallbacksService.schedule(new Runnable() { + @Override + public void run() { + removeSyncPacketListener(packetListener); + } + }, getPacketReplyTimeout(), TimeUnit.MILLISECONDS); + } + private long lastStanzaReceived; public long getLastStanzaReceived() { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java index a8daeccd8..e2b4e64cd 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -556,6 +556,15 @@ public interface XMPPConnection { final ExceptionCallback exceptionCallback, long timeout) throws NotConnectedException; + /** + * Add a callback that is called exactly once and synchronously with the incoming stanza that matches the given + * packet filter. + * + * @param callback the callback invoked once the packet filter matches a stanza. + * @param packetFilter the filter to match stanzas or null to match all. + */ + public void addOneTimeSyncCallback(PacketListener callback, PacketFilter packetFilter); + /** * Returns the timestamp in milliseconds when the last stanza was received. * diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/IQResultReplyFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQResultReplyFilter.java new file mode 100644 index 000000000..a9e327b8c --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQResultReplyFilter.java @@ -0,0 +1,41 @@ +/** + * + * Copyright 2015 Florian Schmaus + * + * Licensed 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.jivesoftware.smack.filter; + +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.Packet; + +/** + * + */ +public class IQResultReplyFilter extends IQReplyFilter { + + + public IQResultReplyFilter(IQ iqPacket, XMPPConnection conn) { + super(iqPacket, conn); + } + + @Override + public boolean accept(Packet packet) { + if (!super.accept(packet)) { + return false; + } + return IQTypeFilter.RESULT.accept(packet); + } + +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyList.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyList.java index 075a1fc14..47f73a148 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyList.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyList.java @@ -70,4 +70,8 @@ public class PrivacyList { return items; } + @Override + public String toString() { + return "Privacy List: " + listName + "(active:" + isActiveList + ", default:" + isDefaultList + ")"; + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java index ea351f02a..57631a824 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java @@ -23,6 +23,7 @@ import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.CopyOnWriteArraySet; +import org.jivesoftware.smack.AbstractConnectionListener; import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPConnection; @@ -32,25 +33,29 @@ import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.XMPPConnectionRegistry; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.AndFilter; +import org.jivesoftware.smack.filter.IQResultReplyFilter; import org.jivesoftware.smack.filter.IQTypeFilter; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; +import org.jivesoftware.smackx.privacy.filter.SetActiveListFilter; +import org.jivesoftware.smackx.privacy.filter.SetDefaultListFilter; import org.jivesoftware.smackx.privacy.packet.Privacy; import org.jivesoftware.smackx.privacy.packet.PrivacyItem; /** * A PrivacyListManager is used by XMPP clients to block or allow communications from other - * users. Use the manager to: