diff --git a/build.gradle b/build.gradle index d705a0cd2..0ae894a8c 100644 --- a/build.gradle +++ b/build.gradle @@ -650,13 +650,16 @@ def getGitCommit() { def dotGit = new File("$projectDir/.git") if (!dotGit.isDirectory()) return 'non-git build' + def projectDir = dotGit.getParentFile() def cmd = 'git describe --always --tags --dirty=+' - def proc = cmd.execute() + def proc = cmd.execute(null, projectDir) + proc.waitForOrKill(10 * 1000) + def gitCommit = proc.text.trim() assert !gitCommit.isEmpty() def srCmd = 'git symbolic-ref --short HEAD' - def srProc = srCmd.execute() + def srProc = srCmd.execute(null, projectDir) srProc.waitForOrKill(10 * 1000) if (srProc.exitValue() == 0) { // Only add the information if the git command was diff --git a/documentation/extensions/index.md b/documentation/extensions/index.md index b5c279f7d..5043f940d 100644 --- a/documentation/extensions/index.md +++ b/documentation/extensions/index.md @@ -56,6 +56,7 @@ Smack Extensions and currently supported XEPs of smack-extensions | [SI File Transfer](filetransfer.md) | [XEP-0096](https://xmpp.org/extensions/xep-0096.html) | n/a | Transfer files between two users over XMPP. | | User Mood | [XEP-0107](https://xmpp.org/extensions/xep-0107.html) | 1.2.1 | Communicate the users current mood. | | [Entity Capabilities](caps.md) | [XEP-0115](https://xmpp.org/extensions/xep-0115.html) | n/a | Broadcasting and dynamic discovery of entity capabilities. | +| User Tune | [XEP-0118](https://xmpp.org/extensions/xep-0118.html) | n/a | Defines a payload format for communicating information about music to which a user is listening. | | Data Forms Validation | [XEP-0122](https://xmpp.org/extensions/xep-0122.html) | n/a | Enables an application to specify additional validation guidelines . | | Service Administration | [XEP-0133](https://xmpp.org/extensions/xep-0133.html) | n/a | Recommended best practices for service-level administration of servers and components using Ad-Hoc Commands. | | Stream Compression | [XEP-0138](https://xmpp.org/extensions/xep-0138.html) | n/a | Support for optional compression of the XMPP stream. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackReactor.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackReactor.java index 342f4694a..1c2477789 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackReactor.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackReactor.java @@ -204,25 +204,25 @@ public class SmackReactor { return; } - ScheduledAction nextScheduledAction = scheduledActions.peek(); - - long selectWait; - if (nextScheduledAction == null) { - // There is no next scheduled action, wait indefinitely in select() or until another thread invokes - // selector.wakeup(). - selectWait = 0; - } else { - selectWait = nextScheduledAction.getTimeToDueMillis(); - } - - if (selectWait < 0) { - // A scheduled action was just released and become ready to execute. - return; - } - int newSelectedKeysCount = 0; List selectedKeys; synchronized (selector) { + ScheduledAction nextScheduledAction = scheduledActions.peek(); + + long selectWait; + if (nextScheduledAction == null) { + // There is no next scheduled action, wait indefinitely in select() or until another thread invokes + // selector.wakeup(). + selectWait = 0; + } else { + selectWait = nextScheduledAction.getTimeToDueMillis(); + } + + if (selectWait < 0) { + // A scheduled action was just released and became ready to execute. + return; + } + // Before we call select, we handle the pending the interest Ops. This will not block since no other // thread is currently in select() at this time. // Note: This was put deliberately before the registration lock. It may cause more synchronization but diff --git a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/Scalar.java b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/Scalar.java index fe2bca23a..9891c2e42 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/Scalar.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/Scalar.java @@ -54,13 +54,29 @@ public abstract class Scalar extends java.lang.Number { } @Override - public final int hashCode() { - return number.hashCode(); - } + public abstract int hashCode(); @Override - public final boolean equals(Object other) { - return number.equals(other); + public boolean equals(Object other) { + if (!(other instanceof Scalar)) { + return false; + } + + Scalar otherScalar = (Scalar) other; + + if (longValue() == otherScalar.longValue()) { + return true; + } + + if (doubleValue() == otherScalar.doubleValue()) { + return true; + } + + if (floatValue() == otherScalar.floatValue()) { + return true; + } + + return false; } @Override diff --git a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt16.java b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt16.java index 999597401..22dd8cd8d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt16.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt16.java @@ -39,4 +39,19 @@ public final class UInt16 extends Scalar { public static UInt16 from(int number) { return new UInt16(number); } + + @Override + public int hashCode() { + return number; + } + + @Override + public boolean equals(Object other) { + if (other instanceof UInt16) { + UInt16 otherUint16 = (UInt16) other; + return number == otherUint16.number; + } + + return super.equals(other); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt32.java b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt32.java index cb6c9aa28..e3e6bc670 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt32.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt32.java @@ -39,4 +39,20 @@ public final class UInt32 extends Scalar { public static UInt32 from(long number) { return new UInt32(number); } + + @Override + public int hashCode() { + // TODO: Use Long.hashCode(number) once Smack's minimum Android SDK level is 24 or higher. + return (int) (number ^ (number >>> 32)); + } + + @Override + public boolean equals(Object other) { + if (other instanceof UInt32) { + UInt32 otherUint32 = (UInt32) other; + return number == otherUint32.number; + } + + return super.equals(other); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java index d4906ff91..9d93f8b14 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java @@ -31,8 +31,6 @@ import org.jivesoftware.smack.util.PacketUtil; import org.jivesoftware.smack.util.XmlStringBuilder; import org.jxmpp.jid.Jid; -import org.jxmpp.jid.impl.JidCreate; -import org.jxmpp.stringprep.XmppStringprepException; /** * Base class for XMPP Stanzas, which are called Stanza in older versions of Smack (i.e. < 4.1). @@ -47,6 +45,7 @@ import org.jxmpp.stringprep.XmppStringprepException; *

* * @author Matt Tucker + * @author Florian Schmaus * @see RFC 6120 ยง 8. XML Stanzas */ public abstract class Stanza implements TopLevelStreamElement { @@ -109,16 +108,6 @@ public abstract class Stanza implements TopLevelStreamElement { return id; } - /** - * Get the Stanza ID. - * @return the stanza id. - * @deprecated use {@link #getStanzaId()} instead. - */ - @Deprecated - public String getPacketID() { - return getStanzaId(); - } - /** * Sets the unique ID of the packet. To indicate that a stanza has no id * pass null as the packet's id value. @@ -132,16 +121,6 @@ public abstract class Stanza implements TopLevelStreamElement { this.id = id; } - /** - * Set the stanza ID. - * @param packetID TODO javadoc me please - * @deprecated use {@link #setStanzaId(String)} instead. - */ - @Deprecated - public void setPacketID(String packetID) { - setStanzaId(packetID); - } - /** * Check if this stanza has an ID set. * @@ -159,9 +138,43 @@ public abstract class Stanza implements TopLevelStreamElement { * * @return the stanza id. * @since 4.2 + * @deprecated use {@link #setNewStanzaId()} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public String setStanzaId() { - if (!hasStanzaIdSet()) { + return ensureStanzaIdSet(); + } + + /** + * Set a new stanza ID even if there is already one set. + * + * @return the stanza id. + * @since 4.4 + */ + public String setNewStanzaId() { + return ensureStanzaIdSet(true); + } + + /** + * Ensure a stanza id is set. + * + * @return the stanza id. + * @since 4.4 + */ + public String ensureStanzaIdSet() { + return ensureStanzaIdSet(false); + } + + /** + * Ensure that a stanza ID is set. + * + * @param forceNew force a new ID even if there is already one set. + * @return the stanza ID. + * @since 4.4 + */ + private String ensureStanzaIdSet(boolean forceNew) { + if (forceNew || !hasStanzaIdSet()) { setStanzaId(StanzaIdUtil.newStanzaId()); } return getStanzaId(); @@ -179,26 +192,6 @@ public abstract class Stanza implements TopLevelStreamElement { return to; } - /** - * Sets who the stanza is being sent "to". The XMPP protocol often makes - * the "to" attribute optional, so it does not always need to be set. - * - * @param to who the stanza is being sent to. - * @throws IllegalArgumentException if to is not a valid JID String. - * @deprecated use {@link #setTo(Jid)} instead. - */ - @Deprecated - public void setTo(String to) { - Jid jid; - try { - jid = JidCreate.from(to); - } - catch (XmppStringprepException e) { - throw new IllegalArgumentException(e); - } - setTo(jid); - } - /** * Sets who the packet is being sent "to". The XMPP protocol often makes * the "to" attribute optional, so it does not always need to be set. @@ -221,27 +214,6 @@ public abstract class Stanza implements TopLevelStreamElement { return from; } - /** - * Sets who the stanza is being sent "from". The XMPP protocol often - * makes the "from" attribute optional, so it does not always need to - * be set. - * - * @param from who the stanza is being sent to. - * @throws IllegalArgumentException if from is not a valid JID String. - * @deprecated use {@link #setFrom(Jid)} instead. - */ - @Deprecated - public void setFrom(String from) { - Jid jid; - try { - jid = JidCreate.from(from); - } - catch (XmppStringprepException e) { - throw new IllegalArgumentException(e); - } - setFrom(jid); - } - /** * Sets who the packet is being sent "from". The XMPP protocol often * makes the "from" attribute optional, so it does not always need to @@ -263,17 +235,6 @@ public abstract class Stanza implements TopLevelStreamElement { return error; } - /** - * Sets the error for this packet. - * - * @param error the error to associate with this packet. - * @deprecated use {@link #setError(org.jivesoftware.smack.packet.StanzaError.Builder)} instead. - */ - @Deprecated - public void setError(StanzaError error) { - this.error = error; - } - /** * Sets the error for this stanza. * diff --git a/smack-core/src/test/java/org/jivesoftware/smack/test/util/XmlUnitUtils.java b/smack-core/src/test/java/org/jivesoftware/smack/test/util/XmlUnitUtils.java index 18404f70f..3d9b5ba0f 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/test/util/XmlUnitUtils.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/test/util/XmlUnitUtils.java @@ -43,7 +43,7 @@ public class XmlUnitUtils { NormalizedSource expected = new NormalizedSource(new StreamSource(new StringReader(expectedString))); NormalizedSource actual = new NormalizedSource(new StreamSource(new StringReader(actualString))); - return XmlAssert.assertThat(expected).and(actual) + return XmlAssert.assertThat(actual).and(expected) .ignoreChildNodesOrder() .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndAllAttributes, ElementSelectors.byNameAndText)) .normalizeWhitespace(); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/util/XmlStringBuilderTest.java b/smack-core/src/test/java/org/jivesoftware/smack/util/XmlStringBuilderTest.java new file mode 100644 index 000000000..8436a4dd2 --- /dev/null +++ b/smack-core/src/test/java/org/jivesoftware/smack/util/XmlStringBuilderTest.java @@ -0,0 +1,47 @@ +/** + * + * Copyright 2019 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.util; + +import org.jivesoftware.smack.packet.StandardExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.test.util.XmlUnitUtils; + +import org.junit.jupiter.api.Test; + +public class XmlStringBuilderTest { + + /** + * Test that {@link XmlStringBuilder} does not omit the second inner namespace declaration. + */ + @Test + public void equalInnerNamespaceTest() { + StandardExtensionElement innerOne = StandardExtensionElement.builder("inner", "inner-namespace").build(); + StandardExtensionElement innerTwo = StandardExtensionElement.builder("inner", "inner-namespace").build(); + + StandardExtensionElement outer = StandardExtensionElement.builder("outer", "outer-namespace").addElement( + innerOne).addElement(innerTwo).build(); + + String expectedXml = ""; + XmlStringBuilder actualXml = outer.toXML(XmlEnvironment.EMPTY); + + XmlUnitUtils.assertXmlSimilar(expectedXml, actualXml); + + StringBuilder actualXmlTwo = actualXml.toXML(XmlEnvironment.EMPTY); + + XmlUnitUtils.assertXmlSimilar(expectedXml, actualXmlTwo); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java index 0ecef64f7..23a129e24 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java @@ -22,7 +22,6 @@ import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.XmlEnvironment; -import org.jivesoftware.smack.packet.id.StanzaIdUtil; import org.jivesoftware.smack.provider.ExtensionElementProvider; import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; @@ -83,9 +82,7 @@ public class DeliveryReceiptRequest implements ExtensionElement { * @return the Message ID which will be used as receipt ID */ public static String addTo(Message message) { - if (message.getStanzaId() == null) { - message.setStanzaId(StanzaIdUtil.newStanzaId()); - } + message.ensureStanzaIdSet(); message.addExtension(new DeliveryReceiptRequest()); return message.getStanzaId(); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneListener.java new file mode 100644 index 000000000..c513579fc --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneListener.java @@ -0,0 +1,27 @@ +/** + * + * Copyright 2019 Aditya Borikar. + * + * 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.usertune; + +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smackx.usertune.element.UserTuneElement; + +import org.jxmpp.jid.BareJid; + +public interface UserTuneListener { + + void onUserTuneUpdated(BareJid jid, Message message, UserTuneElement userTuneElement); +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneManager.java new file mode 100644 index 000000000..70dd900b1 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneManager.java @@ -0,0 +1,143 @@ +/** + * + * Copyright 2019 Aditya Borikar. + * + * 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.usertune; + +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.AsyncButOrdered; +import org.jivesoftware.smack.Manager; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.SmackException.NotConnectedException; +import org.jivesoftware.smack.SmackException.NotLoggedInException; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; +import org.jivesoftware.smackx.pep.PepListener; +import org.jivesoftware.smackx.pep.PepManager; +import org.jivesoftware.smackx.pubsub.EventElement; +import org.jivesoftware.smackx.pubsub.ItemsExtension; +import org.jivesoftware.smackx.pubsub.PayloadItem; +import org.jivesoftware.smackx.pubsub.PubSubException.NotALeafNodeException; +import org.jivesoftware.smackx.usertune.element.UserTuneElement; + +import org.jxmpp.jid.BareJid; +import org.jxmpp.jid.EntityBareJid; + +/** + * Entry point for Smacks API for XEP-0118: User Tune. + *
+ * To publish a UserTune, please use {@link #publishUserTune(UserTuneElement)} method. This will publish the node. + *
+ * To stop publishing a UserTune, please use {@link #clearUserTune()} method. This will send a disabling publish signal. + *
+ * To add a UserTune listener in order to remain updated with other users UserTune, use {@link #addUserTuneListener(UserTuneListener)} method. + *
+ * To link a UserTuneElement with {@link Message}, use 'message.addExtension(userTuneElement)'. + *
+ * An example to illustrate is provided inside UserTuneElementTest inside the test package. + *
+ * @see + * XEP-0118: User Tune + */ +public final class UserTuneManager extends Manager { + + public static final String USERTUNE_NODE = "http://jabber.org/protocol/tune"; + public static final String USERTUNE_NOTIFY = USERTUNE_NODE + "+notify"; + + private static final Map INSTANCES = new WeakHashMap<>(); + + private static boolean ENABLE_USER_TUNE_NOTIFICATIONS_BY_DEFAULT = true; + + private final Set userTuneListeners = new CopyOnWriteArraySet<>(); + private final AsyncButOrdered asyncButOrdered = new AsyncButOrdered<>(); + private final ServiceDiscoveryManager serviceDiscoveryManager; + private final PepManager pepManager; + + public static synchronized UserTuneManager getInstanceFor(XMPPConnection connection) throws NotLoggedInException { + UserTuneManager manager = INSTANCES.get(connection); + if (manager == null) { + manager = new UserTuneManager(connection); + INSTANCES.put(connection, manager); + } + return manager; + } + + private UserTuneManager(XMPPConnection connection) throws NotLoggedInException { + super(connection); + pepManager = PepManager.getInstanceFor(connection); + pepManager.addPepListener(new PepListener() { + @Override + public void eventReceived(EntityBareJid from, EventElement event, Message message) { + if (!USERTUNE_NODE.equals(event.getEvent().getNode())) { + return; + } + + final BareJid contact = from.asBareJid(); + asyncButOrdered.performAsyncButOrdered(contact, () -> { + ItemsExtension itemsExtension = (ItemsExtension) event.getEvent(); + List items = itemsExtension.getExtensions(); + @SuppressWarnings("unchecked") + PayloadItem payload = (PayloadItem) items.get(0); + UserTuneElement tune = payload.getPayload(); + + for (UserTuneListener listener : userTuneListeners) { + listener.onUserTuneUpdated(contact, message, tune); + } + }); + } + }); + serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); + if (ENABLE_USER_TUNE_NOTIFICATIONS_BY_DEFAULT) { + enableUserTuneNotifications(); + } + } + + public static void setUserTuneNotificationsEnabledByDefault(boolean bool) { + ENABLE_USER_TUNE_NOTIFICATIONS_BY_DEFAULT = bool; + } + + public void enableUserTuneNotifications() { + serviceDiscoveryManager.addFeature(USERTUNE_NOTIFY); + } + + public void disableUserTuneNotifications() { + serviceDiscoveryManager.removeFeature(USERTUNE_NOTIFY); + } + + public void clearUserTune() throws NotLoggedInException, NotALeafNodeException, NoResponseException, NotConnectedException, XMPPErrorException, InterruptedException { + publishUserTune(UserTuneElement.EMPTY_USER_TUNE); + } + + public void publishUserTune(UserTuneElement userTuneElement) throws NotLoggedInException, NotALeafNodeException, NoResponseException, NotConnectedException, XMPPErrorException, InterruptedException { + // TODO: To prevent a large number of updates when a user is skipping through tracks, an implementation SHOULD wait several seconds before publishing new tune information. + pepManager.publish(USERTUNE_NODE, new PayloadItem<>(userTuneElement)); + } + + public boolean addUserTuneListener(UserTuneListener listener) { + return userTuneListeners.add(listener); + } + + public boolean removeUserTuneListener(UserTuneListener listener) { + return userTuneListeners.remove(listener); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/element/UserTuneElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/element/UserTuneElement.java new file mode 100644 index 000000000..47a7bfd40 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/element/UserTuneElement.java @@ -0,0 +1,266 @@ +/** + * + * Copyright 2019 Aditya Borikar. + * + * 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.usertune.element; + +import java.net.URI; + +import org.jivesoftware.smack.datatypes.UInt16; +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.EqualsUtil; +import org.jivesoftware.smack.util.HashCode; +import org.jivesoftware.smack.util.XmlStringBuilder; + +/** + * {@link ExtensionElement} that contains the UserTune.
+ * Instance of UserTuneElement can be created using {@link Builder#build()} + * method. + */ +public final class UserTuneElement implements ExtensionElement { + + public static final String NAMESPACE = "http://jabber.org/protocol/tune"; + public static final String ELEMENT = "tune"; + + private final String artist; + private final UInt16 length; + private final Integer rating; + private final String source; + private final String title; + private final String track; + private final URI uri; + + public static final UserTuneElement EMPTY_USER_TUNE = null; + + private UserTuneElement(Builder builder) { + this.artist = builder.artist; + this.length = builder.length; + this.rating = builder.rating; + this.source = builder.source; + this.title = builder.title; + this.track = builder.track; + this.uri = builder.uri; + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + public String getArtist() { + return artist; + } + + public UInt16 getLength() { + return length; + } + + public Integer getRating() { + return rating; + } + + public String getSource() { + return source; + } + + public String getTitle() { + return title; + } + + public String getTrack() { + return track; + } + + public URI getUri() { + return uri; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + XmlStringBuilder xml = new XmlStringBuilder(this); + if (isEmptyUserTune()) { + return xml.closeEmptyElement(); + } + xml.rightAngleBracket(); + xml.optElement("artist", artist); + xml.optElement("length", length); + xml.optElement("rating", rating); + xml.optElement("source", source); + xml.optElement("title", title); + xml.optElement("track", track); + xml.optElement("uri", uri); + return xml.closeElement(getElementName()); + } + + private boolean isEmptyUserTune() { + return this.equals(EMPTY_USER_TUNE); + } + + public static boolean hasUserTuneElement(Message message) { + return message.hasExtension(ELEMENT, NAMESPACE); + } + + public static UserTuneElement from(Message message) { + return message.getExtension(ELEMENT, NAMESPACE); + } + + @Override + public int hashCode() { + return HashCode.builder() + .append(artist) + .append(length) + .append(rating) + .append(source) + .append(title) + .append(track) + .append(uri).build(); + } + + @Override + public boolean equals(Object obj) { + return EqualsUtil + .equals(this, obj, (equalsBuilder, otherTune) -> equalsBuilder + .append(artist, otherTune.artist) + .append(length, otherTune.length) + .append(rating, otherTune.rating) + .append(source, otherTune.source) + .append(title, otherTune.title) + .append(track, otherTune.track) + .append(uri, otherTune.uri)); + } + + /** + * Returns a new instance of {@link Builder}. + * @return Builder + */ + public static Builder getBuilder() { + return new Builder(); + } + + /** + * This class defines a Builder class for {@link UserTuneElement}.
+ * {@link UserTuneElement} instance can be obtained using the {@link #build()} method as follows.
+ * UserTuneElement.Builder builder = new UserTuneElement.Builder(); + * builder.setSource("Yessongs"); builder.setTitle("Heart of the Sunrise"); + * UserTuneElement userTuneElement = builder.build();
+ * Values such as title, source, artist, length, source, track and uri can be set using their respective setters through {@link Builder} + */ + public static final class Builder { + private String artist; + private UInt16 length; + private Integer rating; + private String source; + private String title; + private String track; + private URI uri; + + private Builder() { + } + + /** + * Artist is an optional element in UserTuneElement. + * @param artist. + * @return builder. + */ + public Builder setArtist(String artist) { + this.artist = artist; + return this; + } + + /** + * Length is an optional element in UserTuneElement. + * @param length. + * @return builder. + */ + public Builder setLength(int length) { + return setLength(UInt16.from(length)); + } + + /** + * Length is an optional element in UserTuneElement. + * @param length. + * @return builder. + */ + public Builder setLength(UInt16 length) { + this.length = length; + return this; + } + + /** + * Rating is an optional element in UserTuneElement. + * @param rating. + * @return builder. + */ + public Builder setRating(int rating) { + this.rating = rating; + return this; + } + + /** + * Source is an optional element in UserTuneElement. + * @param source. + * @return builder. + */ + public Builder setSource(String source) { + this.source = source; + return this; + } + + /** + * Title is an optional element in UserTuneElement. + * @param title. + * @return builder. + */ + public Builder setTitle(String title) { + this.title = title; + return this; + } + + /** + * Track is an optional element in UserTuneElement. + * @param track. + * @return builder. + */ + public Builder setTrack(String track) { + this.track = track; + return this; + } + + /** + * URI is an optional element in UserTuneElement. + * @param uri. + * @return builder. + */ + public Builder setUri(URI uri) { + this.uri = uri; + return this; + } + + /** + * This method is called to build a UserTuneElement. + * @return UserTuneElement. + */ + public UserTuneElement build() { + return new UserTuneElement(this); + } + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/element/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/element/package-info.java new file mode 100644 index 000000000..06849e26a --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/element/package-info.java @@ -0,0 +1,21 @@ +/** + * + * Copyright 2019 Aditya Borikar + * + * 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. + */ + +/** + * Smack's API for XEP-0118: User Tune. + */ +package org.jivesoftware.smackx.usertune.element; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/package-info.java new file mode 100644 index 000000000..182ee237e --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/package-info.java @@ -0,0 +1,21 @@ +/** + * + * Copyright 2019 Aditya Borikar + * + * 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. + */ + +/** + * Smack's API for XEP-0118: User Tune. + */ +package org.jivesoftware.smackx.usertune; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/UserTuneProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/UserTuneProvider.java new file mode 100644 index 000000000..5b1c423ef --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/UserTuneProvider.java @@ -0,0 +1,89 @@ +/** + * + * Copyright 2019 Aditya Borikar. + * + * 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.usertune.provider; + +import java.io.IOException; +import java.net.URI; + +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.provider.ExtensionElementProvider; +import org.jivesoftware.smack.util.ParserUtils; +import org.jivesoftware.smack.xml.XmlPullParser; +import org.jivesoftware.smack.xml.XmlPullParserException; +import org.jivesoftware.smackx.usertune.element.UserTuneElement; + +/** + * This is the Provider Class for {@link UserTuneElement}. + */ +public class UserTuneProvider extends ExtensionElementProvider { + + public static final UserTuneProvider INSTANCE = new UserTuneProvider(); + + @Override + public UserTuneElement parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException { + + UserTuneElement.Builder builder = UserTuneElement.getBuilder(); + XmlPullParser.TagEvent tag = parser.nextTag(); + outerloop: while (true) { + switch (tag) { + case START_ELEMENT: + String name = parser.getName(); + String namespace = parser.getNamespace(); + if (!UserTuneElement.NAMESPACE.equals(namespace)) { + continue outerloop; + } + while (tag == XmlPullParser.TagEvent.START_ELEMENT) { + switch (name) { + case "artist": + builder.setArtist(parser.nextText()); + break; + case "length": + builder.setLength(ParserUtils.getIntegerFromNextText(parser)); + break; + case "rating": + builder.setRating(ParserUtils.getIntegerFromNextText(parser)); + break; + case "source": + builder.setSource(parser.nextText()); + break; + case "title": + builder.setTitle(parser.nextText()); + break; + case "track": + builder.setTrack(parser.nextText()); + break; + case "uri": + URI uri = ParserUtils.getUriFromNextText(parser); + builder.setUri(uri); + break; + } + tag = parser.nextTag(); + name = parser.getName(); + } + break; + case END_ELEMENT: + if (parser.getDepth() == initialDepth) { + break outerloop; + } + break; + } + } + return builder.build(); + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/package-info.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/package-info.java new file mode 100644 index 000000000..09bcf2adc --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/package-info.java @@ -0,0 +1,21 @@ +/** + * + * Copyright 2019 Aditya Borikar + * + * 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. + */ + +/** + * Smack's API for XEP-0118: User Tune. + */ +package org.jivesoftware.smackx.usertune.provider; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java index 28e126d7f..45c16f506 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2014 Florian Schmaus + * Copyright 2014-2019 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnectionRegistry; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.packet.id.StanzaIdUtil; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.vcardtemp.packet.VCard; @@ -105,7 +104,7 @@ public final class VCardManager extends Manager { vcard.setType(IQ.Type.set); // Also make sure to generate a new stanza id (the given vcard could be a vcard result), in which case we don't // want to use the same stanza id again (although it wouldn't break if we did) - vcard.setStanzaId(StanzaIdUtil.newStanzaId()); + vcard.setNewStanzaId(); connection().createStanzaCollectorAndSend(vcard).nextResultOrThrow(); } diff --git a/smack-extensions/src/main/resources/org.jivesoftware.smack.extensions/extensions.providers b/smack-extensions/src/main/resources/org.jivesoftware.smack.extensions/extensions.providers index a34d5435d..62adda545 100644 --- a/smack-extensions/src/main/resources/org.jivesoftware.smack.extensions/extensions.providers +++ b/smack-extensions/src/main/resources/org.jivesoftware.smack.extensions/extensions.providers @@ -589,4 +589,11 @@ org.jivesoftware.smackx.mood.provider.MoodProvider + + + tune + http://jabber.org/protocol/tune + org.jivesoftware.smackx.usertune.provider.UserTuneProvider + + diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneElementTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneElementTest.java new file mode 100644 index 000000000..9aea03774 --- /dev/null +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneElementTest.java @@ -0,0 +1,74 @@ +/** + * + * Copyright 2019 Aditya Borikar. + * + * 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.usertune; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.test.util.SmackTestSuite; +import org.jivesoftware.smack.test.util.SmackTestUtil; +import org.jivesoftware.smack.test.util.SmackTestUtil.XmlPullParserKind; +import org.jivesoftware.smack.xml.XmlPullParser; +import org.jivesoftware.smack.xml.XmlPullParserException; +import org.jivesoftware.smackx.usertune.element.UserTuneElement; +import org.jivesoftware.smackx.usertune.provider.UserTuneProvider; + +import org.junit.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +public class UserTuneElementTest extends SmackTestSuite { + + private final String xml = "" + + "Yes" + + "686" + + "8" + + "Yessongs" + + "Heart of the Sunrise" + + "3" + + "http://www.yesworld.com/lyrics/Fragile.html#9" + + ""; + + @Test + public void toXmlTest() throws IOException, XmlPullParserException, SmackParsingException, URISyntaxException { + + URI uri = new URI("http://www.yesworld.com/lyrics/Fragile.html#9"); + + UserTuneElement.Builder builder = UserTuneElement.getBuilder(); + UserTuneElement userTuneElement = builder.setArtist("Yes") + .setLength(686) + .setRating(8) + .setSource("Yessongs") + .setTitle("Heart of the Sunrise") + .setTrack("3") + .setUri(uri) + .build(); + assertXmlSimilar(xml, userTuneElement.toXML().toString()); + } + + @ParameterizedTest + @EnumSource(value = SmackTestUtil.XmlPullParserKind.class) + public void userTuneElementProviderTest(XmlPullParserKind parserKind) throws XmlPullParserException, IOException, SmackParsingException { + XmlPullParser parser = SmackTestUtil.getParserFor(xml, parserKind); + UserTuneElement parsed = UserTuneProvider.INSTANCE.parse(parser); + assertXmlSimilar(xml, parsed.toXML().toString()); + } +} diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java new file mode 100644 index 000000000..bb21fae84 --- /dev/null +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java @@ -0,0 +1,58 @@ +/** + * + * Copyright 2019 Aditya Borikar. + * + * 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.usertune; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNotNull; +import static junit.framework.TestCase.assertTrue; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.test.util.SmackTestSuite; +import org.jivesoftware.smackx.usertune.element.UserTuneElement; + +import org.junit.Test; + +public class UserTuneManagerTest extends SmackTestSuite{ + + @Test + public void addMessage() throws URISyntaxException { + + UserTuneElement.Builder builder = UserTuneElement.getBuilder(); + builder.setArtist("Yes"); + builder.setLength(686); + builder.setRating(8); + builder.setSource("Yessongs"); + builder.setTitle("Heart of the Sunrise"); + builder.setTrack("3"); + URI uri = new URI("http://www.yesworld.com/lyrics/Fragile.html#9"); + builder.setUri(uri); + UserTuneElement userTuneElement = builder.build(); + + Message message = new Message(); + message.addExtension(userTuneElement); + + assertTrue(message.hasExtension(UserTuneElement.ELEMENT, UserTuneElement.NAMESPACE)); + assertTrue(UserTuneElement.hasUserTuneElement(message)); + + UserTuneElement element = UserTuneElement.from(message); + assertNotNull(element); + assertEquals(userTuneElement, element); + } +} diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java index a7ac44581..f09832b25 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java @@ -67,7 +67,7 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest { EntityBareJid userTwo = conTwo.getUser().asEntityBareJid(); Message message = new Message(userTwo); - String messageId = message.setStanzaId(); + String messageId = message.ensureStanzaIdSet(); final String messageBody = "Test MAM message (" + testRunId + ')'; message.setBody(messageBody); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/UserTuneIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/UserTuneIntegrationTest.java new file mode 100644 index 000000000..86383a819 --- /dev/null +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/UserTuneIntegrationTest.java @@ -0,0 +1,89 @@ +/** + * + * Copyright 2019 Aditya Borikar. + * + * 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.usertune; + +import java.net.URI; + +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NotLoggedInException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smackx.usertune.element.UserTuneElement; + +import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; +import org.igniterealtime.smack.inttest.SmackIntegrationTest; +import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; +import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; +import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; +import org.junit.AfterClass; + +import org.jxmpp.jid.BareJid; + +public class UserTuneIntegrationTest extends AbstractSmackIntegrationTest { + + private final UserTuneManager utm1; + private final UserTuneManager utm2; + + public UserTuneIntegrationTest(SmackIntegrationTestEnvironment environment) throws NotLoggedInException { + super(environment); + utm1 = UserTuneManager.getInstanceFor(conOne); + utm2 = UserTuneManager.getInstanceFor(conTwo); + } + + @SmackIntegrationTest + public void test() throws Exception { + URI uri = new URI("http://www.yesworld.com/lyrics/Fragile.html#9"); + UserTuneElement.Builder builder = UserTuneElement.getBuilder(); + UserTuneElement userTuneElement1 = builder.setArtist("Yes") + .setLength(686) + .setRating(8) + .setSource("Yessongs") + .setTitle("Heart of the Sunrise") + .setTrack("3") + .setUri(uri) + .build(); + + IntegrationTestRosterUtil.ensureBothAccountsAreSubscribedToEachOther(conOne, conTwo, timeout); + + final SimpleResultSyncPoint userTuneReceived = new SimpleResultSyncPoint(); + + final UserTuneListener userTuneListener = new UserTuneListener() { + @Override + public void onUserTuneUpdated(BareJid jid, Message message, UserTuneElement userTuneElement) { + if (userTuneElement.equals(userTuneElement1)) { + userTuneReceived.signal(); + } + } + }; + + utm2.addUserTuneListener(userTuneListener); + + try { + utm1.publishUserTune(userTuneElement1); + userTuneReceived.waitForResult(timeout); + } finally { + utm2.removeUserTuneListener(userTuneListener); + } + } + + @AfterClass + public void unsubscribe() + throws SmackException.NotLoggedInException, XMPPException.XMPPErrorException, + SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { + IntegrationTestRosterUtil.ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); + } +} diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/package-info.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/package-info.java new file mode 100644 index 000000000..b4fb83a44 --- /dev/null +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/package-info.java @@ -0,0 +1,17 @@ +/** + * + * Copyright 2019 Aditya Borikar. + * + * 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.usertune; diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/RTPBridge.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/RTPBridge.java index 04668e6ba..bee715507 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/RTPBridge.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/RTPBridge.java @@ -40,6 +40,10 @@ import org.jivesoftware.smack.xml.XmlPullParserException; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; +import org.jxmpp.jid.DomainBareJid; +import org.jxmpp.jid.impl.JidCreate; +import org.jxmpp.stringprep.XmppStringprepException; + /** * RTPBridge IQ Stanza used to request and retrieve a RTPBridge Candidates that can be used for a Jingle Media Transmission between two parties that are behind NAT. * This Jingle Bridge has all the needed information to establish a full UDP Channel (Send and Receive) between two parties. @@ -397,7 +401,6 @@ public class RTPBridge extends IQ { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - @SuppressWarnings("deprecation") public static RTPBridge getRTPBridge(XMPPConnection connection, String sessionID) throws NotConnectedException, InterruptedException { if (!connection.isConnected()) { @@ -405,7 +408,13 @@ public class RTPBridge extends IQ { } RTPBridge rtpPacket = new RTPBridge(sessionID); - rtpPacket.setTo(RTPBridge.NAME + "." + connection.getXMPPServiceDomain()); + DomainBareJid jid; + try { + jid = JidCreate.domainBareFrom(RTPBridge.NAME + "." + connection.getXMPPServiceDomain()); + } catch (XmppStringprepException e) { + throw new AssertionError(e); + } + rtpPacket.setTo(jid); StanzaCollector collector = connection.createStanzaCollectorAndSend(rtpPacket); @@ -469,7 +478,6 @@ public class RTPBridge extends IQ { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - @SuppressWarnings("deprecation") public static RTPBridge relaySession(XMPPConnection connection, String sessionID, String pass, TransportCandidate proxyCandidate, TransportCandidate localCandidate) throws NotConnectedException, InterruptedException { if (!connection.isConnected()) { @@ -477,7 +485,13 @@ public class RTPBridge extends IQ { } RTPBridge rtpPacket = new RTPBridge(sessionID, RTPBridge.BridgeAction.change); - rtpPacket.setTo(RTPBridge.NAME + "." + connection.getXMPPServiceDomain()); + DomainBareJid jid; + try { + jid = JidCreate.domainBareFrom(RTPBridge.NAME + "." + connection.getXMPPServiceDomain()); + } catch (XmppStringprepException e) { + throw new AssertionError(e); + } + rtpPacket.setTo(jid); rtpPacket.setType(Type.set); rtpPacket.setPass(pass); @@ -506,7 +520,6 @@ public class RTPBridge extends IQ { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - @SuppressWarnings("deprecation") public static String getPublicIP(XMPPConnection xmppConnection) throws NotConnectedException, InterruptedException { if (!xmppConnection.isConnected()) { @@ -514,7 +527,13 @@ public class RTPBridge extends IQ { } RTPBridge rtpPacket = new RTPBridge(RTPBridge.BridgeAction.publicip); - rtpPacket.setTo(RTPBridge.NAME + "." + xmppConnection.getXMPPServiceDomain()); + DomainBareJid jid; + try { + jid = JidCreate.domainBareFrom(RTPBridge.NAME + "." + xmppConnection.getXMPPServiceDomain()); + } catch (XmppStringprepException e) { + throw new AssertionError(e); + } + rtpPacket.setTo(jid); rtpPacket.setType(Type.set); // LOGGER.debug("Relayed to: " + candidate.getIp() + ":" + candidate.getPort()); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUN.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUN.java index cd32d7381..ec1080f47 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUN.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUN.java @@ -37,6 +37,10 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverItems; +import org.jxmpp.jid.DomainBareJid; +import org.jxmpp.jid.impl.JidCreate; +import org.jxmpp.stringprep.XmppStringprepException; + /** * STUN IQ Stanza used to request and retrieve a STUN server and port to make p2p connections easier. STUN is usually used by Jingle Media Transmission between two parties that are behind NAT. * @@ -177,7 +181,6 @@ public class STUN extends SimpleIQ { * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ - @SuppressWarnings("deprecation") public static STUN getSTUNServer(XMPPConnection connection) throws NotConnectedException, InterruptedException { if (!connection.isConnected()) { @@ -185,7 +188,13 @@ public class STUN extends SimpleIQ { } STUN stunPacket = new STUN(); - stunPacket.setTo(DOMAIN + "." + connection.getXMPPServiceDomain()); + DomainBareJid jid; + try { + jid = JidCreate.domainBareFrom(DOMAIN + "." + connection.getXMPPServiceDomain()); + } catch (XmppStringprepException e) { + throw new AssertionError(e); + } + stunPacket.setTo(jid); StanzaCollector collector = connection.createStanzaCollectorAndSend(stunPacket);