Improve PepManager.publish()

by using PubSubManager.tryToPublishAndPossibleAutoCreate().

This also swaps the parameters of the method.

Thanks to Guus der Kinderen for suggesting this.
This commit is contained in:
Florian Schmaus 2019-08-28 22:50:58 +02:00
parent 851bd3c5dd
commit 4249c1a845
5 changed files with 57 additions and 32 deletions

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2003-2007 Jive Software, 2015-2018 Florian Schmaus * Copyright 2003-2007 Jive Software, 2015-2019 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,7 +41,6 @@ import org.jivesoftware.smackx.pubsub.EventElement;
import org.jivesoftware.smackx.pubsub.Item; import org.jivesoftware.smackx.pubsub.Item;
import org.jivesoftware.smackx.pubsub.LeafNode; import org.jivesoftware.smackx.pubsub.LeafNode;
import org.jivesoftware.smackx.pubsub.PubSubException.NotALeafNodeException; import org.jivesoftware.smackx.pubsub.PubSubException.NotALeafNodeException;
import org.jivesoftware.smackx.pubsub.PubSubException.NotAPubSubNodeException;
import org.jivesoftware.smackx.pubsub.PubSubFeature; import org.jivesoftware.smackx.pubsub.PubSubFeature;
import org.jivesoftware.smackx.pubsub.PubSubManager; import org.jivesoftware.smackx.pubsub.PubSubManager;
import org.jivesoftware.smackx.pubsub.filter.EventExtensionFilter; import org.jivesoftware.smackx.pubsub.filter.EventExtensionFilter;
@ -151,19 +150,19 @@ public final class PepManager extends Manager {
/** /**
* Publish an event. * Publish an event.
* *
* @param nodeId the ID of the node to publish on.
* @param item the item to publish. * @param item the item to publish.
* @param node the node to publish on. * @return the leaf node the item was published on.
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
* @throws XMPPErrorException * @throws XMPPErrorException
* @throws NoResponseException * @throws NoResponseException
* @throws NotAPubSubNodeException
* @throws NotALeafNodeException * @throws NotALeafNodeException
*/ */
public void publish(Item item, String node) throws NotConnectedException, InterruptedException, public LeafNode publish(String nodeId, Item item) throws NotConnectedException, InterruptedException,
NoResponseException, XMPPErrorException, NotAPubSubNodeException, NotALeafNodeException { NoResponseException, XMPPErrorException, NotALeafNodeException {
LeafNode pubSubNode = pepPubSubManager.getLeafNode(node); // PEP nodes are auto created if not existent. Hence Use PubSubManager.tryToPublishAndPossibleAutoCreate() here.
pubSubNode.publish(item); return pepPubSubManager.tryToPublishAndPossibleAutoCreate(nodeId, item);
} }
/** /**

View File

@ -186,6 +186,17 @@ public final class PubSubManager extends Manager {
pubSubService = toAddress; pubSubService = toAddress;
} }
private void checkIfXmppErrorBecauseOfNotLeafNode(String nodeId, XMPPErrorException xmppErrorException)
throws XMPPErrorException, NotALeafNodeException {
Condition condition = xmppErrorException.getStanzaError().getCondition();
if (condition == Condition.feature_not_implemented) {
// XEP-0060 § 6.5.9.5: Item retrieval not supported, e.g. because node is a collection node
throw new PubSubException.NotALeafNodeException(nodeId, pubSubService);
}
throw xmppErrorException;
}
/** /**
* Creates an instant node, if supported. * Creates an instant node, if supported.
* *
@ -387,13 +398,7 @@ public final class PubSubManager extends Manager {
// Try to ensure that this is not a collection node by asking for one item form the node. // Try to ensure that this is not a collection node by asking for one item form the node.
leafNode.getItems(1); leafNode.getItems(1);
} catch (XMPPErrorException e) { } catch (XMPPErrorException e) {
Condition condition = e.getStanzaError().getCondition(); checkIfXmppErrorBecauseOfNotLeafNode(id, e);
if (condition == Condition.feature_not_implemented) {
// XEP-0060 § 6.5.9.5: Item retrieval not supported, e.g. because node is a collection node
throw new PubSubException.NotALeafNodeException(id, pubSubService);
}
throw e;
} }
nodeMap.put(id, leafNode); nodeMap.put(id, leafNode);
@ -430,12 +435,19 @@ public final class PubSubManager extends Manager {
* @throws XMPPErrorException * @throws XMPPErrorException
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
* @throws NotALeafNodeException
* @since 4.2.1 * @since 4.2.1
*/ */
public <I extends Item> LeafNode tryToPublishAndPossibleAutoCreate(String id, I item) public <I extends Item> LeafNode tryToPublishAndPossibleAutoCreate(String id, I item)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException,
NotALeafNodeException {
LeafNode leafNode = new LeafNode(this, id); LeafNode leafNode = new LeafNode(this, id);
leafNode.publish(item);
try {
leafNode.publish(item);
} catch (XMPPErrorException e) {
checkIfXmppErrorBecauseOfNotLeafNode(id, e);
}
// If LeafNode.publish() did not throw then we have successfully published an item and possible auto-created // If LeafNode.publish() did not throw then we have successfully published an item and possible auto-created
// (XEP-0163 § 3., XEP-0060 § 7.1.4) the node. So we can put the node into the nodeMap. // (XEP-0163 § 3., XEP-0060 § 7.1.4) the node. So we can put the node into the nodeMap.

View File

@ -703,10 +703,11 @@ public final class OmemoManager extends Manager {
* @throws SmackException.NotConnectedException * @throws SmackException.NotConnectedException
* @throws SmackException.NoResponseException * @throws SmackException.NoResponseException
* @throws IOException * @throws IOException
* @throws PubSubException.NotALeafNodeException
*/ */
public void purgeDeviceList() public void purgeDeviceList()
throws SmackException.NotLoggedInException, InterruptedException, XMPPException.XMPPErrorException, throws SmackException.NotLoggedInException, InterruptedException, XMPPException.XMPPErrorException,
SmackException.NotConnectedException, SmackException.NoResponseException, IOException { SmackException.NotConnectedException, SmackException.NoResponseException, IOException, PubSubException.NotALeafNodeException {
getOmemoService().purgeDeviceList(new LoggedInOmemoManager(this)); getOmemoService().purgeDeviceList(new LoggedInOmemoManager(this));
} }
@ -722,10 +723,12 @@ public final class OmemoManager extends Manager {
* @throws SmackException.NoResponseException XMPP error * @throws SmackException.NoResponseException XMPP error
* @throws SmackException.NotLoggedInException * @throws SmackException.NotLoggedInException
* @throws IOException * @throws IOException
* @throws PubSubException.NotALeafNodeException
*/ */
public synchronized void rotateSignedPreKey() public synchronized void rotateSignedPreKey()
throws CorruptedOmemoKeyException, SmackException.NotLoggedInException, XMPPException.XMPPErrorException, throws CorruptedOmemoKeyException, SmackException.NotLoggedInException, XMPPException.XMPPErrorException,
SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException, IOException { SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException,
IOException, PubSubException.NotALeafNodeException {
if (!connection().isAuthenticated()) { if (!connection().isAuthenticated()) {
throw new SmackException.NotLoggedInException(); throw new SmackException.NotLoggedInException();
} }
@ -1032,7 +1035,7 @@ public final class OmemoManager extends Manager {
try { try {
OmemoService.publishDeviceList(connection(), newDeviceList); OmemoService.publishDeviceList(connection(), newDeviceList);
} catch (InterruptedException | XMPPException.XMPPErrorException | } catch (InterruptedException | XMPPException.XMPPErrorException |
SmackException.NotConnectedException | SmackException.NoResponseException e) { SmackException.NotConnectedException | SmackException.NoResponseException | PubSubException.NotALeafNodeException e) {
LOGGER.log(Level.WARNING, "Could not publish our deviceList upon an received update.", e); LOGGER.log(Level.WARNING, "Could not publish our deviceList upon an received update.", e);
} }
} }

View File

@ -74,9 +74,11 @@ import org.jivesoftware.smackx.omemo.trust.TrustState;
import org.jivesoftware.smackx.omemo.util.MessageOrOmemoMessage; import org.jivesoftware.smackx.omemo.util.MessageOrOmemoMessage;
import org.jivesoftware.smackx.omemo.util.OmemoConstants; import org.jivesoftware.smackx.omemo.util.OmemoConstants;
import org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder; import org.jivesoftware.smackx.omemo.util.OmemoMessageBuilder;
import org.jivesoftware.smackx.pep.PepManager;
import org.jivesoftware.smackx.pubsub.LeafNode; import org.jivesoftware.smackx.pubsub.LeafNode;
import org.jivesoftware.smackx.pubsub.PayloadItem; import org.jivesoftware.smackx.pubsub.PayloadItem;
import org.jivesoftware.smackx.pubsub.PubSubException; import org.jivesoftware.smackx.pubsub.PubSubException;
import org.jivesoftware.smackx.pubsub.PubSubException.NotALeafNodeException;
import org.jivesoftware.smackx.pubsub.PubSubManager; import org.jivesoftware.smackx.pubsub.PubSubManager;
import org.jxmpp.jid.BareJid; import org.jxmpp.jid.BareJid;
@ -581,12 +583,13 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
* @throws SmackException.NotConnectedException * @throws SmackException.NotConnectedException
* @throws InterruptedException * @throws InterruptedException
* @throws SmackException.NoResponseException * @throws SmackException.NoResponseException
* @throws NotALeafNodeException
*/ */
static void publishBundle(XMPPConnection connection, OmemoDevice userDevice, OmemoBundleElement bundle) static void publishBundle(XMPPConnection connection, OmemoDevice userDevice, OmemoBundleElement bundle)
throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException,
SmackException.NoResponseException { SmackException.NoResponseException, NotALeafNodeException {
PubSubManager pm = PubSubManager.getInstanceFor(connection, connection.getUser().asBareJid()); PepManager pm = PepManager.getInstanceFor(connection);
pm.tryToPublishAndPossibleAutoCreate(userDevice.getBundleNodeName(), new PayloadItem<>(bundle)); pm.publish(userDevice.getBundleNodeName(), new PayloadItem<>(bundle));
} }
/** /**
@ -635,10 +638,9 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
*/ */
static void publishDeviceList(XMPPConnection connection, OmemoDeviceListElement deviceList) static void publishDeviceList(XMPPConnection connection, OmemoDeviceListElement deviceList)
throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException,
SmackException.NoResponseException { SmackException.NoResponseException, NotALeafNodeException {
PepManager pm = PepManager.getInstanceFor(connection);
PubSubManager.getInstanceFor(connection, connection.getUser().asBareJid()) pm.publish(OmemoConstants.PEP_NODE_DEVICE_LIST, new PayloadItem<>(deviceList));
.tryToPublishAndPossibleAutoCreate(OmemoConstants.PEP_NODE_DEVICE_LIST, new PayloadItem<>(deviceList));
} }
/** /**
@ -1119,7 +1121,9 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
getOmemoStoreBackend().replenishKeys(userDevice); getOmemoStoreBackend().replenishKeys(userDevice);
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice); OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
publishBundle(manager.getConnection(), userDevice, bundleElement); publishBundle(manager.getConnection(), userDevice, bundleElement);
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { } catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException
| SmackException.NotConnectedException | XMPPException.XMPPErrorException
| NotALeafNodeException e) {
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e); LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
} }
} }
@ -1200,7 +1204,9 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
getOmemoStoreBackend().replenishKeys(userDevice); getOmemoStoreBackend().replenishKeys(userDevice);
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice); OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
publishBundle(manager.getConnection(), userDevice, bundleElement); publishBundle(manager.getConnection(), userDevice, bundleElement);
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { } catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException
| SmackException.NotConnectedException | XMPPException.XMPPErrorException
| NotALeafNodeException e) {
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e); LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
} }
} }
@ -1280,7 +1286,9 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
getOmemoStoreBackend().replenishKeys(userDevice); getOmemoStoreBackend().replenishKeys(userDevice);
OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice); OmemoBundleElement bundleElement = getOmemoStoreBackend().packOmemoBundle(userDevice);
publishBundle(manager.getConnection(), userDevice, bundleElement); publishBundle(manager.getConnection(), userDevice, bundleElement);
} catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException | SmackException.NotConnectedException | XMPPException.XMPPErrorException e) { } catch (CorruptedOmemoKeyException | InterruptedException | SmackException.NoResponseException
| SmackException.NotConnectedException | XMPPException.XMPPErrorException
| NotALeafNodeException e) {
LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e); LOGGER.log(Level.WARNING, "Could not republish replenished bundle.", e);
} }
} }
@ -1371,10 +1379,11 @@ public abstract class OmemoService<T_IdKeyPair, T_IdKey, T_PreKey, T_SigPreKey,
* @throws SmackException.NotConnectedException * @throws SmackException.NotConnectedException
* @throws SmackException.NoResponseException * @throws SmackException.NoResponseException
* @throws IOException * @throws IOException
* @throws NotALeafNodeException
*/ */
public void purgeDeviceList(OmemoManager.LoggedInOmemoManager managerGuard) public void purgeDeviceList(OmemoManager.LoggedInOmemoManager managerGuard)
throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, throws InterruptedException, XMPPException.XMPPErrorException, SmackException.NotConnectedException,
SmackException.NoResponseException, IOException { SmackException.NoResponseException, IOException, NotALeafNodeException {
OmemoManager omemoManager = managerGuard.get(); OmemoManager omemoManager = managerGuard.get();
OmemoDevice userDevice = omemoManager.getOwnDevice(); OmemoDevice userDevice = omemoManager.getOwnDevice();

View File

@ -39,6 +39,7 @@ import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.tcp.XMPPTCPConnection; import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.carbons.packet.CarbonExtension; import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
import org.jivesoftware.smackx.muc.MultiUserChat; import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.omemo.OmemoManager; import org.jivesoftware.smackx.omemo.OmemoManager;
@ -56,6 +57,7 @@ import org.jivesoftware.smackx.omemo.signal.SignalOmemoService;
import org.jivesoftware.smackx.omemo.trust.OmemoFingerprint; import org.jivesoftware.smackx.omemo.trust.OmemoFingerprint;
import org.jivesoftware.smackx.omemo.trust.OmemoTrustCallback; import org.jivesoftware.smackx.omemo.trust.OmemoTrustCallback;
import org.jivesoftware.smackx.omemo.trust.TrustState; import org.jivesoftware.smackx.omemo.trust.TrustState;
import org.jivesoftware.smackx.pubsub.PubSubException;
import org.jxmpp.jid.BareJid; import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
@ -202,7 +204,7 @@ public class OmemoClient {
try { try {
omemoManager.purgeDeviceList(); omemoManager.purgeDeviceList();
print("Purged."); print("Purged.");
} catch (XMPPException.XMPPErrorException | SmackException.NoResponseException e) { } catch (XMPPException.XMPPErrorException | SmackException.NoResponseException | PubSubException.NotALeafNodeException e) {
LOGGER.log(Level.SEVERE, "Unexpected Exception", e); LOGGER.log(Level.SEVERE, "Unexpected Exception", e);
} }
} }