mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-06-24 12:24:51 +02:00
While markdown is easier to write, Smack's markdown documentation was never tightly coupled with the source. For example, the markdown documentation never provided links to the actual Java classes and methods. This poses the risk that the documentation and the code diverge over time. Furthermore, javadoc is constantly improving (for example @snippet annotations) and I expect that one will be able to write javadoc in markdown. Fixes SMACK-928.
270 lines
11 KiB
Java
270 lines
11 KiB
Java
/**
|
|
*
|
|
* Copyright 2016-2017 Fernando Ramirez, 2016-2022 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.smackx.blocking;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.WeakHashMap;
|
|
import java.util.concurrent.CopyOnWriteArraySet;
|
|
|
|
import org.jivesoftware.smack.ConnectionCreationListener;
|
|
import org.jivesoftware.smack.ConnectionListener;
|
|
import org.jivesoftware.smack.Manager;
|
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
|
import org.jivesoftware.smack.XMPPConnection;
|
|
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
|
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
|
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
|
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
|
import org.jivesoftware.smack.packet.IQ;
|
|
|
|
import org.jivesoftware.smackx.blocking.element.BlockContactsIQ;
|
|
import org.jivesoftware.smackx.blocking.element.BlockListIQ;
|
|
import org.jivesoftware.smackx.blocking.element.UnblockContactsIQ;
|
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
|
|
|
import org.jxmpp.jid.Jid;
|
|
|
|
/**
|
|
* Block communications with contancts and other entities using XEP-0191.
|
|
* Allows to
|
|
* <ul>
|
|
* <li>Check push notifications support</li>
|
|
* <li>Get blocking list</li>
|
|
* <li>Block contact</li>
|
|
* <li>Unblock conact</li>
|
|
* <li>Unblock all</li>
|
|
* </ul>
|
|
*
|
|
* @author Fernando Ramirez
|
|
* @author Florian Schmaus
|
|
* @see <a href="http://xmpp.org/extensions/xep-0191.html">XEP-0191: Blocking
|
|
* Command</a>
|
|
*/
|
|
public final class BlockingCommandManager extends Manager {
|
|
|
|
public static final String NAMESPACE = "urn:xmpp:blocking";
|
|
|
|
private volatile List<Jid> blockListCached;
|
|
|
|
static {
|
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
|
@Override
|
|
public void connectionCreated(XMPPConnection connection) {
|
|
getInstanceFor(connection);
|
|
}
|
|
});
|
|
}
|
|
|
|
private static final Map<XMPPConnection, BlockingCommandManager> INSTANCES = new WeakHashMap<>();
|
|
|
|
/**
|
|
* Get the singleton instance of BlockingCommandManager.
|
|
*
|
|
* @param connection TODO javadoc me please
|
|
* @return the instance of BlockingCommandManager
|
|
*/
|
|
public static synchronized BlockingCommandManager getInstanceFor(XMPPConnection connection) {
|
|
BlockingCommandManager blockingCommandManager = INSTANCES.get(connection);
|
|
|
|
if (blockingCommandManager == null) {
|
|
blockingCommandManager = new BlockingCommandManager(connection);
|
|
INSTANCES.put(connection, blockingCommandManager);
|
|
}
|
|
|
|
return blockingCommandManager;
|
|
}
|
|
|
|
private final Set<AllJidsUnblockedListener> allJidsUnblockedListeners = new CopyOnWriteArraySet<>();
|
|
|
|
private final Set<JidsBlockedListener> jidsBlockedListeners = new CopyOnWriteArraySet<>();
|
|
|
|
private final Set<JidsUnblockedListener> jidsUnblockedListeners = new CopyOnWriteArraySet<>();
|
|
|
|
private BlockingCommandManager(XMPPConnection connection) {
|
|
super(connection);
|
|
|
|
// block IQ handler
|
|
connection.registerIQRequestHandler(
|
|
new AbstractIqRequestHandler(BlockContactsIQ.ELEMENT, BlockContactsIQ.NAMESPACE, IQ.Type.set, Mode.sync) {
|
|
@Override
|
|
public IQ handleIQRequest(IQ iqRequest) {
|
|
BlockContactsIQ blockContactIQ = (BlockContactsIQ) iqRequest;
|
|
|
|
if (blockListCached == null) {
|
|
blockListCached = new ArrayList<>();
|
|
}
|
|
|
|
List<Jid> blockedJids = blockContactIQ.getJids();
|
|
blockListCached.addAll(blockedJids);
|
|
|
|
for (JidsBlockedListener listener : jidsBlockedListeners) {
|
|
listener.onJidsBlocked(blockedJids);
|
|
}
|
|
|
|
return IQ.createResultIQ(blockContactIQ);
|
|
}
|
|
});
|
|
|
|
// unblock IQ handler
|
|
connection.registerIQRequestHandler(new AbstractIqRequestHandler(UnblockContactsIQ.ELEMENT,
|
|
UnblockContactsIQ.NAMESPACE, IQ.Type.set, Mode.sync) {
|
|
@Override
|
|
public IQ handleIQRequest(IQ iqRequest) {
|
|
UnblockContactsIQ unblockContactIQ = (UnblockContactsIQ) iqRequest;
|
|
|
|
if (blockListCached == null) {
|
|
blockListCached = new ArrayList<>();
|
|
}
|
|
|
|
List<Jid> unblockedJids = unblockContactIQ.getJids();
|
|
if (unblockedJids == null) { // remove all
|
|
blockListCached.clear();
|
|
for (AllJidsUnblockedListener listener : allJidsUnblockedListeners) {
|
|
listener.onAllJidsUnblocked();
|
|
}
|
|
} else { // remove only some
|
|
blockListCached.removeAll(unblockedJids);
|
|
for (JidsUnblockedListener listener : jidsUnblockedListeners) {
|
|
listener.onJidsUnblocked(unblockedJids);
|
|
}
|
|
}
|
|
|
|
return IQ.createResultIQ(unblockContactIQ);
|
|
}
|
|
});
|
|
|
|
connection.addConnectionListener(new ConnectionListener() {
|
|
@Override
|
|
public void authenticated(XMPPConnection connection, boolean resumed) {
|
|
// No need to reset the cache if the connection got resumed.
|
|
if (resumed) {
|
|
return;
|
|
}
|
|
blockListCached = null;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns true if Blocking Command is supported by the server.
|
|
*
|
|
* @return true if Blocking Command is supported by the server.
|
|
* @throws NoResponseException if there was no response from the remote entity.
|
|
* @throws XMPPErrorException if there was an XMPP error returned.
|
|
* @throws NotConnectedException if the XMPP connection is not connected.
|
|
* @throws InterruptedException if the calling thread was interrupted.
|
|
*/
|
|
public boolean isSupportedByServer()
|
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
|
return ServiceDiscoveryManager.getInstanceFor(connection()).serverSupportsFeature(NAMESPACE);
|
|
}
|
|
|
|
/**
|
|
* Returns the block list.
|
|
*
|
|
* @return the blocking list
|
|
* @throws NoResponseException if there was no response from the remote entity.
|
|
* @throws XMPPErrorException if there was an XMPP error returned.
|
|
* @throws NotConnectedException if the XMPP connection is not connected.
|
|
* @throws InterruptedException if the calling thread was interrupted.
|
|
*/
|
|
public List<Jid> getBlockList()
|
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
|
|
|
if (blockListCached == null) {
|
|
BlockListIQ blockListIQ = new BlockListIQ();
|
|
BlockListIQ blockListIQResult = connection().sendIqRequestAndWaitForResponse(blockListIQ);
|
|
blockListCached = blockListIQResult.getBlockedJidsCopy();
|
|
}
|
|
|
|
return Collections.unmodifiableList(blockListCached);
|
|
}
|
|
|
|
/**
|
|
* Block contacts.
|
|
*
|
|
* @param jids TODO javadoc me please
|
|
* @throws NoResponseException if there was no response from the remote entity.
|
|
* @throws XMPPErrorException if there was an XMPP error returned.
|
|
* @throws NotConnectedException if the XMPP connection is not connected.
|
|
* @throws InterruptedException if the calling thread was interrupted.
|
|
*/
|
|
public void blockContacts(List<Jid> jids)
|
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
|
BlockContactsIQ blockContactIQ = new BlockContactsIQ(jids);
|
|
connection().sendIqRequestAndWaitForResponse(blockContactIQ);
|
|
}
|
|
|
|
/**
|
|
* Unblock contacts.
|
|
*
|
|
* @param jids TODO javadoc me please
|
|
* @throws NoResponseException if there was no response from the remote entity.
|
|
* @throws XMPPErrorException if there was an XMPP error returned.
|
|
* @throws NotConnectedException if the XMPP connection is not connected.
|
|
* @throws InterruptedException if the calling thread was interrupted.
|
|
*/
|
|
public void unblockContacts(List<Jid> jids)
|
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
|
UnblockContactsIQ unblockContactIQ = new UnblockContactsIQ(jids);
|
|
connection().sendIqRequestAndWaitForResponse(unblockContactIQ);
|
|
}
|
|
|
|
/**
|
|
* Unblock all.
|
|
*
|
|
* @throws NoResponseException if there was no response from the remote entity.
|
|
* @throws XMPPErrorException if there was an XMPP error returned.
|
|
* @throws NotConnectedException if the XMPP connection is not connected.
|
|
* @throws InterruptedException if the calling thread was interrupted.
|
|
*/
|
|
public void unblockAll()
|
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
|
UnblockContactsIQ unblockContactIQ = new UnblockContactsIQ();
|
|
connection().sendIqRequestAndWaitForResponse(unblockContactIQ);
|
|
}
|
|
|
|
public void addJidsBlockedListener(JidsBlockedListener jidsBlockedListener) {
|
|
jidsBlockedListeners.add(jidsBlockedListener);
|
|
}
|
|
|
|
public void removeJidsBlockedListener(JidsBlockedListener jidsBlockedListener) {
|
|
jidsBlockedListeners.remove(jidsBlockedListener);
|
|
}
|
|
|
|
public void addJidsUnblockedListener(JidsUnblockedListener jidsUnblockedListener) {
|
|
jidsUnblockedListeners.add(jidsUnblockedListener);
|
|
}
|
|
|
|
public void removeJidsUnblockedListener(JidsUnblockedListener jidsUnblockedListener) {
|
|
jidsUnblockedListeners.remove(jidsUnblockedListener);
|
|
}
|
|
|
|
public void addAllJidsUnblockedListener(AllJidsUnblockedListener allJidsUnblockedListener) {
|
|
allJidsUnblockedListeners.add(allJidsUnblockedListener);
|
|
}
|
|
|
|
public void removeAllJidsUnblockedListener(AllJidsUnblockedListener allJidsUnblockedListener) {
|
|
allJidsUnblockedListeners.remove(allJidsUnblockedListener);
|
|
}
|
|
}
|